hecks 2.8.0 → 2.9.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 (404) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +4 -6
  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 +17 -98
  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 +4 -30
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres.rb +145 -134
  25. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  26. data/lib/hecks/adapters/driven/prism.rb +7 -30
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  31. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  32. data/lib/hecks/adapters/driven/tenant_provisioner.rb +5 -48
  33. data/lib/hecks/adapters/driven.rb +5 -36
  34. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  35. data/lib/hecks/behaviors/dsl.rb +7 -25
  36. data/lib/hecks/behaviors/expectations.rb +31 -141
  37. data/lib/hecks/behaviors/ir.rb +7 -20
  38. data/lib/hecks/behaviors/rspec.rb +6 -17
  39. data/lib/hecks/behaviors/runner.rb +10 -34
  40. data/lib/hecks/behaviors.rb +4 -8
  41. data/lib/hecks/bluebook/aggregate.rb +9 -75
  42. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  43. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  44. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  45. data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
  46. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  47. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  48. data/lib/hecks/bluebook/assembly.rb +6 -45
  49. data/lib/hecks/bluebook/attribute.rb +12 -61
  50. data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
  51. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  52. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  53. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  54. data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
  55. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  56. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  57. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  58. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  59. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  60. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  61. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  62. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  63. data/lib/hecks/bluebook/capabilities.rb +17 -49
  64. data/lib/hecks/bluebook/chapter.rb +10 -48
  65. data/lib/hecks/bluebook/command.rb +23 -81
  66. data/lib/hecks/bluebook/domain_port.rb +14 -63
  67. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  68. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  69. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  70. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  71. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
  72. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
  73. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
  74. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  75. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  76. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
  77. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  78. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  79. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -194
  80. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  81. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  82. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  83. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  84. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  85. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  86. data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
  87. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  88. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  89. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  90. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  91. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  92. data/lib/hecks/bluebook/dsl/world_builder.rb +19 -111
  93. data/lib/hecks/bluebook/entity.rb +13 -71
  94. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  95. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  96. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  97. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  98. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  99. data/lib/hecks/bluebook/expression/resolver.rb +37 -660
  100. data/lib/hecks/bluebook/hexagon.rb +5 -28
  101. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  102. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  103. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  104. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  105. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  106. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  107. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
  108. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  109. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
  110. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  111. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  112. data/lib/hecks/bluebook/meta_validator.rb +79 -349
  113. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  114. data/lib/hecks/bluebook/model_check.rb +100 -597
  115. data/lib/hecks/bluebook/pattern_subset.rb +11 -69
  116. data/lib/hecks/bluebook/process_manager.rb +13 -83
  117. data/lib/hecks/bluebook/project_loader.rb +3 -39
  118. data/lib/hecks/bluebook/project_register.rb +12 -60
  119. data/lib/hecks/bluebook/query.rb +9 -48
  120. data/lib/hecks/bluebook/read_model.rb +57 -81
  121. data/lib/hecks/bluebook/reference.rb +7 -41
  122. data/lib/hecks/bluebook/smoke_test.rb +8 -98
  123. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  124. data/lib/hecks/bluebook/translation.rb +26 -62
  125. data/lib/hecks/bluebook/value_object.rb +11 -36
  126. data/lib/hecks/bluebook.rb +5 -22
  127. data/lib/hecks/cache_dir.rb +4 -23
  128. data/lib/hecks/cli/document.rb +3 -21
  129. data/lib/hecks/cli/ir.rb +3 -5
  130. data/lib/hecks/cli/mcp.rb +2 -3
  131. data/lib/hecks/cli/mcp_door.rb +19 -114
  132. data/lib/hecks/cli/model_check.rb +18 -85
  133. data/lib/hecks/cli/project_cli.rb +7 -40
  134. data/lib/hecks/cli/project_diagrams.rb +0 -7
  135. data/lib/hecks/cli/run.rb +12 -58
  136. data/lib/hecks/cli/smoke_test.rb +2 -16
  137. data/lib/hecks/cli/stores.rb +1 -2
  138. data/lib/hecks/cli.rb +18 -24
  139. data/lib/hecks/construct.rb +8 -34
  140. data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
  141. data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
  142. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  143. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  144. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  145. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  146. data/lib/hecks/embryonaut_bluebook.rb +4 -71
  147. data/lib/hecks/facade/cli_door.rb +24 -106
  148. data/lib/hecks/facade/cli_runner.rb +28 -172
  149. data/lib/hecks/facade/command_request.rb +13 -33
  150. data/lib/hecks/facade/handle.rb +34 -121
  151. data/lib/hecks/facade/json_door.rb +31 -146
  152. data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
  153. data/lib/hecks/facade/surface/chapter.rb +10 -54
  154. data/lib/hecks/facade/surface.rb +8 -23
  155. data/lib/hecks/facade.rb +10 -25
  156. data/lib/hecks/forms/app.rb +15 -70
  157. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  158. data/lib/hecks/forms/field_renderer.rb +17 -156
  159. data/lib/hecks/forms/field_shape.rb +30 -222
  160. data/lib/hecks/forms/html.rb +12 -47
  161. data/lib/hecks/forms/index_renderer.rb +1 -4
  162. data/lib/hecks/forms/page.rb +3 -9
  163. data/lib/hecks/forms/params.rb +14 -60
  164. data/lib/hecks/forms/port_argument.rb +2 -19
  165. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  166. data/lib/hecks/forms/record_renderer.rb +8 -75
  167. data/lib/hecks/forms/record_table.rb +7 -50
  168. data/lib/hecks/forms/reference_options.rb +3 -30
  169. data/lib/hecks/forms/value_object_shape.rb +8 -35
  170. data/lib/hecks/forms.rb +5 -33
  171. data/lib/hecks/fqn.rb +5 -12
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  175. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  176. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  177. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  178. data/lib/hecks/framework.rb +11 -80
  179. data/lib/hecks/freezer.rb +5 -39
  180. data/lib/hecks/grammar/expression.bluebook +15 -40
  181. data/lib/hecks/grammar/translation.bluebook +3 -6
  182. data/lib/hecks/grammar.rb +16 -41
  183. data/lib/hecks/ir.rb +14 -83
  184. data/lib/hecks/language/adapter.bluebook +2 -7
  185. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  186. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  187. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
  188. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  189. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  190. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  191. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  192. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  193. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  194. data/lib/hecks/language/bluebook/query.bluebook +12 -43
  195. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  196. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  197. data/lib/hecks/language/bluebook/vocabulary.bluebook +82 -197
  198. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  199. data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
  200. data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
  201. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  202. data/lib/hecks/language/oidc.json +35 -0
  203. data/lib/hecks/language/port.bluebook +4 -17
  204. data/lib/hecks/language/translation/translation.bluebook +3 -9
  205. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  206. data/lib/hecks/language/world/wiring.bluebook +1 -3
  207. data/lib/hecks/language/world/world.bluebook +5 -7
  208. data/lib/hecks/literal.rb +8 -50
  209. data/lib/hecks/mcp_door_scope.rb +9 -90
  210. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  211. data/lib/hecks/naming.rb +29 -137
  212. data/lib/hecks/ports/access_control.rb +7 -23
  213. data/lib/hecks/ports/agent/answers.rb +5 -23
  214. data/lib/hecks/ports/agent.rb +47 -172
  215. data/lib/hecks/ports/authentication.rb +12 -39
  216. data/lib/hecks/ports/authorization.rb +16 -43
  217. data/lib/hecks/ports/clock.rb +5 -45
  218. data/lib/hecks/ports/extraction.rb +7 -12
  219. data/lib/hecks/ports/identity_assignment.rb +8 -29
  220. data/lib/hecks/ports/identity_generation.rb +6 -29
  221. data/lib/hecks/ports/identity_resolution.rb +2 -10
  222. data/lib/hecks/ports/key_vault.rb +9 -45
  223. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  224. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  225. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  226. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  227. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  228. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
  229. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
  231. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  232. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
  233. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
  250. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  251. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  252. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  253. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  254. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  255. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  256. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
  257. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  258. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  259. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  260. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  261. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  262. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  263. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  264. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  265. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  266. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  267. data/lib/hecks/ports/persistence/state_codec.rb +23 -103
  268. data/lib/hecks/ports/persistence.rb +7 -14
  269. data/lib/hecks/ports/projection.rb +42 -84
  270. data/lib/hecks/ports/query/in_memory.rb +10 -58
  271. data/lib/hecks/ports/query/ordering.rb +11 -32
  272. data/lib/hecks/ports/query.rb +14 -37
  273. data/lib/hecks/ports.rb +2 -8
  274. data/lib/hecks/projections/bootstrap_table.rb +11 -43
  275. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  276. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  277. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  278. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  279. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  280. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  281. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  282. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  283. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  284. data/lib/hecks/projections/deploy/fargate.rb +35 -202
  285. data/lib/hecks/projections/deploy/lambda.rb +150 -678
  286. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  287. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  288. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  289. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  290. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  291. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  292. data/lib/hecks/projections/deploy/preview/template.rb +2 -58
  293. data/lib/hecks/projections/deploy/preview.rb +2 -67
  294. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  295. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  296. data/lib/hecks/projections/deploy/shared.rb +47 -146
  297. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  298. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  299. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  300. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  301. data/lib/hecks/projections/diagrams.rb +20 -582
  302. data/lib/hecks/projections/glossary/html.rb +14 -130
  303. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  304. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  305. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  306. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  307. data/lib/hecks/projections/glossary.rb +30 -222
  308. data/lib/hecks/projections/ir.rb +3 -10
  309. data/lib/hecks/projections/model/deviations.rb +15 -42
  310. data/lib/hecks/projections/model.rb +12 -51
  311. data/lib/hecks/projections/oidc.rb +12 -56
  312. data/lib/hecks/projections/parser_table.rb +9 -28
  313. data/lib/hecks/projections/reference.rb +2 -15
  314. data/lib/hecks/projections/rust_vocabulary.rb +12 -250
  315. data/lib/hecks/projections/shape.rb +3 -29
  316. data/lib/hecks/projections/statements.rb +7 -86
  317. data/lib/hecks/projections/vocabulary.rb +6 -22
  318. data/lib/hecks/projections.rb +2 -16
  319. data/lib/hecks/projector/cli_projector.rb +60 -375
  320. data/lib/hecks/projector/docs_projector.rb +10 -201
  321. data/lib/hecks/projector/exporter.rb +42 -134
  322. data/lib/hecks/projector/ir_projector.rb +2 -9
  323. data/lib/hecks/projector/narrate_projector.rb +15 -189
  324. data/lib/hecks/projector/target.rb +13 -76
  325. data/lib/hecks/projector.rb +30 -121
  326. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  327. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  328. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  329. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  330. data/lib/hecks/query_specification/common/options.rb +2 -6
  331. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  332. data/lib/hecks/query_specification/field_path.rb +37 -77
  333. data/lib/hecks/query_specification/hop_path.rb +12 -76
  334. data/lib/hecks/release/gem_pin.rb +2 -26
  335. data/lib/hecks/release/runner/ci_publisher.rb +3 -6
  336. data/lib/hecks/release/runner/commands.rb +2 -4
  337. data/lib/hecks/release/runner/gem_publisher.rb +2 -3
  338. data/lib/hecks/release/runner/npm_publisher.rb +6 -20
  339. data/lib/hecks/release/runner/preflight.rb +4 -19
  340. data/lib/hecks/release/runner/tagger.rb +2 -9
  341. data/lib/hecks/release/runner.rb +3 -32
  342. data/lib/hecks/rendering.rb +4 -26
  343. data/lib/hecks/router/namespace_installer.rb +12 -36
  344. data/lib/hecks/router.rb +4 -8
  345. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  346. data/lib/hecks/runtime/boot_gates.rb +3 -18
  347. data/lib/hecks/runtime/caller.rb +19 -59
  348. data/lib/hecks/runtime/capability_graph.rb +5 -21
  349. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  350. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
  351. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  352. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  353. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  354. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  355. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  356. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  357. data/lib/hecks/runtime/dependency_planning.rb +30 -102
  358. data/lib/hecks/runtime/dispatcher.rb +82 -241
  359. data/lib/hecks/runtime/entity_element.rb +40 -462
  360. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  361. data/lib/hecks/runtime/errors.rb +32 -115
  362. data/lib/hecks/runtime/event.rb +3 -25
  363. data/lib/hecks/runtime/identity.rb +18 -154
  364. data/lib/hecks/runtime/instance.rb +18 -150
  365. data/lib/hecks/runtime/interpreting.rb +11 -70
  366. data/lib/hecks/runtime/invocation.rb +28 -164
  367. data/lib/hecks/runtime/loader.rb +48 -186
  368. data/lib/hecks/runtime/outbox.rb +38 -261
  369. data/lib/hecks/runtime/policy_interpreter.rb +38 -200
  370. data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
  371. data/lib/hecks/runtime/query_interpreter.rb +45 -187
  372. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  373. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  374. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  375. data/lib/hecks/runtime/reference_hop.rb +8 -81
  376. data/lib/hecks/runtime/refusal_wording.rb +8 -89
  377. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  378. data/lib/hecks/runtime/registry/verification.rb +52 -225
  379. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  380. data/lib/hecks/runtime/registry.rb +99 -244
  381. data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
  382. data/lib/hecks/runtime/routing.rb +4 -15
  383. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  384. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  385. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  386. data/lib/hecks/runtime/tenant_check.rb +6 -68
  387. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  388. data/lib/hecks/runtime/value/admission.rb +16 -67
  389. data/lib/hecks/runtime/value/coercion.rb +155 -641
  390. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  391. data/lib/hecks/runtime/value.rb +12 -84
  392. data/lib/hecks/runtime.rb +17 -65
  393. data/lib/hecks/storehouse.rb +141 -568
  394. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
  395. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  396. data/lib/hecks/vendoring/git_environment.rb +2 -8
  397. data/lib/hecks/vendoring/git_source.rb +4 -10
  398. data/lib/hecks/vendoring.rb +7 -46
  399. data/lib/hecks/version.rb +3 -14
  400. data/lib/hecks.rb +26 -81
  401. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  402. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  403. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  404. metadata +3 -2
