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,46 +1,11 @@
1
1
  module Hecks
2
2
  module Bluebook
3
- # Reopened here for `CONTRACTS`/`.contract(category)` — the one table of
4
- # every construct category's own `Contract` (Bluebook, Aggregate,
5
- # Command, ValueObject, Query, ...); see `Contract`'s own header
6
- # (contract.rb) for the struct format each entry below fills in.
3
+ # Reopened for `CONTRACTS`, the table of each category's own `Contract`;
4
+ # see contract.rb for the struct format each entry below fills in.
7
5
  class Assembly
8
- # One table, where there were five hand-written mirrors of it.
9
- #
10
- # `bluebook.bluebook` already declares what every construct is made of, and
11
- # `Plan` already reads it — parent, fields, lists, setters. What the language
12
- # cannot say is the three things Ruby needs to rebuild one, so those are here
13
- # and only those:
14
- #
15
- # holder which class holds it
16
- # make :declare for a construct that became a class, :new for an
17
- # instance — the boundary `Query` sits on, since its body is
18
- # inherited instance methods
19
- # fields each keyword the constructor takes, as
20
- # keyword => [key in the declaration, how to read it]
21
- #
22
- # A reader is a symbol naming a method on Marks, or :plain for a value that
23
- # needs no decoding, or [:each, reader] for a list. Nothing here is a rule
24
- # about whether a declaration is admissible — the language settled that on the
25
- # way in. This is only how a spelling becomes an object again.
26
- #
27
- # Why a table and not a method per category: a hand-written branch per
28
- # category can decorate a verb the language declares without the walk ever
29
- # offering it, and nothing goes red, because a branch that does not exist
30
- # cannot fail. An assembler with a method per category is the same shape.
31
- # The table avoids it because spec/assembly_spec checks it against the
32
- # language: a field the language declares that no contract consumes is a
33
- # failure, not a silence.
34
- #
35
- # The `derived` list is how a field says it needs no assembling — a parent
36
- # pointer the containment tree already knows, or something computed from what
37
- # is here (`query_name` is `Naming.snake(name)`, `creates?` is whether a verb
38
- # names a root). Naming one is a claim, and the coverage gate holds it.
39
- #
40
- # @param category [String, Symbol] the construct category name, such as
41
- # `"Aggregate"` or `:Command`
42
- # @return [Bluebook::Assembly::Contract] the category's field contract
43
- # @raise [KeyError] if no contract is registered for `category`
6
+ # One table of what each category needs beyond what the language states:
7
+ # holder, make (:declare vs :new), and fields. spec/assembly_spec checks
8
+ # it against the language, so an unconsumed declared field fails loudly.
44
9
  def self.contract(category) = CONTRACTS.fetch(category.to_s)
45
10
 
46
11
  CONTRACTS = {
@@ -66,19 +31,10 @@ module Hecks
66
31
  description: [:description, :plain],
67
32
  identified_by: [:identified_by, :plain],
68
33
  attributes: [:attributes, [:each, :attribute]],
69
- # The aggregate boundary, and the precondition a command may
70
- # reference by name (S10, ADR 0025 — "Rules"). Same reader
71
- # shapes ValueObject's own `invariants`/Command's own
72
- # `givens` already use — `invariant` builds an Invariant,
73
- # `given` a Given, the same struct AggregateBuilder#given
74
- # hands a referencing command's own resolved list.
34
+ # Aggregate's own precondition, referenced by name from a command (ADR 0025).
75
35
  invariants: [:invariants, [:each, :invariant]],
76
36
  preconditions: [:preconditions, [:each, :given]],
77
- # S12, ADR 0025 — the local half of "projects :name, from:
78
- # :\"reference.remote_field\"", read the same way
79
- # invariants/preconditions above are: a synthetic command
80
- # (Aggregate.Projects) the judge dispatches once per
81
- # declaration, folded into a list on the owning aggregate.
37
+ # The local half of `projects :name, from: "reference.remote_field"` (ADR 0025).
82
38
  projected_fields: [:projected_fields, [:each, :projected_field]],
83
39
  provenance: [:provenance, :plain]
84
40
  },
@@ -107,10 +63,7 @@ module Hecks
107
63
  ensures: [:ensures, [:each, :given]],
108
64
  mutations: [:mutations, [:each, :mutation]],
109
65
  emits: [:emits, :plain],
110
- # Lifecycle state as a command guard (S10, ADR 0025) — a
111
- # literal the same way `provenance`/`default:` already are;
112
- # one state or an array of them, or nil for a command with
113
- # no such guard.
66
+ # Lifecycle state as a command guard: one state, an array, or nil (ADR 0025).
114
67
  from: [:from, :plain],
115
68
  provenance: [:provenance, :plain]
116
69
  },
