hecks 1.3.0 → 1.5.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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/adapters/driven/claude_code.rb +72 -7
  3. data/lib/hecks/adapters/driven/d1.rb +187 -23
  4. data/lib/hecks/adapters/driven/folder.rb +83 -10
  5. data/lib/hecks/adapters/driven/google_authentication.rb +33 -12
  6. data/lib/hecks/adapters/driven/governance_authorization.rb +87 -18
  7. data/lib/hecks/adapters/driven/heki/journal.rb +13 -4
  8. data/lib/hecks/adapters/driven/heki/saga_store.rb +56 -10
  9. data/lib/hecks/adapters/driven/heki/snapshot.rb +1 -1
  10. data/lib/hecks/adapters/driven/heki.rb +106 -9
  11. data/lib/hecks/adapters/driven/identity_registry.rb +12 -2
  12. data/lib/hecks/adapters/driven/in_memory_ordering.rb +25 -3
  13. data/lib/hecks/adapters/driven/in_process_key_vault.adapter +3 -0
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +53 -0
  15. data/lib/hecks/adapters/driven/lambda/client.rb +67 -14
  16. data/lib/hecks/adapters/driven/lambda.rb +82 -35
  17. data/lib/hecks/adapters/driven/local_storage.rb +83 -10
  18. data/lib/hecks/adapters/driven/memory.rb +205 -9
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +21 -1
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
  24. data/lib/hecks/adapters/driven/postgres.rb +175 -28
  25. data/lib/hecks/adapters/driven/prism.rb +50 -11
  26. data/lib/hecks/adapters/driven/secure_random_identity.rb +3 -0
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
  31. data/lib/hecks/adapters/driven/sqlite.rb +181 -21
  32. data/lib/hecks/adapters/driven/system_clock.rb +3 -0
  33. data/lib/hecks/adapters/driven/tenant_provisioner.adapter +3 -0
  34. data/lib/hecks/adapters/driven/tenant_provisioner.rb +66 -0
  35. data/lib/hecks/adapters/driven.rb +6 -4
  36. data/lib/hecks/adapters/driving/github_webhook.rb +31 -18
  37. data/lib/hecks/behaviors/dsl.rb +60 -2
  38. data/lib/hecks/behaviors/expectations.rb +190 -29
  39. data/lib/hecks/behaviors/ir.rb +12 -1
  40. data/lib/hecks/behaviors/rspec.rb +9 -1
  41. data/lib/hecks/behaviors/runner.rb +21 -2
  42. data/lib/hecks/behaviors.rb +9 -1
  43. data/lib/hecks/bluebook/aggregate.rb +43 -13
  44. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +17 -10
  45. data/lib/hecks/bluebook/assembly/build.rb +26 -5
  46. data/lib/hecks/bluebook/assembly/contract.rb +98 -23
  47. data/lib/hecks/bluebook/assembly/contracts.rb +59 -52
  48. data/lib/hecks/bluebook/assembly/marks.rb +159 -30
  49. data/lib/hecks/bluebook/assembly/specializer.rb +38 -21
  50. data/lib/hecks/bluebook/assembly.rb +32 -14
  51. data/lib/hecks/bluebook/attribute.rb +26 -12
  52. data/lib/hecks/bluebook/behaviour/aggregate.rb +43 -11
  53. data/lib/hecks/bluebook/behaviour/attribute.rb +18 -5
  54. data/lib/hecks/bluebook/behaviour/chapter.rb +76 -5
  55. data/lib/hecks/bluebook/behaviour/command.rb +55 -25
  56. data/lib/hecks/bluebook/behaviour/domain_port.rb +27 -7
  57. data/lib/hecks/bluebook/behaviour/entity.rb +20 -8
  58. data/lib/hecks/bluebook/behaviour/hexagon.rb +30 -4
  59. data/lib/hecks/bluebook/behaviour/lifecycle.rb +27 -6
  60. data/lib/hecks/bluebook/behaviour/policy.rb +42 -17
  61. data/lib/hecks/bluebook/behaviour/process_manager.rb +39 -8
  62. data/lib/hecks/bluebook/behaviour/query.rb +6 -1
  63. data/lib/hecks/bluebook/behaviour/read_model.rb +29 -8
  64. data/lib/hecks/bluebook/behaviour/traits.rb +48 -12
  65. data/lib/hecks/bluebook/behaviour/value_object.rb +21 -9
  66. data/lib/hecks/bluebook/capabilities.rb +27 -0
  67. data/lib/hecks/bluebook/chapter.rb +51 -9
  68. data/lib/hecks/bluebook/command.rb +62 -17
  69. data/lib/hecks/bluebook/domain_port.rb +34 -9
  70. data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
  71. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
  72. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +282 -123
  73. data/lib/hecks/bluebook/dsl/attribute_collector.rb +112 -75
  74. data/lib/hecks/bluebook/dsl/binding_proxy.rb +81 -2
  75. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +486 -117
  76. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +179 -47
  77. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
  78. data/lib/hecks/bluebook/dsl/command_builder.rb +284 -122
  79. data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
  80. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
  81. data/lib/hecks/bluebook/dsl/entity_builder.rb +191 -61
  82. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
  83. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +130 -30
  84. data/lib/hecks/bluebook/dsl/identity_declaration.rb +38 -21
  85. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
  86. data/lib/hecks/bluebook/dsl/policy_builder.rb +86 -36
  87. data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
  88. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
  89. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +111 -47
  90. data/lib/hecks/bluebook/dsl/query_builder.rb +37 -8
  91. data/lib/hecks/bluebook/dsl/read_model_builder.rb +127 -52
  92. data/lib/hecks/bluebook/dsl/rule_reference.rb +97 -43
  93. data/lib/hecks/bluebook/dsl/translation_builder.rb +150 -44
  94. data/lib/hecks/bluebook/dsl/value_object_builder.rb +68 -20
  95. data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
  96. data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
  97. data/lib/hecks/bluebook/entity.rb +40 -11
  98. data/lib/hecks/bluebook/expression/ast_json.rb +128 -36
  99. data/lib/hecks/bluebook/expression/ast_reader.rb +32 -3
  100. data/lib/hecks/bluebook/expression/canonical_form.rb +55 -16
  101. data/lib/hecks/bluebook/expression/evaluator.rb +221 -43
  102. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +54 -18
  103. data/lib/hecks/bluebook/expression/resolver.rb +369 -128
  104. data/lib/hecks/bluebook/hexagon.rb +35 -1
  105. data/lib/hecks/bluebook/lifecycle.rb +12 -1
  106. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +2 -1
  107. data/lib/hecks/bluebook/meta_validator/judge.rb +126 -108
  108. data/lib/hecks/bluebook/meta_validator/plan.rb +81 -46
  109. data/lib/hecks/bluebook/meta_validator/port_judge.rb +3 -2
  110. data/lib/hecks/bluebook/meta_validator/readings.rb +200 -50
  111. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +68 -41
  112. data/lib/hecks/bluebook/meta_validator/shapes.rb +166 -21
  113. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +286 -46
  114. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +11 -10
  115. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -5
  116. data/lib/hecks/bluebook/meta_validator.rb +235 -139
  117. data/lib/hecks/bluebook/model_check.rb +434 -104
  118. data/lib/hecks/bluebook/pattern_subset.rb +32 -10
  119. data/lib/hecks/bluebook/policy.rb +15 -13
  120. data/lib/hecks/bluebook/process_manager.rb +27 -14
  121. data/lib/hecks/bluebook/project_discovery.rb +5 -0
  122. data/lib/hecks/bluebook/project_loader.rb +40 -0
  123. data/lib/hecks/bluebook/project_register.rb +50 -6
  124. data/lib/hecks/bluebook/query.rb +31 -4
  125. data/lib/hecks/bluebook/read_model.rb +35 -15
  126. data/lib/hecks/bluebook/reference.rb +26 -13
  127. data/lib/hecks/bluebook/smoke_test.rb +46 -23
  128. data/lib/hecks/bluebook/synthesizer.rb +46 -12
  129. data/lib/hecks/bluebook/translation.rb +34 -5
  130. data/lib/hecks/bluebook/value_object.rb +29 -11
  131. data/lib/hecks/bluebook.rb +5 -6
  132. data/lib/hecks/codemod.rb +138 -50
  133. data/lib/hecks/construct.rb +21 -7
  134. data/lib/hecks/corpus.rb +438 -0
  135. data/lib/hecks/deploy/bluebook/deploy.hecksagon +19 -0
  136. data/lib/hecks/doc/reference.rb +200 -31
  137. data/lib/hecks/embryonaut_bluebook.rb +38 -15
  138. data/lib/hecks/facade/cli_door.rb +69 -10
  139. data/lib/hecks/facade/cli_runner.rb +105 -24
  140. data/lib/hecks/facade/command_request.rb +23 -0
  141. data/lib/hecks/facade/handle.rb +155 -35
  142. data/lib/hecks/facade/json_door.rb +106 -25
  143. data/lib/hecks/facade/surface/aggregate_door.rb +50 -27
  144. data/lib/hecks/facade/surface/chapter.rb +26 -17
  145. data/lib/hecks/facade/surface.rb +16 -3
  146. data/lib/hecks/facade.rb +15 -4
  147. data/lib/hecks/forms/app.rb +46 -30
  148. data/lib/hecks/forms/command_form_renderer.rb +70 -9
  149. data/lib/hecks/forms/field_renderer.rb +142 -6
  150. data/lib/hecks/forms/field_shape.rb +183 -19
  151. data/lib/hecks/forms/html.rb +51 -7
  152. data/lib/hecks/forms/index_renderer.rb +14 -2
  153. data/lib/hecks/forms/page.rb +14 -0
  154. data/lib/hecks/forms/params.rb +120 -23
  155. data/lib/hecks/forms/port_argument.rb +14 -2
  156. data/lib/hecks/forms/query_form_renderer.rb +65 -2
  157. data/lib/hecks/forms/record_renderer.rb +60 -2
  158. data/lib/hecks/forms/record_table.rb +28 -1
  159. data/lib/hecks/forms/reference_options.rb +24 -0
  160. data/lib/hecks/forms/value_object_shape.rb +13 -3
  161. data/lib/hecks/forms.rb +24 -4
  162. data/lib/hecks/fqn.rb +59 -1
  163. data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
  164. data/lib/hecks/framework/bluebook/privacy.bluebook +155 -0
  165. data/lib/hecks/framework/oidc.json +15 -0
  166. data/lib/hecks/framework.rb +79 -25
  167. data/lib/hecks/freezer.rb +27 -11
  168. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +241 -106
  169. data/lib/hecks/fuzzing/combination_miner.rb +178 -0
  170. data/lib/hecks/fuzzing/concurrent_dispatch.rb +241 -45
  171. data/lib/hecks/fuzzing/coverage_campaign.rb +161 -0
  172. data/lib/hecks/fuzzing/differential.rb +192 -0
  173. data/lib/hecks/fuzzing/domain_generator.rb +871 -0
  174. data/lib/hecks/fuzzing/era_boundary.rb +68 -19
  175. data/lib/hecks/fuzzing/form_census.rb +121 -20
  176. data/lib/hecks/fuzzing/generated_domain_check.rb +171 -0
  177. data/lib/hecks/fuzzing/invalid_value_generator.rb +45 -6
  178. data/lib/hecks/fuzzing/isolated_boot.rb +137 -80
  179. data/lib/hecks/fuzzing/nondeterministic.rb +79 -0
  180. data/lib/hecks/fuzzing/persistence_parity.rb +111 -21
  181. data/lib/hecks/fuzzing/properties/corrections.rb +34 -9
  182. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +300 -51
  183. data/lib/hecks/fuzzing/properties/guards.rb +86 -42
  184. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +80 -32
  185. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +40 -35
  186. data/lib/hecks/fuzzing/properties/outbox.rb +70 -32
  187. data/lib/hecks/fuzzing/properties/querying.rb +82 -28
  188. data/lib/hecks/fuzzing/properties.rb +84 -51
  189. data/lib/hecks/fuzzing/qa_settings.rb +164 -0
  190. data/lib/hecks/fuzzing/replay.rb +241 -133
  191. data/lib/hecks/fuzzing/rotation_priority.rb +48 -28
  192. data/lib/hecks/fuzzing/rust_gap_manifest.rb +139 -0
  193. data/lib/hecks/fuzzing/self_consistency.rb +315 -137
  194. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +46 -40
  195. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
  196. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
  197. data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
  198. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +59 -32
  199. data/lib/hecks/fuzzing/sequence_generator.rb +158 -23
  200. data/lib/hecks/fuzzing/shrinker.rb +309 -0
  201. data/lib/hecks/fuzzing/structural_skips.rb +37 -130
  202. data/lib/hecks/fuzzing/sweep_depth.rb +12 -4
  203. data/lib/hecks/fuzzing/target_capabilities.rb +107 -29
  204. data/lib/hecks/fuzzing/value_generator.rb +110 -22
  205. data/lib/hecks/fuzzing.rb +5 -0
  206. data/lib/hecks/grammar/evolve.rb +188 -12
  207. data/lib/hecks/grammar.rb +53 -7
  208. data/lib/hecks/ir.rb +51 -20
  209. data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
  210. data/lib/hecks/language/bluebook/policy.bluebook +11 -1
  211. data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
  212. data/lib/hecks/language/hecksagon/hecksagon.bluebook +11 -0
  213. data/lib/hecks/language/oidc.json +5 -0
  214. data/lib/hecks/literal.rb +41 -9
  215. data/lib/hecks/naming.rb +112 -31
  216. data/lib/hecks/ports/access_control.rb +53 -2
  217. data/lib/hecks/ports/agent/answers.rb +83 -6
  218. data/lib/hecks/ports/agent.rb +119 -35
  219. data/lib/hecks/ports/authentication.rb +44 -4
  220. data/lib/hecks/ports/authorization.rb +50 -11
  221. data/lib/hecks/ports/clock.rb +42 -23
  222. data/lib/hecks/ports/extraction.rb +16 -0
  223. data/lib/hecks/ports/identity_assignment.rb +23 -2
  224. data/lib/hecks/ports/identity_generation.rb +17 -3
  225. data/lib/hecks/ports/identity_resolution.rb +17 -1
  226. data/lib/hecks/ports/key_vault.port +6 -0
  227. data/lib/hecks/ports/key_vault.rb +58 -0
  228. data/lib/hecks/ports/loading.rb +4 -0
  229. data/lib/hecks/ports/persistence/append_only.rb +172 -8
  230. data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
  231. data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
  232. data/lib/hecks/ports/persistence/execution.rb +4 -0
  233. data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
  234. data/lib/hecks/ports/persistence/plugin.rb +42 -4
  235. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
  236. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
  237. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
  238. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
  239. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +34 -5
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
  250. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
  251. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
  252. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +95 -6
  253. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
  254. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
  255. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
  256. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
  257. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
  258. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +48 -8
  259. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
  260. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
  261. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
  262. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +58 -19
  263. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +96 -5
  264. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +15 -0
  265. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +9 -1
  266. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
  267. data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
  268. data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
  269. data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
  270. data/lib/hecks/ports/persistence/state_codec.rb +319 -0
  271. data/lib/hecks/ports/persistence.rb +36 -1
  272. data/lib/hecks/ports/projection.rb +61 -7
  273. data/lib/hecks/ports/query/in_memory.rb +41 -8
  274. data/lib/hecks/ports/query/ordering.rb +21 -6
  275. data/lib/hecks/ports/query.rb +35 -0
  276. data/lib/hecks/ports.rb +1 -0
  277. data/lib/hecks/projections/bootstrap_table.rb +147 -0
  278. data/lib/hecks/projections/diagrams.rb +315 -79
  279. data/lib/hecks/projections/glossary/html.rb +91 -3
  280. data/lib/hecks/projections/glossary/markdown.rb +50 -3
  281. data/lib/hecks/projections/glossary/mermaid.rb +49 -1
  282. data/lib/hecks/projections/glossary/sections.rb +1 -1
  283. data/lib/hecks/projections/glossary/sentences.rb +110 -5
  284. data/lib/hecks/projections/glossary.rb +173 -31
  285. data/lib/hecks/projections/ir.rb +1 -1
  286. data/lib/hecks/projections/model/deviations.rb +62 -17
  287. data/lib/hecks/projections/model.rb +75 -21
  288. data/lib/hecks/projections/oidc.rb +45 -8
  289. data/lib/hecks/projections/parser_table.rb +53 -12
  290. data/lib/hecks/projections/reference.rb +15 -3
  291. data/lib/hecks/projections/rust_vocabulary.rb +646 -0
  292. data/lib/hecks/projections/shape.rb +10 -2
  293. data/lib/hecks/projections/statements.rb +69 -22
  294. data/lib/hecks/projections/vocabulary.rb +26 -9
  295. data/lib/hecks/projections.rb +5 -3
  296. data/lib/hecks/projector/cli_projector.rb +245 -37
  297. data/lib/hecks/projector/docs_projector.rb +154 -28
  298. data/lib/hecks/projector/exporter.rb +104 -29
  299. data/lib/hecks/projector/ir_projector.rb +7 -1
  300. data/lib/hecks/projector/narrate_projector.rb +144 -23
  301. data/lib/hecks/projector/target.rb +42 -18
  302. data/lib/hecks/projector.rb +86 -18
  303. data/lib/hecks/query_ir.rb +94 -47
  304. data/lib/hecks/query_specification/common/comparators.rb +19 -3
  305. data/lib/hecks/query_specification/common/comparison.rb +109 -27
  306. data/lib/hecks/query_specification/common/dsl.rb +65 -9
  307. data/lib/hecks/query_specification/common/null_policy.rb +61 -15
  308. data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
  309. data/lib/hecks/query_specification/common/options.rb +25 -0
  310. data/lib/hecks/query_specification/field_path.rb +69 -15
  311. data/lib/hecks/query_specification/hop_path.rb +57 -20
  312. data/lib/hecks/query_specification/read_model/specification.rb +4 -0
  313. data/lib/hecks/rendering.rb +9 -3
  314. data/lib/hecks/router/namespace_installer.rb +16 -3
  315. data/lib/hecks/router.rb +56 -1
  316. data/lib/hecks/runtime/aggregate_lock.rb +20 -11
  317. data/lib/hecks/runtime/boot_gates.rb +21 -3
  318. data/lib/hecks/runtime/caller.rb +40 -8
  319. data/lib/hecks/runtime/capability_graph.rb +13 -2
  320. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +40 -41
  321. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +45 -67
  322. data/lib/hecks/runtime/command_interpreter.rb +195 -113
  323. data/lib/hecks/runtime/command_rules/admissibility.rb +231 -80
  324. data/lib/hecks/runtime/command_rules/arithmetic.rb +154 -96
  325. data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
  326. data/lib/hecks/runtime/command_rules/emission.rb +18 -1
  327. data/lib/hecks/runtime/command_rules/references.rb +145 -55
  328. data/lib/hecks/runtime/command_rules.rb +3 -0
  329. data/lib/hecks/runtime/dependency_planning.rb +56 -11
  330. data/lib/hecks/runtime/dispatcher.rb +263 -92
  331. data/lib/hecks/runtime/entity_element.rb +304 -67
  332. data/lib/hecks/runtime/entity_interpreter.rb +149 -88
  333. data/lib/hecks/runtime/errors.rb +37 -23
  334. data/lib/hecks/runtime/event.rb +15 -10
  335. data/lib/hecks/runtime/identity.rb +91 -23
  336. data/lib/hecks/runtime/instance.rb +103 -18
  337. data/lib/hecks/runtime/interpreting.rb +24 -16
  338. data/lib/hecks/runtime/invocation.rb +358 -0
  339. data/lib/hecks/runtime/loader.rb +105 -19
  340. data/lib/hecks/runtime/outbox.rb +164 -26
  341. data/lib/hecks/runtime/policy_interpreter.rb +73 -60
  342. data/lib/hecks/runtime/port_operation_interpreter.rb +42 -19
  343. data/lib/hecks/runtime/query_interpreter.rb +93 -74
  344. data/lib/hecks/runtime/reaction_invocation.rb +73 -28
  345. data/lib/hecks/runtime/read_model_interpreter.rb +60 -44
  346. data/lib/hecks/runtime/rebuild_sweep.rb +32 -4
  347. data/lib/hecks/runtime/reference_hop.rb +48 -6
  348. data/lib/hecks/runtime/refusal_wording.rb +142 -115
  349. data/lib/hecks/runtime/registry/saga_persistence.rb +32 -21
  350. data/lib/hecks/runtime/registry/verification.rb +153 -28
  351. data/lib/hecks/runtime/registry.rb +202 -32
  352. data/lib/hecks/runtime/remote_dispatcher.rb +125 -24
  353. data/lib/hecks/runtime/routing.rb +36 -154
  354. data/lib/hecks/runtime/saga_interpreter/correlation.rb +25 -27
  355. data/lib/hecks/runtime/saga_interpreter.rb +90 -76
  356. data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
  357. data/lib/hecks/runtime/tenant_check.rb +33 -13
  358. data/lib/hecks/runtime/tenant_scope.rb +23 -5
  359. data/lib/hecks/runtime/value/admission.rb +75 -30
  360. data/lib/hecks/runtime/value/coercion.rb +555 -142
  361. data/lib/hecks/runtime/value/entity_list_coercion.rb +132 -60
  362. data/lib/hecks/runtime/value.rb +71 -21
  363. data/lib/hecks/runtime.rb +39 -7
  364. data/lib/hecks/storehouse.rb +368 -72
  365. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +130 -0
  366. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +32 -0
  367. data/lib/hecks/version.rb +3 -3
  368. data/lib/hecks/vocabulary.rb +205 -4
  369. data/lib/hecks.rb +91 -11
  370. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +19 -11
  371. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +24 -12
  372. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +38 -14
  373. metadata +28 -2
