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
@@ -2,202 +2,138 @@ require_relative "word_gate"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # Parses a `.hecksagon` file's top-level DSL block into a `Hecksagon`
6
- # — a domain's own wiring: which adapter binds to which verb
7
- # (`persisted_by`, `projected_by`, ...), which framework/vendored
8
- # bluebooks it attaches, which external events it subscribes to, and
9
- # its bare chapter-root port. Kept separate from the bluebook itself
10
- # (the domain's own declared model) because wiring is an operational
11
- # decision, not a fact the domain states about itself.
5
+ # Parses a `.hecksagon` file's DSL block into a Hecksagon: a domain's adapter bindings,
6
+ # framework/vendored attachments and subscriptions — wiring, not part of the bluebook.
12
7
  class HecksagonBuilder
13
8
  GRAMMAR_CONTEXT = "Hecksagon".freeze
14
9
 
15
10
  include WordGate
16
11
 
17
12
  class << self
18
- attr_accessor :collector
13
+ # The bind collector of the build running on this thread; thread-local, so a build
14
+ # on another thread never sees it.
15
+ #
16
+ # @return [Array, nil] the binds the running build collects into
17
+ def collector = Thread.current.thread_variable_get(:hecks_hecksagon_collector)
18
+
19
+ # @param value [Array, nil] the binds the running build collects into
20
+ def collector=(value)
21
+ Thread.current.thread_variable_set(:hecks_hecksagon_collector, value)
22
+ end
23
+
24
+ # @return [String, nil] the name of the chapter whose hecksagon is being built
25
+ def building = Thread.current.thread_variable_get(:hecks_hecksagon_building)
26
+
27
+ # @param value [String, nil] the name of the chapter whose hecksagon is being built
28
+ def building=(value)
29
+ Thread.current.thread_variable_set(:hecks_hecksagon_building, value)
30
+ end
31
+
32
+ # @return [Hash, nil] the modules this thread's build has taken off `Hecks`
33
+ def hidden_modules = Thread.current.thread_variable_get(:hecks_hecksagon_hidden)
34
+
35
+ # @param value [Hash, nil] the modules this thread's build has taken off `Hecks`
36
+ def hidden_modules=(value)
37
+ Thread.current.thread_variable_set(:hecks_hecksagon_hidden, value)
38
+ end
39
+ end
40
+
41
+ # Lets the Hecks chapter's own hecksagon spell its aggregates `Hecks::Operation`.
42
+ #
43
+ # While the chapter named Hecks builds its hecksagon, a missing constant on `Hecks` is
44
+ # one of that chapter's aggregates; at any other time it is the ordinary `NameError`.
45
+ #
46
+ # A real module of the same name (`Hecks::Release`) would answer first, so
47
+ # `HecksagonBuilder.build` takes each off `Hecks` while the block runs (see `shadowed`).
48
+ # `attaches` loads whole chapters inside the block; the shadow lifts around each load
49
+ # (see `with_real_modules`), so loaded code sees the real modules.
50
+ module ChapterConstants
51
+ # @param name [Symbol] the missing constant
52
+ # @return [Bluebook::DSL::BindingProxy] a proxy for that aggregate while building
53
+ def const_missing(name)
54
+ return super unless HecksagonBuilder.building == "Hecks" && HecksagonBuilder.collector
55
+
56
+ BindingProxy.new("Hecks::#{name}", HecksagonBuilder.collector)
57
+ end
19
58
  end
20
59
 
21
- attr_reader :binds, :subscriptions, :framework_members, :vendored_bluebooks
60
+ attr_reader :binds, :subscriptions, :framework_members, :vendored_bluebooks, :attached_chapters
22
61
 
23
- # @param domain [String] name of the domain whose wiring this hecksagon declares
24
62
  def initialize(domain)
25
63
  @domain = domain
26
64
  @binds = []
27
65
  @subscriptions = []
28
66
  @framework_members = []
29
67
  @vendored_bluebooks = []
68
+ @attached_chapters = []
30
69
  @bounded = false
31
70
  @translates = []
32
71
  end
33
72
 
34
- # Marks this chapter as a bounded context — a consumer-owned chapter
35
- # that `uses_framework` / `uses_embryonaut_bluebook` will not load.
36
- # Framework and vendored packages get the mark automatically from
37
- # those words; they never write `bounded` in their own bluebooks.
38
- # A bounded chapter wraps in its own module (no Object shortcut)
39
- # and must declare at least one `translates` ACL or boot refuses.
40
- #
41
- # @return [Boolean] true
73
+ # Marks this chapter as a bounded context; framework/vendored attachments set it too.
74
+ # Must declare at least one `translates` ACL or boot refuses.
42
75
  def bounded
