hecks 1.2.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 (358) 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 +60 -2
  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/postgres_era.adapter +5 -0
  23. data/lib/hecks/adapters/driven/prism.rb +4 -4
  24. data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
  25. data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
  26. data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
  27. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
  28. data/lib/hecks/adapters/driven/sqlite.rb +181 -21
  29. data/lib/hecks/adapters/driven.rb +4 -4
  30. data/lib/hecks/adapters/driving/github_webhook.rb +145 -0
  31. data/lib/hecks/behaviors/dsl.rb +2 -2
  32. data/lib/hecks/behaviors/expectations.rb +51 -23
  33. data/lib/hecks/behaviors/ir.rb +1 -1
  34. data/lib/hecks/behaviors/rspec.rb +1 -1
  35. data/lib/hecks/behaviors/runner.rb +2 -2
  36. data/lib/hecks/behaviors.rb +1 -1
  37. data/lib/hecks/bluebook/aggregate.rb +13 -13
  38. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +10 -10
  39. data/lib/hecks/bluebook/assembly/build.rb +1 -1
  40. data/lib/hecks/bluebook/assembly/contract.rb +39 -16
  41. data/lib/hecks/bluebook/assembly/contracts.rb +40 -38
  42. data/lib/hecks/bluebook/assembly/marks.rb +18 -18
  43. data/lib/hecks/bluebook/assembly/specializer.rb +19 -21
  44. data/lib/hecks/bluebook/assembly.rb +9 -9
  45. data/lib/hecks/bluebook/attribute.rb +9 -9
  46. data/lib/hecks/bluebook/behaviour/aggregate.rb +11 -11
  47. data/lib/hecks/bluebook/behaviour/attribute.rb +5 -5
  48. data/lib/hecks/bluebook/behaviour/chapter.rb +23 -5
  49. data/lib/hecks/bluebook/behaviour/command.rb +23 -23
  50. data/lib/hecks/bluebook/behaviour/domain_port.rb +27 -3
  51. data/lib/hecks/bluebook/behaviour/entity.rb +8 -8
  52. data/lib/hecks/bluebook/behaviour/hexagon.rb +4 -4
  53. data/lib/hecks/bluebook/behaviour/lifecycle.rb +5 -5
  54. data/lib/hecks/bluebook/behaviour/policy.rb +12 -12
  55. data/lib/hecks/bluebook/behaviour/process_manager.rb +7 -7
  56. data/lib/hecks/bluebook/behaviour/query.rb +1 -1
  57. data/lib/hecks/bluebook/behaviour/read_model.rb +8 -8
  58. data/lib/hecks/bluebook/behaviour/traits.rb +12 -12
  59. data/lib/hecks/bluebook/behaviour/value_object.rb +6 -6
  60. data/lib/hecks/bluebook/capabilities.rb +27 -0
  61. data/lib/hecks/bluebook/chapter.rb +28 -9
  62. data/lib/hecks/bluebook/command.rb +12 -12
  63. data/lib/hecks/bluebook/domain_port.rb +9 -9
  64. data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
  65. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
  66. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +96 -96
  67. data/lib/hecks/bluebook/dsl/attribute_collector.rb +41 -41
  68. data/lib/hecks/bluebook/dsl/binding_proxy.rb +22 -2
  69. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +111 -74
  70. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +48 -30
  71. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
  72. data/lib/hecks/bluebook/dsl/command_builder.rb +103 -103
  73. data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
  74. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
  75. data/lib/hecks/bluebook/dsl/entity_builder.rb +56 -56
  76. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
  77. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +89 -30
  78. data/lib/hecks/bluebook/dsl/identity_declaration.rb +17 -17
  79. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
  80. data/lib/hecks/bluebook/dsl/policy_builder.rb +30 -21
  81. data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
  82. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
  83. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +35 -35
  84. data/lib/hecks/bluebook/dsl/query_builder.rb +5 -5
  85. data/lib/hecks/bluebook/dsl/read_model_builder.rb +34 -34
  86. data/lib/hecks/bluebook/dsl/rule_reference.rb +41 -39
  87. data/lib/hecks/bluebook/dsl/translation_builder.rb +9 -9
  88. data/lib/hecks/bluebook/dsl/value_object_builder.rb +16 -16
  89. data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
  90. data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
  91. data/lib/hecks/bluebook/entity.rb +11 -11
  92. data/lib/hecks/bluebook/expression/ast_json.rb +20 -20
  93. data/lib/hecks/bluebook/expression/ast_reader.rb +3 -3
  94. data/lib/hecks/bluebook/expression/canonical_form.rb +9 -9
  95. data/lib/hecks/bluebook/expression/evaluator.rb +18 -18
  96. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +18 -18
  97. data/lib/hecks/bluebook/expression/resolver.rb +60 -62
  98. data/lib/hecks/bluebook/hexagon.rb +1 -1
  99. data/lib/hecks/bluebook/lifecycle.rb +1 -1
  100. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -1
  101. data/lib/hecks/bluebook/meta_validator/judge.rb +122 -86
  102. data/lib/hecks/bluebook/meta_validator/plan.rb +39 -39
  103. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -2
  104. data/lib/hecks/bluebook/meta_validator/readings.rb +43 -43
  105. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +44 -37
  106. data/lib/hecks/bluebook/meta_validator/shapes.rb +25 -21
  107. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +145 -31
  108. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +6 -6
  109. data/lib/hecks/bluebook/meta_validator/world_judge.rb +5 -5
  110. data/lib/hecks/bluebook/meta_validator.rb +70 -70
  111. data/lib/hecks/bluebook/model_check.rb +301 -84
  112. data/lib/hecks/bluebook/pattern_subset.rb +9 -9
  113. data/lib/hecks/bluebook/policy.rb +15 -13
  114. data/lib/hecks/bluebook/process_manager.rb +14 -14
  115. data/lib/hecks/bluebook/project_register.rb +6 -6
  116. data/lib/hecks/bluebook/query.rb +4 -4
  117. data/lib/hecks/bluebook/read_model.rb +14 -14
  118. data/lib/hecks/bluebook/reference.rb +8 -8
  119. data/lib/hecks/bluebook/smoke_test.rb +19 -19
  120. data/lib/hecks/bluebook/synthesizer.rb +12 -12
  121. data/lib/hecks/bluebook/translation.rb +4 -4
  122. data/lib/hecks/bluebook/value_object.rb +6 -6
  123. data/lib/hecks/bluebook.rb +2 -2
  124. data/lib/hecks/codemod/legacy_dispatch_args.rb +299 -0
  125. data/lib/hecks/codemod/legacy_dispatch_recorder.rb +186 -0
  126. data/lib/hecks/codemod.rb +36 -35
  127. data/lib/hecks/construct.rb +6 -6
  128. data/lib/hecks/corpus.rb +317 -0
  129. data/lib/hecks/deprecation.rb +95 -0
  130. data/lib/hecks/doc/reference.rb +19 -19
  131. data/lib/hecks/embryonaut_bluebook.rb +11 -11
  132. data/lib/hecks/facade/cli_door.rb +69 -10
  133. data/lib/hecks/facade/cli_runner.rb +105 -24
  134. data/lib/hecks/facade/command_request.rb +23 -0
  135. data/lib/hecks/facade/handle.rb +79 -32
  136. data/lib/hecks/facade/json_door.rb +106 -25
  137. data/lib/hecks/facade/surface/aggregate_door.rb +42 -27
  138. data/lib/hecks/facade/surface/chapter.rb +26 -17
  139. data/lib/hecks/facade/surface.rb +16 -3
  140. data/lib/hecks/facade.rb +15 -4
  141. data/lib/hecks/forms/app.rb +46 -30
  142. data/lib/hecks/forms/command_form_renderer.rb +70 -9
  143. data/lib/hecks/forms/field_renderer.rb +142 -6
  144. data/lib/hecks/forms/field_shape.rb +183 -20
  145. data/lib/hecks/forms/html.rb +51 -7
  146. data/lib/hecks/forms/index_renderer.rb +14 -2
  147. data/lib/hecks/forms/params.rb +120 -23
  148. data/lib/hecks/forms/port_argument.rb +2 -2
  149. data/lib/hecks/forms/query_form_renderer.rb +2 -2
  150. data/lib/hecks/forms/record_renderer.rb +2 -2
  151. data/lib/hecks/forms/record_table.rb +1 -1
  152. data/lib/hecks/forms/value_object_shape.rb +3 -3
  153. data/lib/hecks/forms.rb +24 -4
  154. data/lib/hecks/fqn.rb +1 -1
  155. data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
  156. data/lib/hecks/framework.rb +48 -17
  157. data/lib/hecks/freezer.rb +11 -11
  158. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +90 -90
  159. data/lib/hecks/fuzzing/combination_miner.rb +119 -0
  160. data/lib/hecks/fuzzing/concurrent_dispatch.rb +361 -0
  161. data/lib/hecks/fuzzing/coverage_campaign.rb +118 -0
  162. data/lib/hecks/fuzzing/differential.rb +158 -0
  163. data/lib/hecks/fuzzing/domain_generator.rb +694 -0
  164. data/lib/hecks/fuzzing/era_boundary.rb +124 -0
  165. data/lib/hecks/fuzzing/form_census.rb +199 -0
  166. data/lib/hecks/fuzzing/generated_domain_check.rb +95 -0
  167. data/lib/hecks/fuzzing/invalid_value_generator.rb +6 -6
  168. data/lib/hecks/fuzzing/isolated_boot.rb +226 -38
  169. data/lib/hecks/fuzzing/nondeterministic.rb +67 -0
  170. data/lib/hecks/fuzzing/persistence_parity.rb +161 -0
  171. data/lib/hecks/fuzzing/properties/corrections.rb +100 -0
  172. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +321 -41
  173. data/lib/hecks/fuzzing/properties/guards.rb +129 -26
  174. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +32 -32
  175. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +31 -11
  176. data/lib/hecks/fuzzing/properties/outbox.rb +142 -0
  177. data/lib/hecks/fuzzing/properties/querying.rb +17 -17
  178. data/lib/hecks/fuzzing/properties.rb +84 -39
  179. data/lib/hecks/fuzzing/qa_settings.rb +152 -0
  180. data/lib/hecks/fuzzing/replay.rb +224 -114
  181. data/lib/hecks/fuzzing/rotation_priority.rb +94 -0
  182. data/lib/hecks/fuzzing/rust_gap_manifest.rb +113 -0
  183. data/lib/hecks/fuzzing/self_consistency.rb +676 -0
  184. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +526 -0
  185. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +101 -30
  186. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +55 -8
  187. data/lib/hecks/fuzzing/sequence_generator/picker.rb +31 -11
  188. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +123 -32
  189. data/lib/hecks/fuzzing/sequence_generator.rb +152 -31
  190. data/lib/hecks/fuzzing/shrinker.rb +197 -0
  191. data/lib/hecks/fuzzing/structural_skips.rb +39 -0
  192. data/lib/hecks/fuzzing/sweep_depth.rb +53 -0
  193. data/lib/hecks/fuzzing/target_capabilities.rb +180 -0
  194. data/lib/hecks/fuzzing/value_generator.rb +66 -14
  195. data/lib/hecks/fuzzing.rb +11 -0
  196. data/lib/hecks/grammar/evolve.rb +10 -10
  197. data/lib/hecks/grammar.rb +7 -7
  198. data/lib/hecks/ir.rb +13 -13
  199. data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
  200. data/lib/hecks/language/bluebook/policy.bluebook +11 -1
  201. data/lib/hecks/language/bluebook/vocabulary.bluebook +365 -15
  202. data/lib/hecks/language/oidc.json +5 -0
  203. data/lib/hecks/literal.rb +9 -9
  204. data/lib/hecks/naming.rb +89 -21
  205. data/lib/hecks/ports/access_control.rb +58 -2
  206. data/lib/hecks/ports/agent/answers.rb +83 -6
  207. data/lib/hecks/ports/agent.rb +119 -35
  208. data/lib/hecks/ports/authentication.rb +44 -4
  209. data/lib/hecks/ports/authorization.rb +53 -11
  210. data/lib/hecks/ports/clock.rb +42 -23
  211. data/lib/hecks/ports/extraction.rb +16 -0
  212. data/lib/hecks/ports/identity_assignment.rb +24 -2
  213. data/lib/hecks/ports/identity_generation.rb +17 -3
  214. data/lib/hecks/ports/identity_resolution.rb +18 -1
  215. data/lib/hecks/ports/loading.rb +4 -0
  216. data/lib/hecks/ports/persistence/append_only.rb +172 -8
  217. data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
  218. data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
  219. data/lib/hecks/ports/persistence/execution.rb +4 -0
  220. data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
  221. data/lib/hecks/ports/persistence/plugin.rb +42 -4
  222. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
  223. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
  224. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
  225. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
  226. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
  227. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
  228. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
  229. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
  230. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
  231. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +160 -58
  232. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
  233. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +28 -5
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +44 -6
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +57 -4
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +338 -83
  242. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
  243. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
  244. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
  245. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +42 -8
  246. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
  247. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
  248. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
  249. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -19
  250. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +5 -5
  251. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +1 -1
  252. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
  253. data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
  254. data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
  255. data/lib/hecks/ports/persistence/repository_factory.rb +29 -6
  256. data/lib/hecks/ports/persistence/state_codec.rb +319 -0
  257. data/lib/hecks/ports/persistence.rb +36 -1
  258. data/lib/hecks/ports/projection.rb +61 -7
  259. data/lib/hecks/ports/query/in_memory.rb +3 -3
  260. data/lib/hecks/ports/query/ordering.rb +6 -6
  261. data/lib/hecks/ports/query.rb +35 -0
  262. data/lib/hecks/projections/bootstrap_table.rb +112 -0
  263. data/lib/hecks/projections/diagrams.rb +75 -75
  264. data/lib/hecks/projections/glossary/html.rb +250 -0
  265. data/lib/hecks/projections/glossary/markdown.rb +105 -0
  266. data/lib/hecks/projections/glossary/mermaid.rb +110 -0
  267. data/lib/hecks/projections/glossary/page.css +271 -0
  268. data/lib/hecks/projections/glossary/page.js +72 -0
  269. data/lib/hecks/projections/glossary/sections.rb +17 -0
  270. data/lib/hecks/projections/glossary/sentences.rb +205 -0
  271. data/lib/hecks/projections/glossary.rb +214 -286
  272. data/lib/hecks/projections/ir.rb +1 -1
  273. data/lib/hecks/projections/model/deviations.rb +18 -17
  274. data/lib/hecks/projections/model.rb +25 -21
  275. data/lib/hecks/projections/oidc.rb +7 -7
  276. data/lib/hecks/projections/parser_table.rb +5 -5
  277. data/lib/hecks/projections/reference.rb +3 -3
  278. data/lib/hecks/projections/rust_vocabulary.rb +443 -0
  279. data/lib/hecks/projections/shape.rb +2 -2
  280. data/lib/hecks/projections/statements.rb +11 -11
  281. data/lib/hecks/projections/vocabulary.rb +9 -9
  282. data/lib/hecks/projections.rb +5 -3
  283. data/lib/hecks/projector/cli_projector.rb +29 -29
  284. data/lib/hecks/projector/docs_projector.rb +13 -13
  285. data/lib/hecks/projector/exporter.rb +42 -21
  286. data/lib/hecks/projector/ir_projector.rb +1 -1
  287. data/lib/hecks/projector/narrate_projector.rb +15 -22
  288. data/lib/hecks/projector/target.rb +13 -13
  289. data/lib/hecks/projector.rb +15 -15
  290. data/lib/hecks/query_ir.rb +47 -47
  291. data/lib/hecks/query_specification/common/comparators.rb +19 -3
  292. data/lib/hecks/query_specification/common/comparison.rb +132 -24
  293. data/lib/hecks/query_specification/common/dsl.rb +65 -9
  294. data/lib/hecks/query_specification/common/null_policy.rb +57 -13
  295. data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
  296. data/lib/hecks/query_specification/common/options.rb +25 -0
  297. data/lib/hecks/query_specification/field_path.rb +69 -15
  298. data/lib/hecks/query_specification/hop_path.rb +57 -20
  299. data/lib/hecks/query_specification/read_model/specification.rb +4 -0
  300. data/lib/hecks/rendering.rb +3 -3
  301. data/lib/hecks/router/namespace_installer.rb +3 -3
  302. data/lib/hecks/router.rb +1 -1
  303. data/lib/hecks/runtime/aggregate_lock.rb +11 -11
  304. data/lib/hecks/runtime/boot_gates.rb +3 -3
  305. data/lib/hecks/runtime/caller.rb +8 -8
  306. data/lib/hecks/runtime/capability_graph.rb +2 -2
  307. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +22 -25
  308. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +64 -67
  309. data/lib/hecks/runtime/command_interpreter.rb +159 -102
  310. data/lib/hecks/runtime/command_rules/admissibility.rb +69 -69
  311. data/lib/hecks/runtime/command_rules/arithmetic.rb +137 -91
  312. data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
  313. data/lib/hecks/runtime/command_rules/emission.rb +18 -1
  314. data/lib/hecks/runtime/command_rules/references.rb +94 -19
  315. data/lib/hecks/runtime/command_rules.rb +3 -0
  316. data/lib/hecks/runtime/dependency_planning.rb +11 -11
  317. data/lib/hecks/runtime/dispatcher.rb +283 -90
  318. data/lib/hecks/runtime/entity_element.rb +282 -46
  319. data/lib/hecks/runtime/entity_interpreter.rb +160 -69
  320. data/lib/hecks/runtime/errors.rb +19 -19
  321. data/lib/hecks/runtime/event.rb +6 -6
  322. data/lib/hecks/runtime/identity.rb +22 -22
  323. data/lib/hecks/runtime/instance.rb +39 -14
  324. data/lib/hecks/runtime/interpreting.rb +12 -12
  325. data/lib/hecks/runtime/invocation.rb +276 -0
  326. data/lib/hecks/runtime/loader.rb +14 -14
  327. data/lib/hecks/runtime/outbox.rb +23 -23
  328. data/lib/hecks/runtime/policy_interpreter.rb +54 -54
  329. data/lib/hecks/runtime/port_operation_interpreter.rb +22 -19
  330. data/lib/hecks/runtime/query_interpreter.rb +111 -56
  331. data/lib/hecks/runtime/reaction_invocation.rb +76 -9
  332. data/lib/hecks/runtime/read_model_interpreter.rb +40 -40
  333. data/lib/hecks/runtime/rebuild_sweep.rb +4 -4
  334. data/lib/hecks/runtime/reference_hop.rb +6 -6
  335. data/lib/hecks/runtime/refusal_wording.rb +92 -112
  336. data/lib/hecks/runtime/registry/saga_persistence.rb +21 -21
  337. data/lib/hecks/runtime/registry/verification.rb +36 -26
  338. data/lib/hecks/runtime/registry.rb +56 -27
  339. data/lib/hecks/runtime/remote_dispatcher.rb +38 -23
  340. data/lib/hecks/runtime/routing.rb +10 -88
  341. data/lib/hecks/runtime/saga_interpreter/correlation.rb +17 -17
  342. data/lib/hecks/runtime/saga_interpreter.rb +93 -56
  343. data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
  344. data/lib/hecks/runtime/tenant_check.rb +9 -9
  345. data/lib/hecks/runtime/tenant_scope.rb +5 -5
  346. data/lib/hecks/runtime/value/admission.rb +75 -30
  347. data/lib/hecks/runtime/value/coercion.rb +379 -226
  348. data/lib/hecks/runtime/value/entity_list_coercion.rb +248 -0
  349. data/lib/hecks/runtime/value.rb +28 -23
  350. data/lib/hecks/runtime.rb +7 -7
  351. data/lib/hecks/storehouse.rb +64 -64
  352. data/lib/hecks/version.rb +3 -3
  353. data/lib/hecks/vocabulary.rb +207 -5
  354. data/lib/hecks.rb +13 -11
  355. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +11 -11
  356. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +14 -12
  357. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +11 -11
  358. metadata +43 -2