@@ -168,22 +121,15 @@ module Hecks
168
121
  fields: {
169
122
  name: [:name, :plain],
170
123
  description: [:description, :plain],
171
- # A list of paths, exactly as an aggregate's is, with no room left for
172
- # the two to differ. A Symbol here and a String there would look
173
- # identical to `to_h`'s byte-equality check, since both render as a
174
- # string, while diverging at runtime: the assembled graph would carry a
175
- # String, and `element_of`'s lookup of `args["sequence"]` in a
176
- # symbol-keyed payload would find nothing — refusing "Reverse acts on
177
- # one LedgerEntry — pass sequence:" while sequence was in fact passed.
124
+ # A list of paths, like Aggregate's. Must be Symbols: a String looks
125
+ # identical here but a symbol-keyed args lookup downstream would find
126
+ # nothing, silently rejecting a value that was in fact passed.
178
127
  identified_by: [:identified_by, :plain],
179
128
  attributes: [:attributes, [:each, :shape_field]],
180
- # ADR 0028 — the same shape Aggregate's own `preconditions`
181
- # already carries, one level down: a piece's own named
182
- # `given`, referenced back by one of its own commands.
129
+ # Same shape as Aggregate's own `preconditions`, one level down (ADR 0028).
183
130
  preconditions: [:preconditions, [:each, :given]],
184
- # Round 7 — the same shape Aggregate's own `invariants`
185
- # already carries, one level down: checked against every
186
- # instance of this piece, not the aggregate's own flat state.
131
+ # Same shape as Aggregate's own `invariants`, checked per instance of
132
+ # this entity rather than the aggregate's flat state.
187
133
  invariants: [:invariants, [:each, :invariant]]
188
134
  },
189
135
  rows: { transitions: :transition_rows, identified_by: :identity_rows },
@@ -220,35 +166,23 @@ module Hecks
220
166
  holder: ProcessManager, make: :new,
221
167
  fields: {
222
168
  name: [:name, :plain],
223
- # **A symbol**. `SagaInterpreter` does `event.payload[pm.correlates_by]` — a
224
- # hash lookup on a symbol-keyed payload — and `value == pm.correlates_by`
225
- # when resolving a leg s bindings. A String there finds nothing and
226
- # resolves to nothing, so the wire never advanced and a drawer that
227
- # should have held 2500 held 0. to_h could not show it: it stringifies.
169
+ # Must be a Symbol: SagaInterpreter looks it up as a symbol-keyed hash
170
+ # key. A String silently matches nothing, and the saga never advances.
228
171
  correlates_by: [:correlates_by, :identity],
229
172
  starts_on: [:starts_on, :plain],
230
173
  ends_on: [:ends_on, :plain],
231
174
  states: [:states, :plain]
232
175
  },
233
176
  reads: { states: :names },
234
- # S17, ADR 0026 — `handlers` is a real feature of the language's
235
- # own "ProcessManager" declaration now (`attribute :handlers,
236
- # list_of(Handler)`, reaction.bluebook), consumed by the judge
237
- # walking `Plan`'s own containment tree (`Handler`'s own
238
- # `.parent == "ProcessManager"`) rather than by any field this
239
- # contract itself reads — the same `:children` shape Aggregate's
240
- # own `value_objects` claim already uses, one level in.
177
+ # `handlers` comes from the judge walking the containment tree
178
+ # (`Handler.parent == "ProcessManager"`), the same as Aggregate's
179
+ # own `value_objects` — not from any field this contract reads.
241
180
  derived: { position: :walk, handlers: :children }
242
181
  ),
243
182
 
244
- # S17, ADR 0026 — Handler is a genuine entity now, nested under
245
- # ProcessManager (`entity "Handler"`, reaction.bluebook). Neither
246
- # `position` nor `handler` is a stored field: a saga
247
- # answers each event once, so `event_type` is Handler's own real,
248
- # non-positional identity (no walk-minted `position` to derive),
249
- # and the process manager it belongs to is structural now — which
250
- # list this element sits in, not a stored field to fold a parent
251
- # pointer out of.
183
+ # Handler is nested under ProcessManager. `event_type` is its real
184
+ # identity (a saga answers each event once), so unlike other entities
185
+ # it has no walk-minted `position` to derive.
252
186
  "Handler" => Contract.new(
253
187
  holder: ProcessManagerHandler, make: :new,
254
188
  fields: {
@@ -256,46 +190,14 @@ module Hecks
256
190
  from_state: [:from_state, :plain],
257
191
  to_state: [:to_state, :plain]
258
192
  },
259
- # `dispatches` — same reason ProcessManager's own `handlers`
260
- # claim, above, is `:children` : a real feature of the
261
- # language's own "Handler" declaration (`attribute :dispatches,
262
- # list_of(Dispatch)`), consumed by the judge walking `Plan`'s
263
- # own containment tree rather than by any field this contract
264
- # reads.
193
+ # `dispatches` comes from the containment walk, like ProcessManager's
194
+ # own `handlers` above — not from a field this contract reads.
265
195
  derived: { dispatches: :children }
266
196
  ),