43
76
  @bounded = true
44
77
  end
45
78
 
46
- # Subscribes this hecksagon to an event it takes from outside the domain's own bluebook.
47
- #
48
- # @param event [String, Symbol] the external event's name
49
- # @return [Array<String>] every subscription declared so far, this one last
79
+ # Subscribes to an event from outside this domain's own bluebook.
50
80
  def subscribe(event) = @subscriptions << event.to_s
51
81
 
52
- # Attaches a framework member to this domain and loads it into the current registry.
53
- #
54
- # A framework/ member this domain wants attached —
55
- # Governance, Identity, whatever else lands beside them.
56
- # Attaching one is a wiring decision, the same kind `persisted_by`/
57
- # `projected_by` already are, so it lives here rather than as a
58
- # fact stated in the domain's own bluebook. Recorded onto this
59
- # hecksagon, the same way `subscribe` records onto its own
60
- # `subscriptions` — and loads the member's bluebook then its own
61
- # hecksagon into whatever registry this one is loading into, see
62
- # `Framework.load!`.
63
- #
64
- # @param name [String, Symbol] the member's name, such as `"Governance"`
65
- # @return [Boolean, nil] true when this call loaded the member's bluebook, nil when the
66
- # current registry already held it
67
- # @raise [Runtime::WiringError] if no framework member has that name
82
+ # Attaches a framework member (e.g. Governance) and loads it into the current registry.
68
83
  def uses_framework(name)
69
84
  @framework_members << name.to_s
70
85
  Hecks::Framework.load!(name)
71
- # Automatic bounded mark — the framework member is a bounded
72
- # context; the consumer's sibling `Hecks.hecksagon "Name"` is
73
- # the anti-corruption layer. Not written in the framework
74
- # bluebook itself.
86
+ # Marks the framework member as bounded; the consumer's own hecksagon is the
87
+ # anti-corruption layer.
75
88
  Hecks.current_registry&.mark_bounded(name.to_s)
76
89
  end
77
90
 
78
91
  # Attaches a vendored embryonaut bluebook to this domain and loads its files into the
79
- # current registry.
80
- #
81
- # A vendored, external bluebook this domain wants attached — same
82
- # wiring-decision shape `uses_framework` already is, one level
83
- # further out: not a member shipped inside hecks's own lib/,
84
- # but a separate package (embryonaut_bluebooks) vendored into this
85
- # project's own checkout. See EmbryonautBluebook's own header for
86
- # the full reasoning on why its root can't be a fixed constant the
87
- # way Framework::ROOT is, and for the recovery provenance.
88
- #
89
- # Recorded onto @vendored_bluebooks, same shape `uses_framework`
90
- # already gives @framework_members — a separate list on purpose:
91
- # `framework_members` is load-bearing for `refuse_ungoverned_roles!`
92
- # (`Registry::Verification`) and for Governance's own attachment
93
- # check; conflating the two would make a vendored bluebook attachment
94
- # satisfy a Governance check it has nothing to do with.
95
- #
96
- # @param name [String, Symbol] the vendored package's directory name under
97
- # `vendor/embryonaut_bluebooks/`
98
- # @return [Array<String>, nil] paths of the `.bluebook` files this call loaded, or nil
99
- # when the current registry already held the bluebook
100
- # @raise [Runtime::WiringError] if the current registry has no root to vendor from, or
101
- # no vendored bluebook of that name exists under it
92
+ # registry. Recorded separately from @framework_members, which is load-bearing for
93
+ # governance checks.
102
94
  def uses_embryonaut_bluebook(name)
103
95
  @vendored_bluebooks << name.to_s
104
96
  Hecks::EmbryonautBluebook.load!(name)
105
- # Automatic bounded mark — same as `uses_framework`. The
106
- # package's directory name Pascal-cases to the chapter
107
- # (`"membership"` → `Membership`).
97
+ # Marks the chapter bounded, same as `uses_framework`; the directory name Pascal-cases
98
+ # to the chapter name (`"membership"` → `Membership`).
108
99
  Hecks.current_registry&.mark_bounded(Hecks::Naming.pascal(name.to_s))
109
100
  end
110
101
 