@@ -1,13 +1,14 @@
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
- # The judge used to carry one hand-written branch per category, and the
7
- # reason given for keeping it that way was that "which append command
8
- # belongs to which list is not derivable from a name". True — and beside
9
- # the point. It is derivable from the language's own IR, because every
10
- # append command DECLARES its target:
6
+ # ## Why a plan, not a hand-written branch per category
7
+ #
8
+ # "Which append command belongs to which list is not derivable from a
9
+ # name" sounds like a reason to hand-write one branch per category —
10
+ # and is beside the point. It is derivable from the language's own IR,
11
+ # because every append command declares its target:
11
12
  #
12
13
  # command "Argument" do
13
14
  # reference_to Command
@@ -18,13 +19,13 @@ module Hecks
18
19
  # appender for the `arguments` list, and the map binds each value-object
19
20
  # field to the command argument that fills it. Nothing is matched by name.
20
21
  #
21
- # The same reading recovers the containment tree. A command with NO
22
+ # The same reading recovers the containment tree. A command with no
22
23
  # self-reference is the creating one, and the `*_id` argument it carries
23
24
  # names the parent — so Bluebook -> Aggregate -> Command / ValueObject /
24
25
  # Query / Entity, ValueObject -> Member, ProcessManager -> Handler ->
25
26
  # Dispatch all fall out of the declarations rather than being restated here.