@@ -26,39 +26,39 @@ module Hecks
26
26
  # installed by whoever owns value objects (the aggregate).
27
27
  def closed_sets = @closed_sets ||= []
28
28
 
29
- # `admits:` names a closed set that is ALREADY DECLARED elsewhere —
29
+ # `admits:` names a closed set that is already declared elsewhere —
30
30
  #
31
31
  # attribute :op, String, admits: "Vocabulary::QueryComparator"
32
32
  #
33
- # which is the difference between it and `one_of`: `one_of` SYNTHESISES
33
+ # which is the difference between it and `one_of`: `one_of` synthesises
34
34
  # a fresh value object named for the attribute, so it can only ever name
35
35
  # something new. `admits` points at a set the language already holds, so
36
36
  # the same set can be named from many places without being written twice.
37
37
  #
38
- # QUALIFIED, because a closed set is a value object INSIDE an aggregate
38
+ # Qualified, because a closed set is a value object inside an aggregate
39
39
  # and `reference_to` reaches heads only — so this is text, checked where
40
40
  # it is read rather than by reference resolution.
41
41
  #
42
- # AND WRITTEN AS TEXT, not as the constant path `Vocabulary::QueryComparator`
42
+ # And written as text, not as the constant path `Vocabulary::QueryComparator`
43
43
  # it reads like. The constant spelling was tried — `ConstShim` returning