@@ -6,13 +6,12 @@ require_relative "../naming"
6
6
 
7
7
  module Hecks
8
8
  module Runtime
9
+ # Raised when a registry can't resolve required wiring: an unbound aggregate, an
10
+ # unknown adapter, or a port/adapter mismatch.
9
11
  class WiringError < StandardError; end
10
12
 
11
- # The collections a boot gathers — bluebooks, hexagons, ports, adapters,
12
- # worlds, the logs — and how a repository is resolved from them. The
13
- # wiring gate lives in registry/verification.rb, saga persistence
14
- # resolution in registry/saga_persistence.rb, and a `.world`'s project-wide
15
- # defaults in registry/world_defaults.rb.
13
+ # The collections a boot gathers: bluebooks, hecksagons, ports, adapters, worlds, and logs.
14
+ # Wiring verification, saga persistence, and world defaults live under registry/.
16
15
  class Registry
17
16
  include Verification
18
17
  include SagaPersistence
@@ -39,97 +38,48 @@ module Hecks
39
38
  @event_log = []
40
39
  @reaction_log = []
41
40
  @saga_log = []
42
- # A declarative fact, not yet a dispatched one — `AggregateDoor#
43
- # mark_sensitive` (called from a `.hecksagon` file, the same way
44
- # `port`/`persisted_by` already are) appends here at
45
- # hecksagon-build time; `Runtime::Loader.boot`'s own post-dispatcher
46
- # step turns each entry into a real `Privacy::Marking.Mark`,
47
- # idempotently, the same "declared here, taken effect once boot
48
- # actually has a dispatcher" shape `redrive_outbox!` already has.
41
+ # Recorded at hecksagon-build time (AggregateDoor#mark_sensitive); Loader.boot's
42
+ # post-dispatch step turns each entry into a real Privacy::Marking.Mark, idempotently.
49
43
  @pending_privacy_markings = []