26
27
  #
27
- # Usage:
28
+ # ## Usage
28
29
  #
29
30
  # plan = Plan.for(MetaValidator.grammar_registry)
30
31
  # plan.category("Command").parent # => "Aggregate"
@@ -52,28 +53,48 @@ module Hecks
52
53
  # Every verb this category declares, in declaration order. `alternates`
53
54
  # matters here: two commands can append to one list, and a verb missing
54
55
  # from this is a verb the coverage gate stops watching.
56
+ #
57
+ # @return [Array<String>] every command name this category declares
58
+ # (the creating command, every setter, appender, alternate
59
+ # appender, and sealer), `nil` entries dropped
55
60
  def verbs
56
61
  [declare, *setters.map(&:verb), *appends.values.map(&:verb),
57
62
  *alternates.map(&:verb), *sealers].compact
58
63
  end
59
64
 
60
- # DOES THIS ARGUMENT CARRY AN ID? A reference is the id of a head, and
65
+ # Does this argument carry an ID? A reference is the id of a head, and
61
66
  # an id is a scalar — so the judge offers it bare, where every other
62
67
  # field goes as a one-field value object. The language answers this
63
68
  # about itself, so declaring a new reference needs no change here.
69
+ #
70
+ # @param verb [String] the command name declaring `argument`
71
+ # @param argument [String] the argument name to check
72
+ # @return [Boolean] whether `argument` on `verb` is a reference
64
73
  def references?(verb, argument)
