hecks 2.7.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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +11 -0
  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 +18 -99
  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 +15 -37
  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 +32 -142
  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 +17 -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 +38 -26
  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 +17 -65
  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 -189
  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 -106
  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 +54 -268
  109. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -308
  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 +10 -91
  114. data/lib/hecks/bluebook/model_check.rb +102 -600
  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 +84 -0
  128. data/lib/hecks/cli/document.rb +86 -0
  129. data/lib/hecks/cli/ir.rb +45 -0
  130. data/lib/hecks/cli/mcp.rb +31 -0
  131. data/lib/hecks/cli/mcp_door.rb +366 -0
  132. data/lib/hecks/cli/model_check.rb +203 -0
  133. data/lib/hecks/cli/project_cli.rb +90 -0
  134. data/lib/hecks/cli/project_diagrams.rb +36 -0
  135. data/lib/hecks/cli/run.rb +173 -0
  136. data/lib/hecks/cli/smoke_test.rb +45 -0
  137. data/lib/hecks/cli/stores.rb +53 -0
  138. data/lib/hecks/cli.rb +160 -0
  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 +98 -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 +95 -0
  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 +62 -65
  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 +7 -26
  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 +22 -122
  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 +151 -679
  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 +9 -16
  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 +46 -138
  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 +93 -0
  336. data/lib/hecks/release/runner/commands.rb +66 -0
  337. data/lib/hecks/release/runner/console.rb +52 -0
  338. data/lib/hecks/release/runner/gem_publisher.rb +43 -0
  339. data/lib/hecks/release/runner/git.rb +48 -0
  340. data/lib/hecks/release/runner/npm_publisher.rb +75 -0
  341. data/lib/hecks/release/runner/preflight.rb +104 -0
  342. data/lib/hecks/release/runner/published.rb +55 -0
  343. data/lib/hecks/release/runner/tagger.rb +80 -0
  344. data/lib/hecks/release/runner.rb +215 -0
  345. data/lib/hecks/rendering.rb +4 -26
  346. data/lib/hecks/router/namespace_installer.rb +12 -36
  347. data/lib/hecks/router.rb +4 -8
  348. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  349. data/lib/hecks/runtime/boot_gates.rb +3 -18
  350. data/lib/hecks/runtime/caller.rb +19 -59
  351. data/lib/hecks/runtime/capability_graph.rb +5 -21
  352. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  353. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
  354. data/lib/hecks/runtime/command_interpreter.rb +125 -307
  355. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  356. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  357. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  358. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  359. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  360. data/lib/hecks/runtime/dependency_planning.rb +30 -102
  361. data/lib/hecks/runtime/dispatcher.rb +82 -241
  362. data/lib/hecks/runtime/entity_element.rb +40 -462
  363. data/lib/hecks/runtime/entity_interpreter.rb +65 -220
  364. data/lib/hecks/runtime/errors.rb +32 -115
  365. data/lib/hecks/runtime/event.rb +3 -25
  366. data/lib/hecks/runtime/identity.rb +18 -154
  367. data/lib/hecks/runtime/instance.rb +18 -150
  368. data/lib/hecks/runtime/interpreting.rb +11 -70
  369. data/lib/hecks/runtime/invocation.rb +28 -164
  370. data/lib/hecks/runtime/loader.rb +48 -186
  371. data/lib/hecks/runtime/outbox.rb +38 -261
  372. data/lib/hecks/runtime/policy_interpreter.rb +38 -200
  373. data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
  374. data/lib/hecks/runtime/query_interpreter.rb +45 -187
  375. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  376. data/lib/hecks/runtime/read_model_interpreter.rb +139 -208
  377. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  378. data/lib/hecks/runtime/reference_hop.rb +8 -81
  379. data/lib/hecks/runtime/refusal_wording.rb +8 -89
  380. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  381. data/lib/hecks/runtime/registry/verification.rb +52 -225
  382. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  383. data/lib/hecks/runtime/registry.rb +103 -244
  384. data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
  385. data/lib/hecks/runtime/routing.rb +4 -15
  386. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  387. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  388. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  389. data/lib/hecks/runtime/tenant_check.rb +6 -68
  390. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  391. data/lib/hecks/runtime/value/admission.rb +16 -67
  392. data/lib/hecks/runtime/value/coercion.rb +155 -641
  393. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  394. data/lib/hecks/runtime/value.rb +12 -84
  395. data/lib/hecks/runtime.rb +17 -65
  396. data/lib/hecks/storehouse.rb +146 -567
  397. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
  398. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  399. data/lib/hecks/vendoring/git_environment.rb +2 -8
  400. data/lib/hecks/vendoring/git_source.rb +4 -10
  401. data/lib/hecks/vendoring.rb +7 -46
  402. data/lib/hecks/version.rb +3 -14
  403. data/lib/hecks/vocabulary.rb +5 -0
  404. data/lib/hecks.rb +32 -82
  405. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  406. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  407. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  408. metadata +30 -59
  409. data/lib/hecks/bench/cli.rb +0 -74
  410. data/lib/hecks/bench/environment.rb +0 -100
  411. data/lib/hecks/bench/postgres_probe.rb +0 -41
  412. data/lib/hecks/bench/report.rb +0 -116
  413. data/lib/hecks/bench/ruby_runner.rb +0 -151
  414. data/lib/hecks/bench/run.rb +0 -55
  415. data/lib/hecks/bench/rust_runner.rb +0 -165
  416. data/lib/hecks/bench/stats.rb +0 -75
  417. data/lib/hecks/bench/suite.rb +0 -172
  418. data/lib/hecks/bench/workload.rb +0 -137
  419. data/lib/hecks/bench.rb +0 -28
  420. data/lib/hecks/codemod.rb +0 -443
  421. data/lib/hecks/corpus.rb +0 -479
  422. data/lib/hecks/doc/reference.rb +0 -585
  423. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -684
  424. data/lib/hecks/fuzzing/combination_miner.rb +0 -178
  425. data/lib/hecks/fuzzing/concurrent_dispatch.rb +0 -469
  426. data/lib/hecks/fuzzing/coverage_campaign.rb +0 -161
  427. data/lib/hecks/fuzzing/differential.rb +0 -192
  428. data/lib/hecks/fuzzing/domain_generator.rb +0 -871
  429. data/lib/hecks/fuzzing/era_boundary.rb +0 -154
  430. data/lib/hecks/fuzzing/form_census.rb +0 -285
  431. data/lib/hecks/fuzzing/generated_domain_check.rb +0 -171
  432. data/lib/hecks/fuzzing/invalid_value_generator.rb +0 -125
  433. data/lib/hecks/fuzzing/isolated_boot.rb +0 -658
  434. data/lib/hecks/fuzzing/nondeterministic.rb +0 -79
  435. data/lib/hecks/fuzzing/persistence_parity.rb +0 -253
  436. data/lib/hecks/fuzzing/properties/corrections.rb +0 -125
  437. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +0 -688
  438. data/lib/hecks/fuzzing/properties/guards.rb +0 -398
  439. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +0 -399
  440. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +0 -137
  441. data/lib/hecks/fuzzing/properties/outbox.rb +0 -180
  442. data/lib/hecks/fuzzing/properties/querying.rb +0 -260
  443. data/lib/hecks/fuzzing/properties.rb +0 -267
  444. data/lib/hecks/fuzzing/qa_settings.rb +0 -164
  445. data/lib/hecks/fuzzing/replay.rb +0 -930
  446. data/lib/hecks/fuzzing/rotation_priority.rb +0 -114
  447. data/lib/hecks/fuzzing/rust_gap_manifest.rb +0 -139
  448. data/lib/hecks/fuzzing/self_consistency.rb +0 -825
  449. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +0 -532
  450. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +0 -171
  451. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +0 -127
  452. data/lib/hecks/fuzzing/sequence_generator/picker.rb +0 -116
  453. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +0 -138
  454. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +0 -344
  455. data/lib/hecks/fuzzing/sequence_generator.rb +0 -311
  456. data/lib/hecks/fuzzing/shrinker.rb +0 -309
  457. data/lib/hecks/fuzzing/structural_skips.rb +0 -53
  458. data/lib/hecks/fuzzing/sweep_depth.rb +0 -61
  459. data/lib/hecks/fuzzing/target_capabilities.rb +0 -255
  460. data/lib/hecks/fuzzing/value_generator.rb +0 -340
  461. data/lib/hecks/fuzzing.rb +0 -23
  462. data/lib/hecks/grammar/evolve.rb +0 -524
  463. data/lib/hecks/query_ir.rb +0 -482
