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
@@ -4,35 +4,19 @@ module Hecks
4
4
  module Bluebook
5
5
  module Behaviour
6
6
  # What an aggregate does, as opposed to what it holds.
7
- #
8
- # The holding half — the field list, the readers, the emission — is
9
- # the same list the language already declares in
10
- # `language/bluebook/aggregate.bluebook`, said a second and third
11
- # time in Ruby. This half is not: derived identity, the name
12
- # indexes, the owner stamping and the finders are decisions about
13
- # how the declared shape is used, and no grammar states them.
14
- #
15
- # Split so the holding half can be generated from the language
16
- # without any of this being in the blast radius of a regeneration.
17
- # Everything here is hand-written and permanent.
18
- #
19
- # The three traits are shared with Entity (and, for `Indexed`,
20
- # with Command and PortOperation) — see behaviour/traits.rb on why
21
- # they are one module rather than four copies.
7
+ # Hand-written, so regenerating the declared field list never touches it.
22
8
  module Aggregate
23
9
  include Identified
24
10
  include Indexed
25
11
  include Owns
26
12
 
27
- # An aggregate is a member of its chapter's namespace — "Pizzas::Pizza" —
28
- # where everything else is declared on its owner and joins with ".".
13
+ # An aggregate joins its chapter's namespace with "::" ("Pizzas::Pizza");
14
+ # everything else joins its owner with ".".
29
15
  #
30
16
  # @return [String] the literal string `"::"`
31
17
  def hecks_separator = "::"
32
18
 
33
- # The hook the generated constructor calls once every declared
34
- # field is assigned. Nothing here is derivable from the
35
- # declaration, which is exactly why it is not generated.
19
+ # The hook the generated constructor calls once every declared field is assigned.
36
20
  #
37
21
  # @return [Bluebook::Aggregate] self, once identity is derived, every
38
22
  # declaration is indexed and its commands, value objects, entities and
@@ -40,8 +24,7 @@ module Hecks
40
24
  def settle
41
25
  derive_identity
42
26
  index_declarations
43
- # An entity stamps its own commands and queries when it is
44
- # declared, so the chain closes downward from here.
27
+ # An entity stamps its own commands and queries when declared.
45
28
  stamp(@commands, @value_objects, @entities, @queries)
46
29
  self
47
30
  end
@@ -56,10 +39,7 @@ module Hecks
56
39
  @commands_by_name = index_by_hecks_name(@commands)
57
40
  @queries_by_name = index_by_hecks_name(@queries)
58
41
  @ports_by_name = @ports.to_h { |port| [port.name, port] }
59
- # S12, ADR 0025 — keyed by symbol, the same convention
60
- # `Indexed#attribute` already uses; `GuardState` asks for one
61
- # by name at every dispatch, the rebuild sweep walks all of
62
- # them once per pass.
42
+ # Keyed by symbol, like `Indexed#attribute` (ADR 0025).
63
43
  @projected_fields_by_name = @projected_fields.to_h { |field| [field.name, field] }
64
44
  end
65
45
 
@@ -70,11 +50,7 @@ module Hecks
70
50
  # `nil` if none is declared under that name
71
51
  def projected_field(named) = @projected_fields_by_name[named.to_sym]
72
52
 
73
- # A value object is a class now, so `name` is Ruby's answer (the constant
74
- # path) and the declared name is `hecks_name`. This finder is on its way
75
- # out — once an attribute's type is the class there is nothing to find —
76
- # but every consumer still asks by type string, so it stays until they
77
- # stop.
53
+ # Finds a value object by declared name; `name` on the class is the constant path.
78
54
  #
79
55
  # @param named [String, Symbol] the value object's declared name
80
56
  # @return [Class, nil] the value object class (a `Bluebook::ValueObject`
@@ -88,18 +64,42 @@ module Hecks
88
64
  # none is attached under that name
89
65
  def port(named) = @ports_by_name[named.to_s]
90
66
 