65
74
  Array(references[verb.to_s]).include?(argument.to_s)
66
75
  end
67
76
 
77
+ # Reports whether this category is the root of the containment
78
+ # tree.
79
+ #
80
+ # @return [Boolean] whether this category has no parent — the root
81
+ # of the containment tree
68
82
  def root? = parent.nil?
69
83
  end
70
84
 
85
+ # Reads the language's own self-description off `registry`.
86
+ #
87
+ # @param registry [Runtime::Registry] a registry with the language's
88
+ # own "Bluebook" chapter already judged and assembled
89
+ # @return [Plan] the plan, built from that chapter's own aggregates
71
90
  def self.for(registry)
72
91
  new(registry.bluebook("Bluebook"))
73
92
  end
74
93
 
75
94
  attr_reader :categories
76
95
 
96
+ # @param meta [Bluebook::Chapter] the language's own assembled
97
+ # "Bluebook" chapter
77
98
  def initialize(meta)
78
99
  @categories = {}
79
100
  meta.aggregates.each do |aggregate|
@@ -84,33 +105,33 @@ module Hecks
84
105
 
85
106
  @categories[aggregate.hecks_name] = read(aggregate)
86
107
 
87
- # S17, ADR 0026 — Member/Handler/Dispatch are ENTITIES now
108
+ # S17, ADR 0026 — Member/Handler/Dispatch are entities now
88
109
  # (`entity "Member" do ... end`, nested under `ValueObject`/
