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
@@ -3,8 +3,8 @@ require_relative "../ir"
3
3
 
4
4
  module Hecks
5
5
  module Bluebook
6
- # `compensates` — a SECOND `DispatchSpec`, shape-identical to this
7
- # one, naming the command that undoes THIS dispatch specifically
6
+ # `compensates` — a second `DispatchSpec`, shape-identical to this
7
+ # one, naming the command that undoes this dispatch specifically
8
8
  # (see `ProcessManagerBuilder::HandlerBuilder#dispatch_impl`'s own
9
9
  # comment). `nil` for a dispatch with nothing to undo (a pure
10
10
  # bookkeeping mark, or one whose own effect is superseded by a later
@@ -14,7 +14,7 @@ module Hecks
14
14
  # used" bar would refuse a second level speculatively.
15
15
  DispatchSpec = Struct.new(:command_name, :with_spec, :compensates, keyword_init: true) do
16
16
  # A Struct already answers to_h; including the mixin puts the
17
- # DECLARED emission ahead of Struct's own in the ancestry, which
17
+ # declared emission ahead of Struct's own in the ancestry, which
18
18
  # is what makes the shape data rather than a method body.
19
19
  include Hecks::IR
20
20
 
@@ -39,32 +39,32 @@ module Hecks
39
39
 
40
40
  # The compensation half of a procedure, as its own thing.
41
41
  #
42
- # A PROCESS MANAGER coordinates: legs, states, an opinion about who goes
43
- # next. A SAGA undoes: what makes the world good again when a leg it
42
+ # A process manager coordinates: legs, states, an opinion about who goes
43
+ # next. A saga undoes: what makes the world good again when a leg it
44
44
  # dispatched is refused. Two concepts, and the industry slurs them into one
45
45
  # word — so here they are two objects, and a procedure either has a saga or
46
46
  # does not.
47
47
  #
48
48
  # `undoes` is the ordered list of commands the compensation sends — a
49
- # STATIC PREVIEW, declaration order (`Behaviour::ProcessManager#saga`),
49
+ # static preview, declaration order (`Behaviour::ProcessManager#saga`),
50
50
  # not one instance's own runtime history. Per-dispatch compensation
51
51
  # (`compensates`, on the step it compensates for) moved most of what
52
52
  # a saga undoes off this leg's own hand-written body and onto
53
53
  # whichever forward dispatch each one undoes — this reads every
54
- # declared `compensates` across the WHOLE saga first, then whatever
54
+ # declared `compensates` across the whole saga first, then whatever
55
55
  # this leg's own hand-written body still lists, for compensation
56
- # that isn't expressible as "undo command X." WHICH of a declared
56
+ # that isn't expressible as "undo command X." which of a declared
57
57
  # `compensates` actually fires for one instance, and in what order
58
58
  # (newest-first, completed-legs-only), is `SagaInterpreter`'s own
59
59
  # dynamic `completed_compensations` — a per-instance runtime fact
60
60
  # this declaration-only object could never hold.
61
61
  #
62
- # NAMING COLLISION, ONCE FLAGGED, NOW RESOLVED — `command`'s own
62
+ # **Naming collision, once flagged, now resolved** — `command`'s own
63
63
  # `corrects event, reverses: true` (docs/implemented/decisions/0036-
64
64
  # corrects-is-an-appended-fact-not-a-rewrite.md) already claimed
65
- # `reverses` for a different meaning: auto-deriving a command's OWN
66
- # corrective mutation from a past EVENT, not a saga's own
67
- # compensating leg from a past DISPATCH. This feature keeps
65
+ # `reverses` for a different meaning: auto-deriving a command's own
66
+ # corrective mutation from a past event, not a saga's own
67
+ # compensating leg from a past dispatch. This feature keeps
68
68
  # `reverses` reserved for `corrects` and uses `compensates` for
69
69
  # per-dispatch saga compensation instead — a deliberate choice, not
70
70
  # an accidental collision.
@@ -78,10 +78,10 @@ module Hecks
78
78
  # produced by `DSL::ProcessManagerBuilder` — its start/end events,
79
79
  # correlation field, derived states, and handler rows. Its