44
44
  # a Module so Ruby's `::` reaches a second `const_missing` — and it
45
45
  # cannot hold: `Facade::Surface` installs every aggregate name as a
46
- # TOP-LEVEL constant, so the moment any facade exists, `Vocabulary`
46
+ # top-level constant, so the moment any facade exists, `Vocabulary`
47
47
  # resolves to that module and the shim is never asked. A spelling that
48
48
  # works only until a facade is built is worse than a quoted one.
49
49
  #
50
- # THE TYPE POSITION TAKES A BARE CONSTANT, ALWAYS REQUIRED (ADR 0025,
50
+ # The type position takes a bare constant, always required (ADR 0025,
51
51
  # "Attributes") — omitting it (a mint default of String) and quoting
52
52
  # it as text both refuse now. Neither had a real reason left: no
53
53
  # corpus attribute ever omitted the type, and `ConstShim#const_missing`
54
54
  # (S0b) already resolves a bare, not-yet-declared constant to the
55
- # SAME forward reference the quoted form existed for — a bareword
55
+ # same forward reference the quoted form existed for — a bareword
56
56
  # `Name` reaches a value object named "Name" declared later in the
57
57
  # same block exactly as `"Name"` used to, `spell`'s own `to_s`
58
58
  # renders either one identically. Neither form appears in any frozen
