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,13 +1,13 @@
1
1
  module Hecks
2
2
  module Bluebook
3
3
  module MetaValidator
4
- # What the language says about ITSELF, read back as something walkable.
4
+ # What the language says about itself, read back as something walkable.
5
5
  #
6
6
  # The judge used to carry one hand-written branch per category, and the
7
7
  # reason given for keeping it that way was that "which append command
8
8
  # belongs to which list is not derivable from a name". True — and beside
9
9
  # the point. It is derivable from the language's own IR, because every
10
- # append command DECLARES its target:
10
+ # append command declares its target:
11
11
  #
12
12
  # command "Argument" do
13
13
  # reference_to Command
@@ -18,7 +18,7 @@ module Hecks
18
18
  # appender for the `arguments` list, and the map binds each value-object
19
19
  # field to the command argument that fills it. Nothing is matched by name.
20
20
  #
21
- # The same reading recovers the containment tree. A command with NO
21
+ # The same reading recovers the containment tree. A command with no
22
22
  # self-reference is the creating one, and the `*_id` argument it carries
23
23
  # names the parent — so Bluebook -> Aggregate -> Command / ValueObject /
24
24
  # Query / Entity, ValueObject -> Member, ProcessManager -> Handler ->
@@ -57,7 +57,7 @@ module Hecks
57
57
  *alternates.map(&:verb), *sealers].compact
58
58
  end
59
59
 
60
- # DOES THIS ARGUMENT CARRY AN ID? A reference is the id of a head, and
60
+ # Does this argument carry an ID? A reference is the id of a head, and
61
61
  # an id is a scalar — so the judge offers it bare, where every other
62
62
  # field goes as a one-field value object. The language answers this
63
63
  # about itself, so declaring a new reference needs no change here.
@@ -84,33 +84,33 @@ module Hecks
84
84
 
85
85
  @categories[aggregate.hecks_name] = read(aggregate)
86
86
 
87
- # S17, ADR 0026 — Member/Handler/Dispatch are ENTITIES now
87
+ # S17, ADR 0026 — Member/Handler/Dispatch are entities now
88
88
  # (`entity "Member" do ... end`, nested under `ValueObject`/
89
89
  # `ProcessManager`/`Handler`), not their own top-level
90
90
  # aggregates — so `meta.aggregates` alone no longer finds
91
91
  # them the way it always found a standalone `aggregate
92
- # "Member"`. Each STILL needs its own named category here:
92
+ # "Member"`. Each still needs its own named category here:
93
93
  # `Assembly::Contracts` keeps a bespoke entry for each
94
94
  # (Member's own open-map `pairs`, Dispatch's own open-map
95
95
  # `with_spec`), distinct from the single generic "Entity"
96
- # category every ORDINARY real-corpus entity (LedgerEntry,
96
+ # category every ordinary real-corpus entity (LedgerEntry,
97
97
  # Withdrawal, ...) is described through instead. Safe to
98
- # walk EVERY meta-domain aggregate's own `.entities`
99
- # unconditionally — `Plan` only ever reads the META-
100
- # DOMAIN'S OWN self-description (`Plan.for(MetaValidator.
98
+ # walk every meta-domain aggregate's own `.entities`
99
+ # unconditionally — `Plan` only ever reads the meta-
100
+ # domain's own self-description (`Plan.for(MetaValidator.
101
101
  # grammar_registry)`), which never declares a generic,
102
- # nameless entity of its own the way a REAL domain's
102
+ # nameless entity of its own the way a real domain's
103
103
  # `LedgerEntry` is; the only entities the meta-domain
104
104
  # itself ever declares are exactly the three this ADR
105
- # names. `entity_owned: true` records WHY this is a
105
+ # names. `entity_owned: true` records why this is a
106
106
  # category at all — the real runtime has no top-level
107
- # aggregate named "Member" to dispatch a BARE verb into
108
- # any more, so the judge has to build a DOTTED one instead
107
+ # aggregate named "Member" to dispatch a bare verb into
108
+ # any more, so the judge has to build a dotted one instead
109
109
  # (see `Judge#verb_for`).
110
110
  #
111
- # RECURSES — `Dispatch` nests inside `Handler`, which nests
111
+ # Recurses — `Dispatch` nests inside `Handler`, which nests
112
112
  # inside `ProcessManager`, two levels deep, not one. Each