89
110
  # `ProcessManager`/`Handler`), not their own top-level
90
111
  # aggregates — so `meta.aggregates` alone no longer finds
91
112
  # them the way it always found a standalone `aggregate
92
- # "Member"`. Each STILL needs its own named category here:
113
+ # "Member"`. Each still needs its own named category here:
93
114
  # `Assembly::Contracts` keeps a bespoke entry for each
94
115
  # (Member's own open-map `pairs`, Dispatch's own open-map
95
116
  # `with_spec`), distinct from the single generic "Entity"
96
- # category every ORDINARY real-corpus entity (LedgerEntry,
117
+ # category every ordinary real-corpus entity (LedgerEntry,
97
118
  # 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.
119
+ # walk every meta-domain aggregate's own `.entities`
120
+ # unconditionally — `Plan` only ever reads the meta-
121
+ # domain's own self-description (`Plan.for(MetaValidator.
101
122
  # grammar_registry)`), which never declares a generic,
102
- # nameless entity of its own the way a REAL domain's
123
+ # nameless entity of its own the way a real domain's
103
124
  # `LedgerEntry` is; the only entities the meta-domain
104
125
  # itself ever declares are exactly the three this ADR
105
- # names. `entity_owned: true` records WHY this is a
126
+ # names. `entity_owned: true` records why this is a
106
127
  # 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
