hecks 2.8.0 → 3.0.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 (886) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +50 -7
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +32 -100
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
  25. data/lib/hecks/adapters/driven/postgres.rb +149 -136
  26. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  27. data/lib/hecks/adapters/driven/prism.rb +48 -38
  28. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  29. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  30. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  31. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  32. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  33. data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
  34. data/lib/hecks/adapters/driven.rb +5 -36
  35. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  36. data/lib/hecks/behaviors/dsl.rb +7 -25
  37. data/lib/hecks/behaviors/expectations.rb +32 -142
  38. data/lib/hecks/behaviors/ir.rb +7 -20
  39. data/lib/hecks/behaviors/rspec.rb +6 -17
  40. data/lib/hecks/behaviors/runner.rb +10 -34
  41. data/lib/hecks/behaviors.rb +4 -8
  42. data/lib/hecks/bench/cli.rb +62 -0
  43. data/lib/hecks/bench/environment.rb +71 -0
  44. data/lib/hecks/bench/postgres_probe.rb +30 -0
  45. data/lib/hecks/bench/report.rb +76 -0
  46. data/lib/hecks/bench/ruby_runner.rb +93 -0
  47. data/lib/hecks/bench/run.rb +55 -0
  48. data/lib/hecks/bench/rust_runner.rb +101 -0
  49. data/lib/hecks/bench/stats.rb +46 -0
  50. data/lib/hecks/bench/suite.rb +98 -0
  51. data/lib/hecks/bench/workload.rb +89 -0
  52. data/lib/hecks/bench.rb +17 -0
  53. data/lib/hecks/bluebook/aggregate.rb +9 -75
  54. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  55. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  56. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  57. data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
  58. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  59. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  60. data/lib/hecks/bluebook/assembly.rb +6 -45
  61. data/lib/hecks/bluebook/attribute.rb +12 -61
  62. data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
  63. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  64. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  65. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  66. data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
  67. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  68. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  69. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  70. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  71. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  73. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  74. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  75. data/lib/hecks/bluebook/capabilities.rb +17 -49
  76. data/lib/hecks/bluebook/chapter.rb +16 -50
  77. data/lib/hecks/bluebook/command.rb +23 -81
  78. data/lib/hecks/bluebook/domain_port.rb +49 -67
  79. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  80. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  81. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  82. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  83. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
  84. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
  85. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
  86. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  87. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  88. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
  89. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  90. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  91. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
  92. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  93. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  94. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  95. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  96. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  97. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  98. data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
  99. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  100. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  101. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  102. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  103. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  104. data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
  105. data/lib/hecks/bluebook/entity.rb +13 -71
  106. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  107. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  108. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  109. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  110. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  111. data/lib/hecks/bluebook/expression/resolver.rb +39 -661
  112. data/lib/hecks/bluebook/hexagon.rb +18 -33
  113. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  114. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  115. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  116. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  117. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  118. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  119. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
  120. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  121. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
  122. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  123. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
  124. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  125. data/lib/hecks/bluebook/meta_validator.rb +87 -352
  126. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  127. data/lib/hecks/bluebook/model_check.rb +122 -596
  128. data/lib/hecks/bluebook/pattern_subset.rb +49 -69
  129. data/lib/hecks/bluebook/process_manager.rb +13 -83
  130. data/lib/hecks/bluebook/project_loader.rb +3 -39
  131. data/lib/hecks/bluebook/project_register.rb +12 -60
  132. data/lib/hecks/bluebook/query.rb +27 -51
  133. data/lib/hecks/bluebook/read_model.rb +57 -81
  134. data/lib/hecks/bluebook/reference.rb +7 -41
  135. data/lib/hecks/bluebook/smoke_test.rb +9 -99
  136. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  137. data/lib/hecks/bluebook/translation.rb +26 -62
  138. data/lib/hecks/bluebook/value_object.rb +11 -36
  139. data/lib/hecks/bluebook.rb +5 -22
  140. data/lib/hecks/cache_dir.rb +4 -23
  141. data/lib/hecks/canonical_json.rb +30 -0
  142. data/lib/hecks/chapters.rb +102 -0
  143. data/lib/hecks/cli/behaviors.rb +61 -0
  144. data/lib/hecks/cli/canonicalise.rb +25 -0
  145. data/lib/hecks/cli/check_engine_agreement.rb +32 -0
  146. data/lib/hecks/cli/check_era.rb +88 -0
  147. data/lib/hecks/cli/console.rb +66 -0
  148. data/lib/hecks/cli/deploy_template_diff.rb +40 -0
  149. data/lib/hecks/cli/doc_coverage.rb +32 -0
  150. data/lib/hecks/cli/document.rb +5 -23
  151. data/lib/hecks/cli/expression_projection.rb +41 -0
  152. data/lib/hecks/cli/follow.rb +88 -0
  153. data/lib/hecks/cli/history.rb +44 -0
  154. data/lib/hecks/cli/ir.rb +4 -6
  155. data/lib/hecks/cli/mcp.rb +5 -6
  156. data/lib/hecks/cli/model_check.rb +24 -88
  157. data/lib/hecks/cli/pattern_cases.rb +47 -0
  158. data/lib/hecks/cli/present.rb +39 -0
  159. data/lib/hecks/cli/project_cli.rb +223 -64
  160. data/lib/hecks/cli/project_diagrams.rb +4 -10
  161. data/lib/hecks/cli/project_glossary.rb +44 -0
  162. data/lib/hecks/cli/reference.rb +46 -0
  163. data/lib/hecks/cli/refresh_projections.rb +44 -0
  164. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
  165. data/lib/hecks/cli/release.rb +70 -0
  166. data/lib/hecks/cli/release_gem.rb +59 -0
  167. data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
  168. data/lib/hecks/cli/rspec_shard_files.rb +66 -0
  169. data/lib/hecks/cli/run.rb +15 -61
  170. data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
  171. data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
  172. data/lib/hecks/cli/shape.rb +70 -0
  173. data/lib/hecks/cli/smoke_http.rb +230 -0
  174. data/lib/hecks/cli/smoke_test.rb +7 -19
  175. data/lib/hecks/cli/spec_example.rb +27 -0
  176. data/lib/hecks/cli/statements.rb +32 -0
  177. data/lib/hecks/cli/stores.rb +4 -6
  178. data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
  179. data/lib/hecks/cli.rb +216 -73
  180. data/lib/hecks/codemod.rb +324 -0
  181. data/lib/hecks/construct.rb +8 -34
  182. data/lib/hecks/corpus.rb +423 -0
  183. data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
  184. data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
  185. data/lib/hecks/deploy/oidc.json +82 -2
  186. data/lib/hecks/doc/reference.rb +351 -0
  187. data/lib/hecks/doors/cli_door.rb +196 -0
  188. data/lib/hecks/doors/cli_runner.rb +297 -0
  189. data/lib/hecks/{facade → doors}/command_request.rb +14 -34
  190. data/lib/hecks/doors/handle.rb +206 -0
  191. data/lib/hecks/doors/json_door.rb +132 -0
  192. data/lib/hecks/doors/launcher_options.rb +129 -0
  193. data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
  194. data/lib/hecks/doors/mcp_door_scope.rb +97 -0
  195. data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
  196. data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
  197. data/lib/hecks/doors/ruby_door.rb +77 -0
  198. data/lib/hecks/doors.rb +61 -0
  199. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  200. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  201. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  202. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  203. data/lib/hecks/embryonaut_bluebook.rb +5 -72
  204. data/lib/hecks/engine_agreement.rb +156 -0
  205. data/lib/hecks/facade.rb +23 -51
  206. data/lib/hecks/forms/app.rb +21 -76
  207. data/lib/hecks/forms/banking_presentation.rb +50 -0
  208. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  209. data/lib/hecks/forms/field_renderer.rb +17 -156
  210. data/lib/hecks/forms/field_shape.rb +31 -222
  211. data/lib/hecks/forms/html.rb +12 -47
  212. data/lib/hecks/forms/index_renderer.rb +1 -4
  213. data/lib/hecks/forms/page.rb +3 -9
  214. data/lib/hecks/forms/params.rb +14 -60
  215. data/lib/hecks/forms/port_argument.rb +2 -19
  216. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  217. data/lib/hecks/forms/record_renderer.rb +8 -75
  218. data/lib/hecks/forms/record_table.rb +7 -50
  219. data/lib/hecks/forms/reference_options.rb +3 -30
  220. data/lib/hecks/forms/value_object_shape.rb +8 -35
  221. data/lib/hecks/forms.rb +5 -33
  222. data/lib/hecks/fqn.rb +5 -12
  223. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  224. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  225. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  226. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  227. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  228. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  229. data/lib/hecks/framework.rb +11 -80
  230. data/lib/hecks/freezer.rb +5 -39
  231. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
  232. data/lib/hecks/fuzzing/combination_miner.rb +86 -0
  233. data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
  234. data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
  235. data/lib/hecks/fuzzing/differential.rb +156 -0
  236. data/lib/hecks/fuzzing/domain_generator.rb +615 -0
  237. data/lib/hecks/fuzzing/era_boundary.rb +71 -0
  238. data/lib/hecks/fuzzing/form_census.rb +136 -0
  239. data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
  240. data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
  241. data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
  242. data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
  243. data/lib/hecks/fuzzing/outside_world.rb +45 -0
  244. data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
  245. data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
  246. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
  247. data/lib/hecks/fuzzing/properties/guards.rb +190 -0
  248. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
  249. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
  250. data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
  251. data/lib/hecks/fuzzing/properties/querying.rb +175 -0
  252. data/lib/hecks/fuzzing/properties.rb +162 -0
  253. data/lib/hecks/fuzzing/qa_settings.rb +123 -0
  254. data/lib/hecks/fuzzing/replay.rb +505 -0
  255. data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
  256. data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
  257. data/lib/hecks/fuzzing/self_consistency.rb +339 -0
  258. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
  259. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
  260. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
  261. data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
  262. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
  263. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
  264. data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
  265. data/lib/hecks/fuzzing/shrinker.rb +166 -0
  266. data/lib/hecks/fuzzing/structural_skips.rb +33 -0
  267. data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
  268. data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
  269. data/lib/hecks/fuzzing/value_generator.rb +216 -0
  270. data/lib/hecks/fuzzing.rb +23 -0
  271. data/lib/hecks/grammar/evolve.rb +336 -0
  272. data/lib/hecks/grammar/expression.bluebook +15 -40
  273. data/lib/hecks/grammar/translation.bluebook +3 -6
  274. data/lib/hecks/grammar.rb +16 -41
  275. data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
  276. data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
  277. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
  278. data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
  279. data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
  280. data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
  281. data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
  282. data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
  283. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
  284. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
  285. data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
  286. data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
  287. data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
  288. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
  289. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
  290. data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
  291. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
  292. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
  293. data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
  294. data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
  295. data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
  296. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
  297. data/lib/hecks/hecks/adapters/git.adapter +7 -0
  298. data/lib/hecks/hecks/adapters/git.rb +102 -0
  299. data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
  300. data/lib/hecks/hecks/adapters/host_http.rb +65 -0
  301. data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
  302. data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
  303. data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
  304. data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
  305. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
  306. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
  307. data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
  308. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
  309. data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
  310. data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
  311. data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
  312. data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
  313. data/lib/hecks/hecks/adapters/local_files.rb +46 -0
  314. data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
  315. data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
  316. data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
  317. data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
  318. data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
  319. data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
  320. data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
  321. data/lib/hecks/hecks/adapters/shell.adapter +7 -0
  322. data/lib/hecks/hecks/adapters/shell.rb +49 -0
  323. data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
  324. data/lib/hecks/hecks/adapters/terminal.rb +74 -0
  325. data/lib/hecks/hecks/codebase.behaviors +172 -0
  326. data/lib/hecks/hecks/codebase.bluebook +2453 -0
  327. data/lib/hecks/hecks/context_map.hecksagon +13 -0
  328. data/lib/hecks/hecks/custodian.behaviors +179 -0
  329. data/lib/hecks/hecks/custodian.bluebook +1847 -0
  330. data/lib/hecks/hecks/deploy.behaviors +74 -0
  331. data/lib/hecks/hecks/deploy.world +12 -0
  332. data/lib/hecks/hecks/environments/memory.world +10 -0
  333. data/lib/hecks/hecks/governance.world +7 -0
  334. data/lib/hecks/hecks/hecks.behaviors +62 -0
  335. data/lib/hecks/hecks/hecks.bluebook +124 -0
  336. data/lib/hecks/hecks/hecks.hecksagon +390 -0
  337. data/lib/hecks/hecks/hecks.world +42 -0
  338. data/lib/hecks/ir.rb +14 -83
  339. data/lib/hecks/kernel_capabilities.rb +194 -0
  340. data/lib/hecks/language/adapter.bluebook +2 -7
  341. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  342. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  343. data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
  344. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  345. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  346. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  347. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  348. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  349. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  350. data/lib/hecks/language/bluebook/query.bluebook +19 -43
  351. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  352. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  353. data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
  354. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  355. data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
  356. data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
  357. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  358. data/lib/hecks/language/oidc.json +35 -0
  359. data/lib/hecks/language/port.bluebook +4 -17
  360. data/lib/hecks/language/translation/translation.bluebook +3 -9
  361. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  362. data/lib/hecks/language/world/wiring.bluebook +1 -3
  363. data/lib/hecks/language/world/world.bluebook +5 -7
  364. data/lib/hecks/literal.rb +8 -50
  365. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  366. data/lib/hecks/naming.rb +29 -137
  367. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
  368. data/lib/hecks/persistence_legacy_fixture.rb +113 -0
  369. data/lib/hecks/ports/access_control.rb +7 -23
  370. data/lib/hecks/ports/agent/answers.rb +5 -23
  371. data/lib/hecks/ports/agent.rb +47 -172
  372. data/lib/hecks/ports/authentication.rb +12 -39
  373. data/lib/hecks/ports/authorization.rb +16 -43
  374. data/lib/hecks/ports/clock.rb +5 -45
  375. data/lib/hecks/ports/extraction.rb +7 -12
  376. data/lib/hecks/ports/identity_assignment.rb +8 -29
  377. data/lib/hecks/ports/identity_generation.rb +6 -29
  378. data/lib/hecks/ports/identity_resolution.rb +2 -10
  379. data/lib/hecks/ports/key_vault.rb +9 -45
  380. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  381. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  382. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  383. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  384. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  385. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
  386. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  387. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
  388. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  389. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
  390. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  391. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  392. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  393. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  394. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  395. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  396. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  397. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  398. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
  399. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  400. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  401. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  402. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  403. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  404. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
  405. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  406. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
  407. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  408. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
  409. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  410. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  411. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  412. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  413. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  414. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
  415. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  416. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  417. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  418. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  419. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  420. data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
  421. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  422. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  423. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  424. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  425. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  426. data/lib/hecks/ports/persistence/state_codec.rb +47 -108
  427. data/lib/hecks/ports/persistence.rb +7 -14
  428. data/lib/hecks/ports/projection.rb +42 -84
  429. data/lib/hecks/ports/query/in_memory.rb +10 -58
  430. data/lib/hecks/ports/query/ordering.rb +11 -32
  431. data/lib/hecks/ports/query.rb +14 -37
  432. data/lib/hecks/ports.rb +2 -8
  433. data/lib/hecks/projection_files.rb +285 -0
  434. data/lib/hecks/projections/bootstrap_table.rb +12 -44
  435. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  436. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  437. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  438. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  439. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  440. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  441. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  442. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  443. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  444. data/lib/hecks/projections/deploy/fargate.rb +40 -207
  445. data/lib/hecks/projections/deploy/lambda.rb +191 -708
  446. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  447. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  448. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  449. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  450. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  451. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  452. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  453. data/lib/hecks/projections/deploy/preview/template.rb +3 -59
  454. data/lib/hecks/projections/deploy/preview.rb +2 -67
  455. data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
  456. data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
  457. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
  458. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  459. data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
  460. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  461. data/lib/hecks/projections/deploy/shared.rb +48 -147
  462. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  463. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  464. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  465. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  466. data/lib/hecks/projections/diagrams.rb +22 -584
  467. data/lib/hecks/projections/glossary/html.rb +14 -130
  468. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  469. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  470. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  471. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  472. data/lib/hecks/projections/glossary.rb +30 -222
  473. data/lib/hecks/projections/ir.rb +3 -10
  474. data/lib/hecks/projections/model/deviations.rb +16 -43
  475. data/lib/hecks/projections/model.rb +12 -51
  476. data/lib/hecks/projections/oidc.rb +12 -56
  477. data/lib/hecks/projections/parser_table.rb +13 -32
  478. data/lib/hecks/projections/reference.rb +4 -18
  479. data/lib/hecks/projections/rust_vocabulary.rb +13 -251
  480. data/lib/hecks/projections/shape.rb +3 -29
  481. data/lib/hecks/projections/statements.rb +7 -86
  482. data/lib/hecks/projections/vocabulary.rb +6 -22
  483. data/lib/hecks/projections.rb +2 -16
  484. data/lib/hecks/projector/cli_projector.rb +154 -400
  485. data/lib/hecks/projector/docs_projector.rb +10 -201
  486. data/lib/hecks/projector/exporter.rb +42 -134
  487. data/lib/hecks/projector/ir_projector.rb +2 -9
  488. data/lib/hecks/projector/narrate_projector.rb +15 -189
  489. data/lib/hecks/projector/target.rb +13 -76
  490. data/lib/hecks/projector.rb +30 -121
  491. data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
  492. data/lib/hecks/quality_control/adapters/agent.rb +58 -0
  493. data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
  494. data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
  495. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
  496. data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
  497. data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
  498. data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
  499. data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
  500. data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
  501. data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
  502. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
  503. data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
  504. data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
  505. data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
  506. data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
  507. data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
  508. data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
  509. data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
  510. data/lib/hecks/quality_control/cli/child.rb +45 -0
  511. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
  512. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
  513. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
  514. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
  515. data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
  516. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
  517. data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
  518. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
  519. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
  520. data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
  521. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
  522. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
  523. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
  524. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
  525. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
  526. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
  527. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
  528. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
  529. data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
  530. data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
  531. data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
  532. data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
  533. data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
  534. data/lib/hecks/query_ir.rb +346 -0
  535. data/lib/hecks/query_ir_mcp.rb +198 -0
  536. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  537. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  538. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  539. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  540. data/lib/hecks/query_specification/common/options.rb +2 -6
  541. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  542. data/lib/hecks/query_specification/field_path.rb +37 -77
  543. data/lib/hecks/query_specification/hop_path.rb +12 -76
  544. data/lib/hecks/release/gem_pin.rb +2 -26
  545. data/lib/hecks/release/runner/ci_publisher.rb +5 -8
  546. data/lib/hecks/release/runner/clean_tree.rb +42 -0
  547. data/lib/hecks/release/runner/commands.rb +2 -4
  548. data/lib/hecks/release/runner/console.rb +6 -0
  549. data/lib/hecks/release/runner/gem_publisher.rb +15 -9
  550. data/lib/hecks/release/runner/npm_publisher.rb +9 -53
  551. data/lib/hecks/release/runner/preflight.rb +29 -20
  552. data/lib/hecks/release/runner/published.rb +8 -26
  553. data/lib/hecks/release/runner/tagger.rb +31 -23
  554. data/lib/hecks/release/runner.rb +60 -38
  555. data/lib/hecks/rendering.rb +4 -26
  556. data/lib/hecks/router/namespace_installer.rb +15 -39
  557. data/lib/hecks/router.rb +4 -8
  558. data/lib/hecks/runtime/adapter_lookup.rb +124 -0
  559. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  560. data/lib/hecks/runtime/boot_gates.rb +3 -18
  561. data/lib/hecks/runtime/caller.rb +19 -59
  562. data/lib/hecks/runtime/capability_graph.rb +5 -21
  563. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  564. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
  565. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  566. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  567. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  568. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  569. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  570. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  571. data/lib/hecks/runtime/dependency_planning.rb +50 -104
  572. data/lib/hecks/runtime/dispatcher.rb +134 -243
  573. data/lib/hecks/runtime/entity_element.rb +40 -462
  574. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  575. data/lib/hecks/runtime/errors.rb +32 -115
  576. data/lib/hecks/runtime/event.rb +3 -25
  577. data/lib/hecks/runtime/identity.rb +18 -154
  578. data/lib/hecks/runtime/instance.rb +18 -150
  579. data/lib/hecks/runtime/interpreting.rb +14 -70
  580. data/lib/hecks/runtime/invocation.rb +28 -164
  581. data/lib/hecks/runtime/loader.rb +109 -194
  582. data/lib/hecks/runtime/outbox.rb +39 -262
  583. data/lib/hecks/runtime/policy_interpreter.rb +43 -202
  584. data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
  585. data/lib/hecks/runtime/query_interpreter.rb +122 -187
  586. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  587. data/lib/hecks/runtime/reaction_outcome.rb +89 -0
  588. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  589. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  590. data/lib/hecks/runtime/reference_hop.rb +8 -81
  591. data/lib/hecks/runtime/refusal_wording.rb +28 -87
  592. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  593. data/lib/hecks/runtime/registry/verification.rb +213 -227
  594. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  595. data/lib/hecks/runtime/registry.rb +156 -247
  596. data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
  597. data/lib/hecks/runtime/routing.rb +4 -15
  598. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  599. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  600. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  601. data/lib/hecks/runtime/tenant_check.rb +6 -68
  602. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  603. data/lib/hecks/runtime/value/admission.rb +16 -67
  604. data/lib/hecks/runtime/value/coercion.rb +162 -760
  605. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  606. data/lib/hecks/runtime/value/field_checks.rb +172 -0
  607. data/lib/hecks/runtime/value.rb +15 -84
  608. data/lib/hecks/runtime.rb +35 -69
  609. data/lib/hecks/rust_build/conformance.rb +158 -0
  610. data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
  611. data/lib/hecks/rust_build/coverage.rb +218 -0
  612. data/lib/hecks/rust_build/native_build.rb +124 -0
  613. data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
  614. data/lib/hecks/rust_build/project_rust.rb +332 -0
  615. data/lib/hecks/rust_build/wasm.rb +105 -0
  616. data/lib/hecks/rust_build/wasm_browser.rb +113 -0
  617. data/lib/hecks/rust_build.rb +144 -0
  618. data/lib/hecks/storehouse.rb +155 -582
  619. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
  620. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  621. data/lib/hecks/three_zero/forms.yml +127 -0
  622. data/lib/hecks/three_zero.rb +12 -0
  623. data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
  624. data/lib/hecks/tools/comment_style.rb +1070 -0
  625. data/lib/hecks/tools/corpus_report.rb +87 -0
  626. data/lib/hecks/tools/deploy_recipe.rb +255 -0
  627. data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
  628. data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
  629. data/lib/hecks/tools/era_projection_backfill.rb +94 -0
  630. data/lib/hecks/tools/era_reattest.rb +146 -0
  631. data/lib/hecks/tools/evolve_run.rb +189 -0
  632. data/lib/hecks/tools/fuzz_sweep.rb +373 -0
  633. data/lib/hecks/tools/heki_compaction.rb +100 -0
  634. data/lib/hecks/tools/hoist_local_givens.rb +246 -0
  635. data/lib/hecks/tools/journal_compaction.rb +89 -0
  636. data/lib/hecks/tools/oidc_manifests.rb +70 -0
  637. data/lib/hecks/tools/query_ir_run.rb +81 -0
  638. data/lib/hecks/tools/regeneration_run.rb +166 -0
  639. data/lib/hecks/tools/rust_comment_style.rb +642 -0
  640. data/lib/hecks/tools/sequence_script.rb +62 -0
  641. data/lib/hecks/tools/tail_merge.rb +117 -0
  642. data/lib/hecks/tools/tenant_provisioning.rb +142 -0
  643. data/lib/hecks/tools/translation_audit.rb +208 -0
  644. data/lib/hecks/tools/translation_scaffold.rb +131 -0
  645. data/lib/hecks/tools.rb +86 -0
  646. data/lib/hecks/vendoring/git_environment.rb +2 -8
  647. data/lib/hecks/vendoring/git_source.rb +4 -10
  648. data/lib/hecks/vendoring.rb +7 -46
  649. data/lib/hecks/version.rb +3 -14
  650. data/lib/hecks.rb +52 -90
  651. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  652. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  653. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  654. data/qa/settings.yml +66 -0
  655. data/rust/.cargo/config.toml +6 -0
  656. data/rust/.gitignore +2 -0
  657. data/rust/Cargo.lock +54 -0
  658. data/rust/Cargo.toml +61 -0
  659. data/rust/build/.cargo/config.toml +3 -0
  660. data/rust/build/.gitignore +1 -0
  661. data/rust/build/Cargo.lock +7 -0
  662. data/rust/build/Cargo.toml +19 -0
  663. data/rust/build/src/build_artifact.rs +47 -0
  664. data/rust/build/src/cargo_sync.rs +248 -0
  665. data/rust/build/src/json.rs +421 -0
  666. data/rust/build/src/lineage_pass.rs +285 -0
  667. data/rust/build/src/main.rs +51 -0
  668. data/rust/build/src/optional_pass.rs +150 -0
  669. data/rust/build/src/pipeline.rs +264 -0
  670. data/rust/build/src/reserved_names.rs +76 -0
  671. data/rust/build/src/resolve.rs +124 -0
  672. data/rust/build/src/root.rs +25 -0
  673. data/rust/build/src/sidecars.rs +73 -0
  674. data/rust/build/src/subprocess.rs +51 -0
  675. data/rust/build/src/tmp.rs +31 -0
  676. data/rust/codegen/.cargo/config.toml +3 -0
  677. data/rust/codegen/.gitignore +1 -0
  678. data/rust/codegen/Cargo.lock +7 -0
  679. data/rust/codegen/Cargo.toml +20 -0
  680. data/rust/codegen/src/attr.rs +32 -0
  681. data/rust/codegen/src/bridging.rs +481 -0
  682. data/rust/codegen/src/commands.rs +1226 -0
  683. data/rust/codegen/src/constraints.rs +109 -0
  684. data/rust/codegen/src/dependency_planning.rs +209 -0
  685. data/rust/codegen/src/domain_generator.rs +1288 -0
  686. data/rust/codegen/src/exemplar.rs +230 -0
  687. data/rust/codegen/src/expr_emitter.rs +87 -0
  688. data/rust/codegen/src/fielded.rs +192 -0
  689. data/rust/codegen/src/hecks_naming.rs +33 -0
  690. data/rust/codegen/src/json.rs +335 -0
  691. data/rust/codegen/src/json_codec.rs +697 -0
  692. data/rust/codegen/src/literal.rs +207 -0
  693. data/rust/codegen/src/main.rs +290 -0
  694. data/rust/codegen/src/manifest.rs +227 -0
  695. data/rust/codegen/src/mutations.rs +784 -0
  696. data/rust/codegen/src/naming.rs +286 -0
  697. data/rust/codegen/src/ports.rs +208 -0
  698. data/rust/codegen/src/prelude.rs +116 -0
  699. data/rust/codegen/src/queries.rs +786 -0
  700. data/rust/codegen/src/reactions.rs +532 -0
  701. data/rust/codegen/src/read_models.rs +697 -0
  702. data/rust/codegen/src/reference_specs.rs +40 -0
  703. data/rust/codegen/src/registry.rs +966 -0
  704. data/rust/codegen/src/reserved_names.rs +76 -0
  705. data/rust/codegen/src/shared.rs +93 -0
  706. data/rust/codegen/src/skip_reason.rs +25 -0
  707. data/rust/codegen/src/types.rs +362 -0
  708. data/rust/host/.cargo/config.toml +3 -0
  709. data/rust/host/.gitignore +1 -0
  710. data/rust/host/Cargo.lock +4297 -0
  711. data/rust/host/Cargo.toml +61 -0
  712. data/rust/host/HECKS_RELEASE +1 -0
  713. data/rust/host/rds-ca-bundle.pem +2736 -0
  714. data/rust/host/src/api.rs +1596 -0
  715. data/rust/host/src/approval.rs +652 -0
  716. data/rust/host/src/auth.rs +1287 -0
  717. data/rust/host/src/bin/expr_harness.rs +46 -0
  718. data/rust/host/src/bin/lineage_harness.rs +119 -0
  719. data/rust/host/src/bin/mint_harness.rs +135 -0
  720. data/rust/host/src/checkout.rs +265 -0
  721. data/rust/host/src/dispatch.rs +1443 -0
  722. data/rust/host/src/expr_json.rs +1117 -0
  723. data/rust/host/src/field_hints.rs +52 -0
  724. data/rust/host/src/ir.rs +733 -0
  725. data/rust/host/src/journal.rs +874 -0
  726. data/rust/host/src/lambda_client.rs +378 -0
  727. data/rust/host/src/log.rs +147 -0
  728. data/rust/host/src/main.rs +474 -0
  729. data/rust/host/src/mint.rs +1865 -0
  730. data/rust/host/src/payments/keystore.rs +330 -0
  731. data/rust/host/src/payments/tests.rs +1400 -0
  732. data/rust/host/src/payments.rs +767 -0
  733. data/rust/host/src/presentation.rs +698 -0
  734. data/rust/host/src/presentation_write.rs +1431 -0
  735. data/rust/host/src/query_step.rs +149 -0
  736. data/rust/host/src/rate_limit.rs +904 -0
  737. data/rust/host/src/reference_transform.rs +241 -0
  738. data/rust/host/src/reference_validate.rs +338 -0
  739. data/rust/host/src/resend.rs +296 -0
  740. data/rust/host/src/secrets.rs +106 -0
  741. data/rust/host/src/server.rs +663 -0
  742. data/rust/host/src/storage_shape.rs +175 -0
  743. data/rust/host/src/test_pg.rs +40 -0
  744. data/rust/host/src/ui_schema.rs +1351 -0
  745. data/rust/host/src/wasm_runner.rs +191 -0
  746. data/rust/host/src/web/newsletter/cooldown.rs +126 -0
  747. data/rust/host/src/web/newsletter/tests.rs +104 -0
  748. data/rust/host/src/web/newsletter.rs +310 -0
  749. data/rust/host/src/web/newsletter_send.rs +357 -0
  750. data/rust/host/src/web/registrations.rs +1505 -0
  751. data/rust/host/src/web.rs +2937 -0
  752. data/rust/lsp/.gitignore +1 -0
  753. data/rust/lsp/Cargo.lock +7 -0
  754. data/rust/lsp/Cargo.toml +16 -0
  755. data/rust/lsp/README.md +133 -0
  756. data/rust/lsp/src/diagnostics.rs +165 -0
  757. data/rust/lsp/src/json.rs +385 -0
  758. data/rust/lsp/src/main.rs +399 -0
  759. data/rust/lsp/src/outline.rs +177 -0
  760. data/rust/lsp/src/rpc.rs +67 -0
  761. data/rust/parser/.cargo/config.toml +5 -0
  762. data/rust/parser/.gitignore +1 -0
  763. data/rust/parser/Cargo.lock +7 -0
  764. data/rust/parser/Cargo.toml +21 -0
  765. data/rust/parser/src/build/closed_sets.rs +27 -0
  766. data/rust/parser/src/build/identity.rs +276 -0
  767. data/rust/parser/src/build/mod.rs +12 -0
  768. data/rust/parser/src/build/naming.rs +141 -0
  769. data/rust/parser/src/build/pattern_subset.rs +161 -0
  770. data/rust/parser/src/build/query_derive.rs +72 -0
  771. data/rust/parser/src/build/query_inference.rs +269 -0
  772. data/rust/parser/src/build/query_options.rs +100 -0
  773. data/rust/parser/src/build/read_model.rs +94 -0
  774. data/rust/parser/src/build/references.rs +32 -0
  775. data/rust/parser/src/canonical.rs +114 -0
  776. data/rust/parser/src/diag.rs +55 -0
  777. data/rust/parser/src/emit.rs +953 -0
  778. data/rust/parser/src/expr/ast_json.rs +147 -0
  779. data/rust/parser/src/expr/evaluator.rs +81 -0
  780. data/rust/parser/src/expr/mod.rs +84 -0
  781. data/rust/parser/src/expr/resolver.rs +497 -0
  782. data/rust/parser/src/ir.rs +387 -0
  783. data/rust/parser/src/keywords.rs +585 -0
  784. data/rust/parser/src/lex.rs +662 -0
  785. data/rust/parser/src/main.rs +252 -0
  786. data/rust/parser/src/parse/aggregate.rs +612 -0
  787. data/rust/parser/src/parse/chapter.rs +517 -0
  788. data/rust/parser/src/parse/command.rs +637 -0
  789. data/rust/parser/src/parse/domain_port.rs +127 -0
  790. data/rust/parser/src/parse/entity.rs +527 -0
  791. data/rust/parser/src/parse/file.rs +67 -0
  792. data/rust/parser/src/parse/hecksagon.rs +231 -0
  793. data/rust/parser/src/parse/lifecycle.rs +162 -0
  794. data/rust/parser/src/parse/mod.rs +1262 -0
  795. data/rust/parser/src/parse/policy.rs +87 -0
  796. data/rust/parser/src/parse/process_manager.rs +305 -0
  797. data/rust/parser/src/parse/query.rs +100 -0
  798. data/rust/parser/src/parse/read_model.rs +214 -0
  799. data/rust/parser/src/parse/value_object.rs +250 -0
  800. data/rust/parser/src/ruby_value.rs +422 -0
  801. data/rust/project/bridging.rb +257 -0
  802. data/rust/project/commands.rb +877 -0
  803. data/rust/project/constraints.rb +86 -0
  804. data/rust/project/dependency_planning.rb +178 -0
  805. data/rust/project/domain_generator.rb +980 -0
  806. data/rust/project/exemplar.rb +148 -0
  807. data/rust/project/expr_emitter.rb +72 -0
  808. data/rust/project/fielded.rb +141 -0
  809. data/rust/project/json_codec.rb +641 -0
  810. data/rust/project/mutations.rb +721 -0
  811. data/rust/project/naming.rb +205 -0
  812. data/rust/project/ports.rb +65 -0
  813. data/rust/project/queries.rb +493 -0
  814. data/rust/project/reactions.rb +317 -0
  815. data/rust/project/read_models.rb +690 -0
  816. data/rust/project/reference_specs.rb +27 -0
  817. data/rust/project/registry.rb +396 -0
  818. data/rust/project/skip_reason.rb +29 -0
  819. data/rust/project/types.rb +225 -0
  820. data/rust/project/write_if_changed.rb +83 -0
  821. data/rust/project.rb +30 -0
  822. data/rust/project_rust_pipeline.rb +383 -0
  823. data/rust/src/exemplar/commands.rs +279 -0
  824. data/rust/src/exemplar/constraints.rs +18 -0
  825. data/rust/src/exemplar/fielded.rs +280 -0
  826. data/rust/src/exemplar/json.rs +277 -0
  827. data/rust/src/exemplar/mod.rs +17 -0
  828. data/rust/src/exemplar/mutations.rs +80 -0
  829. data/rust/src/exemplar/queries.rs +33 -0
  830. data/rust/src/exemplar/reactions.rs +88 -0
  831. data/rust/src/exemplar/read_models.rs +48 -0
  832. data/rust/src/exemplar/registry.rs +166 -0
  833. data/rust/src/exemplar/types.rs +44 -0
  834. data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
  835. data/rust/src/kernel/attribute_shapes/list.rs +18 -0
  836. data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
  837. data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
  838. data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
  839. data/rust/src/kernel/cli.rs +585 -0
  840. data/rust/src/kernel/dispatch.rs +1090 -0
  841. data/rust/src/kernel/expr.rs +458 -0
  842. data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
  843. data/rust/src/kernel/expression_operators/comparison.rs +48 -0
  844. data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
  845. data/rust/src/kernel/expression_operators/logical.rs +13 -0
  846. data/rust/src/kernel/expression_operators/membership.rs +18 -0
  847. data/rust/src/kernel/expression_operators/mod.rs +68 -0
  848. data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
  849. data/rust/src/kernel/expression_operators/positional.rs +126 -0
  850. data/rust/src/kernel/expression_operators/presence.rs +101 -0
  851. data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
  852. data/rust/src/kernel/expression_operators/sized.rs +35 -0
  853. data/rust/src/kernel/expression_operators/text.rs +79 -0
  854. data/rust/src/kernel/expression_operators/to_string.rs +18 -0
  855. data/rust/src/kernel/json.rs +779 -0
  856. data/rust/src/kernel/mod.rs +133 -0
  857. data/rust/src/kernel/named_query.rs +219 -0
  858. data/rust/src/kernel/orchestrate.rs +1810 -0
  859. data/rust/src/kernel/pattern.rs +307 -0
  860. data/rust/src/kernel/query_comparators.rs +206 -0
  861. data/rust/src/kernel/query_ordering.rs +103 -0
  862. data/rust/src/kernel/read_model.rs +914 -0
  863. data/rust/src/kernel/reference_lookup.rs +149 -0
  864. data/rust/src/kernel/repository.rs +468 -0
  865. data/rust/src/kernel/routing.rs +612 -0
  866. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
  867. data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
  868. data/rust/src/kernel/vocab/field_hint.rs +70 -0
  869. data/rust/src/kernel/vocab/mod.rs +20 -0
  870. data/rust/src/kernel/vocab/query_comparator.rs +65 -0
  871. data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
  872. data/rust/src/lib.rs +8 -0
  873. data/rust/src/main.rs +16 -0
  874. data/rust/web/.gitignore +1 -0
  875. data/rust/web/Cargo.lock +119 -0
  876. data/rust/web/Cargo.toml +18 -0
  877. data/rust/web/src/lib.rs +8 -0
  878. metadata +478 -12
  879. data/lib/hecks/facade/cli_door.rb +0 -178
  880. data/lib/hecks/facade/cli_runner.rb +0 -271
  881. data/lib/hecks/facade/handle.rb +0 -293
  882. data/lib/hecks/facade/json_door.rb +0 -247
  883. data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
  884. data/lib/hecks/facade/surface/chapter.rb +0 -116
  885. data/lib/hecks/facade/surface.rb +0 -61
  886. data/lib/hecks/mcp_door_scope.rb +0 -176