113
- # nested entity's own `parent` names the DIRECT owner it was
113
+ # nested entity's own `parent` names the direct owner it was
114
114
  # actually found under (Dispatch's is "Handler", not
115
115
  # "ProcessManager") — `read`'s own `owner:` argument already
116
116
  # takes whichever name is passed, so walking one level deeper
@@ -125,10 +125,10 @@ module Hecks
125
125
  def names = @categories.keys
126
126
 
127
127
  # Every verb the language declares, spelled as the judge would
128
- # dispatch it. S17, ADR 0026 — an ENTITY-OWNED category (its
128
+ # dispatch it. S17, ADR 0026 — an entity-owned category (its
129
129
  # own `entity_owned` flag) has no real top-level aggregate the
130
- # runtime can route a BARE verb into any more, so it is
131
- # spelled DOTTED here too — `Bluebook::ValueObject.Member.
130
+ # runtime can route a bare verb into any more, so it is
131
+ # spelled dotted here too — `Bluebook::ValueObject.Member.
132
132
  # Declare`, `Bluebook::ProcessManager.Handler.Dispatch.Bind` —
133
133
  # matching `Judge#verb_for`/`#dotted_prefix`'s own build
134
134
  # exactly (recursing the same way, for the same reason: an
@@ -147,8 +147,8 @@ module Hecks
147
147
  # found entity's own `.entities` in turn — S17, ADR 0026's
148
148
  # two-level chain (`Dispatch`, inside `Handler`, inside
149
149
  # `ProcessManager`). `owner` is passed down explicitly rather
150
- # than re-derived, because it names whichever construct THIS
151
- # call actually found the entity under — the DIRECT parent, not
150
+ # than re-derived, because it names whichever construct this
151
+ # call actually found the entity under — the direct parent, not
152
152
  # the root.
153
153
  def add_nested_entities(owner)
154
154
  owner.entities.each do |entity|
@@ -159,9 +159,9 @@ module Hecks
159
159
  end
160
160
  end
161
161
 
162
- # THE FULL DOTTED PREFIX a category's own verbs hang off —
162
+ # The full dotted prefix a category's own verbs hang off —
163
163
  # mirrors `Judge#dotted_prefix` exactly (S17, ADR 0026): the
164
- # plain name for an ordinary category, or its PARENT's own
164
+ # plain name for an ordinary category, or its parent's own
165
165
  # prefix with this category's name appended, for an entity-
166
166
  # owned one, recursing because the parent may itself be
167
167
  # entity-owned.
@@ -172,28 +172,28 @@ module Hecks
172
172
  "#{dotted_prefix(found.parent)}.#{name}"
173
173
  end
174
174
 
175
- # `owner:`/`entity_owned:` — S17, ADR 0026. An AGGREGATE-level
175
+ # `owner:`/`entity_owned:` — S17, ADR 0026. An aggregate-level
176
176
  # creating command carries its own parent as a `reference_to`
177
177
  # argument (read via `parent_reference_of` below), the same
178
- # way it always has. An ENTITY-level one never does — `entity
178
+ # way it always has. An entity-level one never does — `entity
179
179
  # "Member" do ... end`'s own creating command reaches its
180
- # parent through the DOTTED CALL itself (`ValueObject.Member.
180
+ # parent through the dotted call itself (`ValueObject.Member.
181
181
  # Declare`), the same reason an ordinary entity's own commands
182
182
  # never declare `reference_to` either (entity.md's own
183
- # reference page states this). So the OWNING aggregate's name
183
+ # reference page states this). So the owning aggregate's name
184
184
  # is passed in directly here, by the caller who already knows
185
185
  # it (the same `.entities` walk that found this node), rather
186
186
  # than derived from an argument that was never going to be
187
187
  # there.
188
188
  def read(aggregate, owner: nil, entity_owned: false)
189
- # An ENTITY-OWNED category has no creating command of its own to find.
189
+ # An entity-owned category has no creating command of its own to find.
190
190
  # `creating_command` tests `command.references.nil?` — the same test
191
- # a REAL entity's own commands pass too, since `entity "Member" do
191
+ # a real entity's own commands pass too, since `entity "Member" do
192
192
  # command "Pair" ... end end` never writes `reference_to` (an
193
193
  # entity's commands never do — banking's own LedgerEntry.Amend
194
194
  # doesn't either). Calling it here would have it seize on Member's