91
- # A port is declared in the hecksagon, not the bluebook — the
92
- # boundary between the domain and its adapters, in hexagonal terms,
93
- # is exactly what a `.hecksagon` file already is for every other
94
- # port (persistence, projection, ...). So this attaches after the
95
- # aggregate already exists and is registered — `HecksagonBuilder`
96
- # calls it once per `port` declaration, having already stamped each
97
- # operation's reference attributes with `declared_in = self`, since
98
- # nothing upstream of a hecksagon load does that for it.
67
+ # Finds every port whose adapter answers a query.
68
+ #
69
+ # @param named [String, Symbol] the query's declared name
70
+ # @return [Array<Bluebook::DomainPort>] the ports the hecksagon binds to the query; empty
71
+ # when the query is answered from the aggregate's records
72
+ def query_bindings(named) = @ports.select { |port| port.answer_for(named) }
73
+
74
+ # Finds the port whose adapter answers a query.
75
+ #
76
+ # @param named [String, Symbol] the query's declared name
77
+ # @return [Bluebook::DomainPort, nil] the first port bound to the query, or `nil` if
78
+ # the hecksagon binds none
79
+ def query_binding(named) = query_bindings(named).first
80
+
81
+ # Attaches a port declared in the hecksagon, after the aggregate exists.
82
+ # `HecksagonBuilder` stamps each operation's reference attributes with
83
+ # `declared_in = self` before calling it. A port declared again under a name the
84
+ # aggregate already holds merges into it, so an overlay repeating a base
85
+ # declaration adds nothing twice; two different names stay two ports.
99
86
  #
100
87
  # @param port [Bluebook::DomainPort] the aggregate-scoped port to attach
101
88
  # @return [void]
102
89
  def add_port(port)
90
+ held = @ports_by_name[port.name]
91
+ return attach_port(port) unless held
92
+
93
+ operations = held.operations + port.operations.reject { |op| held.operation(op.hecks_name) }
94
+ answers = held.answered_queries + port.answered_queries.reject { |a| held.answer_for(a.name) }
95
+ merged = Bluebook::DomainPort.new(name: held.name, operations: operations, answered_queries: answers)
96
+ @ports[@ports.index(held)] = merged
97
+ @ports_by_name[merged.name] = merged
98
+ end
99
+
100
+ # @param port [Bluebook::DomainPort] a port under a name the aggregate does not hold
101
+ # @return [void]
102
+ def attach_port(port)
103
103
  @ports << port
104
104
  @ports_by_name[port.name] = port
105
105
  end
@@ -1,10 +1,7 @@
1
1
  module Hecks
2
2
  module Bluebook
3
3
  module Behaviour
4
- # **What an attribute does**. The declared half — name, type, list,
5
- # default, optional, pattern, admits — is what the language states
6
- # in `aggregate.bluebook`'s own `Field`. These are the questions
7
- # readers ask about that shape, which no declaration states.
4
+ # **What an attribute does**: the questions readers ask about its declared shape.
8
5
  module Attribute
9
6
  # Says whether this attribute was declared `list`.
10
7
  #
@@ -21,16 +18,8 @@ module Hecks
21
18
  # @return [Boolean] whether this attribute's type is a `reference_to` another aggregate
22
19
  def reference? = @type.is_a?(Reference)
23
20
 
24
- # May this fact be left out?
25
- #
26
- # Required is the default and by far the common case — a command takes
27
- # the arguments it declares, and all of them — so the exception is what
28
- # gets marked. Marking the other way would annotate almost every
29
- # attribute in the corpus to say nothing.
30
- #
31
- # Only a command enforces this. An aggregate's own attributes are filled
32
- # by the commands that set them, and a value object's by its
33
- # constructor ; neither is a payload anyone hands in.
21
+ # May this fact be left out? Required is the default; only a command enforces
22
+ # this, since aggregate and value object attributes are not caller payloads.
34
23
  #
35
24
  # @return [Boolean] whether a command may omit this attribute from its payload
36
25
  def optional? = @optional
@@ -3,22 +3,15 @@ require_relative "traits"
3
3
  module Hecks
4
4
  module Bluebook
5
5
  module Behaviour
6
- # **What a chapter does**. The declared half is the roll-call of what a
7
- # bluebook holds; these are the finders over it, plus `verbs` — the
8
- # chapter's own list of every dispatchable name, which is derived
9
- # from the aggregates rather than declared anywhere.
6
+ # What a chapter does. The declared half is the roll-call of what a
7
+ # bluebook holds; these are the finders over it, plus `verbs`.
10
8
  module Chapter
11
9
  include Owns
12
10
 
13
- # The hook the generated constructor calls. Three things a
14
- # declaration does not state: that a chapter is the root of the
15
- # owner chain (nothing declares it, it is what having no owner
16
- # means), the ports table — which a `.hecksagon` fills later, so
17
- # the bluebook cannot declare it — and stamping its own children,
18
- # the same act an Aggregate performs one level down.
11
+ # Marks this chapter the root of the owner chain, attaches the ports
12
+ # table (filled later by a `.hecksagon`), and stamps ownership.
19
13
  #