@@ -2,12 +2,8 @@ require_relative "word_gate"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # Parses an `aggregate "Name" do ... end` block inside a `.translation`
6
- # file into a `TranslationAggregate` — the per-aggregate rules
7
- # (`rename`/`move`/`convert`/`retype`/`compute`/`rekey`/`backfill`/
8
- # `drop`) that carry one era's stored data forward to the next, plus
9
- # `unresolved` markers the scaffold writes wherever it cannot decide a
10
- # rule for itself.
5
+ # Parses an `aggregate "Name" do ... end` block in a `.translation` file into a
6
+ # `TranslationAggregate`: the rules that carry one era's stored data to the next.
11
7
  class TranslationAggregateBuilder
12
8
  GRAMMAR_CONTEXT = "TranslationAggregate".freeze
13
9
 
@@ -33,17 +29,6 @@ module Hecks
33
29
 
34
30
  # Declares a field rename with no other change: same path, new name.
35
31
  #
36
- # Answers the `rename` word (and, via the same table rows, its
37
- # siblings `move`/`convert`/`retype`/`compute`/`rekey`/`backfill`
38
- # below) through the table's `calls:` column — item #13's full
39
- # metaprogrammed dispatch (slice 4c). Each is carried in
40
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK` like every other
41
- # `calls:`-routed word, but none of their rows are ever consulted
42
- # during real bootstrap: `translation.bluebook` describes its own
43
- # structure with aggregate/entity/attribute, never with these —
44
- # they're words for real, user-authored `.translation` files
45
- # only, loaded after the grammar table already exists.
46
- #
47
32
  # @param old_name [Symbol, String] the field's name in the held era
48
33
  # @param to [Symbol, String] the field's name in the destination era
49
34
  # @return [void]
@@ -72,12 +57,8 @@ module Hecks
72
57
  # Declares an exhaustive value-to-value mapping for a field with nothing structural in
73
58
  # common with its replacement.
74
59
  #
75
- # A value with nothing structural in common with its replacement
76
- # — declared as an exhaustive table, not computed, so every value
77
- # that can appear in old data has a named destination. Paths
78
- # follow `move`'s convention: dotted reaches a value-object member.
79
- #
80
- # @param old_path [String, Symbol] the field's path in the held era
60
+ # @param old_path [String, Symbol] the field's path in the held era; dotted reaches a
61
+ # value-object member
81
62
  # @param to [String, Symbol] the field's path in the destination era
82
63
  # @param values [Hash] every old value mapped to its destination value
83
64
  # @return [Array<Bluebook::TranslationConvert>] every convert declared so far, this one
@@ -92,20 +73,13 @@ module Hecks
92
73
  @converts << TranslationConvert.new(old_path.to_s, to.to_s, values)
93
74
  end
94
75
 
95
- # `drop` — item #13's full metaprogrammed dispatch, slice 2
96
- # (whole-project table-unification survey): a declared,
97
- # deliberate acknowledgment that an attribute's data does not
98
- # survive the rename — the honest alternative to letting it
99
- # vanish because nothing named it. A blank-guarded, kind-driven
100
- # coerce-and-append with nothing else, now executed by
101
- # `GenericDispatch`.
76
+ # `drop` (attribute data that does not survive the rename) is dispatched directly off
77
+ # the grammar table by `GenericDispatch`; no method answers it here.
102
78
 
103
79
  # Declares that a type's name changed while its member structure stayed the same.
104
80
  #
105
- # A value object's or entity's own type name changed, member
106
- # structure unchanged. The stored data never carries the type
107
- # name, so nothing moves — this declares that the pair of names
108
- # means the same shape, which is what lets the era diff accept it.
81
+ # Nothing moves: stored data never carries the type name, so this only tells the era
82
+ # diff that the two names mean the same shape.
109
83
  #
110
84
  # @param old_type [String, Symbol] the type's name in the held era
111
85
  # @param to [String, Symbol] the type's name in the destination era
@@ -121,10 +95,8 @@ module Hecks
121
95
 
122
96
  # Declares a field computed by a hand-written Postgres SQL expression.
123
97
  #
124
- # A computed transform whose only implementation is the SQL
125
- # expression itself — Postgres-only by construction. The scaffold
126
- # never proposes one; a human writes it, and the audit's
127
- # human-sampled review is its only verification.
98
+ # The scaffold never proposes one; a human writes it, and human-sampled review is
99
+ # its only verification.
128
100
  #
129
101
  # @param old_path [String, Symbol] the source field's path in the held era
130
102
  # @param to [String, Symbol] the field's path in the destination era
@@ -143,14 +115,8 @@ module Hecks
143
115
  # Declares a hand-written Postgres SQL expression that recomputes the aggregate's own
144
116
  # identity.
145
117
  #
146
- # The aggregate's own identity, changing what it's computed from —
147
- # not a field crossing a boundary (`move`), not a value's own
148
- # transform (`compute`): the record's key. No path arguments,
149
- # unlike every rule above — nothing is consumed from or moved into
150
- # `state`, only what identifies the record is recomputed. Same
151
- # SQL-only, Postgres-only, human-reviewed-sample-is-the-only-
152
- # verification shape `compute` already has, and for the same
153
- # reason: there is nothing in-process to check this against.
118
+ # No path arguments, unlike the rules above: only the record's key is recomputed, not
119
+ # state moved into it. Verified the same human-reviewed-only way as `compute`.
154
120
  #
155
121
  # @param sql [String] the Postgres SQL expression computing the destination identity
156
122
  # @return [Array<Bluebook::TranslationRekey>] every rekey declared so far, this one last
@@ -164,17 +130,8 @@ module Hecks
164
130
  # Declares a newly added, required attribute and the default existing records read
165
131
  # until a real value is written.
166
132
  #
167
- # A newly added, required attribute — the addition-side sibling of
168
- # `drop`. Nothing to rename, move, or convert from, since old data
169
- # never held this field at all; `default` is what an existing
170
- # record reads until the next command against it writes a real
171
- # value. Adapter-agnostic, unlike `compute` — applied the same
172
- # in-process way rename/move/drop already are
173
- # (`Lineage#translate`), because there is nothing to compute here,
174
- # only a value to declare. This is what
175
- # `EraGuard.refuse_unsafe_addition!` asks for when a non-optional
176
- # attribute with no default: could leave an existing record with
177
- # the field genuinely absent.
133
+ # What `EraGuard.refuse_unsafe_addition!` requires before a non-optional attribute
134
+ # with no default can boot.
178
135
  #