@@ -1,69 +1,27 @@
1
1
  module Hecks
2
2
  module Bluebook
3
3
  module MetaValidator
4
- # Offers every declaration in a built bluebook to the meta-domain.
5
- #
6
- # There are no hand-written branches, one per category: that shape's
7
- # real cost is any verb the language declares that the judge never
8
- # offers — a branch nobody wrote for it — going undetected, since a
9
- # branch that does not exist cannot fail. `Command.Argument` and
10
- # `ValueObject.Field` were both admitted that way once, undetected;
11
- # every rule hanging off them was decoration until offered for real.
12
- #
13
- # So instead the judge walks: it reads the plan the language makes of
14
- # itself (Plan), and for each node offers the creating command, then
15
- # each list through the command that appends to it, then each child. A
16
- # verb in the plan with no offer is now impossible — there is no
17
- # branch left in which to forget one, and spec/judge_coverage_spec
18
- # holds it to that.
19
- #
20
- # What is not uniform lives in Readings, and only where the IR's shape
21
- # differs from the language's. Naming differences do not appear at all: the
22
- # language spells its fields as the IR spells them.
23
- #
24
- # Only the dispatch half of the round trip lives here. Reconstruction is the
25
- # experiment's business ; judging does not need it.
4
+ # Offers every declaration in a built bluebook to the meta-domain by
5
+ # walking the plan itself, so no verb the language declares can go
6
+ # un-offered by omission.
26
7
  class Judge