195
- # own "Pair" and call THAT the creating command, which it is not:
196
- # a Member is created by `ValueObject.Member`, its OWNER's own bare
195
+ # own "Pair" and call that the creating command, which it is not:
196
+ # a Member is created by `ValueObject.Member`, its owner's own bare
197
197
  # append command, the same way a real LedgerEntry is created by
198
198
  # `Account.LogEntry`, never by a dotted verb of its own.
199
199
  declare = entity_owned ? nil : declaration_command(aggregate)
@@ -211,11 +211,11 @@ module Hecks
211
211
  alternates: alternates_in(rest),
212
212
  setters: setters_in(rest),
213
213
  sealers: sealers_in(rest),
214
- # EVERY command, not `rest` — the creating command carries the parent
214
+ # Every command, not `rest` — the creating command carries the parent
215
215
  # link, which is the most common reference of all.
216
216
  references: references_in(aggregate.commands),
217
- # HOW THE CATEGORY NAMES ITS RECORDS, read from the language rather
218
- # than restated. The judge has to know a record's id BEFORE it
217
+ # How the category names its records, read from the language rather
218
+ # than restated. The judge has to know a record's id before it
219
219
  # dispatches, because the children it walks next carry it as their
220
220
  # parent — so it derives the same join the runtime will, off the same
221
221
  # declaration. It used to be a branch per category, and a branch that
@@ -261,7 +261,7 @@ module Hecks
261
261
  aggregate.attributes.find(&:reference?)
262
262
  end
263
263
 
264
- # What the creating command sets directly. EVERY reference
264
+ # What the creating command sets directly. Every reference
265
265
  # argument is dropped, not just the parent link: a reference is
266
266
  # not a field. Command.Declare carries `entity_id` as well as
267
267
  # the parent `aggregate` reference, because an entity declares
@@ -279,7 +279,7 @@ module Hecks
279
279
  Array(command.mutations).each do |mutation|
280
280
  next unless mutation.op == :append
281
281
 
282
- # FIRST wins, not last. Two commands can append to the same list —
282
+ # First wins, not last. Two commands can append to the same list —
283
283
  # Aggregate.Attribute and Aggregate.Reference both extend `attributes`,
284
284
  # because a reference's type is not a value object and cannot go
285
285
  # through the same verb. Overwriting would have let the one declared
@@ -290,7 +290,7 @@ module Hecks
290
290
  end
291
291
  end
292
292
 
293
- # The appenders DISPLACED by first-wins — Aggregate.Reference behind
293
+ # The appenders displaced by first-wins — Aggregate.Reference behind
294
294
  # Aggregate.Attribute. The walk reaches them by reading the row, not the
295
295
  # plan, but they are still verbs the language declares and the coverage
296
296
  # gate has to see them.
@@ -311,7 +311,7 @@ module Hecks
311
311
  end
312
312
  end
313
313
 
314
- # Commands that SET rather than append. Lifecycle sets two targets at once,
314
+ # Commands that set rather than append. Lifecycle sets two targets at once,
315
315
  # so a setter is keyed by its verb and carries every target it writes.
316
316
  def setters_in(commands)
317
317
  commands.filter_map do |command|
@@ -324,7 +324,7 @@ module Hecks
324
324
  end
325
325
  end
326
326
 
327
- # Commands that change nothing — they exist to be REFUSED. Aggregate.Seal is
327
+ # Commands that change nothing — they exist to be refused. Aggregate.Seal is
328
328
  # the whole-document check: dispatched once everything is declared, carrying
329
329
  # only givens. A category with no sealer simply has no such rule.
330
330
  def sealers_in(commands)
@@ -3,7 +3,7 @@ module Hecks
3
3
  module MetaValidator
4
4
  # Offers a built .port to the language that describes ports.
5
5
  #
6
- # A port is a SIBLING of a bluebook, the same shape WorldJudge already
6
+ # A port is a sibling of a bluebook, the same shape WorldJudge already
7
7
  # is one level over — its own file, its own door, judged through its
8
8
  # own self-hosted language (port.bluebook) rather than left as a plain
9
9
  # Ruby struct nothing checks. Whole-project table-unification survey,
@@ -34,7 +34,7 @@ module Hecks
34
34
  end
35
35
 
36
36
  def send_to(verb, label, **payload)
37
- offer(label) { @runtime.dispatch(verb, **args(payload)) }
37
+ offer(label) { @runtime.dispatch_flat(verb, args(payload)) }
38
38
  end
39
39
 
40
40
  def judge!