179
136
  # @param name [String, Symbol] the new attribute's name
180
137
  # @param default [Object] the value an existing record reads until it is written for real
@@ -190,22 +147,6 @@ module Hecks
190
147
 
191
148
  # Always refuses to boot: marks a field the scaffold could not decide a rule for.
192
149
  #
193
- # The scaffold writes this where it cannot decide; a file carrying
194
- # one can only boot into this refusal — never a guess.
195
- #
196
- # Answers the `unresolved` word through the table's `calls:`
197
- # column — item #13's full metaprogrammed
198
- # dispatch (slice 4). Builds its own message with real branching
199
- # (empty vs. named candidates, a special :identity case), not a
200
- # fixed string a boolean `refuses:` flag could express. Carried in
201
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK` like every other
202
- # `calls:`-routed word, but that row is never consulted during
203
- # real bootstrap (checked directly, not assumed):
204
- # translation.bluebook (loaded during bootstrap, to describe the
205
- # translation DSL itself) never writes `unresolved` — that word is
206
- # only ever used by real, user-authored `.translation` files,
207
- # loaded well after the grammar table already exists.
208
- #
209
150
  # @param name [String, Symbol] the unresolved field's name, or `:identity` for an
210
151
  # unresolved identity change
211
152
  # @param candidates [Array<String, Symbol>] paths the scaffold considered but could not
@@ -216,14 +157,8 @@ module Hecks
216
157
  raise Malformed, unresolved_message(name, candidates)
217
158
  end
218
159
 
219
- # `method_missing`/`respond_to_missing?` answer off the self-hosted
220
- # grammar table (via the `include`d `WordGate`, above), giving a
221
- # richer, table-driven "must be rename, move, convert, ..." refusal
222
- # on a genuinely undefined call than a hand-typed list could —
223
- # the exact "hardcoded legal-word list" this whole arc's item #13
224
- # exists to close. A word admitted
225
- # elsewhere in the grammar but not in this context still gets that
226
- # richer refusal.
160
+ # `method_missing`/`respond_to_missing?` (via the included `WordGate`) give a
161
+ # table-driven refusal naming the legal words, rather than a hand-typed list.
227
162
 
228
163
  # Assembles the declared rules into a `TranslationAggregate`.
229
164
  #
@@ -265,11 +200,8 @@ module Hecks
265
200
  end
266
201
  end
267
202
 
268
- # Parses a whole `.translation` file into a `Translation` — the
269
- # domain's own `from:`/`to:` era pair, its list of `aggregate`
270
- # translation blocks (each built by `TranslationAggregateBuilder`
271
- # above), and any `retired` aggregates that no longer exist in the
272
- # destination era.
203
+ # Parses a whole `.translation` file into a `Translation`: the domain's `from:`/`to:`
204
+ # era pair, its `aggregate` blocks, and any `retired` aggregates.
273
205
  class TranslationBuilder
274
206
  GRAMMAR_CONTEXT = "Translation".freeze
275
207
 
@@ -291,43 +223,25 @@ module Hecks
291
223
  @retired = []
292
224
  end
293
225
 
294
- # Declares one aggregate's own translation rules.
295
- #
296
- # Answers the `aggregate` word through the table's `calls:`
297
- # column — item #13's full metaprogrammed
298
- # dispatch (slice 4c). Not bootstrap-reachable — this "Translation"
299
- # -context `aggregate` (opens a TranslationAggregateBuilder) is a
300
- # different (context, word) pair than "Bluebook"-context
301
- # `aggregate` (the one translation.bluebook itself is described
302
- # with), so it never describes the language's own
303
- # translation chapter.
226
+ # Declares one aggregate's own translation rules; a distinct (context, word) pair
227
+ # from "Bluebook"-context `aggregate`, despite sharing the word.
304
228
  #
305
229
  # @param name [String, Symbol] the aggregate's name in the destination era
306
230
  # @param was [String, Symbol, nil] the aggregate's earlier name, when renamed
307
- # @yield the aggregate's own translation body, evaluated against a
308
- # `TranslationAggregateBuilder`
309
- # @return [Array<Bluebook::TranslationAggregate>] every aggregate translation declared
310
- # so far, this one last
311
- # @raise [Bluebook::DSL::Malformed] if `name` is empty, or any rule in the body fails
312
- # its own checks
231
+ # @yield the translation body, evaluated against a `TranslationAggregateBuilder`
232
+ # @return [Array<Bluebook::TranslationAggregate>] every declared so far, this one last
233
+ # @raise [Bluebook::DSL::Malformed] if `name` is empty, or a body rule fails its own checks
313
234
  def aggregate_impl(name, was: nil, &block)
314
235
  builder = TranslationAggregateBuilder.new(name, was: was)
315
236
  builder.instance_eval(&block) if block
316
237
  @aggregates << builder.build
317
238
  end
318
239
 
319
- # `retired` (an aggregate that is gone outright, not renamed — the
320
- # deliberate alternative to a bogus `was:` claim on an unrelated
321
- # aggregate, the same shape `TranslationAggregateBuilder#drop` is)
322
- # is executed straight off the grammar table by `GenericDispatch` —
323
- # item #13's full metaprogrammed dispatch, slice 2 (whole-project
324
- # table-unification survey) — so no hand-written method answers it here.
325
-
326
- # `method_missing`/`respond_to_missing?` answer off the self-hosted
327
- # grammar table (via the `include`d `WordGate`, above, the same
328
- # mechanism `TranslationAggregateBuilder`'s own comment describes
329
- # one level up) instead of a hand-typed "it declares aggregate
330
- # blocks and retired aggregates" message.
240
+ # `retired` (an aggregate gone outright, not renamed) is dispatched straight off the
241
+ # grammar table by `GenericDispatch`; no method answers it here.
242
+
243
+ # `method_missing`/`respond_to_missing?` (via the included `WordGate`) give the same
244
+ # table-driven refusal `TranslationAggregateBuilder` uses.
331
245
 