111
- # Declares a port at the hecksagon's root and attaches it to the registered bluebook.
112
- #
113
- # The primary port, bare at the root — belongs to the chapter as a
114
- # whole, not one aggregate. `BindingProxy#port` is the aggregate-
115
- # scoped sibling (`Payments::Payment.port("Gateway") do ... end`);
116
- # this is what's left when a port isn't about any one record. The
117
- # bluebook must already be built and registered, since a hecksagon
118
- # loads after its bluebook, and this attaches to that real, final
119
- # object directly rather than building a second copy MetaValidator
120
- # would have to know how to reconstruct.
121
- #
122
- # Answers the `port` word through the table's `calls:` column —
123
- # item #13's full metaprogrammed dispatch (slice 5). Not
124
- # bootstrap-reachable (checked directly — no core/attached chapter
125
- # declares a Hecksagon of its own). Reached through `WordGate`'s
126
- # `word_gate_dispatch`, called explicitly below since
127
- # `HecksagonBuilder`'s own class-level `method_missing` (the
128
- # open-verb catch-all beneath this) always wins over the module's —
129
- # see `word_gate.rb`'s own header for the full mechanism.
130
- #
131
- # @param name [String] the port's name
132
- # @yield the port body, evaluated against a `DomainPortBuilder`: either `verb`/`signal`
133
- # or `operation`/`tells`/`asks` blocks
134
- # @return [Bluebook::Port, Bluebook::DomainPort] the built port: a verb-shaped `Port`
135
- # registered on the current registry, or a `DomainPort` attached to the bluebook
136
- # @raise [Bluebook::DSL::Malformed] if the current registry holds no bluebook for this
137
- # domain, or the body declares both a verb and operations, neither, or an operation
138
- # the port grammar refuses
102
+ # Attaches a chapter the gem carries (the language, Expression, Tenancy, Deploy,
103
+ # QualityControl) by name and loads its files into the registry, with the ports and
104
+ # adapters it ships. Marked bounded like a framework member, since this hecksagon is its
105
+ # anti-corruption layer.
106
+ def attaches(name)
107
+ require_relative "../../chapters"
108
+ @attached_chapters << name.to_s
109
+ self.class.with_real_modules { Hecks::Chapters.load!(name) }
110
+ Hecks.current_registry&.mark_bounded(name.to_s)
111
+ end
112
+
113
+ # Declares a port at the hecksagon's root — the chapter as a whole, not one aggregate.
139
114
  def port_impl(name, &block)
140
115
  bluebook_ir = Hecks.current_registry.bluebook(@domain) or
141
116
  raise Malformed, "#{@domain} declares no such bluebook — a port needs one to belong to"
142
117
 
143
- # See BindingProxy#port's own comment on why this resolver swap is
144
- # needed — ConstShim's active resolver is one global for the whole
145
- # dynamic extent, currently this file's own BindingProxy-minting
146
- # one, which would turn a bare constant inside an operation's
147
- # `reference_to`/`attribute` into another BindingProxy instead of
148
- # a name.
118
+ # Swaps the active ConstShim resolver to plain passthrough — without it a bare constant
119
+ # inside `reference_to`/`attribute` would resolve to a BindingProxy instead of a name.
149
120
  built = ConstShim.with(->(const) { const }) { DomainPortBuilder.build(name, &block) }
150
121
 
151
- # See BindingProxy#port's own comment on the same branch — a
152
- # `verb`-shaped port is a plain `Port`, registered the same
153
- # way `Hecks.port`'s top-level method already does, not attached
154
- # to this bluebook's own IR the way an operations-shaped
155
- # `DomainPort` is.
122
+ # A verb-shaped port is a plain `Port`, registered like `Hecks.port`'s top-level method,
123
+ # not attached to this bluebook's IR the way an operations-shaped `DomainPort` is.
156
124
  return Hecks.current_registry.add_port(built) if built.is_a?(Port)
157
125
 
158
126
  bluebook_ir.add_port(built)
159
127
  end
160
128
 