50
- # **Additive, Ruby-only** — never merged into saga_log/reaction_log.
51
- # rust/src/kernel/orchestrate.rs ports those two arrays' exact
52
- # shape byte-for-byte (spec/rust_conformance_spec.rb's own
53
- # equality check) — a landmine found by reading that spec before
54
- # touching anything, not by hitting it. These carry the raw
55
- # inputs a dispatch's own argument binding was resolved from
56
- # (SagaInterpreter#deliver_saga_dispatch / PolicyInterpreter#
57
- # trigger_args), for Properties.dispatch_binding_fidelity's own
58
- # independent re-derivation — a fact neither existing log
59
- # records at all, so there is nothing here for Rust to have
60
- # matched or drifted from.
44
+ # Ruby-only; unlike saga_log/reaction_log (ported byte-for-byte to
45
+ # rust/src/kernel/orchestrate.rs, per spec/rust_conformance_spec.rb), these carry
46
+ # the raw dispatch-binding inputs Properties.dispatch_binding_fidelity re-derives.
61
47
  @saga_dispatch_log = []
62
48
  @policy_dispatch_log = []
63
49
  @saga_instances = Hash.new { |h, k| h[k] = {} }
64
- # Guards `saga_instances`' own mutation+checkpoint sequence
65
- # (`SagaInterpreter`'s 4 write points, §7) — the same shape of
66
- # hazard this codebase's own prior audit already flagged for
67
- # `Dispatcher#reenter`'s reaction-depth counter (M20: a
68
- # thread-shared ivar with no lock, since fixed by moving it to
69
- # `Thread.current`, dispatcher.rb), made meaningfully easier to
70
- # hit here once a persistence write sits in the same critical
71
- # section. Held across the in-memory
72
- # mutation and the checkpoint write together, never across a
73
- # saga's own dispatch cascade — see `SagaInterpreter#advance_saga`'s
74
- # own comment for why that distinction matters (non-reentrant
75
- # Mutex, recursive re-entry is real).
50
+ # Guards saga_instances' mutation+checkpoint sequence together, never held across a
51
+ # saga's own dispatch cascade — Mutex is non-reentrant and recursive re-entry is real.
76
52
  @saga_mutex = Mutex.new