27
8
  include Readings
28
9
 
29
- # Children offered before the parent's own lists, in this order. An
30
- # attribute's type is offered as the id of the thing it names, so the
31
- # value objects have to exist before anything that can name one — an
32
- # aggregate's own attributes, and an entity's own (M13: an entity is its
33
- # own root, repeating the aggregate's whole shape one level down, so its
34
- # attributes resolve against the same value-object pool). ValueObject
35
- # first, Entity second, so an entity's own attributes are never offered
36
- # before the value objects they may reference exist — a self-hosting
37
- # casualty found live: the meta-grammar's own Handler/Dispatch/Member/
38
- # Keyword/Argument entities (S17, ADR 0026) failed reference resolution
39
- # on their own plain value-object-typed attributes (`HandlerText`,
40
- # `MemberPosition`, ...) the moment entity attributes started being
41
- # checked at all, because `@plan.names`' own (incidental) declaration
42
- # order happened to walk Entity first. The order is stated here, not
43
- # left to whatever order the plan's own category table iterates in —
44
- # see `detail_node`'s own use of this constant, below.
10
+ # ValueObject before Entity: an entity's own attributes may
11
+ # reference a value object, which must exist before it resolves.
45
12
  EAGER_CHILDREN = { "Aggregate" => %w[ValueObject Entity] }.freeze