332
246
  # Assembles the declared era pair, aggregates and retirements, judged by the translation
333
247
  # language.
@@ -2,13 +2,8 @@ require_relative "word_gate"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # Parses a `value_object "Name" do ... end` block into a
6
- # `ValueObject` — its attributes, its own invariants (declared once
7
- # and referenceable by name from sibling value objects on the same
8
- # aggregate, `RuleReference`), and its `member` rows when it's a
9
- # closed set (either bare `one_of` member lines, or the single-field
10
- # `attribute ..., one_of: [...]` shorthand `install_inline_closed_set`
11
- # installs).
5
+ # Parses a `value_object "Name" do ... end` block into a `ValueObject`: its attributes,
6
+ # invariants and, for a closed set, its `member` rows.
12
7
  class ValueObjectBuilder
13
8
  GRAMMAR_CONTEXT = "ValueObject".freeze
14
9
 
@@ -27,64 +22,17 @@ module Hecks
27
22
  @owner_value_objects = owner_value_objects
28
23
  end
29
24
 
30
- # The wrapper block is gone (ADR 0025, "Attributes" — "closed sets
31
- # lose the wrapper block"). `member` lines are bare now, written
32
- # directly in the `value_object` body with no `one_of do ... end`
33
- # around them — `build`'s own `closed_set: @closed_set ||
34
- # !@members.empty?` already treats a non-empty `@members` as closed,
35
- # so nothing else has to change for that to work. A single-field set
36
- # has an even shorter spelling: `attribute`'s own `one_of:` keyword
37
- # (`AttributeCollector#install_inline_closed_set`, overridden below).
38
- #
39
- # This also removes a real, documented landmine: the block form
40
- # collided with `AttributeCollector#one_of`'s own type-position
41
- # method (`one_of("a", "b")`, different arity) the moment both were
42
- # mixed into the same builder — a value_object could never actually
43
- # use the inline form on one of its own attributes. One `one_of`
44
- # method now, not two.
45
- #
46
- # Legacy under shadow-parsing (S0a's own bridge) — frozen era text
47
- # still writes the block form (2 locations in
48
- # `examples/banking/data/eras/banking/1.bluebook`, duplicated once
49
- # more in that era's own archive copy), so `EraGuard.shadow_parse`
50
- # still needs to read it. `block_given?` is what tells the two
51
- # calling shapes apart: the type-position form
52
- # (`one_of("a", "b")`) never passes a block, only the wrapper does.
53
- # Declares this value object as a closed set, either from bare values or (under
54
- # shadow-parsing) a legacy `do ... end` wrapper of `member` lines.
55
- #
56
- # Answers the `one_of` word through the table's `calls:` column —
57
- # item #13's full metaprogrammed dispatch
58
- # (slice 5). Same name as `AttributeCollector#one_of_impl`'s own
59
- # — required for the `super(*values)` call below to keep
60
- # resolving; see that method's own comment. Reached directly
61
- # through its own "ValueObject"-context Keyword row (the
62
- # block-wrapper form has its own row, distinct from "Type"'s),
63
- # not through the Type-position fallback this word's other
64
- # context uses.
65
- #
66
- # @param values [Array<String, Symbol>] permitted values, given bare (no block); at
67
- # least one is required
68
- # @yield a legacy `member` wrapper body; only read under shadow-parsing
69
- # @return [void]
70
- # @raise [Bluebook::DSL::Malformed] if given no values and no block, or a block outside
71
- # shadow-parsing
25
+ # Bare values declare a closed set; the block form is read only under shadow-parsing,
26
+ # because frozen era text still writes it. Only the wrapper passes a block.
72
27
  def one_of_impl(*values, &block)
