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
@@ -1,24 +1,10 @@
1
1
  Hecks.bluebook "Bluebook" do
2
2
  aggregate "Vocabulary" do
3
- # These are DECLARATIONS, not runtime state — a language's admitted sets are
4
- # fixed when the language is defined, which is what one_of means. They carry
5
- # no commands on purpose : nothing dispatches a vocabulary. They are READ
6
- # from the IR and projected — bin/project_vocabulary writes the Ruby tables
7
- # (lib/hecks/vocabulary.rb) the runtime's constants read, and
8
- # bin/project_rust_vocabulary writes rust/src/kernel/vocab/ — so the
9
- # runtimes carry no hand-typed copies to drift.
10
- #
11
- # Every one of these is a set the runtime must agree with, and every one has
12
- # already drifted or leaked at least once :
13
- # Comparison went disjoint from the grammar chapter's operator table
14
- # NormalisationStrategy is the third, unchecked copy of the canonical-form table
15
- # Primitive is what "primitives live in value objects only" is ABOUT
16
- # DomainRefusal is the boundary three raw Ruby TypeErrors crossed tonight
3
+ # Closed sets the language admits, projected into matching Ruby and Rust
4
+ # tables (bin/project_vocabulary, bin/project_rust_vocabulary) so both runtimes agree.
17
5
  description "The closed sets the language admits — the whole of what any runtime may accept, declared once."
18
6
 
19
- # ITS NAME, and nothing else. A vocabulary hangs under no other thing — the
20
- # closed sets are the language's own, declared once — so one path is the whole
21
- # identity.
7
+ # Named only by itself; a vocabulary hangs under nothing else.
22
8
  identified_by VocabularyName, as: :name
23
9
 
24
10
 
@@ -27,11 +13,9 @@ Hecks.bluebook "Bluebook" do
27
13
  invariant("a vocabulary is named") { !value.to_s.empty? }
28
14
  end
29
15
 
30
- # Expression::Evaluator::COMPARISONS — six operators, all reduced by the
31
- # evaluator to two primitives (less_than, equal) combined with a small boolean
32
- # algebra: compares_less_than and compares_equal choose which primitive(s) OR
33
- # together, negated inverts the result. `compare` reads this table instead of
34
- # hardcoding a six-way case statement — see Evaluator::COMPARISONS.
16
+ # The six comparison operators. `compare` reduces each to two primitives
17
+ # (less_than, equal) combined by compares_less_than/compares_equal/negated,
18
+ # rather than a six-way case statement (Expression::Evaluator::COMPARISONS).
35
19
  value_object "Comparison" do
36
20
  attribute :symbol, String
37
21
  attribute :compares_less_than, String
@@ -46,12 +30,9 @@ Hecks.bluebook "Bluebook" do
46
30
  member symbol: "!=", compares_less_than: "false", compares_equal: "true", negated: "true"
47
31
  end
48
32
 
49
- # Expression::Resolver::SIGN_TESTS
50
- # Each sign test is comparing against the literal 0, using an operator
51
- # Comparison already declares — compares_via names which one, so a sign
52
- # test is sugar for an existing operator rather than a second algebra
53
- # beside it. `positive?` = value > 0, `negative?` = value < 0, `zero?` =
54
- # value == 0.
33
+ # Each sign test compares against 0 using an operator Comparison already
34
+ # declares (compares_via) — sugar for an existing operator, not a second
35
+ # algebra. positive? = value > 0, negative? = value < 0, zero? = value == 0.
55
36
  value_object "SignTest" do
56
37
  attribute :name, String
57
38
  attribute :compares_via, String
@@ -61,11 +42,9 @@ Hecks.bluebook "Bluebook" do
61
42
  member name: "zero?", compares_via: "=="
62
43
  end
63
44
 
64
- # `.include?`'s haystack type decides its behaviour : Array does
65
- # membership (the same equal? primitive Comparison's == uses), String
66
- # does an exact substring match and refuses a non-String needle. Anything
67
- # else is always false — not declared here, since it is the fallback
68
- # every OTHER haystack type shares, not a case of its own.
45
+ # `.include?`'s haystack type decides its behavior: Array does membership,
46
+ # String does substring match. Every other type is always false and is not
47
+ # declared here — that fallback isn't a case of its own.
69
48
  value_object "IncludeHaystack" do
70
49
  attribute :type, String
71
50
  attribute :strategy, String