46
13
 
47
- # Categories an entity declares as well as an aggregate. The IR reuses
48
- # Command and Query for a piece's own commands and queries, so the
49
- # language reuses Command and Query — and the plan cannot express a second
50
- # parent, because a category's parent is derived from the one `*_id` argument
51
- # its creating command carries. This says the other edge out loud.
14
+ # Command and Query are reused for a piece's own commands/queries,
15
+ # since the plan derives a category's parent from its creating
16
+ # command's one `*_id` argument and cannot express a second parent.
52
17
  WITHIN_ENTITY = %w[Command Query].freeze
53
18
 
54
19
  attr_reader :refusals
55
20
 
56
- # **The records survive the verdict**.
57
- #
58
- # Judging a bluebook and holding one differ by exactly this: whether anyone
59
- # keeps the runtime the declarations were dispatched into. Nobody did, so
60
- # `spec/round_trip_spec` reached the records by `Judge.allocate` and four
61
- # `instance_variable_set` calls. Reading the chapter back is the point now,
62
- # not a curiosity, so the runtime is simply readable.
21
+ # The runtime dispatched into, not just the refusals, so a caller
22
+ # can read the resulting records back out.
63
23
  attr_reader :runtime
64
24
 
65
- # @param bluebook [Object] a built bluebook chapter graph, as
66
- # `MetaValidator.call` receives it
67
25
  def initialize(bluebook)