20
- # @return [Bluebook::Chapter] self, once root marking, the ports table and ownership
21
- # stamping are all set up
14
+ # @return [Bluebook::Chapter] self
22
15
  def settle
23
16
  @hecks_root = true
24
17
  @ports = []
@@ -47,11 +40,7 @@ module Hecks
47
40
  # by that name
48
41
  def port(named) = @ports_by_name[named.to_s]
49
42
 
50
- # What this chapter declared it provides — `{ key => local verb }`
51
- # for one capability, or nil when it declares none. Read by
52
- # everything that resolves a capability's provider from what a
53
- # chapter declares, rather than from the chapter's own name
54
- # (`Registry#authorization_provider_for`).
43
+ # What this chapter declared it provides for one capability.
55
44
  #
56
45
  # @param capability [String, Symbol] the capability's name, such as
57
46
  # `Bluebook::Capabilities::AUTHORIZATION`
@@ -80,9 +69,8 @@ module Hecks
80
69
  local && "#{name}::#{local}"
81
70
  end
82
71
 
83
- # A port is declared in the hecksagon, not the bluebook — so it
84
- # attaches after the chapter already exists, the same way an
85
- # aggregate's own ports do.
72
+ # A port attaches after the chapter already exists, once its
73
+ # hecksagon is built — the same way an aggregate's own ports do.
86
74
  #
87
75
  # @param port [Bluebook::DomainPort] the operations-shaped port to attach
88
76
  # @return [void]
@@ -91,15 +79,9 @@ module Hecks
91
79
  @ports_by_name[port.name] = port
92
80
  end
93
81
 
94
- # A translated reaction is also declared in the hecksagon —
95
- # `HecksagonBuilder#translates` builds an ordinary `Policy` (same
96
- # shape, same `PolicyInterpreter` runtime, as one written inside a
97
- # `policy` block in this chapter's own `.bluebook`) and attaches it
98
- # here, after the chapter already exists, the same reasoning
99
- # `add_port` gives one method up. Kept out of the bluebook itself
100
- # on purpose: which foreign domain's event this chapter reacts to
101
- # is a wiring/context-mapping decision, not a fact the domain
102
- # states about its own model.
82
+ # A translated reaction also attaches after the chapter already
83
+ # exists: which foreign domain's event it reacts to is a wiring
84
+ # decision, not a fact the domain states about its own model.
103
85
  #
104
86
  # @param policy [Bluebook::Policy] the translated reaction to attach
105
87
  # @return [Array<Bluebook::Policy>] this chapter's policies, with `policy` appended
@@ -108,19 +90,9 @@ module Hecks
108
90
  end
109
91
 
110
92
  # Every dispatchable name this chapter answers to, spelled exactly
111
- # as Dispatcher#dispatch takes it. Derived from the aggregates,
112
- # never declared — which is why Projections::OIDC can hold its own
113
- # scope list equal to this and have that mean something.
114
- #
115
- # Recurses into entities, not just an aggregate's own direct
116
- # commands — `Dispatcher#dispatch` already routes a dotted
117
- # `Domain::Aggregate.Entity.Command` verb to `EntityInterpreter`
118
- # (a command_name with a "." in it), so a verb this method left
119
- # out was never "not a verb," only one this list forgot to name.
120
- # Ported from the same recursive shape `spec/judge_coverage_spec.rb`
121
- # already proved out for the meta-domain's own grammar (S17, ADR
122
- # 0026) — entities nest arbitrarily deep (`Dispatch`, inside
123
- # `Handler`), so one flat level isn't enough.
93
+ # as `Dispatcher#dispatch` takes it. Derived from the aggregates,
94
+ # never declared, and recurses into entities since a command can be
95
+ # nested arbitrarily deep.
124
96
  #
125
97
  # @return [Array<String>] every command verb reachable on this chapter, spelled
126
98
  # `"Domain::Aggregate.command"` or, nested, `"Domain::Aggregate.Entity.command"`
@@ -3,13 +3,11 @@ require_relative "traits"
3
3
  module Hecks
4
4
  module Bluebook
5
5
  module Behaviour