128
+ # aggregate named "Member" to dispatch a bare verb into
129
+ # any more, so the judge has to build a dotted one instead
109
130
  # (see `Judge#verb_for`).
110
131
  #
111
- # RECURSES — `Dispatch` nests inside `Handler`, which nests
132
+ # Recurses — `Dispatch` nests inside `Handler`, which nests
112
133
  # inside `ProcessManager`, two levels deep, not one. Each
113
- # nested entity's own `parent` names the DIRECT owner it was
134
+ # nested entity's own `parent` names the direct owner it was
114
135
  # actually found under (Dispatch's is "Handler", not
115
136
  # "ProcessManager") — `read`'s own `owner:` argument already
116
137
  # takes whichever name is passed, so walking one level deeper
@@ -121,20 +142,34 @@ module Hecks
121
142
  @categories.freeze
122
143
  end
123
144
 
145
+ # Looks up one category by name.
146
+ #
147
+ # @param name [String, Symbol] the category name, such as
148
+ # `"Command"` or `"ValueObject"`
149
+ # @return [Category, nil] the named category, or `nil` if the
150
+ # language declares no such category
124
151
  def category(name) = @categories[name.to_s]
152
+
153
+ # Lists every category this plan holds.
154
+ #
155
+ # @return [Array<String>] every category name this plan holds
125
156
  def names = @categories.keys