73
28
  unless block
74
- # No values, no block is the scalar spelling — nonsensical, not
75
- # merely inert: it names a closed set with nothing in it. The
76
- # original block form caught this by a side effect (`@closed_set
77
- # = true` ran unconditionally, before the `if block`), and this
78
- # keeps the same refusal rather than letting the call fall
79
- # through and silently do nothing.
29
+ # An empty one_of names a closed set with nothing in it; refuse rather than no-op.
80
30
  if values.empty?
81
31
  raise Malformed,
82
32
  "#{@name}'s one_of names no values — one_of(\"a\", \"b\") takes at least one, or " \
83
33
  "give the attribute its own one_of: [...] for a named closed set"
84
34
  end
85
35
 
86
- # AttributeCollector's own `one_of(*values)` — Ruby's normal
87
- # `super` reaches the included module's method from here.
88
36
  return super(*values)
89
37
  end
90
38
 
@@ -98,62 +46,24 @@ module Hecks
98
46
  instance_eval(&block)
99
47
  end
100
48
 
101
- # Declares one member row of a closed set, one value per attribute.
102
- #
103
- # Answers the `member` word through the table's `calls:` column —
104
- # item #13's full metaprogrammed dispatch (slice 4c). Bootstrap-reachable, in
105
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
106
- #
107
- # @param fields [Hash{Symbol => Object}] each declared attribute's name mapped to this
108
- # member's value for it
109
- # @return [Array<Hash{Symbol => Object}>] every member declared so far, this one last
110
- # @raise [Bluebook::DSL::Malformed] if `fields` is empty
111
49
  def member_impl(**fields)