68
26
  @bluebook = bluebook
69
27
  @refusals = []
@@ -74,13 +32,9 @@ module Hecks
74
32
 
75
33
  private
76
34
 
77
- # Absent is not empty. The rules read "if you declare it, declare
78
- # something" — a description never given is legal. Passing "" for a nil
79
- # turns every one of them into "you must declare it".
80
- #
81
- # An Integer stays an Integer : RowCount declares `attribute :value,
82
- # Integer`, so stringifying a member count fails the type gate rather than
83
- # feeding the rule it was meant to feed.
35
+ # nil stays nil so an optional field reads as undeclared rather
36
+ # than declared-empty; an Integer passes through raw so a typed
37
+ # field (RowCount's `value`) still hits its own type gate.
84
38
  def v(text)
85
39
  return nil if text.nil?
86
40
  return { value: text } if text.is_a?(Integer)
@@ -88,14 +42,8 @@ module Hecks
88
42
  { value: text.to_s }
89
43
  end
90
44
 
91
- # A reference is an ID, and an ID is a scalar.
92
- #
93
- # Every other field goes to the meta-domain as a one-field value object,
94
- # because that is what it is. A reference is not: it carries the id of a
95
- # head, and wrapping an id in an object was the language saying `{value:
96
- # "Banking::Customer"}` where it meant `"Banking::Customer"`. The plan
97
- # answers which arguments those are, read from the language's own IR, so
98
- # nothing here needs to know the names.
45
+ # A reference argument is passed as the bare id it names; every
46
+ # other field is wrapped as a one-field value object instead.
99
47
  def carried(plan, verb, argument, value)
100
48
  return v(value) unless plan && verb && plan.references?(verb, argument)
101
49
 
@@ -108,48 +56,25 @@ module Hecks
108
56
  yield
109
57
  rescue Runtime::GivenNotMet, Runtime::InvariantViolation,
110
58
  Runtime::TypeMismatch, Runtime::NotFound => e
111
- # NotFound is a verdict, not noise. An attribute's type is a reference to
112
- # its value object, so "no ValueObject with id …" is the rule `attributes
113
- # must use value-object types` refusing.
59
+ # NotFound is a verdict, not noise: an attribute's type is a
60
+ # reference to its value object, so "no ValueObject with id ..."
61
+ # is `attributes must use value-object types` refusing.
114
62
  @refusals << "#{label}: #{e.message}"
115
63
  rescue Runtime::UnknownVerb
116
64
  nil
117
65
  end
118
66
 
119
- # QualityControl BUG#125 — every dispatch the judge makes into the
120
- # meta-domain goes through here, and only here, so this is the one
121
- # place `Runtime::Value.judge_bootstrapping` needs to wrap: it tells
122
- # `Value::Coercion#check_scalar_shapes` this construction is the
123
- # language's own self-hosted grammar walk, not a real domain's
124
- # command, so a String-typed meta-grammar field (`Normalise`'s
125
- # `position`, a `RuleText` — `appends`' generic walk-index handling
126
- # collides with that field's own name, see the flag's own comment
127
- # in coercion.rb) may still arrive as the raw Integer `appends`
128
- # hands it. Scoped to exactly this method: nothing outside a judge's
129
- # own dispatch ever runs inside it, so an ordinary domain command
130
- # (a real caller's own PieceId, Money, …) is never affected.
67
+ # Wrapped in judge_bootstrapping: the walk's own values sometimes
68
+ # arrive as raw types a real domain command would never accept,
69
+ # and only a judge's own dispatch should relax for that.
131
70
  def send_to(verb, label, to: nil, **payload)
132
71
  Runtime::Value.judge_bootstrapping do
133
72
  offer(label) { @runtime.dispatch(verb, to: to, with: args(payload)) }
134
73
  end
135
74
  end
136
75
 