161
- # A translation boundary, not a business rule — `translates "Name"
162
- # do on Foreign::Domain::SomeEvent; trigger Local.Command; end`
163
- # builds the exact same `Policy` a `policy` block inside this
164
- # domain's own `.bluebook` would (same `on_impl`/`trigger_impl`,
165
- # same `PolicyInterpreter` runtime — reusing `PolicyBuilder`
166
- # directly, zero new runtime semantics). What's new is only where
167
- # it can be written: a cross-domain reaction is a wiring/context-
168
- # mapping decision (this chapter conforming to a foreign chapter's
169
- # published event), the same kind of decision `port`/
170
- # `uses_framework` already are — not a fact this domain's own
171
- # model states about itself, which `policy` (inside the bluebook)
172
- # remains the right word for.
173
- #
174
- # Must be a block, not `translates Event, into: Command` — a flat
175
- # call's arguments are evaluated eagerly, under this builder's own
176
- # `ConstShim` resolver (`BindingProxy.namespace`, set up by
177
- # `self.build` below), which mints a `BindingProxy` instance per
178
- # segment and cannot answer a further `::` (it is not a Module) —
179
- # a multi-segment reference like `Deploy::Tenant::TenantProvisioned`
180
- # would raise before this method ever ran. `port_impl`'s own
181
- # `ConstShim.with(->(const) { const })` swap only works because
182
- # its own callers never pass a multi-segment bare constant as an
183
- # eagerly-evaluated argument — everything of that shape lives
184
- # inside its block, evaluated later, under the swapped resolver.
185
- # A block defers evaluation the same way; a flat call cannot.
186
- #
187
- # @param name [String, Symbol] the reaction's name
188
- # @yield the `on`/`trigger` block, evaluated later under the scoped resolver
189
- # @return [Array<Bluebook::Policy>] the chapter's policies, with the new one appended
190
- # @raise [Malformed] if no bluebook is registered for this domain to attach the reaction to
129
+ # A cross-domain reaction, built as the same `Policy` an in-bluebook `policy` block would.
130
+ # Must be a block — the eager const resolver here can't handle multi-segment references.
191
131
  def translates(name, &block)
192
132
  bluebook_ir = Hecks.current_registry.bluebook(@domain) or
193
133
  raise Malformed, "#{@domain} declares no such bluebook — translates needs one to attach its reaction to"
194
134
 
195
- # Same resolver BluebookBuilder itself uses for a `policy`
196
- # block's own `on`/`trigger` (bluebook_builder.rb) — a
197
- # `ScopedConstant`, not the bare passthrough `port_impl` swaps
198
- # to, because `on`/`trigger` here take genuinely multi-segment
199
- # references (`Deploy::Tenant::TenantProvisioned`), not a
200
- # single-segment type name.
135
+ # Same resolver `policy` blocks use for `on`/`trigger` — a ScopedConstant, not the bare
136
+ # passthrough `port_impl` swaps to, since these take multi-segment references.
201
137
  resolver = ->(const) { ConstShim::ScopedConstant.for(const) }
202
138
  built = ConstShim.with(resolver) { PolicyBuilder.build(name, &block) }
203
139
 
@@ -206,58 +142,18 @@ module Hecks
206
142
  end
207
143
 
208
144
  # Assembles the collected binds, subscriptions and attachments into a `Hecksagon`.
209
- #
210
- # No ungoverned-role check here — see
211
- # Registry::Verification#refuse_ungoverned_roles!. It lives outside
212
- # per-block `build`, alongside `environment:`
213
- # (Runtime::Loader.boot's comment has the provenance): a domain
214
- # split across multiple hecksagon blocks (base + an
215
- # `environments/<name>.hecksagon` overlay) would have every
216
- # block but the one declaring `uses_framework "Governance"`
217
- # refused here, even though `Registry#add_hecksagon` merges them
218
- # into one Hecksagon before anything ever dispatches against it.
219
- # Checking the merged result once, at verify! time — after every
220
- # file for this domain has loaded — is both more permissive (no
221
- # need to repeat `uses_framework` in every file) and strictly
222
- # more correct (a check against an incomplete, not-yet-merged
223
- # hecksagon can never see the real final shape).
224
- #
225
- # @return [Bluebook::Hecksagon] this block's wiring, which `Registry#add_hecksagon` merges
226
- # with any other block declared for the same domain
145
+ # No ungoverned-role check here — it runs once on the merged result at verify! time.
227
146
  def build
228
147
  Hecksagon.new(domain: @domain, binds: @binds, subscriptions: @subscriptions,
229
148
  framework_members: @framework_members, vendored_bluebooks: @vendored_bluebooks,
230
- bounded: @bounded, translates: @translates)
149
+ attached_chapters: @attached_chapters, bounded: @bounded, translates: @translates)
231
150
  end
232
151
 