6
- # **What a command does**. Extended, not included — a command is a
7
- # class, one per declared verb.
6
+ # **What a command does**. Extended, not included: a command is a class per verb.
8
7
  module Command
9
8
  include Indexed
10
9
 
11
- # Indexed once — attributes are final once absorbed, and every
12
- # dispatch asks this finder by name.
10
+ # Indexes the attributes once; they are final once absorbed.
13
11
  #
14
12
  # @return [Class] self — the command class, once its attributes are
15
13
  # indexed
@@ -21,25 +19,15 @@ module Hecks
21
19
  # The construct this verb acts upon — the construct itself, not its name.
22
20
  #
23
21
  # A verb declared on an entity always acts on that piece. It never
24
- # self-references, because an element is addressed through its parent —
25
- # which means `creates?` answers true for every one of them, and reading
26
- # `acts_on` off `creates?` alone would report that `LedgerEntry.Amend`
27
- # brings a ledger entry into being. Three of banking's commands were
28
- # about to say exactly that, and nothing would have contradicted them.
29
- #
30
- # On an aggregate, a creating command acts on no existing root, so nil is
31
- # the truth: there is nothing there yet.
22
+ # self-references, so `creates?` is true for it and cannot decide this alone.
23
+ # A creating command on an aggregate acts on nothing yet, so nil.
32
24
  #
33
25
  # @return [Class, Bluebook::Aggregate, nil] the entity class (a
34
26
  # `Bluebook::Entity` subclass) this verb acts on when declared on an
35
27
  # entity, the aggregate instance when declared on an aggregate and
36
28
  # non-creating, or `nil` for a creating command
37
29
  def acts_on
38
- # Fully qualified, and it has to be: inside `module Behaviour`
39
- # the bare name `Entity` resolves to Behaviour::Entity — this
40
- # module's sibling — not to the construct. Comparing a Class to
41
- # a Module answers nil, so the guard silently fell through and
42
- # every entity verb reported acting on nothing.
30
+ # Fully qualified: a bare `Entity` here resolves to Behaviour::Entity, not the construct.
43
31
  return hecks_owner if hecks_owner.is_a?(Class) && hecks_owner < Bluebook::Entity
44
32
 
45
33
  creates? ? nil : hecks_owner
@@ -51,54 +39,18 @@ module Hecks
51
39
  # it declares no `reference_to` back to its own owner
52
40
  def creates? = @references.nil?
53
41
 
54
- # Every reason this verb can refuse on a rule — the descriptions of
55
- # its givens and its ensures, the exact text the runtime quotes
56
- # after "refused — " when a guard is not met (see
57
- # command_rules/admissibility.rb's GivenNotMet/EnsuresNotMet). A
58
- # property that asks "did the runtime only ever refuse for a rule
59
- # the language wrote" reads this rather than re-deriving the two
60
- # collections; `compact` because a rule's description is optional
61
- # (behavior.bluebook's Rule) and an unnamed one quotes nothing.
42
+ # Every reason this verb can refuse on a rule: the descriptions of its givens and
43
+ # ensures, as the runtime quotes them after "refused — ". Unnamed rules are skipped.
62
44
  #
63
45
  # @return [Array<String>] every named given's and ensure's own
64
46
  # description text, skipping unnamed rules
65
47
  def guard_descriptions = (@givens + @ensures).map(&:description).compact
66
48
 
67
- # The argument name that addresses an instance of `aggregate_name`
68
- # for this command — the one fact `PolicyInterpreter`'s own
69
- # `for_each` fan-out needs and, until this reading existed, had
70
- # to guess at (see git blame: `Behaviour::Policy
71
- # #fan_out_reference_key`, which hardcoded `<aggregate>_id`
72
- # unconditionally and refused every dispatch to a self-
73
- # addressing command as a result — `Account.Freeze`, addressed
74
- # by `number`/`account`, not `account_id`).
75
- #
76
- # Two shapes, the same two `CommandBuilder#reference_to` already
77
- # tells apart at declare time (command_builder.rb's own comment
78
- # on `cross_reference` — "`as:` means a named attribute... a
79
- # command can point at another instance of its own kind"):
80
- #
81
- # self-addressing — `references == aggregate_name` (this verb
82
- # is declared on the very aggregate it acts on, `reference_to
83
- # Account` on a command Account itself owns). No attribute was
84
- # minted for it at all; the same bare key
85
- # `CommandInterpreter::ArgumentGate#reference_key` already
86
- # accepts as "addressing, not describing" is reused here
87
- # rather than re-derived — one door, not two.
88
- #
89
- # cross-referencing — a real, declared reference-typed
90
- # attribute whose own target is `aggregate_name` (`customer_id`
91
- # on `Account.Open`, or whatever `as:` named it). Its name is
92
- # the key, exactly as declared — never re-derived from the
93
- # target's name, because an `as:` reference's name and its
94
- # target's snake case can legitimately differ (`Transfer`'s own
95
- # `source`/`destination`, both `Reference<Account>`).
49
+ # The argument name that addresses an instance of `aggregate_name` for this command.
96
50
  #