137
- # The receiver, spelled the way a real caller addresses it.
138
- #
139
- # `receiver` is an internal accumulator — it tracks the aggregate this
140
- # walk is inside and, once it crosses into a real entity-owned category
141
- # (Member/Handler/Dispatch — S17, ADR 0026), every entity hop on top of
142
- # it. But `Routing.envelope`/`parse_envelope_hash` do not want that
143
- # shape restated when there is no entity to route to: a plain aggregate
144
- # command is addressed by its bare id (`Facade::Handle#dispatch` — "to:
145
- # @id" — and `CommandRequest`'s own header: "aggregate command: { to:
146
- # "record-id", ... }"), never `{aggregate:, entities: []}` — that hash
147
- # is the entity route's own shape, degenerate with nothing in it.
148
- #
149
- # So this is the one place `receiver` turns into a `to:` value: bare
150
- # when there is no entity hop (the overwhelming common case — every
151
- # category but those three), the full envelope only when there
152
- # genuinely is one.
76
+ # A bare id when there is no entity hop (the common case); the
77
+ # full {aggregate:, entities:} envelope only when there is one.
153
78
  def address(receiver)
154
79
  return receiver[:aggregate] if receiver[:entities].empty?
155
80
 
@@ -161,19 +86,9 @@ module Hecks
161
86
  detail_node("Bluebook", @bluebook, nil, 0)
162
87
  end
163
88
 
164
- # Declared before detailed, for every set of siblings.
165
- #
166
- # Offering a node whole — declared, then its lists, then its children
167
- # — one sibling at a time would mean an aggregate's attributes are
168
- # offered before its later siblings exist, so an attribute that
169
- # points at another aggregate could only resolve if that aggregate
170
- # happens to be declared earlier in the file: banking would survive
171
- # on luck, Customer written above Account.
172
- #
173
- # So siblings are declared in one pass and detailed in a second. It is the
174
- # same ordering the walk already used one level down — value objects before
175
- # the attributes that name them — lifted to the level above, and it is what
176
- # lets a reference be a reference rather than a string nobody can check.
89
+ # Every sibling is declared before any is detailed, so one
90
+ # sibling's attribute can reference another declared later in
91
+ # the same file.
177
92
  def declare_node(category, node, parent_id, index, extra = {}, receiver: nil)
178
93
  plan = @plan.category(category)
179
94
  return unless plan
@@ -186,51 +101,21 @@ module Hecks
186
101
  return unless plan
187
102
 
188
103
  id = identify(category, parent_id, node, index)
189
- # `extra` is the cumulative identity of every entity-owned
190
- # ancestor above this node (Handler's own `event_type` and
191
- # ProcessManager's own `bluebook`/`name`, by the time Dispatch
192
- # is reached — S17, ADR 0026's two-level chain). `identity`
193
- # adds this node's own on top — computed for every category,
194
- # entity-owned or not, because a node need not be entity-owned
195
- # itself to own one (ValueObject isn't, and Member still needs
196
- # its `aggregate:`/`name:`) — it is simply what this node's own
197
- # `identified_by` resolves to, the same fields `identify` two
198
- # lines up already derives the joined id from.
199
- #
200
- # `own` is the subset actually spent on a dispatch payload —
201
- # only when this category is itself entity-owned, since an
202
- # ordinary category (Command's own "Rule"/"Argument", offered
203
- # through the same `extra` slot for a different reason, see
204
- # `within_entity` below) locates the record it attaches to
205
- # through the parent id `id:` already carries, and merging
206
- # unrecognized `aggregate:`/`entity_id:` into their payload
207
- # would have the runtime refuse them for an argument they
208
- # never declared.
104
+ # `extra` carries every entity-owned ancestor's identity down to
105
+ # this node; an ordinary category ignores it and locates its
106
+ # record through `id:` instead, so merging it in would be
107
+ # refused as an unrecognized argument.
209
108
  identity = extra.merge(node_identity(plan, category, node, index, parent_id))
210
109
  receiver ||= { aggregate: id, entities: [] }
211
110
  eager, later = children_of(category).partition { |child| eager?(category, child) }
212
- # Ordered as `EAGER_CHILDREN` declares, not as `children_of` happens to
213
- # list them — `children_of` reads `@plan.names`, whose own order is an
214
- # accident of which .bluebook file registered which category first,
215
- # never a promise about which of two eager children exists before the
216
- # other. `EAGER_CHILDREN`'s own array is that promise (ValueObject
217
- # before Entity), so the walk keeps only what this parent actually
218
- # has, in the order the constant states — see that constant's own
219
- # comment for the bug this exact reordering fixes.
111
+ # `children_of`'s order is incidental (plan registration order);
112
+ # keep only what EAGER_CHILDREN promises, in the order it does.
220
113
  eager = Array(EAGER_CHILDREN[category]) & eager
221
114
 
222
115
  eager.each { |child| walk_all(child, node, id, entity_child_extra(child, identity), receiver: receiver) }
223
116
  setters(plan, category, node, receiver)
224
- # Before `appends`, not after — the same reason `EAGER_CHILDREN`
225
- # walks an aggregate's own entities before its own attributes
226
- # (M13): a piece nested inside a piece (Handler's own
227
- # `dispatches, list_of(Dispatch)` — S17, ADR 0026) must exist
228
- # before this piece's own attribute list can reference it as a
229
- # held entity, the same way `Account#ledger` needs Account's own
230
- # entities walked eagerly. `nest_entities` is a no-op for every
231
- # category but "Entity" (its own early return), so reordering it
232
- # ahead of `appends` costs nothing for anything else that walks
233
- # through here.
117
+ # Before `appends`: a nested entity referenced from this node's
118
+ # own attribute list must exist before that list is walked.
234
119
  nest_entities(category, node, id, parent_id)
235
120
  appends(plan, category, node, receiver, parent_id)
236
121
  later.each { |child| walk_all(child, node, id, entity_child_extra(child, identity), receiver: receiver) }
@@ -238,42 +123,16 @@ module Hecks
238
123
  sealers(plan, category, receiver)
239
124
  end
240
125
 
241
- # What a child's own `extra` starts from. An entity-owned child's
242
- # own dotted dispatch needs every ancestor's identity, which is
243
- # exactly `identity` — already accumulated one level at a time by
244
- # `detail_node` itself (regardless of whether each ancestor is
245
- # itself entity-owned — ValueObject contributes its own `aggregate:
246
- # `/`name:` to Member's payload despite being an ordinary top-
247
- # level category), so there is nothing left to re-derive here. An
248
- # ordinary child (one with a real top-level aggregate of its own
249
- # to dispatch a bare verb into) needs none of it.
126
+ # Only an entity-owned child needs the accumulated ancestor
127
+ # identity; an ordinary child dispatches through its own
128
+ # top-level aggregate.
250
129
  def entity_child_extra(child, identity)
251
130
  @plan.category(child)&.entity_owned ? identity : {}
252
131
  end
253
132
 
254
- # One node's own identity, read off its own declaration — S17,
255
- # ADR 0026. Three cases, the same three `identify`/`identity_part`
256
- # already resolve one level up, unified here because a chain now
257
- # walks more than one level (Handler -> Dispatch) and each level
258
- # needs the same three answered about itself, not just the first:
259
- #
260
- # the parent link (plan.parent_key) -> `parent_id`, the id
261
- # the walk already carries in from one level up
262
- # a walk-minted one (`POSITION`) -> the walk index itself ;
263
- # never a stored field (Member's own header:
264
- # "position is not a mint — it is read straight
265
- # out of the source file")
266
- # a real field (anything else) -> `field_value`, same
267
- # reader every other field in this file uses
268
- # (Handler's own `event_type`, Dispatch's own
269
- # `command_name`)
270
- #
271
- # `carried` still decides bare-vs-wrapped the normal way ; `POSITION`
272
- # is the one case with no verb to ask `carried` about (`plan.
273
- # declare` is always nil for an entity-owned category — Plan#read's
274
- # own comment says why), so it is minted straight as a value object,
275
- # matching exactly what `declare`'s own field loop already mints a
276
- # `POSITION` field as.
133
+ # Each identity field comes from one of three places: the parent
134
+ # link, the walk's own index (`POSITION`), or a real field read off
135
+ # the node.
277
136
  def node_identity(plan, category, node, index, parent_id)
278
137
  plan.identity_paths.each_with_object({}) do |path, fields|
279
138
  head = path.to_s.split(".").first
@@ -288,26 +147,19 @@ module Hecks
288
147
  end
289
148
  end
290
149
 
291
- # The full dotted prefix a category's own verbs hang off — the
292
- # plain name for an ordinary category (its own top-level
293
- # aggregate reaches every verb bare), or its parent's own prefix
294
- # with this category's name appended, for an entity-owned one.
295
- # Dispatch's own parent, Handler, is itself entity-owned (S17,
296
- # ADR 0026's two-level chain — `ProcessManager.Handler.Dispatch`),
297
- # so this recurses rather than reading one level and stopping.
150
+ # An ordinary category's own top-level aggregate reaches every
151
+ # verb bare; an entity-owned one prefixes its parent's own dotted
152
+ # path instead (ADR 0026), since a nested entity's parent may
153
+ # itself be entity-owned.
298
154
  def dotted_prefix(plan)
299
155
  return plan.name unless plan.entity_owned
300
156
 
301
157
  "#{dotted_prefix(@plan.category(plan.parent))}.#{plan.name}"
302
158
  end
303
159
 