59
59
  # era text (checked directly), so both are refused unconditionally —
60
60
  # nothing for `MetaValidator.shadow_parsing?` to answer for.
61
- # RENAMED FROM `attribute` — item #13's full metaprogrammed
61
+ # Renamed from `attribute` — item #13's full metaprogrammed
62
62
  # dispatch (slice 3, whole-project table-unification survey).
63
63
  # The word `attribute` itself is no longer a real method any
64
64
  # builder answers directly: every (context, word) Keyword row
@@ -109,20 +109,20 @@ module Hecks
109
109
  install_inline_closed_set(name, one_of) if one_of
110
110
  end
111
111
 
112
- # RENAMED FROM `list_of` — item #13's full metaprogrammed
113
- # dispatch (slice 5). Called in an attribute's own TYPE
112
+ # Renamed from `list_of` — item #13's full metaprogrammed
113
+ # dispatch (slice 5). Called in an attribute's own type
114
114
  # position (`attribute :x, list_of(Y)`), never through a `def
115
- # list_of` any ONE builder answers as its own word — reached
115
+ # list_of` any one builder answers as its own word — reached
116
116
  # via `WordGate#word_gate_dispatch`'s new "Type"-context
117
117
  # fallback, the same one `one_of_impl` below uses. Bootstrap-