97
- # `nil` when neither shape matches — a creating command (nothing
98
- # to address yet) or one that simply never references this
99
- # aggregate at all. A caller minting a fan-out dispatch is
100
- # expected to treat `nil` as "this command cannot be addressed by
101
- # a row of this aggregate," not to fall back on a guess.
51
+ # Self-addressing commands (`references == aggregate_name`) use the bare reference
52
+ # key. Cross-referencing ones use the declared reference attribute's own name, never
53
+ # re-derived from the target, since `as:` names can differ.
102
54
  #
103
55
  # @param aggregate_name [String, Symbol] the aggregate a fan-out dispatch is
104
56
  # addressing an instance of
@@ -112,14 +64,10 @@ module Hecks
112
64
  end
113
65
  end
114
66
 
115
- # **A mutation's own readings**. Included (not extended) — Mutation is
116
- # a Struct, so these are instance methods.
67
+ # **A mutation's own readings**. Included, not extended: Mutation is a Struct.
117
68
  module Mutation
118
- # An append binds several fields at once, each from either a command
119
- # argument (a Symbol) or a literal. Spelled through `Literal.render`,
120
- # the same self-describing form a where-clause's own value already
121
- # uses, rather than a bare Symbol paired with an inspected literal —
122
- # see Hecks::Literal.
69
+ # An append binds several fields at once, each from a command argument (a Symbol)
70
+ # or a literal, spelled through `Literal.render`.
123
71
  #
124
72
  # @return [Hash{Symbol => String}] the append's field bindings, each
125
73
  # value rendered through `Literal.render`
@@ -13,16 +13,8 @@ module Hecks
13
13
  # @return [nil] always `nil`
14
14
  def references = nil
15
15
 
16
- # Never a creating command — a port operation always acts on an
17
- # aggregate that already exists (`operation.to`/`identity_attribute`
18
- # both name where its receiver comes from, never a birth). Answered
19
- # explicitly, not derived from `references` the way `Command
20
- # #creates?` is (`references.nil?` would read every operation as
21
- # creating, since `references` above is unconditionally nil) —
22
- # needed so `ReactionInvocation#source_receiver_for` can call
23
- # `target.command.creates?` on a port operation the same way it
24
- # already does on an ordinary command, and correctly lift a
25
- # same-aggregate policy's own Event.id as the operation's receiver.
16
+ # A port operation always acts on an existing aggregate. Answered explicitly
17
+ # because `references.nil?` would read every operation as creating.
26
18
  #
27
19
  # @return [Boolean] always `false`
28
20
  def creates? = false
@@ -37,16 +29,8 @@ module Hecks
37
29
  @attributes.find { |attribute| attribute.reference? && attribute.type.target_name == owner_name.to_s }
38
30
  end
39
31
 
40
- # The same reading `Command#addressing_key_for` gives, minus its
41
- # self-addressing branch — a port operation's `references` is
42
- # unconditionally nil (above), so it never means "this verb is
43
- # declared on the very aggregate it acts on" the way a command's
44
- # does; a port operation's only path back to its owner is a real,
45
- # declared reference-typed attribute, which is exactly what
46
- # `identity_attribute` already finds. Needed for the identical
47
- # reason `Command#addressing_key_for` is: `ReactionInvocation
48
- # #aggregate_aliases` calls it on whatever `target.command` holds,
49
- # a `PortOperation` now included since a policy can trigger one.
32
+ # Like `Command#addressing_key_for` without the self-addressing branch: the
33
+ # reference attribute is the only path back to the owner.
50
34
  #
51
35
  # @param aggregate_name [String, Symbol] the name of the aggregate a row of which
52
36
  # would address this operation
@@ -63,6 +47,13 @@ module Hecks
63
47
  # @return [Bluebook::PortOperation, nil] the operation, or `nil` if none is