80
80
  # compensation half (`saga`, `Behaviour::ProcessManager#saga`) is
81
- # DERIVED from the handler answering `REFUSED`, below, not declared as
81
+ # derived from the handler answering `REFUSED`, below, not declared as
82
82
  # its own construct.
83
83
  class ProcessManager
84
- # The BLUEBOOK's name for this construct, asked the same way of a class
84
+ # The bluebook's name for this construct, asked the same way of a class
85
85
  # that has crossed over and of an IR object that has not. Collapses into
86
86
  # Construct when this one crosses.
87
87
  # The trigger of a compensating leg. Not an event name — no aggregate
@@ -86,15 +86,15 @@ module Hecks
86
86
  end
87
87
  end
88
88
 
89
- # THE ACTUAL "more than one tenant" MOMENT — Runtime::TenantCheck's
89
+ # The actual "more than one tenant" moment — Runtime::TenantCheck's
90
90
  # own header names this table as the one place real multitenancy
91
- # happens: the SAME on-disk directory (one domain, one
92
- # `persisted_by` binding) registering a SECOND time, under a
93
- # different realm, into this SAME shared route table. A directory's
94
- # FIRST registration is never refused here — nothing shares its
91
+ # happens: the same on-disk directory (one domain, one
92
+ # `persisted_by` binding) registering a second time, under a
93
+ # different realm, into this same shared route table. A directory's
94
+ # first registration is never refused here — nothing shares its
95
95
  # data yet, so a plain single-tenant deployment on an ordinary
96
96
  # adapter (Postgres, no schema story) still boots exactly as
97
- # before. Only the SECOND (and any later) registration of that
97
+ # before. Only the second (and any later) registration of that
98
98
  # same directory is refused, and refused before this call adds its
99
99
  # routes to the table — so a leaking tenant's requests never
100
100
  # become reachable through `Router#resolve` in the first place.
@@ -8,14 +8,14 @@ module Hecks
8
8
  module Bluebook
9
9
  def self.render_value(value) = Literal.render(value)
10
10
 
11
- # A query — an ASK, declared on an aggregate or on one of its entities.
11
+ # A query — an ask, declared on an aggregate or on one of its entities.
12
12
  #
13
- # It crosses over as an INSTANCE rather than a class, and the reason is worth
13
+ # It crosses over as an instance rather than a class, and the reason is worth
14
14
  # stating because it is the boundary of the pattern. A query inherits its
15
15
  # whole body from `QuerySpecification::Common::Options` — `wheres`,
16
16
  # `order_by`, `limit`, `offset`, `cursor`,
17
17
  # `authorization`, `null_semantics`, `inspection` — and those
18
- # are INSTANCE methods that the runtime and the SQLite adapter both read.
18
+ # are instance methods that the runtime and the SQLite adapter both read.
19
19
  # Hoisting the declaration onto a metaclass would put the identity and the
20
20
  # specification on opposite sides of the object.
21
21
  #
@@ -54,7 +54,7 @@ module Hecks
54
54
  @attributes = attributes
55
55
  end
56
56
 
57
- # A query's shape is NOT fixed — `extra_options_to_h` carries
57
+ # A query's shape is not fixed — `extra_options_to_h` carries
58
58
  # whatever options the specification layer grew (count, median,
59
59
  # group_by, scope_to). Declared emission covers the settled part
60
60
  # and `super` hands it over; the tail stays dynamic, which is the
@@ -4,11 +4,11 @@ module Hecks
4
4
  module Bluebook
5
5
  # A read model — an ask that gathers heads from more than one aggregate.
6
6
  #
7
- # Like a query it crosses over as an INSTANCE, and for the same reason: its
7
+ # Like a query it crosses over as an instance, and for the same reason: its
8
8
  # body is inherited from `QuerySpecification::ReadModel::Specification`, whose
9
9
  # readers the runtime and the SQLite adapter both call on the object. It gains
10
10
  # an identity and an owner ; it keeps the name it always had, because only a
11
- # CLASS ever had a competing answer for `name`.
11
+ # class ever had a competing answer for `name`.
12
12
  class ReadModel < QuerySpecification::ReadModel::Specification
13
13
  include Construct