118
118
  # reachable (every core chapter's own list-typed attributes use
119
119
  # it), so `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK` carries a
120
- # SINGLE `["Type", "list_of"]` entry rather than one per calling
120
+ # single `["Type", "list_of"]` entry rather than one per calling
121
121
  # context — the bootstrap branch checks that key too now, same
122
122
  # reasoning as the ordinary fallback.
123
123
  def list_of_impl(type) = ListOf.new(type)
124
124
 
125
- # `reference_to Account` MINTS `:account` — no `_id` — the default
125
+ # `reference_to Account` mints `:account` — no `_id` — the default
126
126
  # every `reference_to`-shaped word (`AggregateBuilder`,
127
127
  # `EntityBuilder`, `CommandBuilder#cross_reference`,
128
128
  # `QueryBuilder`, `PortOperationBuilder`, all `include
@@ -132,13 +132,13 @@ module Hecks
132
132
  # `.`; deriving the hop name from `account_id` is what made an
133
133
  # explicit operator impossible before).
134
134
  #
135
- # LEGACY UNDER SHADOW-PARSING (S0a's own bridge): frozen era text
136
- # was minted under the OLD default, and `EraGuard.shadow_parse`
137
- # reconstructs a held aggregate's shape to DIFF against the
138
- # current one — reading that text through the NEW default would
139
- # silently reconstruct the WRONG historical name, not merely
135
+ # Legacy under shadow-parsing (S0a's own bridge): frozen era text
136
+ # was minted under the old default, and `EraGuard.shadow_parse`
137
+ # reconstructs a held aggregate's shape to diff against the
138
+ # current one — reading that text through the new default would
139
+ # silently reconstruct the wrong historical name, not merely
140
140
  # refuse a spelling the way S1's `identified_by` legacy forms do.