112
50
  raise Malformed, "#{@name} declared an empty member" if fields.empty?
113
51
 
114
52
  @members << fields
115
53
  end
116
54
 
117
- # No block is a reference, not a fresh declaration — the same
118
- # move S10 already made for `CommandBuilder#given` (ADR 0025,
119
- # "a precondition shared across commands is declared once... a
120
- # command references it by name"), one level over: a rule
121
- # shared across sibling value objects on the same aggregate,
122
- # declared once, on the first one to need it. Real, live
123
- # redundancy this closes: `Account`'s own `Money`/`PositiveMoney`
124
- # both declared `invariant("a currency is a three-letter code")
125
- # { currency.to_s.size == 3 }`, byte for byte. Declare it before
126
- # the value objects that reference it — resolution happens at
127
- # the referencing value object's own build time, against
128
- # whatever sibling value objects the aggregate has already
129
- # built, the same ordering rule `given` carries.
130
- # Declares a rule this value object's own value must satisfy, or references one a sibling
131
- # value object on the same aggregate already declared.
132
- #
133
- # Answers the `invariant` word through the table's `calls:` column —
134
- # item #13's full metaprogrammed dispatch (slice 4b). Bootstrap-reachable, in
135
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
136
- #
137
- # @param description [String] the rule's description; also the name a sibling value
138
- # object references it by when no block is given
139
- # @yield the predicate body; evaluated for its extracted source, never called directly
140
- # @return [void]
141
- # @raise [Bluebook::DSL::Malformed] if given a block whose source cannot be extracted or
142
- # uses a pattern construct engines disagree on, or given no block and no sibling value
143
- # object on this aggregate declares a rule with this description
55
+ # Without a block this references a rule a sibling value object already declared.
56
+ # Resolution runs at build time, so declare the rule before its referrers.
144
57
  def invariant_impl(description, &predicate)