@@ -6,10 +6,10 @@ module Hecks
6
6
  # The language now spells its fields exactly as the IR spells them, so the
7
7
  # judge reads almost everything straight through: `command.givens`,
8
8
  # `value_object.invariants`, `read_model.aggregate_heads`. What remains here
9
- # is not naming drift — it is places where the IR's SHAPE differs from the
9
+ # is not naming drift — it is places where the IR's shape differs from the
10
10
  # language's, and no amount of renaming would close that:
11
11
  #
12
- # transitions one declaration expands to SEVERAL rows, because `from`
12
+ # transitions one declaration expands to several rows, because `from`
13
13
  # may be a list of states
14
14
  # value_objects the IR holds objects ; the language holds their names
15
15
  # normalisations not on the bluebook at all — they come from the canonical
@@ -18,11 +18,11 @@ module Hecks
18
18
  # lifecycle one IR object feeding two separate fields
19
19
  #
20
20
  # Everything in this file is a difference in shape. If something here is
21
- # only a difference in NAME, it is in the wrong file: rename the language.
21
+ # only a difference in name, it is in the wrong file: rename the language.
22
22
  module Readings
23
23
  # A list the walk is about to offer, as rows it can shape into dispatches.
24
24
  #
25
- # FROM THE TABLE. This was nine hand-written cases keyed "Category.list", and
25
+ # From the table. This was nine hand-written cases keyed "Category.list", and
26
26
  # every one of them was a fact `Assembly::Contracts` is the right place to
27
27
  # keep: which shaper turns this list into rows. A list with no shaper reads
28
28
  # straight off the node, which is most of them.
@@ -34,17 +34,17 @@ module Hecks
34
34
  end
35
35
 
36
36
  # A where-clause is read through its own to_h, which is where the IR spells a
37
- # symbol argument as ":ceiling". Reading the OBJECT instead lost the colon,
37
+ # symbol argument as ":ceiling". Reading the object instead lost the colon,
38
38
  # and nothing downstream could tell an argument from a literal of the same
39
39
  # name.
40
40
  def where_rows(node) = Array(node.wheres).map(&:to_h)
41
41
 
42
- # The language holds a value object's NAME here ; the IR holds the object.
42
+ # The language holds a value object's name here ; the IR holds the object.
43
43
  def value_object_names(node) = node.value_objects.map { |shape| { name: shape.hecks_name } }
44
44
 
45
- # AN IDENTITY IS A LIST OF PARTS, so it is offered one part at a time — the
45
+ # An identity is a list of parts, so it is offered one part at a time — the
46
46
  # same way attributes and transitions are. The IR holds the paths ; the
47
- # language holds a row per path, and the ORDER between them is the whole
47
+ # language holds a row per path, and the order between them is the whole
48
48
  # meaning, because the identity is their join.
49
49
  def identity_rows(node) = node.identity_paths.map { |path| { value: path } }
50
50
 
@@ -53,10 +53,10 @@ module Hecks
53
53
  # argument became indistinguishable from one carrying a literal string.
54
54
  def with_spec_rows(node) = pair_rows(node.to_h[:with_spec])
55
55
 
56
- # THE SAME READ, ONE LEVEL IN — `compensates` folds `DispatchSpec`
56
+ # The same read, one level in — `compensates` folds `DispatchSpec`
57
57
  # into the language's own `compensates_command_name`/
58
58
  # `compensates_with_spec` (`Assembly::Contracts`' own comment on
59
- # "Dispatch"), so its OWN with_spec pairs live nested one hash
59
+ # "Dispatch"), so its own with_spec pairs live nested one hash
60
60
  # down from where `with_spec_rows` looks. `&.dig(...)` — no
61
61
  # compensation at all is not an error, it is `pair_rows(nil)`, empty.
62
62
  def compensates_with_spec_rows(node) = pair_rows(node.to_h[:compensates]&.dig(:with_spec))
@@ -70,7 +70,7 @@ module Hecks
70
70
  def normalisation_table(_node) = normalisation_rows
71
71
 
72
72
  # `lifecycle :status do transition "Retire" => "retired", from: ["issued", "active"] end`
73
- # is ONE declaration and TWO transitions. Offering it once would leave the
73
+ # is one declaration and two transitions. Offering it once would leave the
74
74
  # second unjudged, which is the whole failure this judge exists to avoid.
75
75
  def transition_rows(node)