14
14
 
@@ -29,7 +29,7 @@ module Hecks
29
29
  attr_reader :name, :description, :reference_name, :reference_target, :aggregate_heads, :group_by,
30
30
  :count, :median_field
31
31
 
32
- # `reference_name:`/`reference_target:` are nil for a ROOTLESS read
32
+ # `reference_name:`/`reference_target:` are nil for a rootless read
33
33
  # model (no `reference_to` declared) — `&.` throughout, rather than
34
34
  # the `.to_s`/`.to_sym` this used to require unconditionally, so
35
35
  # `reference_target.nil?` stays a real, checkable fact for the
@@ -47,11 +47,11 @@ module Hecks
47
47
  # `group_by_fields` is the convenience reader everything but
48
48
  # `to_h`/the Judge's own generic walk actually wants.
49
49
  @group_by = group_by
50
- # ABSENT IS NOT FALSE. `@count` stays nil rather than becoming
50
+ # **Absent is not false**. `@count` stays nil rather than becoming
51
51
  # `false` when undeclared — the same "if you declare it, declare
52
52
  # something" reading `Lifecycle`'s own optional fields rely on
53
53
  # (MetaValidator::Judge#setters skips a setter whose every
54
- # source is `nil`, so an ALWAYS-false `@count` would dispatch
54
+ # source is `nil`, so an always-false `@count` would dispatch
55
55
  # `ReadModel.Count` on every read model that never wrote the
56
56
  # word at all). `!!count` collapses a truthy DSL `true` (or a
57
57
  # reconstructed `true`) to the same `true`/`nil` pair either path
@@ -60,15 +60,15 @@ module Hecks
60
60
  @median_field = median_field&.to_sym
61
61
  end
62
62
 
63
- # `.to_sym` regardless of source — the DIRECT builder path stores
63
+ # `.to_sym` regardless of source — the direct builder path stores
64
64
  # symbols, but `Reconstruction::Shapes#group_by_field` (the
65
- # replayed-from-the-meta-domain path every REAL boot actually
65
+ # replayed-from-the-meta-domain path every real boot actually
66
66
  # goes through) reads the field back as a String, the same way
67
- # `aggregate_heads`' own `:as` does. Row hash KEYS built by
67
+ # `aggregate_heads`' own `:as` does. Row hash keys built by
68
68
  # `Value.materialize_unwrapped` are symbols (`attr.name`), so
69
69
  # this has to be too, or `row[field]` in `nest` silently misses.
70
70
 
71
- # `wheres`/`order_by`/`limit` are spelled explicitly here, the SAME
71
+ # `wheres`/`order_by`/`limit` are spelled explicitly here, the same
72
72
  # mechanism `Query#to_h` already uses (query.rb, read directly
73
73
  # before this was written) — always present, `wheres` a (possibly
74
74
  # empty) array and `order_by`/`limit` nil when undeclared, exactly
@@ -78,16 +78,16 @@ module Hecks
78
78
  # than a reader needing to learn a second one. See this file's own
79
79
  # `filtered_head_name` and language/bluebook/syntax.bluebook's
80
80
  # `ReadModel` `where`/`order_by`/`limit` member rows for the history
81
- # of why this WAS narrower, and 2026-08-11's read-model where/
81
+ # of why this was narrower, and 2026-08-11's read-model where/
82
82
  # order_by/limit task for why it stopped being.
83
83
  # Same dynamic tail as a Query's, plus two collections whose
84
- # ROWS are plain hashes rather than constructs — they are
84
+ # rows are plain hashes rather than constructs — they are
85
85
  # normalised here rather than by `many`, which recurses through
86
86
  # `to_h` and would have nothing to call.
87
- # `count`/`median_field` are ABSENT (no key at all), not `nil`,
87
+ # `count`/`median_field` are absent (no key at all), not `nil`,
88
88
  # when undeclared — unlike `group_by` (always a `[]`, never
89
- # missing) they are the FIRST fields this construct has ever
90
- # added that no OLDER real corpus member could possibly carry, so
89
+ # missing) they are the first fields this construct has ever
90
+ # added that no older real corpus member could possibly carry, so
91
91
  # merging them unconditionally would have put a `null` onto every