@@ -74,18 +53,15 @@ Hecks.bluebook "Bluebook" do
74
53
  member type: "String", strategy: "substring"
75
54
  end
76
55
 
77
- # `.to_s` admits exactly these scalar types, and every one of them uses
78
- # the SAME rule (Ruby's own to_s — nil renders "", a bool its name, a
79
- # number its digits, a string itself) — a closed set to admit into, not a
80
- # table of different rules per type.
56
+ # Scalar types `.to_s` admits; every one uses Ruby's own to_s (nil → "",
57
+ # a bool its name, a number its digits) — one rule, not a table per type.
81
58
  value_object "ToStringType" do
82
59
  attribute :type, String, one_of: ["String", "Integer", "Float", "TrueClass", "FalseClass", "NilClass"]
83
60
  end
84
61
 
85
- # `.size` and `.empty?` admit exactly the same closed set — a list, a
86
- # string, or an open map — and each just calls the one Ruby method
87
- # already named for it. One declaration for both, since the set itself is
88
- # the only thing either needed to say.
62
+ # The closed set `.size` and `.empty?` both admit — a list, a string, or
63
+ # an open map — sharing one declaration since both just call Ruby's own
64
+ # method of the same name.
89
65
  value_object "SizedType" do
90
66
  attribute :type, String, one_of: ["Array", "String", "Hash"]
91
67
  end
@@ -100,12 +76,9 @@ Hecks.bluebook "Bluebook" do
100
76
  attribute :name, String, one_of: ["collapse_whitespace", "replace"]
101
77
  end
102
78
 
103
- # the ops Runtime::CommandInterpreter applies. `sign` is the arithmetic
104
- # delta increment/decrement share one primitive by — CommandRules#arithmetic
105
- # applies `current + sign *
106
- # amount`, differing only in which sign. set and append do no arithmetic,
107
- # so they carry no sign — ABSENT IS NOT EMPTY, same reading as elsewhere in
108
- # this file.
79
+ # Ops Runtime::CommandInterpreter applies. `sign` is the arithmetic delta
80
+ # increment/decrement share (current + sign * amount); set and append do
81
+ # no arithmetic, so they carry no sign.
109
82
  value_object "MutationOp" do
110
83
  attribute :name, String
111
84
  attribute :sign, String
@@ -114,46 +87,27 @@ Hecks.bluebook "Bluebook" do
114
87
  member name: "append", sign: ""
115
88
  member name: "increment", sign: "1"
116
89
  member name: "decrement", sign: "-1"
117
- # Vendored addition, not (yet) upstream hecks (migration plan
118
- # task 4, i106 in-DSL math — CommandRules::Arithmetic#multiply/
119
- # #clamp): multiply scales (`current * amount`), clamp bounds
120
- # (`current.clamp(min, max)`) — neither is an add/subtract, so
121
- # neither carries a sign, same reading as set/append above.
90
+ # multiply scales (current * amount), clamp bounds
91
+ # (current.clamp(min, max)) — neither is add/subtract, so neither
92
+ # carries a sign.
122
93
  member name: "multiply", sign: ""
123
94
  member name: "clamp", sign: ""
124
- # Vendored addition, not (yet) upstream hecks (migration plan
125
- # task 4): remove — the list-removal counterpart to append,
126
- # matching an element by value. No sign, same reading as append.
95
+ # remove is append's list-removal counterpart, matching an element
96
+ # by value; no sign, same reading as append.
127
97
  member name: "remove", sign: ""
128
- # Vendored addition, not (yet) upstream hecks — CommandBuilder
129
- # #delegates_to's own comment gives the full reasoning: an
130
- # aggregate-level command's synchronous, single-dispatch handoff
131
- # into one nested entity command, rather than a policy/saga's own
132
- # commit-then-react reentry. Rides the SAME multi-binding wire
133
- # shape append does (`with: {...}` is a field map, same as
134
- # append's own `fields:`), so it carries no sign, same reading.
98
+ # delegate is an aggregate command's synchronous handoff into a nested
99
+ # entity command (see CommandBuilder#delegates_to). Shares append's
100
+ # multi-binding wire shape (`with:` ~ `fields:`), so it carries no sign.
135
101
  member name: "delegate", sign: ""