267
197
 
268
- # S17, ADR 0026 — Dispatch is a genuine entity now, nested under
269
- # Handler (`entity "Dispatch"`, process_manager.bluebook) — two
270
- # levels deep, "no life outside its Handler" (the ADR's own
271
- # words). `command_name` alone is not Dispatch's own identity —
272
- # items #151/#152 (`process_manager.bluebook`'s own
273
- # `DispatchPosition` comment) found it collides the instant a
274
- # real handler fans the same command out more than once, so
275
- # `position` joins it, walk-minted the same way every other
276
- # category's own `position` is (`derived: { position: :walk }`,
277
- # the same entry ProcessManager's own contract carries above) —
278
- # never a stored field on `DispatchSpec` itself, exactly like
279
- # `handler` before it.
280
- # `compensates_command_name`/`compensates_with_spec` — folded,
281
- # the same kind `Lifecycle`'s own `state_field`/`default` claim
282
- # (one IR object, `DispatchSpec#compensates`, feeding two
283
- # separate language fields): `Readings#field_value`'s own
284
- # `contract.folded` branch reads
285
- # `node.compensates.to_h[:command_name]` / `[:with_spec]` for
286
- # the judge's offering side, nil-safe when there is no
287
- # compensation at all (`through`'s own `return nil unless
288
- # held`). `compensates_with_spec` also needs its own row shaper
289
- # (`compensates_with_spec_rows`, readings.rb) for the judge's
290
- # list-offering side — the with_spec pairs still need one
291
- # "BindCompensation" append per pair, the same reason
292
- # `with_spec` itself needs `with_spec_rows`, one level deeper.
293
- # `Reconstruction#dispatch` reads the two flat fields back off
294
- # the row and assembles the nested `DispatchSpec` by hand — a
295
- # nested object is not one of the shapes `declaration()`'s own
296
- # generic per-field hash-build can produce, the identical reason
297
- # `handler`/`process_manager` pass a `:children` list through
298
- # `extra:` instead.
198
+ # Dispatch is nested under Handler, two levels deep. `command_name` alone
199
+ # is not identity — a handler can fan the same command out more than
200
+ # once, so `position` (walk-minted) disambiguates.
299
201
  "Dispatch" => Contract.new(
300
202
  holder: DispatchSpec, make: :new,
301
203
  fields: {
@@ -304,6 +206,7 @@ module Hecks
304
206
  },
305
207
  rows: { with_spec: :with_spec_rows, compensates_with_spec: :compensates_with_spec_rows },
306
208
  reads: { with_spec: [:from, :with_spec] },
209
+ # compensates_* fold one IR object (`DispatchSpec#compensates`) into two fields.
307
210
  derived: {
308
211
  position: :walk,
309
212
  compensates_command_name: [:folded, :compensates, :command_name],
@@ -311,15 +214,9 @@ module Hecks
311
214
  }
312
215
  ),
313
216
 
314
- # S14, ADR 0026 — Syntax/Keyword/Argument are never built via
315
- # `Build`/`Reconstruction`'s own generic path — their own data
316
- # lives in a dedicated repository `SyntaxBoot` (meta_validator/
317
- # syntax_boot.rb) reads directly, never through the meta-
318
- # domain's own reconstruction, the same reason `Member`'s own
319
- # entry (above) carries `holder: nil, make: nil` too. These
320
- # entries exist purely so the introspection specs
321
- # (assembly_spec.rb) can hold them to the same "every field
322
- # claimed" discipline every other category answers to.
217
+ # Syntax/Keyword/Argument bypass Build/Reconstruction entirely (ADR 0026) —
218
+ # SyntaxBoot reads them directly. These entries exist only so assembly_spec
219
+ # can hold them to the same "every field claimed" discipline as the rest.
323
220
  "Syntax" => Contract.new(
324
221
  holder: nil, make: nil,
325
222
  fields: { name: [:name, :plain] },
@@ -374,14 +271,18 @@ module Hecks
374
271
  reference_target: [:reference_target, :plain],
375
272
  aggregate_heads: [:aggregate_heads, [:each, :head]],
376
273
  group_by: [:group_by, [:each, :group_by_field]],
377
- # `count`/`median_field` are `group_by`'s own two siblings —
378
- # scalars, not lists, so no `[:each, ...]` shape ; `:plain`
379
- # is what `Assembly::Build` needs (fed the native `to_h`
380
- # value directly, already `true`/`nil`/a String), and the
381
- # `reads:` entry below is what `Reconstruction` needs
382
- # instead (fed the stringified meta-domain row).
274
+ # Scalars, not lists: `:plain` is for Build (native to_h value);
275
+ # the `reads:` entry below is for Reconstruction (stringified row).
383
276
  count: [:count, :plain],
384
277
  median_field: [:median_field, :plain],
278
+ sum_field: [:sum_field, :plain],
279
+ avg_field: [:avg_field, :plain],
280
+ min_field: [:min_field, :plain],
281
+ max_field: [:max_field, :plain],
282
+ percentile_field: [:percentile_field, :plain],
283
+ percentile_at: [:percentile_at, :plain],
284
+ any_field: [:any_field, :plain],
285
+ all_field: [:all_field, :plain],
385
286
  # A read model inherits every option an ask has, so it reads them the
386
287
  # same way — see Query.
387
288
  wheres: [:wheres, [:each, :where_clause]],
@@ -394,31 +295,18 @@ module Hecks
394
295
  inspection: [:inspection, [:option, :inspection]]
395
296
  },