92
92
  # existing read model's own wire shape (banking's
93
93
  # `ComplianceDashboard`/`CustomerPortfolio`, the language's own
@@ -2,15 +2,15 @@ module Hecks
2
2
  module Bluebook
3
3
  # An attribute that points at another aggregate's head.
4
4
  #
5
- # This used to be the STRING `"Reference<Customer>"`, minted by
5
+ # This used to be the string `"Reference<Customer>"`, minted by
6
6
  # `AggregateBuilder#reference_to` and `CommandBuilder#cross_reference` from
7
7
  # a real constant that had just been handed in, and then parsed back apart
8
8
  # by a regex in the command interpreter, by string equality in the read-model
9
9
  # interpreter and the SQLite adapter, and by `delete_prefix` in the bluebook
10
10
  # builder. Five readers of a spelling one writer invented.
11
11
  #
12
- # It holds the TARGET instead, and answers `resolve` with the target's
13
- # Aggregate. Resolution is LAZY and deliberately so: `reference_to
12
+ # It holds the target instead, and answers `resolve` with the target's
13
+ # Aggregate. Resolution is lazy and deliberately so: `reference_to
14
14
  # Customer` may name an aggregate declared lower in the file — banking's
15
15
  # Account points at Customer and survives only because Customer happens to
16
16
  # be written above — so the edge cannot be resolved at declaration time.
@@ -34,7 +34,7 @@ module Hecks
34
34
  end
35
35
 
36
36
  # The Aggregate this points at, or nil when the target belongs to
37
- # ANOTHER domain — a cross-domain target may legitimately not be loaded,
37
+ # another domain — a cross-domain target may legitimately not be loaded,
38
38
  # the same reading `across` policies get.
39
39
  def resolve
40
40
  unless declared_in
@@ -51,13 +51,13 @@ module Hecks
51
51
  def to_s = "Reference<#{@target_name}>"
52
52
  def inspect = "#<Reference #{@target_name}>"
53
53
 
54
- # VALUE EQUALITY, not identity — without this, two references to
55
- # the SAME target, parsed from two SEPARATE bluebook reads (era
54
+ # Value equality, not identity — without this, two references to
55
+ # the same target, parsed from two separate bluebook reads (era
56
56
  # N's own boot and a held era's own shadow reconstruction,
57
57
  # coverage_check.rb's own comparison), are different objects and
58
58
  # compare unequal by Ruby's default `==`. `EraGuard::ShapeDiff
59
59
  # #diff_type`'s `held_type != current_type` check then reads as
60
- # true for EVERY reference_to attribute on EVERY mint, regardless
60
+ # true for every reference_to attribute on every mint, regardless
61
61
  # of whether the reference actually changed — a real refusal for
62
62
  # attributes nothing about. `declared_in` (which aggregate carries
63
63
  # this reference) is deliberately excluded: the same reference
@@ -65,7 +65,7 @@ module Hecks
65
65
  # from separately-parsed bluebooks with structurally different
66
66
  # (if same-shaped) owning aggregates, and `declared_in` is a
67
67
  # cross-reference for `resolve`, not part of what this attribute
68
- # itself IS.
68
+ # itself is.
69
69
  def ==(other) = other.is_a?(Reference) && target_name == other.target_name
70
70
  alias eql? ==
71
71
  def hash = [self.class, target_name].hash
@@ -4,10 +4,10 @@ require "fileutils"
4
4
 
5
5
  module Hecks
6
6
  module Bluebook
7
- # BOOTS A REAL BLUEBOOK AND ACTUALLY DISPATCHES AGAINST IT — the
7
+ # Boots a real bluebook and actually dispatches against it — the
8
8
  # sibling `bin/model_check` never had: that tool proves a bluebook
9
- # is STRUCTURALLY sound (no dead states, no unreachable transitions)
10
- # without ever running a single command; this proves it WORKS,
9
+ # is structurally sound (no dead states, no unreachable transitions)
10
+ # without ever running a single command; this proves it works,
11
11
  # catching exactly the class of bug static analysis structurally
12
12
  # cannot see. Built and proved inside `bin/interview`'s own `smoke`