136
- # CommandBuilder#corrects_impl's own comment gives the full
137
- # reasoning — a command declaring a past event it amends, rather
138
- # than a fresh mutation of its own. Rides the SAME multi-binding
139
- # wire shape append/delegate do (`as:`/`reason:`/`reverses:`,
140
- # assembled into one `source` hash by hand, same as `with:` is),
141
- # so it carries no sign either.
102
+ # corrects declares a past event it amends rather than a fresh
103
+ # mutation (see CommandBuilder#corrects_impl). Shares append/delegate's
104
+ # multi-binding wire shape (as:/reason:/reverses:), so no sign either.
142
105
  member name: "corrects", sign: ""
143
106
  end
144
107
 
145
- # QuerySpecification::Common::Comparators::COMPARATORS — a where-clause's
146
- # admitted operators. Unlike Comparison, these do not reduce to one shared
147
- # boolean algebra (eq/ne compare values, gt/gte/lt/lte order them, in/contains
148
- # test membership in opposite directions), so this stays a flat closed set —
149
- # the same shape MutationOp had before it grew a sign.
150
- # `none_in_state` (the last member) is a vendored addition, not (yet)
151
- # upstream hecks (migration plan task 4) — see
152
- # query_specification/common/comparators.rb's own comment on
153
- # none_in_state. Both closed sets (the Ruby COMPARATORS constant and
154
- # this self-hosted grammar entry) must agree, the same two-places-
155
- # must-agree discipline MutationOp/multiply/clamp already required
156
- # earlier this pass.
108
+ # A where-clause's admitted operators (QuerySpecification::Common::
109
+ # Comparators::COMPARATORS) — flat, not one shared algebra like Comparison,
110
+ # since eq/ne/gt/lt/in/contains differ in kind. Must stay in sync with that constant.
157
111
  value_object "QueryComparator" do
158
112
  attribute :name, String, one_of: ["eq", "ne", "gt", "gte", "lt", "lte", "in", "contains", "none_in_state"]
159
113
  end
@@ -164,24 +118,13 @@ Hecks.bluebook "Bluebook" do
164
118
  one_of: ["*.port", "*.adapter", "*.bluebook", "translations/*.bluebook", "*.hecksagon", "*.world"]
165
119
  end
166
120
 
167
- # CommandInterpreter#call — an aggregate command's
168
- # own interpretation, ending at the events it emits. Reaction (policies,
169
- # sagas) is a structurally separate phase and is not part
170
- # of this : CommandInterpreter#call returns before it runs, in a
171
- # different class — reaction is
172
- # what a command's OWN emitted events cause, not what interpreting
173
- # the command does. Two conditional steps — assign_creation_attributes only
174
- # fires for a creating command, advance_lifecycle only when a transition
175
- # applies — so this is the order a command that does both follows,
176
- # confirmed by tracing a real dispatch, not read off the source.
121
+ # The order CommandInterpreter#call follows, ending at the events it
122
+ # emits — reaction (policies, sagas) is a separate phase that runs after,
123
+ # in a different class. assign_creation_attributes only fires for a
124
+ # creating command; advance_lifecycle only when a transition applies.
177
125
  #
178
- # decode_arguments leads both dispatch orders: turning the caller's raw
179
- # facts into a command's declared arguments, before any argument gate
180
- # judges them. A no-op in Ruby today (routing already hands the
181
- # interpreter a decoded hash) and in the Rust kernel's dispatch loop
182
- # (generated `from_json` still decodes and gates in one pass) — declared
183
- # now so the Rust kernel's step enum has a place for a generated decoder
184
- # to move into, rather than the order being implied by generated code.
126
+ # decode_arguments is a no-op today in both runtimes but is declared here
127
+ # so a future generated decoder has a step to occupy.
185
128
  value_object "AggregateDispatchOrder" do
186
129
  attribute :step, String,
187
130
  one_of: ["decode_arguments", "refuse_unknown_arguments", "refuse_absent_arguments", "normalize_args",
@@ -191,21 +134,12 @@ Hecks.bluebook "Bluebook" do
191
134
  "save", "emit"]
192
135
  end
193
136
 