76
76
  lifecycle = node.respond_to?(:lifecycle) ? node.lifecycle : nil
@@ -84,17 +84,17 @@ module Hecks
84
84
  end
85
85
  end
86
86
 
87
- # An OPEN MAP — a member's fields, a dispatch's argument bindings — has no
87
+ # An open map — a member's fields, a dispatch's argument bindings — has no
88
88
  # value object that can hold it, so each entry becomes its own row. This is
89
89
  # why Member and Dispatch are roots in the language rather than lists.
90
90
  def pair_rows(map)
91
91
  Array(map&.to_h).map { |key, value| { key: key, value: value } }
92
92
  end
93
93
 
94
- # EVERY SPECIFICATION OPTION AN ASK CARRIES, flattened to rows.
94
+ # Every specification option an ask carries, flattened to rows.
95
95
  #
96
96
  # `offset`, `cursor`, `nulls`, `authorize` and `inspect_query` are
97
- # five options, one compound (authorize names a policy AND a
97
+ # five options, one compound (authorize names a policy and a
98
98
  # tenant). `extra_options_to_h` already spells every one of them
99
99
  # and drops the absent ones, so this reads that rather than
100
100
  # naming them here — a sixth option needs no change on either
@@ -103,18 +103,18 @@ module Hecks
103
103
  # `filters: true` adds a read model's wheres, order_by and limit —
104
104
  # `at` tells repeated rows apart, so two wheres do not collapse.
105
105
  #
106
- # THE LANGUAGE MAY HOLD MORE THAN `to_h` CARRIES, and this is where that
106
+ # The language may hold more than `to_h` carries, and this is where that
107
107
  # mattered. Until 2026-08-11, `ReadModel#to_h` omitted all three —
108
108
  # `extra_options_to_h` rejects them by name, still does — so a read
109
109
  # model's filtering had never been in the wire contract, and I first
110
110
  # read that as a wall: if the wire cannot carry it, the language cannot
111
111
  # hold it, and a graph assembled from the language must lose it.
112
112
  #
113
- # That was the wrong conclusion. `to_h` is a PROJECTION ; the language
114
- # is the SOURCE. They have to agree about everything
113
+ # That was the wrong conclusion. `to_h` is a projection ; the language
114
+ # is the source. They have to agree about everything
115
115
  # to_h spells, not about everything the language knows. Held as option
116
116
  # rows, the filters survived the round trip regardless of whether the
117
- # wire carried them too — which is exactly why, when a LATER task
117
+ # wire carried them too — which is exactly why, when a later task
118
118
  # (Rust read-model codegen) needed `wheres`/`order_by`/`limit` on the
119
119
  # wire for an unrelated reason, `ReadModel#to_h` could be extended to
120
120
  # spell them (the same mechanism `Query#to_h` already used) without
@@ -153,8 +153,8 @@ module Hecks
153
153
  end
154
154
  end
155
155
 
156
- # A mutation is ONE declaration, but the language's Change holds a single
157
- # field/kind/source triple — and an append binds SEVERAL fields at once
156
+ # A mutation is one declaration, but the language's Change holds a single
157
+ # field/kind/source triple — and an append binds several fields at once
158
158
  # (`append: { name: :name, amount: :amount }`). So an append is offered
159
159
  # once per binding, and each one is judged.
160
160
  #
@@ -164,7 +164,7 @@ module Hecks
164
164
  def mutation_rows(node)
165
165
  Array(node.mutations).flat_map do |mutation|
166
166
  # `:delegate`/`:corrects` (CommandBuilder#delegates_to's and
167
- # #corrects_impl's own comments) ride the SAME multi-binding
167
+ # #corrects_impl's own comments) ride the same multi-binding
168
168
  # shape `:append` does — `with: {...}`/the assembled
169
169
  # `as:`/`reason:`/`reverses:` hash is a field map, same as
170
170
  # append's own `fields:`.
@@ -174,7 +174,7 @@ module Hecks
174
174
  # Spelled the way Mutation#appended_fields spells it, because
175
175
  # Assembly::Marks reads this row back through the same reader it
176
176
  # reads that field with. `then_set :marks, append: { direction:
177
- # "out" }` binds a LITERAL, and storing it raw made it
177
+ # "out" }` binds a literal, and storing it raw made it
178
178
  # indistinguishable from an argument called out.