77
53
  @repositories = {}
78
54
  @projection_repositories = {}
79
55
  @bluebook_builders = {}
80
- # **Eager, not lazy** — see `#resolved_eras`'s own comment for why. Built
81
- # here rather than `@resolved_eras ||= {}` on first access so there is
82
- # no window, post-boot, where two concurrently dispatching threads
83
- # could race creating this Hash (Hecks/ThreadSharedIvarMutation; the
84
- # same shape of hazard `Dispatcher#reenter`'s `@reaction_depth` was
85
- # fixed for). Every write into it still only ever happens at boot,
86
- # single-threaded (`EraResolver.check!`, a `:pre_verify` boot gate) —
87
- # this only removes the race on standing up the container itself for
88
- # a boot with no era-plugin domain at all, whose first touch would
89
- # otherwise be a live dispatch's own `RepositoryFactory.build` read.
56
+ # Eager, not lazy: avoids a race where two dispatching threads could create this
57
+ # Hash on first access. All writes still happen at boot, single-threaded
58
+ # (EraResolver.check!).
90
59
  @resolved_eras = {}
91
- # The sibling fact `EraResolver.check!` records for an old checkout:
92
- # domain name -> the newest held ordinal that superseded the era this
93
- # boot resolved to; absent for every domain booting the current era.
94
- # `RepositoryFactory.build` hands it to the adapter as
95
- # `superseded_by:`, and `PostgresEra#append` refuses on it before
96
- # ever issuing an INSERT — the in-process half of the era fence, the
97
- # half that holds even for a connection row-level security cannot
98
- # bite (BUG#24). Eager for exactly the reason `@resolved_eras` is.
60
+ # domain name -> the ordinal that superseded this boot's era, for an old checkout only.
61
+ # RepositoryFactory.build passes it to PostgresEra#append, which refuses before the
62
+ # INSERT — the in-process half of the era fence. Eager for the same reason as
63
+ # @resolved_eras.
99
64
  @superseded_eras = {}
100
- # **Eager, not lazy** — see `#capability_graph`'s own comment for why.
101
- # `CapabilityGraph.new` only stores the registry reference; there is
102
- # no reason to defer it, and doing so removes the exact same
103
- # first-access race `#resolved_eras` above does, while preserving the
104
- # "same instance every call" identity `spec/runtime/capability_graph_
105
- # spec.rb` already requires.
65
+ # Eager: CapabilityGraph.new only stores the registry reference, and eager
66
+ # construction avoids the same first-access race as @resolved_eras while
67
+ # keeping one instance per registry.
106
68
  @capability_graph = CapabilityGraph.new(self)
107
- # `@saga_persistence` itself is eager (see `#saga_persistence`'s own
108
- # comment) — only the per-domain resolution inside it is genuinely
109
- # expensive and lazy, guarded by this dedicated mutex. Not the same
110
- # mutex as `@saga_mutex`: `checkpoint` (saga_interpreter.rb) calls
111
- # `saga_persistence(domain)` from inside an `@saga_mutex.synchronize`
112
- # block, so reusing `@saga_mutex` here would deadlock the very first
113
- # time a saga advanced (a `Mutex` is not reentrant — the exact
114
- # warning `@saga_mutex`'s own comment already gives for a different
115
- # reason).
69
+ # Guards only the lazy per-domain resolution inside @saga_persistence. Must not reuse
70
+ # @saga_mutex: checkpoint calls saga_persistence(domain) from inside
71
+ # @saga_mutex.synchronize, and Mutex is not reentrant.
116
72
  @saga_persistence = {}
117
73
  @saga_persistence_mutex = Mutex.new
118
74
  @outbox = Outbox::Relay.new(self)
119
75
  end
120
76
 
121
- # **The outbox relay** — one per registry, for its whole life (built
122
- # here, never swapped, so no thread ever sees a different one).
123
- # It can enqueue from the moment the registry exists; a Dispatcher
124
- # attaches the interpreters that let it deliver. See
125
- # `Runtime::Outbox`.
77
+ # One outbox per registry, built once here and never swapped. Can enqueue immediately;
78
+ # a Dispatcher attaches the interpreters that let it deliver (see Runtime::Outbox).
126
79
  attr_reader :outbox
127
80
 
128
- # The builder stays open for the life of this registry, keyed by chapter
129
- # name — see the comment on `BluebookBuilder.build`. A chapter split across
130
- # several files (`language/bluebook/*.bluebook`, all `Hecks.bluebook "Bluebook"`)
131
- # needs its declarations to accumulate into one builder rather than each
132
- # file minting its own and silently discarding the one before.
81
+ # Stays open for the life of the registry, keyed by chapter name, so a chapter split
82
+ # across several files (language/bluebook/*.bluebook) accumulates into one builder.
133
83
  #