194
- # EntityInterpreter#call — the same shape
195
- # one level down, on a piece an aggregate holds rather than the aggregate
196
- # itself. `refuse_unknown_arguments`/`refuse_absent_arguments` lead it,
197
- # the same position they hold in AggregateDispatchOrder — bug audit H1
198
- # (docs/audits/2026-08-10-main-bug-audit.md): an entity command used to
199
- # run NEITHER at all, on a since-corrected comment claiming it "inherits
200
- # its aggregate's own gate" — nothing on this path ever ran one, and a
201
- # bogus argument or a silently-nil'd absent one both went straight
202
- # through. The only real difference from AggregateDispatchOrder now is
203
- # that an entity is never CREATED through this path (no
204
- # assign_creation_attributes) — hydrating the parent and locating the
205
- # element replace a single hydrate. resolve_references stayed, though —
206
- # an entity command can declare a reference-typed attribute the same way
207
- # an aggregate command can (CommandRules#resolve_references is shared by
208
- # both interpreters), even though nothing in the real corpus does yet.
137
+ # EntityInterpreter#call — the same shape as AggregateDispatchOrder, one
138
+ # level down on an entity. Differs in that an entity is never created
139
+ # through this path (hydrate_parent + locate_element replace hydrate;
140
+ # no assign_creation_attributes). resolve_references stays: an entity
141
+ # command can declare a reference-typed attribute too, shared via
142
+ # CommandRules#resolve_references.
209
143
  value_object "EntityDispatchOrder" do
210
144
  attribute :step, String,
211
145
  one_of: ["decode_arguments", "refuse_unknown_arguments", "refuse_absent_arguments", "normalize_args",
@@ -224,23 +158,15 @@ Hecks.bluebook "Bluebook" do
224
158
  "RemoteRefusal", "TypeMismatch", "Unauthorized", "UnknownArgument", "UnknownVerb"]
225
159
  end
226
160
 
227
- # THE WORDING ITSELF, for every DomainRefusal site that is not already
228
- # data — `given`/`ensures`/a declared `invariant` already carry their own
229
- # description, read at dispatch time off the command or value object that
230
- # declared them. Everything here is different in kind: a LANGUAGE-LEVEL
231
- # refusal, the same wording for every domain, not authored per-bluebook —
232
- # closer to Comparison/SignTest beside it than to a given. So it follows
233
- # THEIR pattern, not given's: declared here, and projected into the
234
- # generated tables a dispatch actually reads (Runtime::RefusalWording in
235
- # Ruby, kernel::vocab::RefusalSite in Rust) rather than read live off
236
- # this very chapter at every call.
161
+ # The wording for every DomainRefusal site not already carried by data
162
+ # (given/ensures/invariant already describe themselves). Language-level
163
+ # and the same for every domain, so it is declared here and projected
164
+ # into Runtime::RefusalWording (Ruby) / kernel::vocab::RefusalSite (Rust)
165
+ # rather than read live off this chapter at every call.
237
166
  #
238
- # `{name}` markers are placeholders — plain text substitution, not
239
- # expression syntax ; a template is read, never evaluated. Two call
240
- # sites that happen to raise the same sentence share one `site` row
241
- # (entity_interpreter.rb and command_interpreter.rb's own "not found"
242
- # messages, for instance) rather than being declared as two facts that
243
- # would have to be kept identical by hand.
167
+ # `{name}` markers are plain text substitution, not expression syntax —
168
+ # a template is read, never evaluated. Two call sites that raise the
169
+ # same sentence share one `site` row instead of duplicating it.
244
170
  value_object "RefusalTemplate" do
245
171
  attribute :refusal, String, admits: "Vocabulary::DomainRefusal"
246
172
  attribute :site, String
@@ -294,18 +220,8 @@ Hecks.bluebook "Bluebook" do
294
220
  template: "{command} refused — {field} is {current}, and {command} moves it only from {allowed}"
295
221
  member refusal: "TypeMismatch", site: "value_object_shape",
296
222
  template: "{name} is a {type} — pass its fields as an object, not {offered}"
297
- # RENAMED FROM `reference_as_object` (BUG#27, QualityControl ledger) —
298
- # a reference command argument that is an object was never the only
299
- # wrong shape, only the first one anyone noticed: a bare Boolean,
300
- # Array, or `null` used to sail past this refusal entirely, get
301
- # `.to_s`'d into a lookup key by `CommandRules::References#
302
- # reference_key` ("true", "false", "[8, 8]"), and answer NotFound (or,
303
- # for `null`, skip the lookup outright and answer whatever the
304
- # command's own `given` said instead) — a shape error misreading as a
305
- # missing record. `{offered}` now names what actually arrived; the
306
- # Hash/Value case still renders "an object" (Value::Coercion's own
307
- # `reference_shape_description`), so the wording already pinned byte
308
- # for byte in spec/runtime/reference_shape_spec.rb is unchanged.
223
+ # A bare Boolean, Array, or null reference argument is a shape error,
224
+ # not a missing record — {offered} names what arrived.
309
225
  member refusal: "TypeMismatch", site: "reference_wrong_shape",