179
179
  { target: mutation.target, op: mutation.op, field: field,
180
180
  kind: argument.is_a?(Symbol) ? "argument" : "literal",
@@ -215,7 +215,7 @@ module Hecks
215
215
  []
216
216
  end
217
217
 
218
- # What the BLUEBOOK calls a node, whichever kind of thing the node is.
218
+ # What the bluebook calls a node, whichever kind of thing the node is.
219
219
  #
220
220
  # This used to sniff — `respond_to?(:hecks_name) ? … : node.name` — because
221
221
  # only value objects had crossed over. Every construct answers now, so
@@ -225,7 +225,7 @@ module Hecks
225
225
 
226
226
  # One field of a Declare payload. Mostly a reader of the same name — the
227
227
  # exceptions are fields the IR keeps somewhere else, or not at all.
228
- # READ FROM THE TABLE, not from a branch per category.
228
+ # Read from the table, not from a branch per category.
229
229
  #
230
230
  # These were eight hand-written cases — `Entity.owner`, `Member.shape`, two
231
231
  # lifecycle members twice over, and three of a query's — each one restating
@@ -237,7 +237,7 @@ module Hecks
237
237
  return declared_name(node) if field == :name
238
238
 
239
239
  contract = Assembly.contract(category)
240
- # A setter names its target as a STRING and a Declare field arrives a Symbol,
240
+ # A setter names its target as a string and a Declare field arrives a Symbol,
241
241
  # so the lookup keys on a Symbol either way. The case statement this replaced
242
242
  # was type-blind because it interpolated ; a Hash is not.
243
243
  named = field.to_sym
@@ -246,19 +246,19 @@ module Hecks
246
246
  object, member = contract.folded(named)
247
247
  return through(node, object, member) if member
248
248
 
249
- # `limit` is a language field AND an object in the IR — `Array(an_object)`
249
+ # `limit` is a language field and an object in the IR — `Array(an_object)`
250
250
  # wraps rather than destructures, so offering it stored
251
251
  # "#<struct LimitSpec value=3>".
252
252
  return node.limit&.to_h&.fetch(:value, nil) if "#{category}.#{field}" == "Query.limit"
253
253
 
254
- # `provenance from: {...}` is a HASH offered into a text field, and
254
+ # `provenance from: {...}` is a hash offered into a text field, and
255
255
  # handing it over raw let the runtime's own coercion spell it — which
256
256
  # meant Ruby's `Hash#to_s`, whose spelling changed under us between
257
257
  # 3.3 and 3.4. Encoded here, the same way `default:` already is and the
258
258
  # same way Shapes#provenance reads it back.
259
259
  return encode_literal(node.provenance) if field == :provenance
260
260
 
261
- # `identified_by` is no longer a FIELD of any declaration — it is a list,
261
+ # `identified_by` is no longer a field of any declaration — it is a list,
262
262
  # filled by Identify one part at a time, so it is read through `identity_rows`
263
263
  # like every other list rather than special-cased here. What this branch
264
264
  # existed to protect is now structural : a path cannot come back as its head,
@@ -268,7 +268,7 @@ module Hecks
268
268
  end
269
269
 
270
270
  # One member of the object a field folds into. `to_h` first, because the
271
- # member names are the ones the IR SPELLS — a Lifecycle's `default`, an
271
+ # member names are the ones the IR spells — a Lifecycle's `default`, an
272
272
  # OrderBy's `direction` — and reading the object raw is how a colon or a type
273
273
  # goes missing.
274
274
  def through(node, object, member)
@@ -279,7 +279,7 @@ module Hecks
279
279
  end
280
280
 
281
281
  # What a setting command writes. A setter whose source is absent is not
282
- # dispatched at all — ABSENT is not EMPTY, and offering "" would turn every
282
+ # dispatched at all — absent is not empty, and offering "" would turn every
283
283
  # "if you declare it, declare something" rule into "you must declare it".
284
284
  def setter_value(category, node, target)
285
285
  # `rows` folds into `closed_set` and `members` between them, with no single
@@ -292,7 +292,7 @@ module Hecks
292
292
  node.respond_to?(target) ? node.public_send(target) : nil
293
293
  end
294
294
 
295
- # Only a DECLARED closed set has a row count. An empty one is the defect,
295
+ # Only a declared closed set has a row count. An empty one is the defect,
296
296
  # so `rows` must stay absent rather than arrive as zero.
297
297
  def closed_set_size(node)
298
298
  return nil unless node.respond_to?(:closed_set?) && node.closed_set?
@@ -300,7 +300,7 @@ module Hecks
300
300
  Array(node.members).size
301
301
  end
302
302
 
303
- # `Reference<Customer>` is an IR ENCODING, not a domain fact. The fact is
303
+ # `Reference<Customer>` is an IR encoding, not a domain fact. The fact is
304
304
  # that the attribute points at Customer's head — so the language is offered
305
305
  # that head's ID, and resolution does the rest. Encoding and decoding both
306
306
  # live here, because this is where the IR's shape differs from the
@@ -308,24 +308,24 @@ module Hecks
308
308
  def points_at(row, aggregate_id)
309
309
  return nil unless row.reference?
310
310
 
311
- # THE CHAPTER THIS HEAD IS IN, AND THE HEAD IT POINTS AT — which is exactly
311
+ # The chapter this head is in, and the head it points at — which is exactly
312
312
  # how an aggregate is identified, so it is built the same way rather than
313
- # spelled again with a separator of its own. This is dispatched as a REAL
314
- # REFERENCE VALUE (`Aggregate.Reference`'s `points_at:`), resolved by
315
- # `repository.find` against the target Aggregate-within-Meta record's OWN
316
- # stored id — so it MUST equal what that record's identity actually
313
+ # spelled again with a separator of its own. This is dispatched as a real
314
+ # reference value (`Aggregate.Reference`'s `points_at:`), resolved by
315
+ # `repository.find` against the target Aggregate-within-Meta record's own
316
+ # stored id — so it must equal what that record's identity actually
317
317
  # derives, not a wire-format spelling. `reference_type`, below, is the
318
318
  # separate later reader that un-derives it back into "Reference<X>".
319
319
  Naming.identity([aggregate_id.split(Naming::IDENTITY_JOIN).first, row.type.target_name])
320
320
  end
321
321
 
322
- # A LITERAL, written so it can be read back exactly.
322
+ # A literal, written so it can be read back exactly.
323
323
  #
324
324
  # The language holds a default and a literal mutation source as text, and
325
325
  # `to_s` threw the type away: 0.0 came back "0.0", and `{ value: "good" }`
326
326
  # came back its inspect string with nowhere to say it had been a hash. The
327
327
  # language already stores code as text — `canonical: "cents >= 0"` — so an
328
- # encoding is in keeping; it simply has to be SELF-DESCRIBING. That rule is
328
+ # encoding is in keeping; it simply has to be self-describing. That rule is
329
329
  # now Hecks::Literal's, stated once and shared with every other
330
330
  # to_h-bound literal field ; Shapes#decode_literal reads it back.
331
331
  #
@@ -334,23 +334,23 @@ module Hecks
334
334
  def encode_literal(value) = value.nil? ? nil : Literal.render(value)
335
335
 
336
336
  # The way back out: an aggregate id becomes the type the IR spells. The
337
- # id is a JOIN of chapter + name (Naming::IDENTITY_JOIN, the same join
337
+ # id is a join of chapter + name (Naming::IDENTITY_JOIN, the same join
338
338
  # `points_at` built it with, not the "::" a real bluebook's own type
339
339
  # names never carry) ; the wire format wants only the bare name.
340
340
  def reference_type(points_at_id) = "Reference<#{points_at_id.to_s.split(Naming::IDENTITY_JOIN).last}>"
341
341
 
342
342
  # One value out of a row, named by the value object's field.
343
343
  def row_value(row, field)
344
- # A Hash FIRST. Hash answers to `key` (Hash#key(value)) and to `value` on
344
+ # A Hash first. Hash answers to `key` (Hash#key(value)) and to `value` on
345
345
  # some rows, so asking respond_to? before checking for a Hash reads a
346
346
  # member pair through entirely the wrong method.
347
347
  return row[field] if row.is_a?(Hash)
348
348
  return row.public_send(field) if row.respond_to?(field)
349
- # A Struct answers to [] but RAISES for a member it does not have, so it
349
+ # A Struct answers to [] but raises for a member it does not have, so it
350
350
  # is read through to_h — a field the row simply lacks reads as absent.
351
351
  return row.to_h[field] if row.respond_to?(:to_h) && !row.is_a?(String)
352
352
 
353
- # A bare scalar row — `emits` is a list of event NAMES, and the
353
+ # A bare scalar row — `emits` is a list of event names, and the
354
354
  # Announcement value object has to call that string something.
355
355
  row
356
356
  end