233
- # Records any verb the grammar does not own as a domain-wide bind to the named adapter.
234
- #
235
- # **Domain-level default binds** — `persisted_by "Heki"` bare, at the top
236
- # of a hecksagon block, applies to every aggregate in this domain
237
- # that doesn't declare its own override. Mirrors `BindingProxy`'s own
238
- # `method_missing` one level down (`aggregate:` filled in there,
239
- # `nil` here) — generic over verb name, not hardcoded to
240
- # `persisted_by`/`projected_by` specifically, so any future verb
241
- # gets a domain-level default for free too. See `Hecksagon#bind_for`
242
- # for the fallback lookup this feeds.
243
- #
244
- # @param verb [Symbol] the word called, such as `:persisted_by`
245
- # @param args [Array<Object>] positional arguments; the first names the adapter
246
- # @param kwargs [Hash{Symbol => Object}] keyword arguments; `:role` is kept on the bind
247
- # @yield an optional block, called once after the bind is recorded
248
- # @return [Object] this builder after recording a bind, or the grammar word's own result
249
- # when `verb` is one the `Hecksagon` grammar admits
250
- # @raise [NoMethodError] if `verb` is no grammar word and names no adapter
251
- # @raise [Bluebook::DSL::Malformed] if the grammar admits `verb` only in another context,
252
- # or admits it here and its implementation refuses the declaration
152
+ # Records any verb the grammar doesn't own as a domain-wide default bind, e.g. bare
153
+ # `persisted_by "Heki"` at the top of a block, applied unless an aggregate overrides it.
253
154
  def method_missing(verb, *args, **kwargs, &block)
254
- # A closed-set grammar word (`port`, today) gets first refusal
255
- # — item #13's full metaprogrammed dispatch (slice 5); see
256
- # `WordGate#word_gate_dispatch`'s own header for why this class
257
- # needs to call it explicitly rather than including it the
258
- # ordinary way. Only once that says "not admitted" does the
259
- # genuinely open-ended `persisted_by "Heki"`-style bind
260
- # vocabulary below get a turn.
155
+ # Grammar words (like `port`) get first refusal via explicit dispatch; only when that's
156
+ # not admitted does the open-ended `persisted_by`-style bind vocabulary below apply.
261
157
  result = word_gate_dispatch(verb, args, kwargs, block)
262
158
  return result unless result.equal?(WordGate::NOT_ADMITTED)
263
159
 
@@ -272,29 +168,84 @@ module Hecks
272
168
 
273
169
  # Evaluates a `Hecks.hecksagon` block with bare `Domain::Aggregate` constants resolving to
274
170
  # bind-collecting proxies, and returns the wiring it declared.
275
- #
276
- # @param domain [String] name of the domain being wired
277
- # @yield the hecksagon body, evaluated with the builder as `self`; may be omitted
278
- # @return [Bluebook::Hecksagon] the declared wiring
279
- # @raise [Bluebook::DSL::Malformed] if a `port` names no registered bluebook or aggregate,
280
- # or declares a shape the port grammar refuses
281
- # @raise [Runtime::WiringError] if `uses_framework` or `uses_embryonaut_bluebook` names
282
- # something that cannot be found
283
171
  def self.build(domain, &block)
284
172
  builder = new(domain)
285
173
  resolver = ->(name) { BindingProxy.namespace(name, builder.binds) }
286
174
 
287
175
  previous = collector
176
+ previous_name = building
288
177
  self.collector = builder.binds
178
+ self.building = domain.to_s
179
+ previous_hidden = hidden_modules
180
+ hidden = previous_name == "Hecks" ? {} : shadowed(domain)
181
+ self.hidden_modules = hidden.empty? ? previous_hidden : hidden
289
182
  begin
290
183
  ConstShim.with(resolver) { builder.instance_eval(&block) } if block
291
184
  ensure
185
+ restore_shadowed(hidden)
186
+ self.hidden_modules = previous_hidden
292
187
  self.collector = previous
188
+ self.building = previous_name
293
189
  end
294
190
 
295
191
  builder.build
296
192
  end