310
226
  template: "{command} refused — a reference is an id, and {attribute} arrived as {offered}{known_by}"
311
227
  member refusal: "TypeMismatch", site: "multi_field_scalar",
@@ -367,33 +283,17 @@ Hecks.bluebook "Bluebook" do
367
283
  "or read {reference}.{remote_field} directly if this rule cannot wait"
368
284
  end
369
285
 
370
- # THE ARGUMENTS EACH RefusalTemplate TAKES, AND HOW EACH ONE IS WRITTEN.
371
- # A template says WHERE a value goes; this says WHICH values a site
372
- # takes (in the order its placeholders first appear) and how each is
373
- # rendered before it goes there — so a caller hands over the raw value
374
- # (a list of names, a name) rather than a string it formatted itself.
375
- # BUG#134 was exactly the hand-formatted kind: Ruby's `declared_reading`
376
- # fell back to "none" for an empty list, the Rust generators joined
377
- # the list themselves and never did.
378
- #
379
- # Read by Runtime::RefusalWording.render_site (a missing or extra
380
- # argument refuses to render at all) and projected into
381
- # rust/src/kernel/vocab/refusal_template.rs as one typed args struct
382
- # per site (`render_args` — a missing argument does not compile).
286
+ # Which values a RefusalTemplate site takes (in placeholder order) and how
287
+ # each renders, so a caller hands over a raw value rather than a
288
+ # pre-formatted string. Read by Runtime::RefusalWording.render_site and
289
+ # projected into rust/src/kernel/vocab/refusal_template.rs as one typed
290
+ # args struct per site.
383
291
  #
384
- # shape — "scalar" (one value) or "list" (a collection of them)
385
- # quoting — "none" (the value's own text) or "inspect" (Ruby's
386
- # `#inspect`; Rust's `{:?}`), per value or per item
387
- # separator — what a list's items are joined with
388
- # sorted — "true" sorts a list's items first (before quoting)
292
+ # shape — "scalar" or "list"
293
+ # quoting — "none" (raw text) or "inspect" (Ruby #inspect / Rust {:?})
294
+ # separator — what joins a list's items
295
+ # sorted — "true" sorts a list's items before quoting
389
296
  # when_empty — what an empty list renders as
390
- #
391
- # Recorded from what the Ruby call sites did when this table was
392
- # introduced; no wording changed. A value whose rendering depends on
393
- # its runtime type (`Rendering.describe`, `offered.inspect` of an
394
- # arbitrary value) stays a caller-rendered "none" scalar, as do the
395
- # identity readings (`identity`, `heads`, `wants`) the Rust side already
396
- # joins once at codegen time or inside `extract_wants`.
397
297
  value_object "RefusalSiteArgument" do
398
298
  attribute :refusal, String, admits: "Vocabulary::DomainRefusal"
399
299
  attribute :site, String
@@ -674,36 +574,23 @@ Hecks.bluebook "Bluebook" do
674
574
  shape: "scalar", quoting: "none", separator: "", sorted: "false", when_empty: ""
675
575
  end
676
576
 
677
- # SagaInterpreter::REFUSED.
678
- #
679
- # A leg answers an EVENT — `on "AccountDebited"` — or it answers one of these,
680
- # which are not events at all: no aggregate announces that a leg the procedure
681
- # dispatched was declined. `on :refused` is the compensating leg, and without
682
- # this declaration the word lived only as a magic string in the interpreter,
683
- # and a reader of the language could not discover the
684
- # trigger existed.
577
+ # A leg answers an event (`on "AccountDebited"`) or one of these non-event
578
+ # outcomes — `on :refused` is the compensating leg for a dispatch the
579
+ # procedure declined (SagaInterpreter::REFUSED).
685
580
  value_object "Trigger" do
686
581
  attribute :name, String, one_of: ["refused"]
687
582
  end
688
583
 