141
- # This is a mint DEFAULT changing, not a syntax being removed, so
141
+ # This is a mint default changing, not a syntax being removed, so
142
142
  # there is nothing to refuse here — only a fork in what gets
143
143
  # minted when `as:` is omitted.
144
144
  private def default_reference_name(target)
@@ -146,24 +146,24 @@ module Hecks
146
146
  :"#{Naming.snake(target)}#{suffix}"
147
147
  end
148
148
 
149
- # A closed set declared INLINE on the attribute:
149
+ # A closed set declared inline on the attribute:
150
150
  #
151
151
  # attribute :status, one_of("open", "shut")
152
152
  #
153
153
  # Desugars to a value object named for the attribute, so it goes through
154
154
  # exactly the machinery a hand-written one_of does — and so the
155
- # attribute's type is still a DECLARED value object, which is now a
155
+ # attribute's type is still a declared value object, which is now a
156
156
  # structural rule rather than a predicate.
157
157
  #
158
158
  # An earlier reading of this spelling parsed it and threw the values
159
159
  # away: the attribute became a plain String and the closed set meant
160
160
  # nothing, in a construct that looked supported. The desugaring is
161
161
  # pinned now — the same bluebook must always yield the same IR.
162
- # RENAMED FROM `one_of` — item #13's full metaprogrammed dispatch
163
- # (slice 5), same reasoning as list_of_impl above. SAME NAME as
162
+ # Renamed from `one_of` — item #13's full metaprogrammed dispatch
163
+ # (slice 5), same reasoning as list_of_impl above. Same name as
164
164
  # `ValueObjectBuilder#one_of_impl`'s own override on purpose —