193
+
194
+ # Takes off `Hecks` each real module a chapter aggregate shares its name with, so the
195
+ # name reaches `ChapterConstants#const_missing`. Only the chapter named Hecks has this
196
+ # collision; a nested build of it leaves the outer build's shadows in place.
197
+ #
198
+ # @param domain [String, Symbol] the chapter whose hecksagon is being built
199
+ # @return [Hash{Symbol => Object}] what was taken off, by name: the module, or the
200
+ # autoload path when the constant had not loaded yet
201
+ def self.shadowed(domain)
202
+ return {} unless domain.to_s == "Hecks"
203
+
204
+ chapter = Hecks.current_registry&.bluebook("Hecks")
205
+ names = chapter ? chapter.aggregates.map { |aggregate| aggregate.hecks_name.to_sym } : []
206
+ names.select { |name| Hecks.const_defined?(name, false) }.to_h do |name|
207
+ pending = Hecks.autoload?(name)
208
+ held = pending ? [:autoload, pending] : [:module, Hecks.const_get(name, false)]
209
+ Hecks.send(:remove_const, name)
210
+ [name, held]
211
+ end
212
+ end
213
+
214
+ # Runs the block with every module the running build shadowed back on `Hecks`, and a
215
+ # missing `Hecks::X` an ordinary `NameError`, then shadows them again. A chapter loaded
216
+ # from inside the hecksagon block is ordinary code, not the hecksagon's own vocabulary.
217
+ # A no-op when nothing is shadowed.
218
+ #
219
+ # @yield the code that must see `Hecks`'s real modules
220
+ # @return [Object] the block's result
221
+ def self.with_real_modules
222
+ hidden = hidden_modules
223
+ return yield if hidden.nil? || hidden.empty?
224
+
225
+ name = building
226
+ restore_shadowed(hidden)
227
+ self.building = nil
228
+ begin
229
+ yield
230
+ ensure
231
+ self.building = name
232
+ hidden.replace(shadowed(name))
233
+ end
234
+ end
235
+
236
+ # Puts back what `shadowed` took off.
237
+ #
238
+ # @param hidden [Hash{Symbol => Array}] `shadowed`'s answer
239
+ # @return [void]
240
+ def self.restore_shadowed(hidden)
241
+ hidden.each do |name, (kind, held)|
242
+ Hecks.send(:remove_const, name) if Hecks.const_defined?(name, false)
243
+ kind == :autoload ? Hecks.autoload(name, held) : Hecks.const_set(name, held)
244
+ end
245
+ end
297
246
  end
298
247
  end
299
248
  end
300
249
  end
250
+
251
+ Hecks.singleton_class.prepend(Hecks::Bluebook::DSL::HecksagonBuilder::ChapterConstants)
@@ -1,68 +1,19 @@
1
1
  module Hecks
2
2
  module Bluebook
3
3
  module DSL
4
- # `identified_by` — shared by AggregateBuilder and EntityBuilder
5
- # only (S9, ADR 0025 — "EntityBuilder's duplicate identified_by and
6
- # resolve_pending_identity! go"): a piece's own identity cannot
7
- # spell differently from its aggregate's, and until this slice it
8
- # was hand-duplicated onto both rather than shared.
9
- #
10
- # A separate module from AttributeCollector on purpose — every
11
- # `attribute()`-taking builder (Command, Query, PortOperation,
12
- # ValueObject, ...) `include`s that one too, and none of them
13
- # declares an identity of its own ; folding `identified_by` in
14
- # there made it answer for six builders that never earned the
15
- # word (`syntax_conformance_spec.rb` catches exactly this — a
16
- # builder answering a method the grammar never grants it).
17
- #
18
- # Requires its includer to also `include AttributeCollector`
19
- # (for `attributes`/`resolve_identity_field!`/`resolve_identity_
20
- # type!`, still declared there since every includer of that
21
- # module needs them) and to supply `identity_pool` (private) —
22
- # the value-object list a bare field's own type resolves
23
- # against: AggregateBuilder's own `@value_objects + closed_sets`,
24
- # or EntityBuilder's owner's, since a piece mints none of its own.
4
+ # `identified_by`, shared by AggregateBuilder and EntityBuilder (ADR 0025).
5
+ # The includer must include AttributeCollector and define a private `identity_pool`.
25
6
  module IdentityDeclaration
26
- # Records which of the three live `identified_by` forms a builder declared, deferring
27
- # resolution until build time.
28
- #
29
- # There are three live forms, deliberately distinguishable at the
30
- # declaration site:
7
+ # Records which `identified_by` form a builder declared; resolution waits for build time.
31
8
  #
32
9
  # identified_by AccountNumber, as: :number # one identity concept
33
10
  # identified_by do ... end # a bespoke concept
34
11
  # identified_by :branch, :number # an existing compound key
35
12
  #