134
84
  # @param name [String, Symbol] the chapter name the builder accumulates
135
85
  # declarations for
@@ -142,19 +92,9 @@ module Hecks
142
92
  @bluebook_builders[name.to_s] ||= yield
143
93
  end
144
94
 
145
- # Boot-time-only, single-threaded — every `add_*` below (through
146
- # `add_translation`) is called exclusively from `Hecks.collect`
147
- # (hecks.rb), which is what `Hecks.bluebook`/`.hecksagon`/`.port`/
148
- # `.adapter`/`.world`/`.translation` run inside while a `.bluebook`/
149
- # `.hecksagon`/`.world` file is being `Kernel.load`ed — i.e. strictly
150
- # during `Loader.boot`/`.boot_files`, before `dispatcher_for` ever
151
- # hands this registry to a live, multi-threaded caller. Nothing
152
- # downstream of boot ever calls these — verified by grepping every
153
- # call site in lib/ and spec/ before writing this — so unlike
154
- # `#resolved_eras`/`#capability_graph`/`#saga_persistence` (each
155
- # reachable from live dispatch, and fixed for real above/in
156
- # registry/saga_persistence.rb) there is no concurrent caller for
157
- # `Hecks/ThreadSharedIvarMutation` to actually be warning about here.
95
+ # Boot-time-only, single-threaded: every add_* below runs from Hecks.collect while a
96
+ # .bluebook/.hecksagon/.world file is being Kernel.loaded, strictly during Loader.boot,
97
+ # before dispatcher_for hands this registry to a live, multi-threaded caller.
158
98
  # rubocop:disable Hecks/ThreadSharedIvarMutation
159
99
  # Registers a loaded chapter, keyed by its own declared name.
160
100
  #
@@ -162,19 +102,9 @@ module Hecks
162
102
  # @return [Bluebook::Chapter] `item`, unchanged
163
103
  def add_bluebook(item) = @bluebooks[item.name] = item
164
104
 
165
- # Provenance, side-channel — which real `.bluebook` file(s)
166
- # contributed to a chapter name, never part of the exported IR (a
167
- # boot-time loading fact, not a domain fact) and never Rust-mirrored
168
- # (the same "additive, Ruby-only" shape `@translations` above already
169
- # is). Legitimate accumulation (several files declaring the same
170
- # chapter name on purpose — `lib/hecks/language/bluebook/*.bluebook`
171
- # all open `Hecks.bluebook "Bluebook"`) pushes more than one path
172
- # here too; that alone is not a problem. What this exists to let
173
- # `refuse_cross_package_bluebook_merge!` (registry/verification.rb)
174
- # catch is two unrelated packages accumulating into the same name by
175
- # coincidence — a stale vendored fork's own copy of a real gem's
176
- # chapter, still reachable on the load path, silently merging its
177
- # aggregates into the real one via this exact accumulation mechanism.
105
+ # Tracks which .bluebook file(s) contributed to a chapter name (a boot-time loading
106
+ # fact, never Rust-mirrored) so refuse_cross_package_bluebook_merge! can catch two
107
+ # unrelated packages accumulating into the same name by coincidence.
178
108
  #
179
109
  # @param name [String, Symbol] the chapter name the file contributed to
180
110
  # @param path [String] the `.bluebook` file that declared it
@@ -183,12 +113,8 @@ module Hecks
183
113
  (@bluebook_sources[name.to_s] ||= []) << path
184
114
  end
185
115
 
186
- # Merged, not replaced — recovered, not new (see Runtime::Loader
187
- # .boot's own comment for the provenance). A domain's hecksagon can
188
- # now load in more than one block for the same domain (base file
189
- # plus an `environments/<name>.hecksagon` overlay), and the second
190
- # block should add to what the first declared, not silently
191
- # discard it.
116
+ # Merges into any wiring already registered for the domain rather than replacing it,
117
+ # so a base .hecksagon file plus an environments/<name>.hecksagon overlay both take effect.
192
118
  #
193
119
  # @param item [Bluebook::Hecksagon] the declared wiring to register
194
120
  # @return [void]
@@ -230,16 +156,10 @@ module Hecks
230
156
  # @return [Bluebook::Adapter] `item`, unchanged
231
157
  def add_adapter(item) = @adapters[item.name] = item
232
158
 
233
- # Merged, not replaced — the same generalization for `World` that
234
- # `add_hecksagon` above recovers for `Hecksagon`: an
235
- # `environments/<name>.world` overlay (or a host-owned tenancy
236
- # overlay world, same mechanism) can now add or override settings
237
- # for a domain a base `.world` file already declared, without
238
- # restating everything the base file said. Settings merge shallow,
239
- # keyed exactly the way WorldBuilder already stores them (both the
240
- # bare verb key and the `"verb:adapter"` qualified key point at the
241
- # same resolved hash) — an overlay's key wins over the base's same
242
- # key; a key only the base declares survives untouched.
159
+ # Merges into any world already registered for the domain, the same shape as
160
+ # add_hecksagon. Settings merge shallow, keyed by verb (and "verb:adapter"); an
161
+ # overlay key wins over the base's same key, and a key only the base declares
162
+ # survives untouched.
243
163
  #
244
164
  # @param item [Bluebook::World] the declared world settings to register
245
165
  # @return [void]
@@ -255,13 +175,10 @@ module Hecks
255
175
  # `item` last
256
176
  def add_translation(item) = @translations << item
257
177
 