64
48
  # declared by that name
65
49
  def operation(named) = @operations.find { |op| op.hecks_name == named.to_s }
50
+
51
+ # Finds the binding this port gives a query, if it answers that query.
52
+ #
53
+ # @param named [String, Symbol] the query's declared name
54
+ # @return [Bluebook::QueryAnswer, nil] the binding, or `nil` if this port does not
55
+ # answer that query
56
+ def answer_for(named) = @answered_queries.find { |answer| answer.name == named.to_s }
66
57
  end
67
58
  end
68
59
  end
@@ -6,12 +6,8 @@ module Hecks
6
6
  # **What an entity does**. Extended, not included — an entity is a
7
7
  # class, so this is singleton behaviour.
8
8
  #
9
- # `settle` is the same seam an Aggregate has, reached from `absorb`
10
- # rather than from a constructor because a declared entity is built
11
- # by subclassing rather than by `new`. The traits are the same
12
- # ones, which is the whole point of them being traits: an entity's
13
- # identity is derived exactly as an aggregate's is, and was written
14
- # out twice before anyone could see that.
9
+ # `settle` is reached from `absorb` rather than a constructor, because a declared
10
+ # entity is built by subclassing.
15
11
  module Entity
16
12
  include Identified
17
13
  include Indexed
@@ -36,32 +32,16 @@ module Hecks
36
32
  @queries_by_name = index_by_hecks_name(@queries)
37
33
  end
38
34
 
39
- # S17, ADR 0026 — `@entities`, now genuinely nested entities
40
- # (Dispatch, inside Handler) rather than always `[]`. Kept as a
41
- # real reader rather than a hardcoded empty list for two
42
- # reasons at once: `Value::Coercion#for_attribute` calls
43
- # `.entities` on whatever owner it is handed — an aggregate's or
44
- # an entity's own — the moment it meets any `list_of(...)`
45
- # attribute (entity-typed or not — `hydrate_entity_list`'s own
46
- # fallback, `return value unless entity`, only runs once
47
- # `.entities` has already answered) ; and `EntityInterpreter`
48
- # now walks a dotted chain of entities one level at a time
49
- # (`walk_entity_chain`) exactly the way an aggregate's own
50
- # `.entities` is walked for its direct children. Entity's own
51
- # header comment already promises it stays "structurally
52
- # interchangeable with an aggregate" for exactly this reason.
35
+ # Nested entities, structurally interchangeable with an aggregate's `entities`:
36
+ # `Value::Coercion#for_attribute` and `EntityInterpreter` both read it (ADR 0026).
53
37
  #
54
38
  # @return [Array<Class>] this entity's own nested entities (each a `Bluebook::Entity`
55
39
  # subclass), or `[]` if it declares none
56
40
  def entities = @entities || []
57
41
 
58
- # A piece owns the verbs declared on it, so they can state an
59
- # identity — `Banking::Account.Ledger.Deposit` rather than a
60
- # command that cannot say what it belongs to. Separate from
61
- # `settle` because `declare` stamps after absorbing, once the
62
- # subclass that will own them exists. `@entities` too now
63
- # (S17, ADR 0026) — a nested entity states its own owner chain
64
- # exactly the way a nested command does.
42
+ # Stamps this entity as owner of its commands, queries and nested entities, so
43
+ # verbs read `Banking::Account.Ledger.Deposit`. Separate from `settle` because
44
+ # `declare` stamps after the owning subclass exists.
65
45
  #
66
46
  # @return [void]
67
47
  def stamp_children = stamp(@commands, @queries, @entities)
@@ -1,32 +1,26 @@
1
1
  module Hecks
2
2
  module Bluebook
3
3
  module Behaviour
4
- # **What a hecksagon does** — the lookups over its declared binds.
4
+ # Lookups over a hecksagon's declared binds.
5
5
  module Hecksagon
6
- # Aggregate-specific bind wins when one was declared; otherwise
7
- # falls back to a domain-level default (`b.aggregate.nil?` — see
8
- # `HecksagonBuilder#method_missing`). Checked directly rather than
9
- # via `aggregate_name`/`Naming.demodulise`, which would need its own
10
- # nil-handling for the default row.
6
+ # Finds the bind for an aggregate and verb, falling back to the domain-level default.
11
7
  #