145
58
  return reference_named_invariant(description) unless predicate
146
59
 
147
- # moved to the language: given "a rule says what it means", on Shape.Assert
148
-
149
60
  @invariants << build_rule(Invariant, description, predicate, owner_name: @name, word: "invariant",
150
61
  extraction_failure: "it would be a rule the IR cannot carry")
151
62
  end
152
63
 
153
64
  private
154
65
 
155
- # Primitive 3 (RuleReference#resolve_sibling_scan) — see that
156
- # method's own comment for why this is a live scan, not a pool.
66
+ # A live scan of the siblings built so far, not a pool (see RuleReference).
157
67
  def reference_named_invariant(description)
158
68
  verify_resolves_via!("invariant", "ValueObject", "sibling_scan")
159
69
  named = resolve_sibling_scan(@owner_value_objects, description, reader: :invariants) ||
@@ -167,12 +77,6 @@ module Hecks
167
77
 
168
78
  public
169
79
 
170
- # Assembles the declared attributes, invariants and members into a `ValueObject`.
171
- #
172
- # @return [Bluebook::ValueObject] the built value object; `closed_set` is true when any
173
- # member was declared
174
- # @raise [Bluebook::DSL::Malformed] if `one_of:` was declared on an attribute alongside
175
- # other attributes on the same value object
176
80
  def build