13
13
  # command, where it first found two real bugs — a lifecycle field
@@ -15,20 +15,20 @@ module Hecks
15
15
  # missing `Command.ActsOn` — that reloaded clean, checked clean,
16
16
  # and only broke once something actually dispatched against them.
17
17
  #
18
- # SYNTHESIZED ARGS, NEVER RANDOM (`Synthesizer`) — a String becomes
18
+ # Synthesized args, never random (`Synthesizer`) — a String becomes
19
19
  # a fixed marker, a closed set uses its own first admitted member, a
20
20
  # reference reuses whatever this same run already minted for that
21
- # target. ONE call per declared command, ONE call per declared
21
+ # target. One call per declared command, one call per declared
22
22
  # report, per created root; every failure is collected and reported
23
23
  # together rather than stopping at the first.
24
24
  #
25
- # WHAT THIS CANNOT CATCH: a call that dispatches cleanly but answers
26
- # WRONG — the read-model join bug this exact tool's own first user
25
+ # **What this cannot catch**: a call that dispatches cleanly but answers
26
+ # wrong — the read-model join bug this exact tool's own first user
27
27
  # hit is the textbook case, a query that silently returned an empty
28
28
  # array rather than raising. Smoke-testing proves nothing crashes;
29
29
  # it does not prove the answer is the right one.
30
30
  #
31
- # A FAILURE HERE IS NOT NECESSARILY A DOMAIN BUG, either — it may
31
+ # A failure here is not necessarily a domain bug, either — it may
32
32
  # just be `Synthesizer`'s own naive values (0, an empty list,
33
33
  # "smoke-test") not satisfying a real invariant this simple
34
34
  # generator was never built to reason about (a positive amount, a
@@ -54,11 +54,11 @@ module Hecks
54
54
  # per-domain realm resolution requires and a plain boot never
55
55
  # did. Reports are reachable the identical way regardless of
56
56
  # boot path — `dispatcher.query("Domain.report_name", **args)`
57
- # is the SAME `Dispatcher#query` either boot hands back; Router
58
- # was never actually required for this, only its OWN namespace
59
- # SUGAR (`Domain.report_name(...)` as a bare method call) was.
57
+ # is the same `Dispatcher#query` either boot hands back; Router
58
+ # was never actually required for this, only its own namespace
59
+ # sugar (`Domain.report_name(...)` as a bare method call) was.
60
60
  #
61
- # NEVER BOOTS `dir`'S OWN REAL BINDINGS — measured, not a
61
+ # Never boots `dir`'s own real bindings — measured, not a
62
62
  # precaution taken on spec: pointed at `examples/pizzas` (a real,
63
63
  # persistent store carrying real accumulated records), a
64
64
  # synthesized `CreatePizza` collided with an actual pre-existing
@@ -73,7 +73,7 @@ module Hecks
73
73
  # `install_facade: false` — this only ever dispatches by FQN string
74
74
  # (below), so it never needs the `Widget::Item.Add(...)` Ruby
75
75
  # sugar `Hecks.boot` installs by default. Skipping it matters
76
- # here specifically: that sugar lands as a BARE global constant on
76
+ # here specifically: that sugar lands as a bare global constant on
77
77
  # `Object` per domain and per aggregate name, with no scoping and
78
78
  # no cleanup — and this tool boots throwaway domains under
79
79
  # whatever generic names the caller's `.bluebook` happens to use
@@ -93,9 +93,9 @@ module Hecks
93
93
  end
94
94
  end
95
95
 
96
- # ONLY THE `.bluebook`, NEVER `.world` EITHER — a real world's own
96
+ # Only the `.bluebook`, never `.world` either — a real world's own
97
97
  # settings (`persisted_by("Heki") { dir "..." }`) are keyed to the
98
- # REAL adapter it names, not to Memory; copied verbatim, they
98
+ # real adapter it names, not to Memory; copied verbatim, they
99
99
  # apply to the wrong binding and refuse with a `WiringError`
100
100
  # ("Memory does not declare :dir") — measured, not assumed, the
101
101
  # first time this ran against Banking. A plain `Hecks.boot`