689
- # Hecks::Forms::FieldShape's own EMAIL_HINT/URL_HINT/
690
- # TEL_HINT/TEXTAREA_HINT (lib/hecks/forms/field_shape.rb)
691
- # — the regexes `text_field` matches a text attribute's own NAME
692
- # against (case-insensitively) to guess an HTML input type or a
693
- # textarea kind, when nothing more specific (a `pattern:`, an
694
- # `admits:`, a closed set) already answered the question. Declared
695
- # here for the same reason RefusalTemplate is: a LANGUAGE-LEVEL
696
- # rendering convention, the same guess for every domain, not
697
- # authored per-bluebook — closer to Comparison/SignTest than to a
698
- # given. `pattern` is the regex SOURCE, no delimiters or flags
699
- # (Ruby's own `Regexp#source`) — FieldShape builds its four constants
700
- # off these rows, and bin/project_field_hints writes the Rust host's
701
- # copy from them, so neither side is typed by hand.
584
+ # Regexes `text_field` matches a text attribute's name against
585
+ # (case-insensitively) to guess an HTML input type or textarea kind, when
586
+ # nothing more specific already answered (Hecks::Forms::FieldShape's
587
+ # EMAIL_HINT/URL_HINT/TEL_HINT/TEXTAREA_HINT). `pattern` is the regex
588
+ # source, no delimiters or flags. bin/project_field_hints writes the Rust
589
+ # host's copy from these rows, so neither side is typed by hand.
702
590
  #
703
- # `resolves_to` names WHICH Field attribute a match sets — `html_type`
704
- # for email/url/tel (three candidates, only one wins, checked in that
705
- # order), `kind` for textarea (checked separately, and only once
706
- # html_type has already fallen through to "text").
591
+ # `resolves_to` names which Field attribute a match sets: html_type for
592
+ # email/url/tel (checked in that order, first match wins), kind for
593
+ # textarea (checked once html_type has fallen through to "text").
707
594
  value_object "FieldHint" do
708
595
  attribute :name, String
709
596
  attribute :pattern, String
@@ -715,13 +602,11 @@ Hecks.bluebook "Bluebook" do
715
602
  member name: "textarea", pattern: '\b(text|body|note|notes|description|message|comment)\b', resolves_to: "kind"
716
603
  end
717
604
 
718
- # The Rust keywords (strict + reserved) a generated identifier must not
719
- # collide with — RustProjection::Projector::RUST_KEYWORDS (rust/project/
720
- # naming.rb) reads this, and bin/project_reserved_names projects it into
721
- # rust/codegen/src/reserved_names.rs, so the Ruby and Rust generators
722
- # escape (a field: `r#type`) or refuse (a module name) the SAME words.
723
- # Declared once here because the two hand-typed copies were held equal
724
- # by nothing but a comment.
605
+ # Rust keywords (strict + reserved) a generated identifier must not
606
+ # collide with. RustProjection::Projector::RUST_KEYWORDS reads this;
607
+ # bin/project_reserved_names projects it into
608
+ # rust/codegen/src/reserved_names.rs, so Ruby and Rust escape or refuse
609
+ # the same words from one declaration instead of two hand-typed copies.
725
610
  value_object "RustReservedWord" do
726
611
  attribute :word, String,