304
- # Entity-owned categories have no top-level aggregate for the runtime
305
- # to route a bare verb into — `Member`'s own "Pair" reaches
306
- # the runtime as `ValueObject.Member.Pair`, and a nested one
307
- # (`Dispatch`, inside `Handler`) reaches it as `ProcessManager.
308
- # Handler.Dispatch.Bind` — the dotted shape `EntityInterpreter#call`
309
- # already splits any real entity's own verb into, one hop per
310
- # segment (`walk_entity_chain`, entity_interpreter.rb).
160
+ # Entity-owned categories have no top-level aggregate to route a
161
+ # bare verb into, so the verb is addressed by this category's
162
+ # full dotted path instead.
311
163
  def verb_for(plan, verb)
312
164
  "#{dotted_prefix(plan)}.#{verb}"
313
165
  end
@@ -329,15 +181,10 @@ module Hecks
329
181
  end
330
182
  end
331
183
 
332
- # A piece's commands and queries, addressed under the piece so two commands
333
- # of the same name on an aggregate and on one of its entities cannot collide,
334
- # while `aggregate` still names the aggregate the reference resolves
335
- # against and `entity_id` says which piece declared it. `entity_id`
336
- # keeps its own `_id` — an explicit `as:` on `reference_to Entity`,
337
- # never touched by ADR 0025's rename (only the default, un-aliased
338
- # mint dropped the suffix; `aggregate` did precisely because
339
- # `Command#reference_to Aggregate`/`Query#reference_to Aggregate`
340
- # carry no `as:` of their own).
184
+ # Addressed under the piece so a command name can't collide
185
+ # between an aggregate and one of its entities; `aggregate` says
186
+ # what a reference resolves against, `entity_id` says which
187
+ # piece declared it.
341
188
  def within_entity(category, node, id, aggregate)
342
189
  return unless category == "Entity"
343
190
 
@@ -350,30 +197,10 @@ module Hecks
350
197
  end
351
198
  end
352
199
 
353
- # An entity may nest further entities — S17, ADR 0026's own words:
354
- # "That is what `entity` is for, and `entity` is declared by the
355
- # language and used zero times in it." `Dispatch`, inside
356
- # `Handler`, is the first real use. The generic "Entity" category
357
- # cannot express this through `children_of`/`EAGER_CHILDREN` the
358
- # way Aggregate's own entities/value_objects can — there is only
359
- # one "Entity" Plan category, describing what any entity looks
360
- # like, not one per nesting level — so this recurses by hand,
361
- # the same special case `within_entity` (above) already is for
362
- # Command/Query.
363
- #
364
- # `owner` is the field this repurposes — `entity.bluebook`
365
- # declares it (`attribute :owner, EntityText`) and it has held
366
- # exactly one value since ADR 0025's rename: the same id
367
- # `aggregate` already carries, kept as a wrapped-text copy,
368
- # never read back anywhere else in this codebase (grep finds no
369
- # second reference). For a nested entity, the two finally
370
- # diverge — `aggregate` stays the root (Dispatch resolves
371
- # exactly the way any other Entity record does, by its root
372
- # aggregate), and `owner` becomes this entity's own direct
373
- # parent (Handler, not ProcessManager) — which is exactly the
374
- # fact `Reconstruction#direct_entities` needs to tell a
375
- # root-level entity apart from a nested one sharing the same
376
- # root.
200
+ # An entity may nest further entities (ADR 0026): `aggregate`
201
+ # stays the walk's root, while `owner` is this entity's own
202
+ # direct parent — what tells a nested entity apart from a
203
+ # root-level one sharing that same root.
377
204
  def nest_entities(category, node, id, aggregate)
378
205
  return unless category == "Entity"
379
206
 
@@ -384,16 +211,11 @@ module Hecks
384
211
  })
385
212
  end
386
213
 
387
- # Where it sits among its siblings is a fact about the walk, not about the
388
- # node : a command does not know it is the third command on its aggregate.
389
- # The walk knows, so the walk supplies it, and every other field still
390
- # comes from the node. Without this, declaration order would survive only
391
- # because the meta store happens to iterate in insertion order — an
392
- # accident that an ask ordered any other way would take away, and
393
- # Reconstruction is the one reader that must have the source's order
394
- # rather than a stable one.
214
+ # Where a node sits among siblings is a fact about the walk, not
215
+ # the node, so the walk supplies it rather than reading a stored
216
+ # field; Reconstruction depends on this being the source order.
395
217
  # `private` above has no effect on a constant; kept here anyway,
396
- # beside the method that reads it, for the narrative.
218
+ # beside the method that reads it.
397
219
  # rubocop:disable-next Lint/UselessConstantScoping
398
220
  POSITION = "position".freeze
399
221
 
@@ -413,10 +235,9 @@ module Hecks
413
235
  send_to("Bluebook::#{verb_for(plan, plan.declare)}", id, to: id, **payload.merge(extra))
414
236
  end
415
237
 
416
- # A setter whose every source is absent is not dispatched. An aggregate
417
- # with no lifecycle has no Lifecycle to offer, and a creating command has
418
- # no root to act on — offering either as "" would make a rule refuse a
419
- # bluebook that is perfectly well formed.
238
+ # A setter whose every source is absent is not dispatched —
239
+ # offering "" would make a rule refuse a bluebook that is
240
+ # well-formed.
420
241
  def setters(plan, category, node, receiver)
421
242
  plan.setters.each do |setter|
422
243
  payload = setter.targets.to_h do |target, argument|
@@ -434,10 +255,8 @@ module Hecks
434
255
  plan.appends.each do |list_name, append|
435
256
  rows_for(category, list_name, node).each_with_index do |row, index|
436
257
  chosen = append_for(category, list_name, append, row, node)
437
- # `position` is the walk index here exactly as it is in `declare` —
438
- # an appended element that names its position (ValueObject.Member,
439
- # S17) is ordered by where the walk found it, never by a field the
440
- # row happens to hold.
258
+ # `position` is the walk index, as in `declare`: an appended
259
+ # element is ordered by where the walk found it.
441
260
  payload = chosen.map.to_h do |field, argument|
442
261
  value = if field.to_s == POSITION
443
262
  v(index)
@@ -454,16 +273,10 @@ module Hecks
454
273
  end
455
274
  end
456
275
 
457
- # Which aggregate owns the value objects an attribute's type may
458
- # resolve against. An aggregate owns its own — `id` already names
459
- # it. An entity never has value objects of its own (Entity
460
- # deliberately never answers `value_object` — see entity.rb's own
461
- # comment on why); its attributes read the same pool its
462
- # enclosing aggregate declares, one level up the construct tree
463
- # no matter how many entities deep this attribute is nested —
464
- # `parent_id` names it because `detail_node`/`nest_entities`
465
- # thread the root aggregate's id down as `parent_id` at every
466
- # entity level, never the direct (possibly entity) parent.
276
+ # An entity has no value objects of its own; its attributes
277
+ # resolve against its enclosing aggregate's pool, so the root
278
+ # aggregate id (`parent_id`, not the direct parent) is what this
279
+ # returns for it.
467
280
  def owning_aggregate_ref(category, id, parent_id)
468
281
  category == "Entity" ? parent_id : id
469
282
  end
@@ -473,68 +286,36 @@ module Hecks
473
286
  plan.sealers.each { |verb| send_to("Bluebook::#{verb_for(plan, verb)}", id, to: address(receiver)) }
474
287
  end
475
288
 
476
- # An aggregate's or an entity's attribute names its value object by type,
477
- # and the language models that as a reference — so the type is offered as
478
- # the value object's own id. This is the rule "attributes must use
479
- # value-object types", enforced by reference resolution rather than by a
480
- # predicate — for a head's own attributes, aggregate or entity alike: an
481
- # entity is its own root, repeating the aggregate's whole shape one level
482
- # down (entity.rb's own words), and an undeclared type on an entity's
483
- # attribute must fail the same reference resolution an aggregate's own
484
- # does, not go unchecked because only "Aggregate.attributes" was ever
485
- # asked.
486
- # An attribute's type is offered as the ID of the thing it names, so the
487
- # language resolves it as a reference and "the type is declared" costs no
488
- # predicate. Three kinds, three ids: a value object and an entity both hang
489
- # off this aggregate, so they share its prefix; another aggregate's head
490
- # hangs off the chapter.
289
+ # An attribute's type is offered as the id of the value object it
290
+ # names, so "attributes must use value-object types" is enforced
291
+ # by reference resolution rather than a predicate — for an
292
+ # entity's own attributes too, since an entity is its own root.
491
293
  def cell(category, list_name, row, field, id, append, aggregate_id)
492
294
  value = row_value(row, field)
493
- # A default keeps its type by being written as a literal — 0.0 rather than
494
- # "0.0" — because the language holds it as text and text alone forgets.
295
+ # A default keeps its type by being written as a literal (0.0,
296
+ # not "0.0"): the language holds it as text, and text alone forgets.
495
297
  return encode_literal(value) if field == :default
496
298
  return value unless field == :type
497
- # A reference names another head wherever it is written — on a head, on
498
- # a command, on a piece, on an ask — so it is offered as that head's
499
- # id in all four. Only a head's own attributes additionally qualify
500
- # an ordinary type into a value object's id ; a command argument's
501
- # type is text and stays text.
299
+ # A reference names another head wherever it's written (on a
300
+ # head, a command, a piece, or an ask), so it's offered as that
301
+ # head's id in all four; only a head's own attributes further
302
+ # qualify a plain type into a value object's id.
502
303
  return points_at(row, id) if append.verb == "Reference"