396
297
  rows: { options: :read_model_option_rows },
397
- # `wheres` needs its own reader for the same reason Query's does — a
398
- # list defaults to `[]`, not the generic `text(row[key])` cell reader's
399
- # `nil` — even though a read model's row never carries `wheres` as a
400
- # native field the way Query's does (`[:each, :where_clause]` over an
401
- # absent `row[:wheres]` is `Array(nil).map { ... }`, i.e. `[]`, always).
402
- # The real values, when a read model declares any, arrive through
403
- # `options_of(row)`'s merge in `read_model` below (dispatched as
404
- # generic Option rows, `read_model_option_rows`/`filter_options` — not
405
- # as dedicated where-clause rows), which overrides this default. Until
406
- # `ReadModel#to_h` spelled `wheres`/`order_by`/`limit`
407
- # unconditionally, `round_trip_spec`'s own "source keys only" +compare
408
- # never asked about this key at all, so the `nil`-vs-`[]` gap between
409
- # this contract's default and `to_h`'s own `[]` default went unnoticed.
410
- # `order_by`/`limit` need no matching entry — the generic reader's
411
- # `nil` already agrees with `to_h`'s own nil-when-undeclared default
412
- # for those two. `group_by` needs its own reader the same way — a
413
- # rootless read model's grouping keys, added independently on main.
298
+ # `wheres` needs its own reader so an undeclared list defaults to `[]`,
299
+ # not the generic reader's `nil`; real values arrive via the options
300
+ # merge in `read_model` below, which overrides this default.
414
301
  reads: { reference_name: :symbol, aggregate_heads: [:each, :head],
415
302
  group_by: [:each, :group_by_field], wheres: [:each, :where_clause],
416
- # `count` needs the boolean coercion `Shapes#read_model_count`
417
- # gives it (a stringified "true"/absent on the wire, a real
418
- # `true`/`nil` in `to_h`) — `median_field` needs none: the
419
- # default `text(row[key])` cell reader already returns the
420
- # same String-or-nil `ReadModel#to_h`'s own `&.to_s` does.
421
- count: :read_model_count },
303
+ # `count` needs boolean coercion (stringified on the wire);
304
+ # `median_field` needs none — the default reader already
305
+ # matches `to_h`'s String-or-nil.
306
+ count: :read_model_count,
307
+ # `percentile_at` needs Float coercion; every other reduction field
308
+ # is a Symbol-like name the default text reader already matches.
309
+ percentile_at: :read_model_percentile_at },
422
310
  derived: {
423
311
  position: :walk,
424
312
  query_name: [:computed, :query_name],
@@ -426,17 +314,9 @@ module Hecks
426
314
  }
427
315
  ),
428
316
 
429
- # A member's pairs are an open map, which is why Member is its own root in
430
- # the language. The IR keeps them as a plain hash on the value object, so
431
- # they are assembled with their shape rather than as a construct.
432
- # S17, ADR 0026 — Member is a genuine entity, nested under
433
- # ValueObject (`entity "Member"`, shape.bluebook). It holds no
434
- # `shape` field at all (a free-text, un-parsed spelling would suit
435
- # only a standalone root ; an entity's element is
436
- # never serialized as text) — only `position` (walk-minted, see
437
- # `entity_own_identity`, judge.rb) and `pairs` (still an open map,
438
- # still one row per entry, still why a value object cannot hold it
439
- # directly).
317
+ # Member is nested under ValueObject. Its pairs are an open map, so it
318
+ # holds no `shape` field — only walk-minted `position` and `pairs`
319
+ # (still one row per entry, still an open map).
440
320
  "Member" => Contract.new(
441
321
  holder: nil, make: nil,
442
322
  fields: {},