12
- # @param aggregate_name [String, Symbol] the aggregate to find a bind for
13
- # @param verb [String, Symbol] the port verb name to find a bind for
14
- # @return [Bluebook::Bind, nil] the aggregate-specific bind when one is
15
- # declared, the domain-level default bind for `verb` otherwise, or
16
- # `nil` when neither exists
8
+ # The default row is matched with `b.aggregate.nil?` rather than via
9
+ # `aggregate_name`, which would need its own nil handling.
10
+ #
11
+ # @param aggregate_name [String, Symbol]
12
+ # @param verb [String, Symbol]
13
+ # @return [Bluebook::Bind, nil]
17
14
  def bind_for(aggregate_name, verb)
18
15
  @binds.find { |b| b.aggregate_name == aggregate_name.to_s && b.verb.to_s == verb.to_s } ||
19
16
  @binds.find { |b| b.aggregate.nil? && b.verb.to_s == verb.to_s }
20
17
  end
21
18
 
22
- # Every bind for `verb`, aggregate-specific ones winning as a group over
23
- # the domain-level default.
19
+ # Every bind for `verb`; aggregate-specific ones win as a group over the default.
24
20
  #
25
- # @param aggregate_name [String, Symbol] the aggregate to find binds for
26
- # @param verb [String, Symbol] the port verb name to find binds for
27
- # @return [Array<Bluebook::Bind>] every aggregate-specific bind for
28
- # `verb` when any are declared, otherwise every domain-level default
29
- # bind for `verb`
21
+ # @param aggregate_name [String, Symbol]
22
+ # @param verb [String, Symbol]
23
+ # @return [Array<Bluebook::Bind>]
30
24
  def binds_for(aggregate_name, verb)
31
25
  specific = @binds.select { |b| b.aggregate_name == aggregate_name.to_s && b.verb.to_s == verb.to_s }
32
26
  return specific if specific.any?
@@ -35,34 +29,22 @@ module Hecks
35
29
  end
36
30
  end
37
31
 
38
- # **What a world does** — settings lookup, with the adapter-specific
39
- # entry falling back to the verb's own.
32
+ # Settings lookup for a world, with adapter-specific entries falling back to the verb's own.
40
33
  module World
41
- # Finds the generic settings declared for a port verb.
34
+ # The settings declared for a port verb.
42
35
  #
43
- # @param verb [String, Symbol] the port verb name, such as `"persistence"`
44
- # @return [Hash{Symbol => Object}] the settings declared for `verb`, or
45
- # `{}` when none are declared
36
+ # @param verb [String, Symbol] such as `"persistence"`
37
+ # @return [Hash{Symbol => Object}] empty when none are declared
46
38
  def for_verb(verb) = @settings.fetch(verb.to_s, {})
47
39
 
48
- # The generic `verb` entry (`persisted_by("Heki") do dir :default
49
- # end`) only answers for the adapter it actually names — falling
50
- # back to it unconditionally applies one adapter's settings to an
51
- # unrelated one. Real, corpus-caught bug: a hecksagon binding two
52
- # aggregates to two different adapters under the same verb (one to
53
- # Heki, one to Memory) sent Memory's lookup down Heki's generic
54
- # entry, then failed `check_settings` with "Memory does not
55
- # declare :dir" — the generic entry's own `settings[:adapter]`
56
- # names Heki, not Memory, so the fallback was never actually for
57
- # this bind. `{}` is exactly right when nothing was configured for
58
- # this adapter — Memory, which takes no values at all.
40
+ # The generic verb entry only answers for the adapter it names. Falling back to it
41
+ # unconditionally would apply one adapter's settings (Heki's `dir`) to another
42
+ # (Memory), which then fails `check_settings`.
59
43
  #
60
- # @param verb [String, Symbol] the port verb name to find settings for
61
- # @param adapter [String, Symbol] the adapter name, such as `"Heki"`, to
62
- # find settings for
63
- # @return [Hash{Symbol => Object}] the adapter-qualified settings when
64
- # declared, the generic verb settings when they name this same
65
- # adapter, or `{}` otherwise
44
+ # @param verb [String, Symbol]
45
+ # @param adapter [String, Symbol] such as `"Heki"`
46
+ # @return [Hash{Symbol => Object}] the adapter-qualified settings, else the generic
47
+ # ones when they name this adapter, else `{}`
66
48
  def for_binding(verb, adapter)
67
49
  qualified = @settings["#{verb}:#{adapter.to_s.downcase}"]
68
50
  return qualified if qualified