503
304
  return value unless attribute_list?(category, list_name)
504
305
 
505
306
  Naming.identity([owning_aggregate_id(aggregate_id, value), value])
506
307
  end
507
308
 
508
- # A head's own attributes — an aggregate's, or an entity's (its own root,
509
- # one level down). Every other "attributes" list belongs to something that
510
- # is not a head at all (a command's arguments, a value object's own
511
- # fields), and a type written there is a name, not a reference — the same
512
- # distinction `cell`'s own comment draws.
309
+ # A head's own attributes (an aggregate's, or an entity's own
310
+ # root). Every other "attributes" list belongs to something that
311
+ # isn't a head, so a type written there is a name, not a reference.
513
312
  def attribute_list?(category, list_name)
514
313
  list_name.to_s == "attributes" && %w[Aggregate Entity].include?(category)
515
314
  end
516
315
 
517
- # `id` names the attribute's own aggregate, not necessarily the
518
- # value object's — Wave 7's own translation.bluebook/translation_
519
- # aggregate.bluebook split proved the difference live:
520
- # TranslationAggregate's own `was`/every rename-rule's own `from`/
521
- # `to`/... all deliberately reuse the sibling "Translation"
522
- # aggregate's own `TranslationName` (that file's own header:
523
- # "the shared TranslationName every non-identity field below
524
- # uses"), a real, intentional cross-aggregate reuse — not the
525
- # local-only ownership every other real domain in this corpus
526
- # happens to have used until now.
527
- #
528
- # `id` (already `Naming.identity([chapter, aggregate])`-joined)
529
- # only ever composes with the local aggregate for real, non-
530
- # entity-owned attributes — an entity's own `id` never matches
531
- # any top-level aggregate here, so `local` stays nil and this
532
- # returns `id` unchanged, exactly the prior behavior. Same for
533
- # every attribute whose type is locally declared (the overwhelming
534
- # common case, Banking's own Customer/Account included) — this
535
- # only ever changes the answer when the local aggregate does not
536
- # declare `value` itself, falling back to the first (declaration-
537
- # order) other aggregate in the same chapter that does.
316
+ # A value object's type may be declared on a different aggregate
317
+ # in the same chapter; the local aggregate is tried first, then
318
+ # the first (declaration-order) other aggregate that declares it.
538
319
  def owning_aggregate_id(id, value)
539
320
  local = @bluebook.aggregates.find { |aggregate| Naming.identity([@bluebook.name, aggregate.name]) == id }
540
321
  return id unless local
@@ -546,37 +327,20 @@ module Hecks
546
327
  Naming.identity([@bluebook.name, owner.name])
547
328
  end
548
329
 
549
- # Whichever construct kind `value` actually is — a value object
550
- # (Attribute) or an entity this aggregate holds (Holds); `cell`'s
551
- # own caller already knows which verb it dispatches, but not
552
- # which collection to search here without re-deriving that same
553
- # decision, so this simply checks both. The self-hosted grammar's
554
- # own Bluebook:Syntax#attributes proved entities need the same
555
- # cross-aggregate fallback value objects do — Syntax's own
556
- # `Argument`-typed attribute names Command's entity, not one of
557
- # Syntax's own.
330
+ # Checks both value objects and entities this aggregate declares:
331
+ # the caller already knows which verb it dispatches, not which
332
+ # collection to search, without re-deriving that here.
558
333
  def names?(aggregate, value)
559
334
  aggregate.value_objects.any? { |vo| vo.hecks_name == value } ||
560
335
  aggregate.entities.any? { |entity| entity.hecks_name == value }
561
336
  end
562
337
 
563
- # Which verb an attribute row belongs to. The plan cannot decide this — all
564
- # three append to the same list — and what tells them apart is the row:
565
- #
566
- # Attribute its type names a value object of this aggregate
567
- # Reference its type is Reference<X>, another aggregate's head
568
- # Holds its type names an entity this aggregate declares
569
- #
570
- # Nothing is skipped. Without Reference and Holds the walk would drop
571
- # both kinds and the meta-domain would silently not contain
572
- # Account#customer_id or Account#ledger.
573
- # Each alternate carries its own map, read from the language. Borrowing the
574
- # primary's map dispatched `type:` where Reference declares `points_at:`,
575
- # and the payload gate caught it — which is the gate paying for itself.
576
- # `reference_to` can be written in four places — on a head, a command, a
577
- # piece, an ask — and each keeps its own list of attributes, so each
578
- # needs the Reference alternate. Only a head can hold a piece, so Holds
579
- # stays where it was.
338
+ # The row itself decides which verb an attribute belongs to:
339
+ # Attribute for a value-object type, Reference<X> for another
340
+ # aggregate's head, Holds for an entity this aggregate declares.
341
+ # Each alternate carries its own field map — borrowing the
342
+ # primary's would dispatch `type:` where Reference declares
343
+ # `points_at:`.
580
344
  def append_for(category, list_name, append, row, node)
581
345
  return append unless list_name.to_s == "attributes"
582
346
  return alternate(category, "Reference") || append if reference_row?(row)
@@ -591,28 +355,19 @@ module Hecks
591
355
 
592
356
  def reference_row?(row) = row.respond_to?(:reference?) && row.reference?
593
357
 
594
- # Only a head declares pieces, and now that every attribute list reaches
595
- # this, the node may be a command, a piece or an ask — none of which
596
- # answer `entities` at all.
358
+ # Only a head declares pieces; since every attribute list reaches
359
+ # here now, `node` may be a command, a piece or an ask, none of
360
+ # which answer `entities`.
597
361
  def entity_row?(row, node)
598
362
  return false unless node.respond_to?(:entities)
599
363
 
600
364
  Array(node.entities).any? { |entity| entity.hecks_name == row.type.to_s }
601
365
  end
602
366
 
603
- # A record's ID is its declared identity, joined — the same join the runtime
604
- # does, off the same declaration, because there is only one way to name a
605
- # thing and it should be written once.
606
- #
607
- # This was a branch per category: "#{parent}::#{name}" for an aggregate,
608
- # "#{parent}.#{name}" for most, "#{parent}##{index}" for the three that had
609
- # no name to use. It was the composite identity all along, hand-written here
610
- # because the language could not say it — which is why the language having
611
- # no identity of its own and this method existing were the same fact.
612
- #
613
- # A part resolves from one of three places, and the declaration says which:
614
- # the parent reference is the walk's parent_id, `position` is where the walk
615
- # is, and anything else is read off the node.
367
+ # A record's id is its declared identity, joined the same way the
368
+ # runtime joins it, so there is exactly one way to name a thing.
369
+ # Each part comes from the parent link, the walk index
370
+ # (`position`), or a field read off the node.
616
371
  def identify(category, parent_id, node, index)
617
372
  plan = @plan.category(category)
618
373
  return declared_name(node) unless plan
@@ -620,17 +375,13 @@ module Hecks
620
375
  Naming.identity(plan.identity_paths.map { |path| identity_part(plan, path, parent_id, node, index, category) })
621
376
  end
622
377
 
623
- # "owner_id" is a second reserved head, beside `position` : it names
624
- # whichever record is walking this one right now, aggregate or entity
625
- # alike, without saying which — Command and Query read it so an
626
- # entity's verbs are the entity's own. It is never a declared
627
- # attribute (declaring one for a field that names two different types
628
- # would be a lie about which), so it cannot be read through
629
- # `field_value` ; it is read the same way `plan.parent_key` already is,
630
- # because it is that fact, spelled for the walk's immediate parent
631
- # rather than for one specific kind of one.
378
+ # `owner_id` is a second reserved head (beside `position`): it
379
+ # names whichever record is walking this one right now, aggregate
380
+ # or entity, so Command/Query address the right piece. It is
381
+ # never a declared attribute, so it can't be read through
382
+ # `field_value`.
632
383
  # `private` above has no effect on a constant; kept here anyway,
633
- # beside the method that reads it, for the narrative.
384
+ # beside the method that reads it.
634
385
  # rubocop:disable-next Lint/UselessConstantScoping
635
386
  OWNER = "owner_id".freeze
636
387
 
@@ -642,8 +393,8 @@ module Hecks
642
393
  v_scalar(field_value(category, node, head.to_sym, parent_id))
643
394
  end
644
395
 
645
- # The scalar inside whatever the reading handed back — a name is already one,
646
- # a value object is not.
396
+ # The scalar inside whatever the reading handed back: a name is
397
+ # already one, a value object is not.
647
398
  def v_scalar(held)
648
399
  return held.to_s unless held.respond_to?(:to_h) && !held.is_a?(String)
649
400
 
@@ -656,10 +407,9 @@ module Hecks
656
407
 
657
408
  def eager?(category, child) = Array(EAGER_CHILDREN[category]).include?(child)
658
409
 
659
- # Command -> commands, ValueObject -> value_objects, Query -> queries.
660
- # Convention, not a table : the IR names a collection after what it holds.
661
- # The pluraliser lives in Naming, kept to exactly one implementation — a
662
- # second one risks disagreeing with it — see Naming.plural.
410
+ # Command -> commands, ValueObject -> value_objects, Query ->
411
+ # queries: convention, not a table. Naming.plural is kept as the
412
+ # single implementation, so a second one can't disagree with it.
663
413
  def collection_reader(category) = Naming.plural(Naming.snake(category))
664
414
  end
665
415
  end