36
- # One symbol is retired: it cannot say whether the author means a
37
- # value concept or a field-shaped database key. Frozen source still
38
- # reaches the old interpretation through `legacy_identified_by`.
39
- # Both `AggregateBuilder` and `EntityBuilder` name this method in their Keyword rows'
40
- # `calls:` column, so `GenericDispatch` forwards `identified_by` here unchanged, both
41
- # after boot (reading the live grammar table) and during it
42
- # (`GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`, which carries every `calls:`-routed row
43
- # unconditionally, not a hand-picked bootstrap-reachable subset — though this one is
44
- # exercised during boot too, since every self-hosted aggregate/entity declares an identity).
45
- # Dispatches across the three live forms documented above (value-
46
- # object + block, single type target, single/compound field
47
- # target), each an early return that sets exactly one pending
48
- # ivar. Splitting per form would need each branch's own `return`-
49
- # with-nil semantics and the shared `@name`/`identity_pool`
50
- # threaded back out as parameters, for no gain beyond what the
51
- # three-forms comment above already documents.
52
- #
53
- # @param targets [Array<Symbol, Module>] zero or more identity targets: a value-object
54
- # type (a bareword, resolved by `ConstShim` to a `Module`), one or more attribute-name
55
- # symbols for a field or compound key, or empty when `definition` is given
56
- # @param as [Symbol, nil] the field name to mint for a value-object-type target; not
57
- # accepted with a field or compound-key target
58
- # @yield a bespoke value-object body, `instance_eval`'d by `ValueObjectBuilder.build` to
59
- # mint the identity's own anonymous value object
60
- # @return [Array<Symbol>, Array<String>, nil] `targets` when a compound key is declared,
61
- # the resolved identity paths from `legacy_identified_by` in shadow-parsing mode, or
62
- # `nil` otherwise; callers reach this through `GenericDispatch`, which discards it
63
- # @raise [Bluebook::DSL::Malformed] if `identified_by` was already called, combines a
64
- # block with targets, names no identity, mixes a value-object type with field names,
65
- # passes `as:` with a field or compound key, or the block declares no attributes
13
+ # @param targets [Array<Symbol, Module>] a value-object type or attribute names
14
+ # @param as [Symbol, nil] the field name to mint for a value-object-type target
15
+ # @yield a bespoke value-object body for the identity's own value object
16
+ # @raise [Bluebook::DSL::Malformed] on a repeat declaration or an invalid mix of forms
66
17
  # rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
67
18
  def identified_by_impl(*targets, as: nil, &definition)
68
19
  return legacy_identified_by(*targets, as: as, &definition) if MetaValidator.shadow_parsing?
@@ -84,20 +35,8 @@ module Hecks
84
35
  &definition
85
36
  )
86
37
  rescue NameError => e
87
- # A removed spelling must refuse loudly, not degrade into a raw
88
- # Ruby error — the one contract `EraGuard.shadow_parse` leans
89
- # on to know a normal parse genuinely could not read this text
90
- # (only `Malformed` triggers its shadow-mode retry, era_guard.rb's
91
- # own comment). The old `identified_by { name.value }` — a block
92
- # whose text was never called, only extracted (legacy_
93
- # identified_by, below) — is exactly this shape: read under the
94
- # current grammar it is instead instance_eval'd as a value-object
95
- # definition, and a bare identifier like `name` inside it resolves
96
- # to nothing WordGate#method_missing recognizes, so Ruby itself
97
- # raises NameError. Left uncaught, that NameError skipped
98
- # shadow_parse's rescue entirely and reached callers as a raw
99
- # crash instead of the frozen-era fallback that exists for
100
- # precisely this text.
38
+ # Must raise Malformed: EraGuard.shadow_parse retries frozen text only on
39
+ # Malformed, and a bare identifier in an old block form raises NameError here.
101
40
  raise Malformed,
102
41
  "#{@name}.identified_by do ... end could not be read as a value-object " \
103
42
  "definition: #{e.message}"
@@ -122,10 +61,7 @@ module Hecks
122
61
  raise Malformed,
123
62
  "#{@name}.identified_by takes no as: — name the declared field itself"
124
63
  end
125
- # Transitional compatibility: the self-hosted language and live
126
- # corpus still contain this form. Keep it readable until their
127
- # exemplar-led migration is complete; the final lifecycle cutover
128
- # replaces this assignment with the targeted refusal.
64
+ # Transitional: the self-hosted language and live corpus still use this form.
129
65
  @identity_field_pending = field
130
66
  return
131
67
  end
@@ -141,11 +77,7 @@ module Hecks
141
77
 
142
78
  private
143
79
 