@@ -112,8 +112,8 @@ module Hecks
112
112
  Dir.glob(File.join(source, "*.bluebook")).each { |file| FileUtils.cp(file, target) }
113
113
  end
114
114
 
115
- # AGGREGATES WALKED IN DECLARATION ORDER, on purpose — so whatever
116
- # a LATER aggregate's own shape needs from an EARLIER one (a
115
+ # Aggregates walked in declaration order, on purpose — so whatever
116
+ # a later aggregate's own shape needs from an earlier one (a
117
117
  # `TripItem` needing a real `PackingItem`, say) already exists by
118
118
  # the time that aggregate's own turn comes, the same reason
119
119
  # `Synthesizer#args_for`'s `created` map is threaded through in
@@ -136,7 +136,7 @@ module Hecks
136
136
  creating.each do |command|
137
137
  args = Synthesizer.args_for(chapter, aggregate, command, created)
138
138
  begin
139
- result = dispatcher.dispatch("#{domain}::#{aggregate.name}.#{command.hecks_name}", **args)
139
+ result = dispatcher.dispatch_flat("#{domain}::#{aggregate.name}.#{command.hecks_name}", args)
140
140
  created[aggregate.name] = result.instance.id
141
141
  rescue StandardError => e
142
142
  failures << Failure.new(domain: domain, aggregate: aggregate.name, command: command.hecks_name,
@@ -146,7 +146,7 @@ module Hecks
146
146
 
147
147
  noncreating.each do |nc_command|
148
148
  nc_args = Synthesizer.args_for(chapter, aggregate, nc_command, created).merge(id: created[aggregate.name])
149
- dispatcher.dispatch("#{domain}::#{aggregate.name}.#{nc_command.hecks_name}", **nc_args)
149
+ dispatcher.dispatch_flat("#{domain}::#{aggregate.name}.#{nc_command.hecks_name}", nc_args)
150
150
  rescue StandardError => e
151
151
  failures << Failure.new(domain: domain, aggregate: aggregate.name, command: nc_command.hecks_name,
152
152
  error: "#{e.class}: #{e.message}")
@@ -1,12 +1,12 @@
1
1
  module Hecks
2
2
  module Bluebook
3
- # ONE SYNTHESIZED ARGUMENT PER DECLARED ATTRIBUTE — never a random
3
+ # **One synthesized argument per declared attribute** — never a random
4
4
  # guess. Reads only real `IR` (`Aggregate`, `Command`,
5
- # `Attribute`, `ValueObject`), so it works against ANY
5
+ # `Attribute`, `ValueObject`), so it works against any
6
6
  # loaded bluebook, not one particular domain: a String becomes a
7
- # fixed marker; an Integer becomes 0; a closed set uses ITS OWN
7
+ # fixed marker; an Integer becomes 0; a closed set uses its own
8
8
  # first admitted member (never a value a real `one_of` would
9
- # legitimately refuse); a reference uses whatever id the CALLER
9
+ # legitimately refuse); a reference uses whatever id the caller
10
10
  # already knows for that target (`created`), so a command whose
11
11
  # own shape depends on an earlier-created record — a `TripItem`
12
12
  # needing a real `PackingItem`, say — gets something real to work
@@ -16,8 +16,8 @@ module Hecks
16
16
  # got built and proved — the logic never actually knew anything
17
17
  # about the Interview domain or any one app; it only ever read IR.
18
18
  module Synthesizer
19
- # THE ONLY TYPE NAMES THAT ARE EVER TRULY SCALAR — anything else
20
- # a value object's own field names is ANOTHER value object,
19
+ # The only type names that are ever truly scalar — anything else
20
+ # a value object's own field names is another value object,
21
21
  # nested (`Pizza.price_cents: Price`, itself wrapping `cents:
22
22
  # Integer` — a real, ordinary shape, not an edge case). Missing
23
23
  # this the first time round meant a nested field silently
@@ -26,7 +26,7 @@ module Hecks
26
26
  # only by testing against Pizzas instead of re-testing against
27
27
  # the one simpler domain this was first built for, where every
28
28
  # value object happened to be single-field and primitive-typed.
29
- # THE SAME LIST `Attribute::PRIMITIVES` holds, referenced rather
29
+ # The same list `Attribute::PRIMITIVES` holds, referenced rather
30
30
  # than repeated. It was a second, byte-identical copy — and only
31
31
  # the Attribute one is held to `vocabulary.bluebook` by
32
32
  # spec/vocabulary_conformance_spec, so this copy could drift from
@@ -38,7 +38,7 @@ module Hecks
38
38
  # `chapter`/`aggregate` are the real `Bluebook`/`Aggregate`
39
39
  # the command belongs to — needed to resolve a value object type
40
40
  # name back to its own declared shape. `created` maps an
41
- # aggregate NAME to a real id already minted for it earlier in
41
+ # aggregate name to a real id already minted for it earlier in
42
42
  # the same run; a reference whose target isn't in there yet gets
43
43
  # a placeholder instead of failing outright, since the caller may
44
44
  # not care about that particular argument's real value.
@@ -52,13 +52,13 @@ module Hecks
52
52
  end
53
53
  end
54
54
 
55
- # A value object's OWN synthesized value — its first admitted
55
+ # A value object's own synthesized value — its first admitted
56
56
  # member if it's a closed set (the one value guaranteed not to be
57
57
  # refused), otherwise one synthesized scalar per declared field.
58
58
  # Falls back to searching every aggregate in the chapter, the
59
59
  # same tolerance `bin/interview shape`'s own lookup already
60
60
  # needed: a value object referenced by name doesn't have to be
61
- # declared on the SAME aggregate using it.
61
+ # declared on the same aggregate using it.
62
62
  def value_for(chapter, aggregate, type_name)
63
63
  value_object = aggregate.value_object(type_name) ||
64
64
  chapter.aggregates.filter_map { |a| a.value_object(type_name) }.first
@@ -72,7 +72,7 @@ module Hecks
72
72
 
73
73
  # A single field's own synthesized value — a plain scalar if its
74
74
  # type is one of the true primitives, otherwise that type names
75
- # ANOTHER value object, resolved the identical way `value_for`
75
+ # another value object, resolved the identical way `value_for`
76
76
  # resolves any other one (its own closed set or its own nested
77
77
  # fields, however deep that nesting actually goes).
78
78
  def field_value_for(chapter, aggregate, type_name)
@@ -80,7 +80,7 @@ module Hecks
80
80
  end
81
81
 
82
82
  # A bare primitive's own synthesized value. Never used for a
83
- # closed set's OWN field (that's `value_for`'s job, reading the
83
+ # closed set's own field (that's `value_for`'s job, reading the
84
84
  # set's real first member) — only for a plain scalar field with
85
85
  # no declared vocabulary to respect.
86
86
  def scalar_for(primitive)
@@ -5,7 +5,7 @@ module Hecks
5
5
  # Paths are dotted ("price.cents") for a VO member, bare otherwise.
6
6
  TranslationMove = Struct.new(:from, :to)
7
7
 
8
- # One field whose VALUE, not just its name or position, changed —
8
+ # One field whose value, not just its name or position, changed —
9
9
  # an old value has nothing in common with a new one, so the only
10
10
  # honest way to bridge it is a declared, exhaustive lookup table.
11
11
  # Paths follow `TranslationMove`'s convention (dotted reaches a VO
@@ -16,7 +16,7 @@ module Hecks
16
16
  # rubocop:disable-next Lint/StructNewOverride
17
17
  TranslationConvert = Struct.new(:from, :to, :values)
18
18
 
19
- # A value object's or entity's own TYPE NAME changed with its member
19
+ # A value object's or entity's own type name changed with its member
20
20
  # structure unchanged — the one drift `rename`/`move` cannot express,
21
21
  # because the attribute kept its name and only the type it points at
22
22
  # was renamed. Mirrors `was:` one level deeper.
@@ -29,7 +29,7 @@ module Hecks
29
29
  # every other adapter.
30
30
  TranslationCompute = Struct.new(:from, :to, :sql)
31
31
 
32
- # The aggregate's own IDENTITY changed what it's computed from — not
32
+ # The aggregate's own identity changed what it's computed from — not
33
33
  # a field crossing a boundary (that's `move`), a value objects's type
34
34
  # name (`retype`), or a value transform (`compute`): the record's own
35
35
  # key. No `from:`/`to:` path, unlike every other rule here, because
@@ -41,7 +41,7 @@ module Hecks
41
41
  TranslationRekey = Struct.new(:sql)
42
42
 
43
43
  # A newly added, required attribute with no source in old data at
44
- # all — not a rename, move, or convert, all of which need a FROM
44
+ # all — not a rename, move, or convert, all of which need a from
45
45
  # path in the old shape. `default` is the value an existing record
46
46
  # reads until the next command against it writes a real one; unlike
47
47
  # `compute`, this is adapter-agnostic — applied in-process by
@@ -5,7 +5,7 @@ module Hecks
5
5
  module Bluebook
6
6
  Invariant = Struct.new(:description, :canonical, :predicate, :ast, keyword_init: true)
7
7
 
8
- # A value object — a DECLARATION HOLDER, never instantiated.
8
+ # A value object — a declaration holder, never instantiated.
9
9
  #
10
10
  # `ValueObjectBuilder` returns an anonymous subclass whose singleton
11
11
  # carries the declaration : attributes, invariants, members. Nothing ever
@@ -16,11 +16,11 @@ module Hecks
16
16
  #
17
17
  # `to_h` does not move. It is a byte-for-byte contract pinned by the
18
18
  # golden fixtures, so it keeps spelling the short declared name, which
19
- # is what `hecks_name` carries. DECLARATIONS IN THE GRAPH, STRINGS IN THE
20
- # EXPORT.
19
+ # is what `hecks_name` carries. Declarations in the graph, strings in the
20
+ # export.
21
21
  class ValueObject
22
22
  extend Construct
23
- # EXTENDED, not included — this construct is a class, so its
23
+ # Extended, not included — this construct is a class, so its
24
24
  # emission is a class method. See Hecks::IR's own note on
25
25
  # the two shapes.
26
26
  extend Hecks::IR
@@ -29,7 +29,7 @@ module Hecks
29
29
  emits_ir(
30
30
  name: :hecks_name,
31
31
  attributes: many(:attributes),
32
- # `ast:` — a JSON-serializable rendering of the SAME predicate
32
+ # `ast:` — a JSON-serializable rendering of the same predicate
33
33
  # `canonical` already spells as text, alongside it rather than
34
34
  # replacing it (`canonical` stays the human-facing/doctest-facing
35
35
  # form; parsing it back would just re-derive what `ast` already
@@ -39,7 +39,7 @@ module Hecks
39
39
  # has no kernel crate to parse `canonical` with.
40
40
  invariants: -> { invariants.map { |rule| Expression::AstJson.rule_row(rule) } },
41
41
  closed_set: :closed_set?,
42
- # THE FIELD NAME IS STRINGIFIED, NEVER THE VALUE. A `member` row can
42
+ # The field name is stringified, never the value. A `member` row can
43
43
  # hold any of the scalar types an attribute declares — `Integer 84`
44
44
  # (`StatementFrequency#retention_months`, statements.bluebook), not
45
45
  # only `String` — and `value.to_s` used to erase that on the way
@@ -13,7 +13,7 @@
13
13
  # the meta-validator that its builders call at build time.
14
14
 
15
15
  module Hecks
16
- # Declared as a CLASS, not a module — `Hecks::Bluebook` IS a
16
+ # Declared as a class, not a module — `Hecks::Bluebook` is a
17
17
  # chapter (bluebook/chapter.rb carries its body). Everything a chapter
18
18
  # declares nests under it, as do the ways to build one (`DSL`) and to
19
19
  # judge one (`MetaValidator`). Reopening this anywhere must say `class`.
@@ -29,7 +29,7 @@ require_relative "literal"
29
29
  require_relative "query_specification"
30
30
 
31
31
  require_relative "bluebook/expression"
32
- # THE MODEL ITSELF — the chapter class's own body first, then everything
32
+ # **The model itself** — the chapter class's own body first, then everything
33
33
  # a chapter declares. Order matters only for reading: each is a bag of
34
34
  # declarations with no load-time cross-references.
35
35
  require_relative "bluebook/chapter"