258
- # Declares one attribute of one domain's own aggregate sensitive — called from a
259
- # terminal `has_<category>(readable_by:)` on a `Bluebook::DSL::AttributePath`
260
- # (reached by chaining off a bare `Domain::Aggregate` inside a `.hecksagon` file
261
- # being `Kernel.load`ed, or off an already-installed `AggregateDoor`), same timing
262
- # (and same thread-safety argument, above) as `add_bluebook`/`add_port`. Recorded,
263
- # not dispatched: `Runtime::Loader.boot`'s own `seed_privacy_markings!` turns each
264
- # entry into a real `Privacy::Marking.Mark` once a dispatcher exists.
178
+ # Declares one attribute of a domain's aggregate sensitive, called from a terminal
179
+ # has_<category>(readable_by:). Recorded, not dispatched: Loader.boot's
180
+ # seed_privacy_markings! turns each entry into a real Privacy::Marking.Mark once a
181
+ # dispatcher exists.
265
182
  #
266
183
  # @param domain [String] the marked attribute's own aggregate FQN, e.g.
267
184
  # `"Site::Registration"`
@@ -276,16 +193,11 @@ module Hecks
276
193
  end
277
194
  # rubocop:enable Hecks/ThreadSharedIvarMutation
278
195
 
279
- # {domain name => era ordinal} as resolved by the boot-time era
280
- # gate. A lineage adapter writes into its own era's partition —
281
- # which, for an old checkout booting a held-but-superseded shape,
282
- # is not the newest one. The Hash itself is stood up in `initialize`
283
- # (see that comment) — this is a plain reader, not a memoizer;
284
- # `Hecks/ThreadSharedIvarMutation` is the reason there is no `||=`
285
- # left here to flag.
196
+ # {domain name => era ordinal} resolved by the boot-time era gate. Stood up eagerly
197
+ # in initialize; this is a plain reader, not a memoizer.
286
198
  attr_reader :resolved_eras
287
- # Domain name -> the ordinal that superseded this boot's own era, for
288
- # an old checkout only — see `initialize`'s own comment on it.
199
+ # Domain name -> the ordinal that superseded this boot's own era, for an old
200
+ # checkout only.
289
201
  attr_reader :superseded_eras
290
202
 
291
203
  # Finds a loaded chapter by name.
@@ -314,12 +226,8 @@ module Hecks
314
226
  # @return [Array<String>] every declared verb, across every loaded chapter
315
227
  def verbs = @bluebooks.values.flat_map(&:verbs).sort
316
228
 
317
- # The chapter that answers a role check for `domain` — the domain's
318
- # own chapter, or any framework member its hecksagon attaches, that
319
- # declares `provides "authorization"`. Nil when none does. Replaces
320
- # every check for the literal name "Governance": Governance is
321
- # recognised by what it declares, and a chapter that declares the
322
- # same thing is recognised the same way.
229
+ # The chapter that answers a role check for `domain`: the domain's own chapter, or
230
+ # a framework member its hecksagon attaches, that declares `provides "authorization"`.
323
231
  #
324
232
  # @param domain [String, Symbol] the domain whose role checks are being resolved
325
233
  # @return [Bluebook::Chapter, nil] the chapter that answers `domain`'s role
@@ -338,12 +246,9 @@ module Hecks
338
246
  @bluebooks.values.select { |chapter| chapter.provides?(Bluebook::Capabilities::AUTHORIZATION) }
339
247
  end
340
248
 
341
- # The chapter that answers "who is this authenticated pair" for
342
- # `domain` — the domain's own chapter, or any framework member its
343
- # hecksagon attaches, that declares `provides "identity"`. Nil when
344
- # none does. Replaces every check for the literal name "Identity":
345
- # Identity is recognised by what it declares (Register/Link/ResolvedBy),
346
- # and a chapter that declares the same thing is recognised the same way.
249
+ # The chapter that answers "who is this authenticated pair" for `domain`: the
250
+ # domain's own chapter, or a framework member its hecksagon attaches, that
251
+ # declares `provides "identity"`.
347
252
  #
348
253
  # @param domain [String, Symbol] the domain whose identity chapter is being resolved
349
254
  # @return [Bluebook::Chapter, nil] the chapter that answers `domain`'s identity
@@ -354,29 +259,19 @@ module Hecks
354
259
  .find { |chapter| chapter.provides?(Bluebook::Capabilities::IDENTITY) }
355
260
  return attached if attached
356
261
 
357
- # Sibling hecksagons — a consuming domain often wires Identity as
358
- # `Hecks.hecksagon "Identity"` (so Register can attach Governance
359
- # on that named hexagon), not only via uses_framework on the
360
- # consuming domain. The chapter is loaded; it just isn't listed
361
- # on the consumer's own hexagon.
262
+ # Falls back to any loaded chapter: a consuming domain often wires Identity as
263
+ # Hecks.hecksagon "Identity" rather than via uses_framework, so it's loaded but
264
+ # not listed on the consumer's own hexagon.
362
265
  @bluebooks.values.find { |chapter| chapter.provides?(Bluebook::Capabilities::IDENTITY) }
363
266
  end
364
267
 
365
- # The chapter that answers "who may sign in" for `domain` — the
366
- # domain's own chapter, any framework member its hecksagon attaches,
367
- # or any vendored embryonaut bluebook it attaches, that declares
368
- # `provides "membership"`. Nil when none does. Replaces rust/host's
369
- # own HECKS_MEMBERSHIP_AGGREGATE env var: Membership is recognised
370
- # by what it declares (Person.Admit/GrantAccess/All), and a chapter
371
- # that declares the same thing (Embryonaut::Member, say) is
372
- # recognised the same way.
373
- #
374
- # Vendored packages are included here and not in
375
- # `authorization_provider_for` because membership is a vendored
376
- # embryonaut_bluebooks chapter (`uses_embryonaut_bluebook
377
- # "membership"`), not a framework member shipped inside hecks.
378
- # `Naming.pascal` is the same directory-to-chapter convention
379
- # `EmbryonautBluebook.load!` already uses.
268
+ # The chapter that answers "who may sign in" for `domain`: the domain's own
269
+ # chapter, a framework member, or a vendored embryonaut bluebook it attaches,
270
+ # that declares `provides "membership"`.
271
+ #
272
+ # Vendored packages are included here (unlike `authorization_provider_for`)
273
+ # because membership ships as a vendored embryonaut_bluebooks chapter, not a
274
+ # framework member.
380
275
  #