165
165
  # that method's own `super(*values)` call (the no-block, bare
166
- # type-position case) resolves by METHOD NAME up the ancestor
166
+ # type-position case) resolves by method name up the ancestor
167
167
  # chain, and renaming only one side would silently break it.
168
168
  def one_of_impl(*values) = OneOf.new(values)
169
169
 
@@ -180,11 +180,11 @@ module Hecks
180
180
  )
181
181
  end
182
182
 
183
- # `one_of:` NAMES A CLOSED SET ON THE FIELD ITSELF (ADR 0025,
183
+ # `one_of:` names a closed set on the field itself (ADR 0025,
184
184
  # "Attributes") — joining `pattern:`/`admits:` where value
185
185
  # constraints already live, for the one context where it means
186
186
  # anything: a `value_object` block, where it replaces the old
187
- # `one_of do member ... end` wrapper for a SINGLE-FIELD set (a
187
+ # `one_of do member ... end` wrapper for a single-field set (a
188
188
  # multi-field set still writes bare `member` lines, unwrapped).
189
189
  # `ValueObjectBuilder` overrides this; every other includer
190
190
  # (Aggregate/Entity/Command/Query/PortOperation) inherits this
@@ -198,15 +198,15 @@ module Hecks
198
198
  "with the type-position one_of(...) instead"
199
199
  end
200
200
 
201
- # A NAME DECLARED TWICE ON THE SAME OWNER IS TWO ATTRIBUTES SHARING
202
- # ONE NAME, and nothing downstream disambiguates them — every
201
+ # A name declared twice on the same owner is two attributes sharing
202
+ # one name, and nothing downstream disambiguates them — every
203
203
  # reader that walks `attributes` looking for one by name
204
204
  # (`seal_mutation_targets`, `seal_query_field`, `projects`'s own
205
205
  # local check, `Instance#[]`, ...) uses `Array#find`/`any?`, which
206
206
  # silently answers whichever declaration happens to come first and
207
207
  # discards the second. Used to boot clean and stay that way : both
208
208
  # declarations survived into the IR, one of them permanently
209
- # unreachable by name. Refused HERE, at the one place every owner
209
+ # unreachable by name. Refused here, at the one place every owner
210
210
  # (Aggregate/Entity/Command/Query/PortOperation/ValueObject, each
211
211
  # `include AttributeCollector`) mints an attribute through, rather
212
212
  # than taught to each of those readers individually.
@@ -216,7 +216,7 @@ module Hecks
216
216
  raise Malformed, "#{name} is declared twice — an attribute name is declared once, not twice"
217
217
  end
218
218
 
219
- # A pattern is refused AT DECLARATION, not when a value first meets it :
219
+ # A pattern is refused at declaration, not when a value first meets it :
220
220
  # a regex whose meaning depends on which engine reads it is a defect in
221
221
  # the bluebook, and a bluebook that loads is one whose patterns carry
222
222
  # one meaning. PatternSubset says which those are, and why each is refused.
@@ -246,9 +246,9 @@ module Hecks
246
246
  def resolve_identity_field!(field, value_objects, context_name)
247
247
  attr = attributes.find { |a| a.name == field }
248
248
 
249
- # `:id` OR AN `_id`-SUFFIXED NAME WITH NO MATCHING ATTRIBUTE is
250
- # not a typo to refuse — it is the language's own WALK-PARENT/
251
- # FALLBACK-IDENTITY convention. The `_id` suffix is the meta-
249
+ # `:id` or an `_id`-suffixed name with no matching attribute is
250
+ # not a typo to refuse — it is the language's own walk-parent/
251
+ # fallback-identity convention. The `_id` suffix is the meta-
252
252
  # domain's own (the `Command`/`Entity`/`Aggregate` etc. records
253
253
  # identify by `owner_id`/`bluebook_id`/`aggregate_id`, supplied
254
254
  # by the judge's replay rather than declared locally — see
@@ -285,20 +285,20 @@ module Hecks
285
285
  "#{context_name}.identified_by #{target} mints :#{field}, but that attribute is already declared"
286
286
  end
287
287
 
288
- # `Attribute.new` DIRECTLY, not the public `attribute(...)` DSL
289
- # entry — `target` is `Naming.demodulise`'d TEXT, not a bareword
288
+ # `Attribute.new` directly, not the public `attribute(...)` DSL
289
+ # entry — `target` is `Naming.demodulise`'d text, not a bareword
290
290
  # the bluebook author typed (the type position's own quoted-text
291
291
  # refusal is about DSL source, not internal minting), and `vo`