727
612
  one_of: ["as", "break", "const", "continue", "crate", "dyn", "else", "enum", "extern", "false",
@@ -2,15 +2,10 @@ Hecks.bluebook "Hecksagon" do
2
2
  aggregate "AdapterBinding" do
3
3
  description "One aggregate-to-adapter binding inside a hecksagon — the verb it answers, the adapter it names. Its own root because a hecksagon's binds are an open set of verbs (one per declared port), which no value object can hold — the same reasoning Wiring carries for a world's settings."
4
4
 
5
- # The retained parent edge is structural state. `hecksagon` below is
6
- # separately the text component of this binding's own compound identity,
7
- # so the relationship keeps the same explicit `_ref` distinction World::
8
- # Wiring uses for its parent edge.
5
+ # The parent edge is `hecksagon_ref`; `hecksagon` below is the text part of the identity.
9
6
  belongs_to Hecksagon, as: :hecksagon_ref
10
7
 
11
- # THE HECKSAGON IT IS IN, THE AGGREGATE IT NAMES, THE VERB IT ANSWERS.
12
- # One hecksagon binds one adapter per (aggregate, verb) pair — that is
13
- # what a binding IS — so the triple identifies it.
8
+ # One adapter per (aggregate, verb) pair within a hecksagon, so the triple identifies it.
14
9
  identified_by :hecksagon, :aggregate, :verb
15
10
 
16
11
  attribute :hecksagon, BindingText
@@ -27,9 +22,7 @@ Hecks.bluebook "Hecksagon" do
27
22
  role "Deployment"
28
23
  goal "Name the adapter one aggregate answers one verb through"
29
24
 
30
- # A creating command receives the parent's identity as an ordinary
31
- # value fact. It does not declare a behavioral relationship or use the
32
- # parent as a hidden receiver.
25
+ # The parent's identity arrives as an ordinary value, not as a receiver.
33
26
  attribute :hecksagon_ref, HecksagonName
34
27
  attribute :aggregate, BindingText
35
28
  attribute :verb, BindingText
@@ -18,27 +18,18 @@ Hecks.bluebook "Hecksagon" do
18
18
  invariant("a verb is named") { !value.to_s.empty? }
19
19
  end
20
20
 
21
- # SAME CLOSED SET port.bluebook's own "Port" aggregate declares —
22
- # kept as its own local value object rather than shared cross-
23
- # chapter, the same way PortVerb already is here.
21
+ # Same closed set as port.bluebook's Port, kept local rather than shared across chapters.
24
22
  value_object "PortSignal" do
25
23
  attribute :value, String, one_of: ["reply", "effect"]
26
24
  end
27
25
 
28
- # `answers` — DomainPortBuilder's own twin of PortBuilder#answers
29
- # (port.bluebook's "Port" aggregate, same shape), added once a real
30
- # `.port` file migrated to parse through this builder (the repoint
31
- # `lib/hecks.rb#port`'s own comment describes) used the word
32
- # (`extraction.port`'s own `answers :canonical`). Local, not shared
33
- # cross-chapter, same reasoning as PortSignal just above.
26
+ # Twin of port.bluebook's PortAnswer, kept local for the same reason as PortSignal.
34
27
  value_object "PortAnswer" do
35
28
  attribute :value, String
36
29
  invariant("an answer names a real method") { !value.to_s.empty? }
37
30
  end
38
31
 
39
- # HOW DOMAINPORT IS SPELLED. These rows live with the concept
40
- # they describe; SyntaxBoot discovers every aggregate-local seed table.
41
- # Contexts represented here: DomainPort.
32
+ # Keyword rows for DomainPort; SyntaxBoot discovers every aggregate-local seed table.
42
33
  value_object "KeywordSeed" do
43
34
  attribute :word, String
44
35
  attribute :context, String, admits: "Syntax::Context"
@@ -84,13 +75,7 @@ Hecks.bluebook "Hecksagon" do
84
75
  member keyword: "signal", context: "DomainPort", at: "1", named: "", kind: "symbol", required: "true", fills: "signal"
85
76
  member keyword: "answers", context: "DomainPort", at: "1", named: "", kind: "symbol", required: "true", fills: "answers"
86
77
 
87
- # THE RECEIVING AGGREGATE — PortOperationBuilder's own `reference_to`
88
- # (inside the block) is refused (#335); this is the sanctioned
89
- # replacement, named directly on the word that opens the block
90
- # rather than a statement inside it. `kind: "constant"`, matching
91
- # `reference_to`'s own first positional argument
92
- # (port_operation.bluebook) — same bareword-constant resolution,
93
- # just moved.
78
+ # The receiving aggregate is named on the opening word (`to:`), not by `reference_to` inside.
94
79
  member keyword: "operation", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
95
80
  member keyword: "tells", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
96
81
  member keyword: "asks", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
@@ -18,19 +18,13 @@ Hecks.bluebook "Hecksagon" do
18
18
  invariant("a subscription names an event") { !value.to_s.empty? }
19
19
  end
20
20
 
21
- # A `framework/bluebook/` member this hecksagon attaches — Governance,
22
- # Identity, whatever else lands beside them. Same shape as
23
- # `Subscription` beside it, one word over.
21
+ # A `framework/bluebook/` member this hecksagon attaches, such as Governance or Identity.
24
22
  value_object "FrameworkMember" do
25
23
  attribute :value, String
26
24
  invariant("a framework member is named") { !value.to_s.empty? }
27
25
  end
28
26
 
29
- # A vendored, external bluebook this hecksagon attaches — one level
30
- # further out than `FrameworkMember`: not a member shipped inside
31
- # hecks's own lib/, but a separate package vendored into the
32
- # consuming project's own checkout. Same shape as `FrameworkMember`
33
- # beside it, one word over — see EmbryonautBluebook's own header.
27
+ # A separate bluebook package vendored into the consuming project, not shipped in hecks's lib/.
34
28
  value_object "VendoredBluebook" do
35
29
  attribute :value, String
36
30
  invariant("a vendored bluebook is named") { !value.to_s.empty? }
@@ -80,9 +74,7 @@ Hecks.bluebook "Hecksagon" do
80
74
  emits "VendoredBluebookAttached"
81
75
  end
82
76
 
83
- # HOW HECKSAGON IS SPELLED. These rows live with the concept
84
- # they describe; SyntaxBoot discovers every aggregate-local seed table.
85
- # Contexts represented here: File, Hecksagon.
77
+ # Keyword rows for File and Hecksagon; SyntaxBoot discovers every aggregate-local seed table.
86
78
  value_object "KeywordSeed" do
87
79
  attribute :word, String
88
80
  attribute :context, String, admits: "Syntax::Context"
@@ -100,21 +92,10 @@ Hecks.bluebook "Hecksagon" do
100
92
  member word: "uses_framework", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "framework_members"
101
93
  member word: "uses_embryonaut_bluebook", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "vendored_bluebooks"
102
94
  member word: "port", context: "Hecksagon", body: "keywords", inner: "DomainPort", opens: "DomainPort", fills: "", calls: "port_impl"
103
- # A CROSS-DOMAIN REACTION, WIRED HERE INSTEAD OF THE BLUEBOOK — same
104
- # underlying `Policy` shape a `policy` block already builds
105
- # (`inner`/`opens: "Policy"` reuses that context's own `on`/`trigger`
106
- # wholesale, zero new inner vocabulary), but declared as a wiring
107
- # decision (which FOREIGN domain's event this chapter conforms to),
108
- # the same kind of decision `port`/`uses_framework` already are.
109
- # No `calls:` — `HecksagonBuilder#translates` is an ordinary method,
110
- # the same shape `subscribe`/`uses_framework` already are, reached
111
- # by Ruby's own method lookup before `word_gate` ever runs.
95
+ # A cross-domain reaction wired here rather than in the bluebook; reuses the Policy context.
96
+ # No `calls:` — HecksagonBuilder#translates is an ordinary method, found before `word_gate`.
112
97
  member word: "translates", context: "Hecksagon", body: "keywords", inner: "Policy", opens: "Policy", fills: ""
113
- # A CONSUMER-OWNED bounded context — framework/vendored packages
114
- # get this mark automatically from uses_framework /
115
- # uses_embryonaut_bluebook and never write it in their own files.
116
- # No `calls:` — `HecksagonBuilder#bounded` is an ordinary method,
117
- # same shape `subscribe` already is.
98
+ # Marks a consumer-owned bounded context; framework and vendored packages get it implicitly.
118
99
  member word: "bounded", context: "Hecksagon", body: "none", inner: "", opens: "", fills: ""
119
100
 
120
101
  end
@@ -7,17 +7,8 @@ Hecks.bluebook "Hecksagon" do
7
7
  attribute :attributes, list_of(PortOperationField)
8
8
  attribute :emits, list_of(EmittedEvent)
9
9
 
10
- # THE TWO ENDINGS OF AN `asks`, held by the language about itself.
11
- #
12
- # `emits` above is what an inbound `tells` says once the fact is in.
13
- # These two are the outbound half: what the adapter came back with, and
14
- # what it said instead. Singular where `emits` is a list, because an ask
15
- # has exactly one of each — a call that could answer two different ways
16
- # is two calls.
17
- #
18
- # Empty on every `tells`, which is why neither carries an invariant
19
- # demanding a value; `PortOperationBuilder` refuses the wrong word for
20
- # the direction long before a record gets here.
10
+ # The two endings of an `asks`: what the adapter answered, or what it refused with.
11
+ # Singular because an ask has exactly one of each; empty on every `tells`, so no invariant.
21
12
  attribute :answers, AnsweringEvent
22
13
  attribute :refuses, RefusingEvent
23
14
 
@@ -44,9 +35,7 @@ Hecks.bluebook "Hecksagon" do
44
35
  attribute :value, String
45
36
  end
46
37
 
47
- # HOW PORTOPERATION IS SPELLED. These rows live with the concept
48
- # they describe; SyntaxBoot discovers every aggregate-local seed table.
49
- # Contexts represented here: PortOperation.
38
+ # Keyword rows for PortOperation; SyntaxBoot discovers every aggregate-local seed table.
50
39
  value_object "KeywordSeed" do
51
40
  attribute :word, String
52
41
  attribute :context, String, admits: "Syntax::Context"