126
157
 
127
158
  # Every verb the language declares, spelled as the judge would
128
- # dispatch it. S17, ADR 0026 — an ENTITY-OWNED category (its
159
+ # dispatch it. S17, ADR 0026 — an entity-owned category (its
129
160
  # 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.
161
+ # runtime can route a bare verb into any more, so it is
162
+ # spelled dotted here too — `Bluebook::ValueObject.Member.
132
163
  # Declare`, `Bluebook::ProcessManager.Handler.Dispatch.Bind` —
133
164
  # matching `Judge#verb_for`/`#dotted_prefix`'s own build
134
165
  # exactly (recursing the same way, for the same reason: an
135
166
  # entity-owned category's own parent may itself be entity-
136
167
  # owned), so this stays what it already is: the judge's own
137
168
  # coverage promise, not a second guess at it.
169
+ #
170
+ # @return [Array<String>] every verb the language declares, dotted
171
+ # and prefixed with `"Bluebook::"`, such as `"Bluebook::Aggregate.
172
+ # Command.Argument"`
138
173
  def verbs
139
174
  @categories.flat_map do |name, category|
140
175
  category.verbs.map { |verb| "Bluebook::#{dotted_prefix(name)}.#{verb}" }
@@ -147,8 +182,8 @@ module Hecks
147
182
  # found entity's own `.entities` in turn — S17, ADR 0026's
148
183
  # two-level chain (`Dispatch`, inside `Handler`, inside
149
184
  # `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
185
+ # than re-derived, because it names whichever construct this
186
+ # call actually found the entity under — the direct parent, not
152
187
  # the root.
153
188
  def add_nested_entities(owner)
154
189
  owner.entities.each do |entity|
@@ -159,9 +194,9 @@ module Hecks
159
194
  end
160
195
  end
161
196
 
162
- # THE FULL DOTTED PREFIX a category's own verbs hang off —
197
+ # The full dotted prefix a category's own verbs hang off —
163
198
  # mirrors `Judge#dotted_prefix` exactly (S17, ADR 0026): the
164
- # plain name for an ordinary category, or its PARENT's own
199
+ # plain name for an ordinary category, or its parent's own
165
200
  # prefix with this category's name appended, for an entity-
166
201
  # owned one, recursing because the parent may itself be
167
202
  # entity-owned.
@@ -172,28 +207,28 @@ module Hecks
172
207
  "#{dotted_prefix(found.parent)}.#{name}"
173
208
  end
174
209
 
175
- # `owner:`/`entity_owned:` — S17, ADR 0026. An AGGREGATE-level
210
+ # `owner:`/`entity_owned:` — S17, ADR 0026. An aggregate-level
176
211
  # creating command carries its own parent as a `reference_to`
177
212
  # argument (read via `parent_reference_of` below), the same
178
- # way it always has. An ENTITY-level one never does — `entity
213
+ # way it always has. An entity-level one never does — `entity
179
214
  # "Member" do ... end`'s own creating command reaches its
180
- # parent through the DOTTED CALL itself (`ValueObject.Member.
215
+ # parent through the dotted call itself (`ValueObject.Member.
181
216
  # Declare`), the same reason an ordinary entity's own commands
182
217
  # never declare `reference_to` either (entity.md's own
183
- # reference page states this). So the OWNING aggregate's name
218
+ # reference page states this). So the owning aggregate's name
184
219
  # is passed in directly here, by the caller who already knows
185
220
  # it (the same `.entities` walk that found this node), rather
186
221
  # than derived from an argument that was never going to be
187
222
  # there.
188
223
  def read(aggregate, owner: nil, entity_owned: false)