144
- # Resolves whichever of the three `identified_by` shapes is
145
- # pending, against `identity_pool` — the includer's own private
146
- # hook. Called at build time, not at `identified_by`'s own call
147
- # time — see `AttributeCollector#resolve_identity_field!`'s own
148
- # comment on why.
80
+ # Resolves the pending identity against `identity_pool` at build time, not call time.
149
81
  def resolve_pending_identity!
150
82
  if @identity_type_pending
151
83
  type, as, insert_at = @identity_type_pending
@@ -162,11 +94,7 @@ module Hecks
162
94
  def identity_type?(target) = target.to_s.match?(/\A[A-Z]/)
163
95
 
164
96
  def refuse_second_identity!
165
- # During the staged migration a transitional one-symbol declaration
166
- # may be replaced by the new declaration later in the same builder.
167
- # This keeps existing builder fixtures/source readable while their
168
- # exemplar is migrated. Once one-symbol identity is retired this
169
- # compatibility branch disappears with it.
97
+ # Transitional: a one-symbol declaration may still be replaced by a later one.
170
98
  if @identity_field_pending && !@identity_type_pending && !@identity_fields_pending
171
99
  @identity_field_pending = nil
172
100
  return
@@ -178,10 +106,7 @@ module Hecks
178
106
  raise Malformed, "#{@name} declares identified_by more than once"
179
107
  end
180
108
 
181
- # Legacy — the two removed spellings (a value object + as:, and the
182
- # multi-line block), kept alive only for `EraGuard.shadow_parse`
183
- # (S0a, ADR 0025) to still make sense of frozen era text that used
184
- # them; unreachable outside `MetaValidator.shadow_parsing?`.
109
+ # Parses the spellings frozen era text uses, for `EraGuard.shadow_parse`.
185
110
  def legacy_identified_by(*targets, as:, &path)
186
111
  target = targets.first
187
112
  if target
@@ -2,11 +2,7 @@ require_relative "word_gate"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # Parses a `lifecycle :field, default: ... do transition ... end`
6
- # block into a `Lifecycle` — the field an aggregate or entity's own
7
- # state machine lives on, its starting value, and the `command =>
8
- # target_state` transition table (with an optional `from:` guard)
9
- # each `transition_impl` call adds a row to.
5
+ # Parses a `lifecycle :field, default: ... do transition ... end` block into a `Lifecycle`.
10
6
  class LifecycleBuilder
11
7
  GRAMMAR_CONTEXT = "Lifecycle".freeze
12
8
 
@@ -22,11 +18,7 @@ module Hecks
22
18
 
23
19
  # Records one transition row per command in `mapping`, all sharing its `from:` guard.
24
20
  #
25
- # Answers the `transition` word, which the grammar table routes here
26
- # through its `calls:` column — item #13's full metaprogrammed
27
- # dispatch (slice 4c). Bootstrap-reachable (syntax.bluebook's
28
- # own Keyword/Argument entities describe their `status`
29
- # lifecycle with it), so in `BOOTSTRAP_CALLS_FALLBACK`.
21
+ # Listed in `BOOTSTRAP_CALLS_FALLBACK` because syntax.bluebook uses it during boot.
30
22
  #
31
23
  # @param mapping [Hash{String, Symbol => String, Symbol, Array<String>}] command name to
32
24
  # target state, as in `"Purchase" => "sold"`; the optional `:from` key holds the
@@ -70,17 +62,11 @@ module Hecks
70
62
 
71
63
  private
72
64
 
73
- # C5.3 (docs/semantics/bluebook-semantics.md) — two transitions for
74
- # one command whose `from:` sets overlap (or where either has no
75
- # `from:` at all) were silently first-wins; refused where the state
76
- # machine can be read whole. Two transitions for one command from
77
- # disjoint states are the legitimate shape (`match_transition`
78
- # picks by the current state) and stay. A `from:` naming a state
79
- # nothing declares is not refused here: it is a reachability
80
- # finding `bin/model_check` already reports (unreachable state,
81
- # dead transition), and a bluebook may declare it on purpose.
65
+ # C5.3 (docs/semantics/bluebook-semantics.md): overlapping `from:` sets for one command
66
+ # are refused. Disjoint sets are legitimate. An undeclared `from:` state is left to
67
+ # `hecks model_check`.
82
68
  def refuse_ambiguity!
83
- return if MetaValidator.shadow_parsing? # frozen era text is history
69
+ return if MetaValidator.shadow_parsing? # frozen era text is exempt
84
70
 
85
71
  @transitions.each_with_index do |(command, transition), index|
86
72
  earlier = @transitions[0...index].find do |other_command, other|