292
- # ITSELF can't be passed either: it is the real, already-built
292
+ # itself can't be passed either: it is the real, already-built
293
293
  # `ValueObject` subclass, permanently anonymous from Ruby's own
294
294
  # `to_s` (only `hecks_name` carries its name) — `Attribute#spell`
295
295
  # would demodulise it to "#<Class:0x...>", not "PizzaName".
296
296
  attributes << Attribute.new(name: field, type: target)
297
- # MOVED to `insert_at` — the attribute count AT THE MOMENT
297
+ # Moved to `insert_at` — the attribute count at the moment
298
298
  # `identified_by` was actually called, captured by the caller —
299
299
  # not left where `attribute` just appended it. Resolution happens
300
- # at BUILD time, after every other attribute in the block has
301
- # already run, so appending would put the identity field LAST
300
+ # at build time, after every other attribute in the block has
301
+ # already run, so appending would put the identity field last
302
302
  # regardless of where `identified_by` was actually written.
303
303
  # Most real bluebooks write it first (insert_at 0); one (a
304
304
  # ScheduledPayment corpus member) writes it after a reference_to
@@ -332,9 +332,9 @@ module Hecks
332
332
  raise Malformed, "#{context_name}'s identity value objects form a cycle: #{cycle}"
333
333
  end
334
334
 
335
- # A BARE FIELD DERIVES ONE SCALAR. `identified_by :ref` (or one leg
335
+ # **A bare field derives one scalar**. `identified_by :ref` (or one leg
336
336
  # of a compound `identified_by :a, :b`) names a single field, and
337
- # deriving ITS path only makes sense while every value object along
337
+ # deriving its path only makes sense while every value object along
338
338
  # the way wraps exactly one field itself — the same "single-field
339
339
  # value object" ADR 0025 names this shape after. A multi-field
340
340
  # value object here used to expand silently into every one of its
@@ -7,6 +7,13 @@ module Hecks
7
7
  # `Payment.persisted_by "Postgres"` into a queued `Bind`, and `#port`
8
8
  # is the one real method, for `Aggregate.port("Name") do ... end`.
9
9
  class BindingProxy
10
+ # Mints the stand-in module a bare domain constant resolves to inside a `.hecksagon` block.
11
+ #
12
+ # @param domain [Symbol, String] the domain name, the first segment of `Domain::Aggregate`
13
+ # @param collector [Array<Bluebook::Bind>] the list every bind made through the module's
14
+ # proxies is appended to
15
+ # @return [Module] an anonymous module whose `const_missing` answers a `BindingProxy`
16
+ # for `"Domain::Aggregate"`
10
17
  def self.namespace(domain, collector)
11
18
  Module.new do
12
19
  define_singleton_method(:const_missing) do |aggregate|
@@ -15,17 +22,30 @@ module Hecks
15
22
  end
16
23
  end
17
24
 
25
+ # @param fqn [String] the aggregate's qualified name, `"Domain::Aggregate"`
26
+ # @param collector [Array<Bluebook::Bind>] the list each bind made on this proxy is
27
+ # appended to
18
28
  def initialize(fqn, collector)
19
29
  @fqn = fqn
20
30
  @collector = collector
21
31
  end
22
32
 
23
- # THE AGGREGATE-SCOPED PORT `Payments::Payment.port("Gateway") do
33
+ # Declares a port on this aggregate and attaches it to the already-registered bluebook.
34
+ #
35
+ # **The aggregate-scoped port** — `Payments::Payment.port("Gateway") do
24
36
  # ... end`, the same receiver a plain bind like `.persisted_by(...)`
25
37
  # already reaches, because a port belongs to exactly one aggregate
26
- # the same way a bind does. A REAL method, not method_missing : its
38
+ # the same way a bind does. A real method, not method_missing : its
27
39
  # shape (a name and a block building operations) has nothing to do
28
40
  # with `Bind`, so it does not belong in that generic verb path.
41
+ #
42
+ # @param name [String] the port's name, such as `"Gateway"`
43
+ # @yield the port body, evaluated against a `DomainPortBuilder`: either `verb`/`signal`
44
+ # or `operation`/`tells`/`asks` blocks
45
+ # @return [Bluebook::DSL::BindingProxy] this proxy, so further binds can chain
46
+ # @raise [Bluebook::DSL::Malformed] if the current registry holds no such aggregate, or
47
+ # the body declares both a verb and operations, neither, or an operation the port
48
+ # grammar refuses
29
49
  def port(name, &block)
30
50
  domain, aggregate_name = @fqn.split("::")
31
51
  aggregate_ir = Hecks.current_registry.bluebook(domain)&.aggregate(aggregate_name) or