189
- # An ENTITY-OWNED category has no creating command of its own to find.
224
+ # An entity-owned category has no creating command of its own to find.
190
225
  # `creating_command` tests `command.references.nil?` — the same test
191
- # a REAL entity's own commands pass too, since `entity "Member" do
226
+ # a real entity's own commands pass too, since `entity "Member" do
192
227
  # command "Pair" ... end end` never writes `reference_to` (an
193
228
  # entity's commands never do — banking's own LedgerEntry.Amend
194
229
  # 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
230
+ # own "Pair" and call that the creating command, which it is not:
231
+ # a Member is created by `ValueObject.Member`, its owner's own bare
197
232
  # append command, the same way a real LedgerEntry is created by
198
233
  # `Account.LogEntry`, never by a dotted verb of its own.
199
234
  declare = entity_owned ? nil : declaration_command(aggregate)
@@ -211,15 +246,15 @@ module Hecks
211
246
  alternates: alternates_in(rest),
212
247
  setters: setters_in(rest),
213
248
  sealers: sealers_in(rest),
214
- # EVERY command, not `rest` — the creating command carries the parent
249
+ # Every command, not `rest` — the creating command carries the parent
215
250
  # link, which is the most common reference of all.
216
251
  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
252
+ # How the category names its records, read from the language rather
253
+ # than restated. The judge has to know a record's id before it
219
254
  # dispatches, because the children it walks next carry it as their
220
255
  # parent — so it derives the same join the runtime will, off the same
221
- # declaration. It used to be a branch per category, and a branch that
222
- # disagreed with the runtime by one separator was a broken reference.
256
+ # declaration: a hand-written branch per category, disagreeing with
257
+ # the runtime by even one separator, would be a broken reference.
223
258
  identity_paths: aggregate.identity_paths,
224
259
  entity_owned: entity_owned
225
260
  )
@@ -261,7 +296,7 @@ module Hecks
261
296
  aggregate.attributes.find(&:reference?)
262
297
  end
263
298
 
264
- # What the creating command sets directly. EVERY reference
299
+ # What the creating command sets directly. Every reference
265
300
  # argument is dropped, not just the parent link: a reference is
266
301
  # not a field. Command.Declare carries `entity_id` as well as
267
302
  # the parent `aggregate` reference, because an entity declares
@@ -279,7 +314,7 @@ module Hecks
279
314
  Array(command.mutations).each do |mutation|
280
315
  next unless mutation.op == :append
281
316
 
282
- # FIRST wins, not last. Two commands can append to the same list —
317
+ # First wins, not last. Two commands can append to the same list —
283
318
  # Aggregate.Attribute and Aggregate.Reference both extend `attributes`,
284
319
  # because a reference's type is not a value object and cannot go
285
320
  # through the same verb. Overwriting would have let the one declared
@@ -290,7 +325,7 @@ module Hecks
290
325
  end
291
326
  end
292
327
 
293
- # The appenders DISPLACED by first-wins — Aggregate.Reference behind
328
+ # The appenders displaced by first-wins — Aggregate.Reference behind
294
329
  # Aggregate.Attribute. The walk reaches them by reading the row, not the
295
330
  # plan, but they are still verbs the language declares and the coverage
296
331
  # gate has to see them.
@@ -311,7 +346,7 @@ module Hecks
311
346
  end
312
347
  end
313
348
 
314
- # Commands that SET rather than append. Lifecycle sets two targets at once,
349
+ # Commands that set rather than append. Lifecycle sets two targets at once,
315
350
  # so a setter is keyed by its verb and carries every target it writes.
316
351
  def setters_in(commands)
317
352
  commands.filter_map do |command|
@@ -324,7 +359,7 @@ module Hecks
324
359
  end
325
360
  end
326
361
 
327
- # Commands that change nothing — they exist to be REFUSED. Aggregate.Seal is
362
+ # Commands that change nothing — they exist to be refused. Aggregate.Seal is
328
363
  # the whole-document check: dispatched once everything is declared, carrying
329
364
  # only givens. A category with no sealer simply has no such rule.
330
365
  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,
@@ -11,6 +11,7 @@ module Hecks
11
11
  class PortJudge
12
12
  attr_reader :refusals
13
13
 
14
+ # @param port [Bluebook::Port] the built port to judge
14
15
  def initialize(port)
15
16
  @port = port
16
17
  @refusals = []
@@ -34,7 +35,7 @@ module Hecks
34
35
  end
35
36
 
36
37
  def send_to(verb, label, **payload)
37
- offer(label) { @runtime.dispatch(verb, **args(payload)) }
38
+ offer(label) { @runtime.dispatch_flat(verb, args(payload)) }
38
39
  end
39
40
 
40
41
  def judge!