177
81
  if @inline_closed_set_field && attributes.size > 1
178
82
  raise Malformed,
@@ -188,15 +92,6 @@ module Hecks
188
92
  )
189
93
  end
190
94
 
191
- # Evaluates a `value_object` block against a fresh builder and returns what it built.
192
- #
193
- # @param name [String] the value object's name
194
- # @param owner_value_objects [Array<Bluebook::ValueObject>] the owning aggregate's other
195
- # value objects, for `invariant` references to resolve against
196
- # @yield the value object body, evaluated with the builder as `self`; may be omitted
197
- # @return [Bluebook::ValueObject] the built value object
198
- # @raise [Bluebook::DSL::Malformed] if the body declares a rule extraction cannot read,
199
- # `one_of:` on more than one attribute, or uses a word the grammar does not admit
200
95
  def self.build(name, owner_value_objects: [], &block)
201
96
  builder = new(name, owner_value_objects: owner_value_objects)
202
97
  builder.instance_eval(&block) if block
@@ -205,17 +100,8 @@ module Hecks
205
100
 
206
101
  private
207
102
 
208
- # **The new spelling** — `attribute :name, String, one_of: %w[...]`,
209
- # overriding `AttributeCollector`'s own refusal (every other
210
- # includer has no meaningful use for this). Private, like the
211
- # module's own version it overrides — it is a callback `attribute`
212
- # invokes on itself, never a word a bluebook author calls by name.
213
- # Refuses a second attribute naming one_of: on the same value
214
- # object outright — a single-field set names exactly one field, by
215
- # construction; two would be structurally ambiguous about which
216
- # field each member line belongs to. `build` refuses the other
217
- # half of that same rule (this attribute coexisting with unrelated
218
- # ones on a multi-field object).
103
+ # Private callback `attribute` invokes for `one_of:`. A single-field set names exactly one
104
+ # field; a second one would leave it ambiguous which field each member line belongs to.
219
105
  def install_inline_closed_set(field, values)
220
106
  if @inline_closed_set_field && @inline_closed_set_field != field
221
107
  raise Malformed,