381
276
  # @param domain [String, Symbol] the domain whose sign-in aggregate is being resolved
382
277
  # @return [Bluebook::Chapter, nil] the chapter that answers `domain`'s membership
@@ -385,12 +280,9 @@ module Hecks
385
280
  vendored_provider_for(domain, Bluebook::Capabilities::MEMBERSHIP)
386
281
  end
387
282
 
388
- # The chapter that answers the guest newsletter signup for `domain` —
389
- # the domain's own chapter, a framework member, or a vendored
390
- # embryonaut bluebook it attaches, that declares `provides
391
- # "newsletter"`. Nil when none does. Newsletter is recognised by
392
- # what it declares (Subscribe/AddName/Confirm/Unsubscribe), so a
393
- # chapter that declares the same thing is recognised the same way.
283
+ # The chapter that answers the guest newsletter signup for `domain`: the domain's
284
+ # own chapter, a framework member, or a vendored embryonaut bluebook it attaches,
285
+ # that declares `provides "newsletter"`.
394
286
  #
395
287
  # @param domain [String, Symbol] the domain whose newsletter chapter is being resolved
396
288
  # @return [Bluebook::Chapter, nil] the chapter that answers `domain`'s newsletter
@@ -410,9 +302,8 @@ module Hecks
410
302
  vendored_provider_for(domain, Bluebook::Capabilities::NEWSLETTER_ISSUES)
411
303
  end
412
304
 
413
- # The chapter that answers scheduling sessions and taking registrations
414
- # for `domain` — resolved the same way as `payments_provider_for`, by what
415
- # it declares (`provides "registrations"`). Nil when none does.
305
+ # The chapter that answers scheduling sessions and registrations for `domain`,
306
+ # resolved the same way as `payments_provider_for`, by declaring `provides "registrations"`.
416
307
  #
417
308
  # @param domain [String, Symbol] the domain whose registrations chapter is being resolved
418
309
  # @return [Bluebook::Chapter, nil] the chapter that answers `domain`'s registrations,
@@ -425,19 +316,17 @@ module Hecks
425
316
  # `domain` — resolved by what it declares (`provides "payment_connection"`).
426
317
  # Nil when none does.
427
318
  #
428
- # @param domain [String, Symbol] the domain whose payment-connection chapter is being resolved
319
+ # @param domain [String, Symbol] the domain whose payment-connection chapter is
320
+ # being resolved
429
321
  # @return [Bluebook::Chapter, nil] the chapter that owns `domain`'s payment connection,
430
322
  # or nil if none does
431
323
  def payment_connection_provider_for(domain)
432
324
  vendored_provider_for(domain, Bluebook::Capabilities::PAYMENT_CONNECTION)
433
325
  end
434
326
 
435
- # The chapter that takes payments for `domain` — the domain's own
436
- # chapter, a framework member, or a vendored embryonaut bluebook it
437
- # attaches, that declares `provides "payments"`. Nil when none does.
438
- # Payments is recognised by what it declares (Initiate and the
439
- # processor's two verdicts), so a chapter that declares the same
440
- # thing is recognised the same way.
327
+ # The chapter that takes payments for `domain`: the domain's own chapter, a
328
+ # framework member, or a vendored embryonaut bluebook it attaches, that
329
+ # declares `provides "payments"`.
441
330
  #
442
331
  # @param domain [String, Symbol] the domain whose payments chapter is being resolved
443
332
  # @return [Bluebook::Chapter, nil] the chapter that takes `domain`'s payments, or nil
@@ -446,14 +335,13 @@ module Hecks
446
335
  vendored_provider_for(domain, Bluebook::Capabilities::PAYMENTS)
447
336
  end
448
337
 
449
- # The chapter that provides `capability` for `domain`: the domain's
450
- # own chapter, any framework member its hecksagon attaches, or any
451
- # vendored embryonaut bluebook it attaches, that declares it. Falls
452
- # back to any loaded chapter that does, because a consuming domain
453
- # often wires a vendored chapter as its own `Hecks.hecksagon "Name"`
454
- # (so that chapter can attach Governance on that named hexagon)
455
- # rather than via `uses_embryonaut_bluebook` on itself — the chapter
456
- # is loaded, it just isn't listed on the consumer's own hexagon.
338
+ # The chapter that provides `capability` for `domain`: the domain's own chapter,
339
+ # a framework member its hecksagon attaches, or a vendored embryonaut bluebook
340
+ # it attaches, that declares it.
341
+ #
342
+ # Falls back to any loaded chapter, since a consuming domain often wires a
343
+ # vendored chapter as its own `Hecks.hecksagon "Name"` rather than via
344
+ # `uses_embryonaut_bluebook`, so it's loaded but not listed on the consumer's hexagon.
457
345
  #
458
346
  # @param domain [String, Symbol] the domain the provider is resolved for
459
347
  # @param capability [String] the capability's name, such as
@@ -485,32 +373,13 @@ module Hecks
485
373
  @repositories[[domain.to_s, aggregate.hecks_name]] ||= Ports::Persistence.repository(self, domain, aggregate)
486
374
  end
487
375
 
488
- # Everything a dispatch wrote, cleared; nothing a boot declared,
489
- # touched. Bluebooks, hecksagons, ports, adapters, worlds and the
490
- # resolved eras are what loading the files produced and stay as
491
- # they are; the logs, the saga instances and the repositories are
492
- # what running commands against them produced, and go back to
493
- # exactly what a fresh boot of the same files hands out. Dropping
494
- # the repositories (rather than emptying each) is deliberate: a
495
- # fresh boot's own repositories are new adapter instances too, so
496
- # a Memory adapter starts empty and a durable one sees whatever
497
- # it persisted — the same reading either way. Sagas rehydrate off
498
- # that store again, the way `Loader.boot_files` does after
499
- # `verify!`.
500
- #
501
- # What this is for: a test runner that would otherwise boot a runtime
502
- # per test to get isolation (`Behaviors::Expectations.run_one`) — ~2s a
503
- # boot, 76 chess behaviours = two and a half minutes of booting the
504
- # same two files — can now boot once and reset between tests.
505
- #
506
- # Single-threaded caller, the same reason the `add_*` cluster above
507
- # is exempt — `Behaviors::Expectations.run_one` is this method's only
508
- # caller (verified by grep before writing this), and it runs one
509
- # test at a time: `Runner#run` maps over tests sequentially, and
510
- # `Behaviors.rspec`'s generated examples run under RSpec's own
511
- # single-threaded example loop. No production dispatch path calls
512
- # this at all — a live Puma worker pool never resets a registry out
513
- # from under itself mid-flight.
376
+ # Clears everything a dispatch produced (logs, saga instances, repositories); leaves
377
+ # what booting the files produced (bluebooks, hecksagons, ports, adapters, worlds,
378
+ # resolved eras) untouched.
379
+ #
380
+ # Repositories are dropped, not emptied, so a fresh Memory adapter starts empty while
381
+ # a durable one still sees what it persisted. Single-threaded caller only
382
+ # (Behaviors::Expectations.run_one runs one test at a time).
514
383
  #
515
384
  # @return [Runtime::Registry] self
516
385
  # rubocop:disable-next Hecks/ThreadSharedIvarMutation
@@ -528,10 +397,8 @@ module Hecks
528
397
  self
529
398
  end
530
399
 
531
- # Built eagerly in `initialize` (see that comment) — this is a plain
532
- # reader, not a memoizer; `spec/runtime/capability_graph_spec.rb`
533
- # asserts the same instance comes back every call, which this still
534
- # gives, just without a lazy `||=` race on standing it up.
400
+ # Built eagerly in `initialize`; this is a plain reader, not a memoizer.
401
+ # `spec/runtime/capability_graph_spec.rb` asserts the same instance comes back every call.
535
402
  attr_reader :capability_graph
536
403
 
537
404
  # Resolves and memoizes the repository to read `aggregate` from — a caught-up
@@ -583,15 +450,10 @@ module Hecks
583
450
  false
584
451
  end
585
452
 
586
- # Recovered — see `add_hecksagon`'s own comment for provenance.
587
- # Concatenates every list-shaped fact; `binds` in particular is
588
- # additive because an overlay rebinding an aggregate (a new
589
- # `persisted_by` for the same aggregate/verb) is meant to shadow
590
- # the base's own bind at resolution time, not erase it outright —
591
- # `Ports::Persistence::BindingPolicy.resolve`'s own "exactly one
592
- # authoritative bind" check is what actually catches a genuine
593
- # double-bind; this merge only concatenates, it does not itself
594
- # decide which of two binds for the same aggregate wins.
453
+ # Concatenates every list-shaped fact from base and overlay. `binds` is additive too:
454
+ # an overlay rebinding an aggregate is meant to shadow the base's bind at resolution
455
+ # time, not erase it — `Ports::Persistence::BindingPolicy.resolve`'s "exactly one
456
+ # authoritative bind" check is what actually catches a genuine double-bind.
595
457
  #
596
458
  # @param base [Bluebook::Hecksagon] the domain's already-registered wiring
597
459
  # @param overlay [Bluebook::Hecksagon] the newly loaded block's own wiring to
@@ -599,12 +461,8 @@ module Hecks
599
461
  # @return [Bluebook::Hecksagon] a new wiring with every list-shaped fact
600
462
  # concatenated, `base` then `overlay`
601
463
  def merge_hecksagons(base, overlay)
602
- # Same-name blocks concatenate regardless of which file they came
603
- # from (`site.hecksagon`, `context_map.hecksagon`, an
604
- # environment overlay). Order-independent: list facts uniq, so
605
- # loading context_map before or after the domain file is the same
606
- # merged hecksagon. Binds stay concatenated (BindingPolicy still
607
- # refuses a genuine double-bind).
464
+ # Order-independent: list facts uniq, so loading context_map before or after the
465
+ # domain file yields the same merged hecksagon.
608
466
  Bluebook::Hecksagon.new(
609
467
  domain: base.domain,
610
468
  binds: base.binds + overlay.binds,
@@ -616,13 +474,10 @@ module Hecks
616
474
  )
617
475
  end
618
476
 
619
- # Recovered and generalized — see `add_world`'s own comment. `realm`/
620
- # `latest`, `default_database` and `default_adapter` are scalars, so the overlay's
621
- # value wins when present, else the base's survives; `settings` is a shallow merge keyed by
622
- # verb (and `"verb:adapter"`) — an overlay entry for a key the base
623
- # also declares replaces that key's whole resolved hash (the same
624
- # all-or-nothing shape `WorldBuilder#method_missing` already builds
625
- # each entry as), it does not deep-merge field by field within it.
477
+ # Scalars (`realm`, `latest`, `default_database`, `default_adapter`): the overlay's
478
+ # value wins when present, else the base's survives. `settings` is a shallow merge
479
+ # keyed by verb (and `"verb:adapter"`); an overlay key replaces the base's whole
480
+ # resolved hash for that key, it does not deep-merge within it.
626
481
  #
627
482
  # @param base [Bluebook::World] the domain's already-registered world
628
483
  # @param overlay [Bluebook::World] the newly loaded block's own world to fold in