hecks 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +4 -6
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +17 -98
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres.rb +145 -134
  25. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  26. data/lib/hecks/adapters/driven/prism.rb +7 -30
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  31. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  32. data/lib/hecks/adapters/driven/tenant_provisioner.rb +5 -48
  33. data/lib/hecks/adapters/driven.rb +5 -36
  34. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  35. data/lib/hecks/behaviors/dsl.rb +7 -25
  36. data/lib/hecks/behaviors/expectations.rb +31 -141
  37. data/lib/hecks/behaviors/ir.rb +7 -20
  38. data/lib/hecks/behaviors/rspec.rb +6 -17
  39. data/lib/hecks/behaviors/runner.rb +10 -34
  40. data/lib/hecks/behaviors.rb +4 -8
  41. data/lib/hecks/bluebook/aggregate.rb +9 -75
  42. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  43. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  44. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  45. data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
  46. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  47. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  48. data/lib/hecks/bluebook/assembly.rb +6 -45
  49. data/lib/hecks/bluebook/attribute.rb +12 -61
  50. data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
  51. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  52. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  53. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  54. data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
  55. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  56. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  57. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  58. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  59. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  60. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  61. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  62. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  63. data/lib/hecks/bluebook/capabilities.rb +17 -49
  64. data/lib/hecks/bluebook/chapter.rb +10 -48
  65. data/lib/hecks/bluebook/command.rb +23 -81
  66. data/lib/hecks/bluebook/domain_port.rb +14 -63
  67. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  68. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  69. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  70. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  71. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
  72. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
  73. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
  74. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  75. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  76. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
  77. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  78. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  79. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -194
  80. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  81. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  82. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  83. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  84. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  85. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  86. data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
  87. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  88. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  89. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  90. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  91. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  92. data/lib/hecks/bluebook/dsl/world_builder.rb +19 -111
  93. data/lib/hecks/bluebook/entity.rb +13 -71
  94. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  95. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  96. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  97. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  98. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  99. data/lib/hecks/bluebook/expression/resolver.rb +37 -660
  100. data/lib/hecks/bluebook/hexagon.rb +5 -28
  101. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  102. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  103. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  104. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  105. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  106. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  107. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
  108. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  109. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
  110. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  111. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  112. data/lib/hecks/bluebook/meta_validator.rb +79 -349
  113. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  114. data/lib/hecks/bluebook/model_check.rb +100 -597
  115. data/lib/hecks/bluebook/pattern_subset.rb +11 -69
  116. data/lib/hecks/bluebook/process_manager.rb +13 -83
  117. data/lib/hecks/bluebook/project_loader.rb +3 -39
  118. data/lib/hecks/bluebook/project_register.rb +12 -60
  119. data/lib/hecks/bluebook/query.rb +9 -48
  120. data/lib/hecks/bluebook/read_model.rb +57 -81
  121. data/lib/hecks/bluebook/reference.rb +7 -41
  122. data/lib/hecks/bluebook/smoke_test.rb +8 -98
  123. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  124. data/lib/hecks/bluebook/translation.rb +26 -62
  125. data/lib/hecks/bluebook/value_object.rb +11 -36
  126. data/lib/hecks/bluebook.rb +5 -22
  127. data/lib/hecks/cache_dir.rb +4 -23
  128. data/lib/hecks/cli/document.rb +3 -21
  129. data/lib/hecks/cli/ir.rb +3 -5
  130. data/lib/hecks/cli/mcp.rb +2 -3
  131. data/lib/hecks/cli/mcp_door.rb +19 -114
  132. data/lib/hecks/cli/model_check.rb +18 -85
  133. data/lib/hecks/cli/project_cli.rb +7 -40
  134. data/lib/hecks/cli/project_diagrams.rb +0 -7
  135. data/lib/hecks/cli/run.rb +12 -58
  136. data/lib/hecks/cli/smoke_test.rb +2 -16
  137. data/lib/hecks/cli/stores.rb +1 -2
  138. data/lib/hecks/cli.rb +18 -24
  139. data/lib/hecks/construct.rb +8 -34
  140. data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
  141. data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
  142. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  143. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  144. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  145. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  146. data/lib/hecks/embryonaut_bluebook.rb +4 -71
  147. data/lib/hecks/facade/cli_door.rb +24 -106
  148. data/lib/hecks/facade/cli_runner.rb +28 -172
  149. data/lib/hecks/facade/command_request.rb +13 -33
  150. data/lib/hecks/facade/handle.rb +34 -121
  151. data/lib/hecks/facade/json_door.rb +31 -146
  152. data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
  153. data/lib/hecks/facade/surface/chapter.rb +10 -54
  154. data/lib/hecks/facade/surface.rb +8 -23
  155. data/lib/hecks/facade.rb +10 -25
  156. data/lib/hecks/forms/app.rb +15 -70
  157. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  158. data/lib/hecks/forms/field_renderer.rb +17 -156
  159. data/lib/hecks/forms/field_shape.rb +30 -222
  160. data/lib/hecks/forms/html.rb +12 -47
  161. data/lib/hecks/forms/index_renderer.rb +1 -4
  162. data/lib/hecks/forms/page.rb +3 -9
  163. data/lib/hecks/forms/params.rb +14 -60
  164. data/lib/hecks/forms/port_argument.rb +2 -19
  165. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  166. data/lib/hecks/forms/record_renderer.rb +8 -75
  167. data/lib/hecks/forms/record_table.rb +7 -50
  168. data/lib/hecks/forms/reference_options.rb +3 -30
  169. data/lib/hecks/forms/value_object_shape.rb +8 -35
  170. data/lib/hecks/forms.rb +5 -33
  171. data/lib/hecks/fqn.rb +5 -12
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  175. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  176. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  177. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  178. data/lib/hecks/framework.rb +11 -80
  179. data/lib/hecks/freezer.rb +5 -39
  180. data/lib/hecks/grammar/expression.bluebook +15 -40
  181. data/lib/hecks/grammar/translation.bluebook +3 -6
  182. data/lib/hecks/grammar.rb +16 -41
  183. data/lib/hecks/ir.rb +14 -83
  184. data/lib/hecks/language/adapter.bluebook +2 -7
  185. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  186. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  187. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
  188. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  189. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  190. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  191. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  192. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  193. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  194. data/lib/hecks/language/bluebook/query.bluebook +12 -43
  195. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  196. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  197. data/lib/hecks/language/bluebook/vocabulary.bluebook +82 -197
  198. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  199. data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
  200. data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
  201. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  202. data/lib/hecks/language/oidc.json +35 -0
  203. data/lib/hecks/language/port.bluebook +4 -17
  204. data/lib/hecks/language/translation/translation.bluebook +3 -9
  205. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  206. data/lib/hecks/language/world/wiring.bluebook +1 -3
  207. data/lib/hecks/language/world/world.bluebook +5 -7
  208. data/lib/hecks/literal.rb +8 -50
  209. data/lib/hecks/mcp_door_scope.rb +9 -90
  210. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  211. data/lib/hecks/naming.rb +29 -137
  212. data/lib/hecks/ports/access_control.rb +7 -23
  213. data/lib/hecks/ports/agent/answers.rb +5 -23
  214. data/lib/hecks/ports/agent.rb +47 -172
  215. data/lib/hecks/ports/authentication.rb +12 -39
  216. data/lib/hecks/ports/authorization.rb +16 -43
  217. data/lib/hecks/ports/clock.rb +5 -45
  218. data/lib/hecks/ports/extraction.rb +7 -12
  219. data/lib/hecks/ports/identity_assignment.rb +8 -29
  220. data/lib/hecks/ports/identity_generation.rb +6 -29
  221. data/lib/hecks/ports/identity_resolution.rb +2 -10
  222. data/lib/hecks/ports/key_vault.rb +9 -45
  223. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  224. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  225. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  226. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  227. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  228. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
  229. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
  231. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  232. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
  233. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
  250. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  251. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  252. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  253. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  254. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  255. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  256. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
  257. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  258. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  259. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  260. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  261. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  262. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  263. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  264. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  265. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  266. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  267. data/lib/hecks/ports/persistence/state_codec.rb +23 -103
  268. data/lib/hecks/ports/persistence.rb +7 -14
  269. data/lib/hecks/ports/projection.rb +42 -84
  270. data/lib/hecks/ports/query/in_memory.rb +10 -58
  271. data/lib/hecks/ports/query/ordering.rb +11 -32
  272. data/lib/hecks/ports/query.rb +14 -37
  273. data/lib/hecks/ports.rb +2 -8
  274. data/lib/hecks/projections/bootstrap_table.rb +11 -43
  275. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  276. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  277. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  278. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  279. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  280. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  281. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  282. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  283. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  284. data/lib/hecks/projections/deploy/fargate.rb +35 -202
  285. data/lib/hecks/projections/deploy/lambda.rb +150 -678
  286. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  287. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  288. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  289. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  290. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  291. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  292. data/lib/hecks/projections/deploy/preview/template.rb +2 -58
  293. data/lib/hecks/projections/deploy/preview.rb +2 -67
  294. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  295. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  296. data/lib/hecks/projections/deploy/shared.rb +47 -146
  297. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  298. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  299. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  300. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  301. data/lib/hecks/projections/diagrams.rb +20 -582
  302. data/lib/hecks/projections/glossary/html.rb +14 -130
  303. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  304. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  305. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  306. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  307. data/lib/hecks/projections/glossary.rb +30 -222
  308. data/lib/hecks/projections/ir.rb +3 -10
  309. data/lib/hecks/projections/model/deviations.rb +15 -42
  310. data/lib/hecks/projections/model.rb +12 -51
  311. data/lib/hecks/projections/oidc.rb +12 -56
  312. data/lib/hecks/projections/parser_table.rb +9 -28
  313. data/lib/hecks/projections/reference.rb +2 -15
  314. data/lib/hecks/projections/rust_vocabulary.rb +12 -250
  315. data/lib/hecks/projections/shape.rb +3 -29
  316. data/lib/hecks/projections/statements.rb +7 -86
  317. data/lib/hecks/projections/vocabulary.rb +6 -22
  318. data/lib/hecks/projections.rb +2 -16
  319. data/lib/hecks/projector/cli_projector.rb +60 -375
  320. data/lib/hecks/projector/docs_projector.rb +10 -201
  321. data/lib/hecks/projector/exporter.rb +42 -134
  322. data/lib/hecks/projector/ir_projector.rb +2 -9
  323. data/lib/hecks/projector/narrate_projector.rb +15 -189
  324. data/lib/hecks/projector/target.rb +13 -76
  325. data/lib/hecks/projector.rb +30 -121
  326. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  327. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  328. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  329. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  330. data/lib/hecks/query_specification/common/options.rb +2 -6
  331. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  332. data/lib/hecks/query_specification/field_path.rb +37 -77
  333. data/lib/hecks/query_specification/hop_path.rb +12 -76
  334. data/lib/hecks/release/gem_pin.rb +2 -26
  335. data/lib/hecks/release/runner/ci_publisher.rb +3 -6
  336. data/lib/hecks/release/runner/commands.rb +2 -4
  337. data/lib/hecks/release/runner/gem_publisher.rb +2 -3
  338. data/lib/hecks/release/runner/npm_publisher.rb +6 -20
  339. data/lib/hecks/release/runner/preflight.rb +4 -19
  340. data/lib/hecks/release/runner/tagger.rb +2 -9
  341. data/lib/hecks/release/runner.rb +3 -32
  342. data/lib/hecks/rendering.rb +4 -26
  343. data/lib/hecks/router/namespace_installer.rb +12 -36
  344. data/lib/hecks/router.rb +4 -8
  345. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  346. data/lib/hecks/runtime/boot_gates.rb +3 -18
  347. data/lib/hecks/runtime/caller.rb +19 -59
  348. data/lib/hecks/runtime/capability_graph.rb +5 -21
  349. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  350. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
  351. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  352. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  353. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  354. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  355. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  356. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  357. data/lib/hecks/runtime/dependency_planning.rb +30 -102
  358. data/lib/hecks/runtime/dispatcher.rb +82 -241
  359. data/lib/hecks/runtime/entity_element.rb +40 -462
  360. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  361. data/lib/hecks/runtime/errors.rb +32 -115
  362. data/lib/hecks/runtime/event.rb +3 -25
  363. data/lib/hecks/runtime/identity.rb +18 -154
  364. data/lib/hecks/runtime/instance.rb +18 -150
  365. data/lib/hecks/runtime/interpreting.rb +11 -70
  366. data/lib/hecks/runtime/invocation.rb +28 -164
  367. data/lib/hecks/runtime/loader.rb +48 -186
  368. data/lib/hecks/runtime/outbox.rb +38 -261
  369. data/lib/hecks/runtime/policy_interpreter.rb +38 -200
  370. data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
  371. data/lib/hecks/runtime/query_interpreter.rb +45 -187
  372. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  373. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  374. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  375. data/lib/hecks/runtime/reference_hop.rb +8 -81
  376. data/lib/hecks/runtime/refusal_wording.rb +8 -89
  377. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  378. data/lib/hecks/runtime/registry/verification.rb +52 -225
  379. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  380. data/lib/hecks/runtime/registry.rb +99 -244
  381. data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
  382. data/lib/hecks/runtime/routing.rb +4 -15
  383. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  384. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  385. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  386. data/lib/hecks/runtime/tenant_check.rb +6 -68
  387. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  388. data/lib/hecks/runtime/value/admission.rb +16 -67
  389. data/lib/hecks/runtime/value/coercion.rb +155 -641
  390. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  391. data/lib/hecks/runtime/value.rb +12 -84
  392. data/lib/hecks/runtime.rb +17 -65
  393. data/lib/hecks/storehouse.rb +141 -568
  394. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
  395. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  396. data/lib/hecks/vendoring/git_environment.rb +2 -8
  397. data/lib/hecks/vendoring/git_source.rb +4 -10
  398. data/lib/hecks/vendoring.rb +7 -46
  399. data/lib/hecks/version.rb +3 -14
  400. data/lib/hecks.rb +26 -81
  401. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  402. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  403. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  404. metadata +3 -2
@@ -6,12 +6,8 @@ require_relative "../../query_specification/common/comparison"
6
6
  module Hecks
7
7
  module Ports
8
8
  module Query
9
- # In-memory implementation of a declared query specification:
10
- # applies wheres/order_by/offset/limit directly to an Array of
11
- # records instead of compiling SQL. Deliberately kept in exact
12
- # LIMIT/OFFSET-order agreement with SqlQueryBuilder (see #execute's
13
- # own comment) so a query answers the same page regardless of
14
- # which adapter backs it.
9
+ # Applies wheres, order_by, offset and limit to an Array of records, in the same order
10
+ # as `SqlQueryBuilder` so every adapter answers the same page.
15
11
  module InMemory
16
12
  FieldPath = QuerySpecification::FieldPath
17
13
  Comparison = QuerySpecification::Common::Comparison
@@ -20,17 +16,12 @@ module Hecks
20
16
 
21
17
  # Filters, orders and pages `records` against a declared query specification.
22
18
  #
23
- # @param records [Array<Runtime::Instance, Hash>] the candidate records to filter —
24
- # an Instance, a Value, or a plain row hash per record (see `FieldPath.dig`)
25
- # @param declared [QuerySpecification::Common::Options,
26
- # Bluebook::Behaviour::ReadModel::FilteredOptions] the specification providing
27
- # `wheres`, `order_by`, `offset` and `limit`
28
- # @param args [Hash{Symbol => Object}] bound values for any Symbol placeholder in a
29
- # where clause, `offset`, or `limit`
30
- # @param registry [Runtime::Registry, nil] the booted registry, passed through to a
31
- # registry-aware comparison; nil when none is available
32
- # @return [Array<Runtime::Instance, Hash>] the matching records, ordered and paged;
33
- # the same element type as `records`
19
+ # @param records [Array<Runtime::Instance, Hash>] the candidates
20
+ # @param declared [QuerySpecification::Common::Options] provides `wheres`, `order_by`,
21
+ # `offset` and `limit`
22
+ # @param args [Hash{Symbol => Object}] values for Symbol placeholders
23
+ # @param registry [Runtime::Registry, nil] passed to registry-aware comparisons
24
+ # @return [Array<Runtime::Instance, Hash>] the matching records, ordered and paged
34
25
  def execute(records, declared, args = {}, registry: nil)
35
26
  matched = records.select do |record|
36
27
  declared.wheres.all? do |clause|
@@ -40,58 +31,19 @@ module Hecks
40
31
  field = declared.order_by&.field
41
32
  matched = Ordering.apply(matched, declared.order_by, declared.null_semantics,
42
33
  identity: ->(record) { record.id.to_s }) { |record| comparable(FieldPath.dig(record, field)) }
43
- # **Offset first, then limit** — the order SQL means by `LIMIT n
44
- # OFFSET m`, which is what `SqlQueryBuilder` emits and therefore
45
- # what every SQL-backed aggregate already answers. Written the
46
- # other way round here, and the two engines disagreed on the
47
- # same declaration: `limit 2, offset 1` over three rows is rows
48
- # two and three in Postgres and Sqlite, and was row two alone in
49
- # memory. Silently — a short page reads exactly like a page that
50
- # ran out of rows.
51
- #
52
- # It gets worse the further you page, which is the case nobody
53
- # writing the first page ever sees: at `limit 10, offset 10`,
54
- # taking ten and then dropping ten leaves nothing, so page two
55
- # of a memory-backed query came back empty however many rows
56
- # were really there.
34
+ # Offset before limit, as SQL means `LIMIT n OFFSET m`; the reverse order returns a short
35
+ # or empty page (`limit 10, offset 10` would drop everything).
57
36
  matched = matched.drop(resolve(declared.offset.value, args).to_i) if declared.offset
58
37
  matched = matched.first(resolve(declared.limit.value, args).to_i) if declared.limit
59
38
  matched
60
39
  end
61
40
 
62
- # The comparator table itself lives in
63
- # QuerySpecification::Common::Comparison, not duplicated per
64
- # caller — this module and Runtime::QueryInterpreter drifted
65
- # when each carried its own copy (see that file's own comment
66
- # for what it cost). What stays here is how a value is reached
67
- # for this path: a registry arrives as an argument rather than
68
- # as instance state, and the field is dug through FieldPath
69
- # before it arrives.
70
- # @param clause [QuerySpecification::Common::WhereClause] the declared comparison
71
- # @param held [Object, nil] the record's own value for `clause.field`
72
- # @param args [Hash{Symbol => Object}] bound values for a Symbol-named `clause.value`
73
- # @param registry [Runtime::Registry, nil] used only by `none_in_state`; see
74
- # `Comparison.holds?`
75
- # @return [Boolean] whether the comparison holds
76
- # @raise [Runtime::WiringError] if `clause.op` names no comparator in
77
- # `Comparison`'s table, or `none_in_state`'s target aggregate has no wired repository
78
41
  def holds?(clause, held, args, registry: nil)
79
42
  Comparison.holds?(clause.op, held, comparable(resolve(clause.value, args)), registry: registry)
80
43
  end
81
44
 
82
- # Resolves a where-clause value, looking up a Symbol placeholder in `args`.
83
- #
84
- # @param value [Object] a literal value, or a Symbol naming a key in `args`
85
- # @param args [Hash{Symbol => Object}] bound argument values
86
- # @return [Object] `args[value]` when `value` is a Symbol, else `value` unchanged
87
45
  def resolve(value, args) = value.is_a?(Symbol) ? args[value] : value
88
46
 
89
- # Normalises a value into the shape `Comparison` compares against.
90
- #
91
- # @param value [Runtime::Value, Hash, Object, nil] a held or wanted value; a
92
- # `Runtime::Value` is read through its `to_h`
93
- # @return [Object, nil] the sole numeric member, or the sole member, of a Hash-shaped
94
- # value; otherwise `value` unchanged
95
47
  def comparable(value) = Comparison.comparable(value)
96
48
  end
97
49
  end
@@ -3,46 +3,25 @@ require_relative "../../query_specification/common/null_policy"
3
3
  module Hecks
4
4
  module Ports
5
5
  module Query
6
- # What order an ask answers in — the meaning of the ask, not a property
7
- # of the store that happens to hold it. Declared here once so an adapter
8
- # may satisfy it natively but never redefine it : SQLite pushes both
9
- # tiers into SQL (NullPolicy.sql_order renders `field DIR, id DIR`),
10
- # while Heki and Memory have no query engine and delegate straight back
11
- # to InMemory.
6
+ # The order an ask answers in: the declared order_by, then identity as a total tiebreaker.
12
7
  #
13
- # Two tiers, in this order : the declared order_by when there is one,
14
- # then identity, always. The identity tier is what makes an ask total.
15
- # Without it, an ask with no order_by — or a declared order with tied
16
- # keys — hands back whatever order the store happened to hold, and
17
- # store order was quietly standing in for a rule while every
18
- # hand-written query in the corpus stayed green : not one of them
19
- # had a tie for store order to decide.
20
- #
21
- # An adapter that pushes ordering down must push limit down with it.
22
- # Re-ordering a page the store already cut would be a top-N of the
23
- # wrong N — the one way this can be got quietly, expensively wrong.
8
+ # An adapter that pushes ordering down must push limit down with it; re-ordering
9
+ # a page the store already cut yields a top-N of the wrong N.
24
10
  module Ordering
25
11
  module_function
26
12
 
27
- # Orders an Array of rows by the declared order, with identity as the total-order
28
- # tiebreaker.
13
+ # Orders rows by `order_by`, breaking ties by `identity`.
29
14
  #
30
- # @param rows [Array<Object>] the rows to order; any shape `identity` and the block
31
- # can read (a `Runtime::Instance`, a plain Hash row, …)
32
- # @param order_by [QuerySpecification::Common::OrderBy, nil] the declared order;
33
- # nil orders by identity alone
34
- # @param null_semantics [QuerySpecification::Common::NullSemantics, nil] where a
35
- # nil-valued row sorts, passed to `NullPolicy.order`; nil uses its native default
36
- # @param identity [Proc] yields a row, returns its comparable identity value, used
37
- # as the stable tiebreaker
15
+ # @param rows [Array<Object>] the rows to order
16
+ # @param order_by [QuerySpecification::Common::OrderBy, nil] nil orders by identity alone
17
+ # @param null_semantics [QuerySpecification::Common::NullSemantics, nil] where nil values
18
+ # sort; nil uses the native default
19
+ # @param identity [Proc] returns a row's comparable identity value
38
20
  # @yieldparam row [Object] one row being ordered
39
21
  # @yieldreturn [Object, nil] the row's comparable value for `order_by`'s field
40
- # @return [Array<Object>] `rows`, ordered by `order_by` then identity (identity
41
- # alone when `order_by` is nil)
22
+ # @return [Array<Object>] the ordered rows
42
23
  def apply(rows, order_by, null_semantics = nil, identity:, &value_of)
43
- # Stable, because sort_by is not : two rows whose identity ties would
44
- # otherwise swap arbitrarily, and a tier meant to remove store-dependence
45
- # would be adding a coin flip of its own.
24
+ # The index keeps the sort stable; sort_by alone would order tied identities arbitrarily.
46
25
  rows = rows.each_with_index.sort_by { |row, index| [identity.call(row), index] }.map(&:first)
47
26
  return rows unless order_by
48
27
 
@@ -1,39 +1,25 @@
1
1
  module Hecks
2
2
  module Ports
3
- # Common query execution boundary. Adapters expose one optional native
4
- # hook; all other query behavior remains in the shared interpreter.
5
- # Ordering (the meaning of an ask's answer order) and InMemory (the
6
- # fallback engine for stores with no query engine of their own) are
7
- # its collaborators — query/ordering.rb and query/in_memory.rb.
3
+ # Query execution boundary: an adapter may expose one native `query` hook, and everything
4
+ # else runs in the shared interpreter (`query/ordering.rb`, `query/in_memory.rb`).
8
5
  module Query
9
- # A declared query the chosen adapter cannot honour as written — refused
10
- # by `validate!` before the adapter runs it.
6
+ # A declared query the chosen adapter cannot honour as written.
11
7
  class Unsupported < StandardError; end
12
8
 
13
9
  module_function
14
10
 
15
11
  # Runs a declared query through the adapter's own `query` hook, if it has one.
16
12
  #
17
- # A nil answer means "no native engine here", and the caller falls back to the shared
18
- # interpreter or to `InMemory.execute`; it never means "no rows", which is `[]`.
13
+ # nil means "no native engine here" and the caller falls back to `InMemory.execute`; no
14
+ # rows is `[]`.
19
15
  #
20
- # @param repository [Persistence::AppendOnly, Object] the repository whose `adapter` is
21
- # asked, or a bare persistence adapter (anything that does not answer `adapter`)
22
- # @param specification [QuerySpecification::Common::Options] the declared query: a
23
- # `Bluebook::Query`, a read-model specification, or a delegator wrapping one
24
- # @param args [Hash{Symbol => Object}] the caller's arguments, which a where-clause,
25
- # limit or offset written as a Symbol reads its value from
26
- # @param context [Hash{Symbol => Object}] passed through to the adapter: `domain:`,
27
- # `aggregate:` and, where a comparator needs one, `registry:`
28
- # @return [Array<Runtime::Instance>, nil] the matching records, filtered, ordered and
29
- # paged by the adapter (`[]` when none match); nil if the adapter has no `query`
30
- # method
31
- # @raise [Ports::Query::Unsupported] if the specification combines cursor and offset
32
- # pagination, or asks for inspection the adapter cannot provide
33
- # @raise [Runtime::WiringError] if a where-clause names an operation no comparator
34
- # handles (raised by the in-memory engine behind `Memory`, `Heki` and the like)
35
- # @raise [ArgumentError] if a SQL-backed adapter cannot compile a where-clause's
36
- # operator
16
+ # @param repository [Persistence::AppendOnly, Object] a repository, or a bare adapter
17
+ # @param specification [QuerySpecification::Common::Options] the declared query
18
+ # @param args [Hash{Symbol => Object}] values for Symbol-valued wheres, limit and offset
19
+ # @param context [Hash{Symbol => Object}] passed to the adapter: `domain:`, `aggregate:`,
20
+ # and `registry:` where a comparator needs one
21
+ # @return [Array<Runtime::Instance>, nil] matches, or nil if the adapter has no `query`
22
+ # @raise [Ports::Query::Unsupported] see `validate!`
37
23
  def execute(repository, specification, args = {}, context: {})
38
24
  adapter = repository.respond_to?(:adapter) ? repository.adapter : repository
39
25
  return nil unless adapter.respond_to?(:query)
@@ -42,17 +28,8 @@ module Hecks
42
28
  adapter.query(specification, args, context: context)
43
29
  end
44
30
 
45
- # Refuses a specification the adapter about to run it cannot honour.
46
- #
47
- # Inspection is honoured by an adapter with an `inspect_query` method, or, for the
48
- # `"sql"` mode alone, by any adapter with a native `query`.
49
- #
50
- # @param specification [QuerySpecification::Common::Options] the declared query to check
51
- # @param adapter [Object] the persistence adapter that would run it; only what it
52
- # responds to (`inspect_query`, `query`) is read
53
- # @return [void]
54
- # @raise [Ports::Query::Unsupported] if the specification declares both a cursor and
55
- # an offset, or asks for inspection the adapter cannot provide
31
+ # Refuses cursor with offset pagination, and inspection the adapter cannot provide (`"sql"`
32
+ # mode needs only a native `query`, other modes an `inspect_query` method).
56
33
  def validate!(specification, adapter)
57
34
  raise Unsupported, "a query cannot combine cursor and offset pagination" if specification.cursor && specification.offset
58
35
 
data/lib/hecks/ports.rb CHANGED
@@ -1,15 +1,9 @@
1
1
  # Hecks::Ports
2
2
  #
3
- # The runtime's named boundaries. Each port is a file beside this one —
4
- # `ports/persistence.rb`, `ports/query.rb`, … — and a port with supporting
5
- # cast keeps it in a same-named directory (`ports/persistence/` holds the
6
- # binding policy, the journal-translation lineage, the repository factory).
7
- # The `.port` files beside them are the DSL declarations the meta-validator
8
- # and the Folder adapter load as data.
3
+ # The runtime's named boundaries; each port is a file under `ports/`.
9
4
 
10
5
  module Hecks
11
- # Declared empty here — each `ports/*.rb` file required below reopens it
12
- # to add its own port; see the header comment above for what a port is.
6
+ # The runtime's named boundaries; each port is a file under `ports/`.
13
7
  module Ports
14
8
  end
15
9
  end
@@ -2,28 +2,12 @@ require_relative "../projector"
2
2
 
3
3
  module Hecks
4
4
  module Projections
5
- # **The bootstrap-window fallbacks, projected** — lib/hecks/bluebook/dsl/
6
- # bootstrap_table.rb rendered from the chapter's own Keyword rows.
5
+ # Projects lib/hecks/bluebook/dsl/bootstrap_table.rb from the chapter's Keyword rows.
6
+ # Committed, not built at boot: it is read before the grammar table exists.
7
7
  #
8
8
  # Projector.call(:bootstrap_table, bluebook: <the Bluebook chapter>)
9
9
  #
10
- # While `MetaValidator.bootstrapping?` the grammar table does not exist
11
- # yet, so `WordGate#method_missing` and `RuleReference#lookup` cannot
12
- # read `calls:`/`resolves_via:`/`disambiguator:` off it — this table is
13
- # what they read instead.
14
- #
15
- # A partition, not a filter: every live row lands in the table, not only
16
- # the ones a bootstrap chapter happens to call. Picking a subset by
17
- # grepping which words the core chapters use during bootstrap would risk
18
- # quietly dropping any word a chapter starts using later. Including
19
- # every row instead costs nothing: a builder with its own `def` never
20
- # reaches `method_missing` at all, so a row no bootstrap chapter calls
21
- # is simply never read.
22
- #
23
- # The table cannot be built at boot for the same reason it exists: it
24
- # is read before the grammar it comes from has been assembled. So it is
25
- # committed, like lib/hecks/vocabulary.rb, and spec/bootstrap_table_
26
- # spec.rb re-projects it in memory and refuses a diff.
10
+ # Every live row is included, not only those a bootstrap chapter calls.
27
11
  module BootstrapTable
28
12
  extend Projector::Target
29
13
 
@@ -45,20 +29,13 @@ module Hecks
45
29
 
46
30
  module_function
47
31
 
48
- # Projects the bootstrap fallback table — the only real work this projector
49
- # does, `bluebook` unused because the table is the whole language's grammar,
50
- # not any one chapter's.
32
+ # Projects the bootstrap fallback table; both arguments are ignored (the table is
33
+ # the whole grammar) and exist for the `Projector::Target` calling convention.
51
34
  #
52
- # @param bluebook [Bluebook::Chapter] ignored; present to satisfy the
53
- # `Projector::Target` calling convention
54
- # @param options [Hash{Symbol => Object}] ignored; present to satisfy the
55
- # `Projector::Target` calling convention
56
35
  # @return [String] the rendered `lib/hecks/bluebook/dsl/bootstrap_table.rb` source
57
36
  def call(bluebook:, options: {}) = render(bluebook)
58
37
 
59
- # Retired rows are out of the language; admitted and deprecated rows
60
- # still dispatch — the same `status != "retired"` reading
61
- # `GenericDispatch.shape_for` gives the live table.
38
+ # Every keyword row that is not retired; admitted and deprecated rows still dispatch.
62
39
  #
63
40
  # @return [Array<Hash{Symbol => String}>] every non-retired keyword row, each with
64
41
  # at least `:context`, `:word`, `:status`, `:calls`, `:resolves_via` and
@@ -67,11 +44,8 @@ module Hecks
67
44
  Bluebook::MetaValidator::SyntaxBoot.call[:keywords].reject { |row| row[:status] == "retired" }
68
45
  end
69
46
 
70
- # `[context, word] => :method` — WordGate's own key order.
71
- #
72
- # An overloaded word has one row per argument shape, and they all
73
- # name the same method. Two that don't would make the table keep
74
- # whichever came last, so that is refused instead.
47
+ # `[context, word] => :method`, in WordGate's key order.
48
+ # Overloaded rows must all name the same method; a mismatch raises rather than last-wins.
75
49
  #
76
50
  # @param rows [Array<Hash{Symbol => String}>] the keyword rows to build from,
77
51
  # defaulting to every live one
@@ -90,9 +64,7 @@ module Hecks
90
64
  end
91
65
  end
92
66
 
93
- # `[word, context] => { resolves_via:, disambiguator: }` —
94
- # RuleReference's own key order, blank columns omitted, the same
95
- # shape its live `lookup` answers.
67
+ # `[word, context] => { resolves_via:, disambiguator: }`, in RuleReference's key order.
96
68
  #
97
69
  # @param rows [Array<Hash{Symbol => String}>] the keyword rows to build from,
98
70
  # defaulting to every live one
@@ -106,13 +78,9 @@ module Hecks
106
78
  end
107
79
  end
108
80
 
109
- # Renders the bootstrap table as committable Ruby source — `CALLS` and
110
- # `RESOLVES` frozen Hash literals under the generated-file header.
81
+ # Renders the `CALLS` and `RESOLVES` frozen Hash literals as Ruby source.
111
82
  #
112
- # @param _bluebook [Bluebook::Chapter] ignored; the table draws from the whole
113
- # language's grammar, not this argument
114
- # @return [String] the full `lib/hecks/bluebook/dsl/bootstrap_table.rb` source,
115
- # ready to write to disk
83
+ # @return [String] the full `lib/hecks/bluebook/dsl/bootstrap_table.rb` source
116
84
  def render(_bluebook)
117
85
  rows = live_keywords
118
86
  calls_lines = calls(rows).map { |key, target| " #{key.inspect} => #{target.inspect}" }
@@ -5,25 +5,12 @@ module Hecks
5
5
  module Projections
6
6
  module Deploy
7
7
  module Fargate
8
- # Fills the optional sections of a rendered Fargate template.
9
- #
10
- # The template text carries `# TMPL:<name>` marker lines where an
11
- # optional section belongs. `apply` replaces each with what the stack's
12
- # `Settings::Plan` calls for, and with nothing when the plan sets
13
- # nothing there, so a world that uses none of the optional settings
14
- # renders the template it always did.
8
+ # Fills the optional `# TMPL:<name>` sections of a rendered Fargate template with
9
+ # what the plan calls for, or nothing when a world uses none of them.
15
10
  module Assembly
16
11
  module_function
17
12
 
18
13
  # Replaces every optional-section marker in a rendered template.
19
- #
20
- # @param template [String] the rendered template holding `# TMPL:` marker lines
21
- # @param plan [Settings::Plan] the stack's checked optional settings
22
- # @param context [Hash{Symbol => Object}] `:stack_name`, `:vpc_ref`, `:listener_id`,
23
- # `:alb_id`, `:distribution_id` and `:db_secret_ref`
24
- # @return [String] the template with the markers replaced
25
- # @raise [ArgumentError] if `domain_env` removes a variable the generator does not set, or
26
- # the finished template declares one logical id or parameter twice
27
14
  def apply(template, plan, context)
28
15
  text = override_domain_env(template, plan.domain_env)
29
16
  sections(plan, context).each { |marker, block| text = Yaml.splice(text, marker, block) }
@@ -7,38 +7,7 @@ module Hecks
7
7
  module Deploy
8
8
  module Fargate
9
9
  # The CloudFront distribution in front of the load balancer.
10
- #
11
- # With no `cdn` setting the stack gets `default_yaml`: the default
12
- # certificate, one origin, and one behavior that caches nothing. A
13
- # `cdn` setting replaces that with a distribution described by the
14
- # world.
15
- #
16
- # ## Settings
17
- #
18
- # `cdn` is a hash with these optional keys:
19
- #
20
- # - `aliases`: hostnames the distribution answers to. Needs `certificate_arn`.
21
- # - `certificate_arn`: an `ACM` certificate in us-east-1, or an intrinsic such as
22
- # `"!Ref CertArn"`.
23
- # - `minimum_protocol`: the TLS policy for the certificate; `TLSv1.2_2021` by default.
24
- # - `origin_id`: the id of the load-balancer origin; `<AlbId>Origin` by default.
25
- # - `origin_ssl_protocols`: the TLS versions CloudFront may use to reach the origin, such
26
- # as `["TLSv1.2"]`.
27
- # - `explicit_origin_ports`: false leaves `HTTPPort` and `HTTPSPort` unset; true by
28
- # default.
29
- # - `origin_secret`: `{header:, parameter:}` sends a secret header to the origin, filled
30
- # from a `NoEcho` template parameter the stack declares under that name.
31
- # - `extra_origins`: S3 origins, each `{id:, domain_name:, origin_access_control_id:}`.
32
- # - `default_behavior`: `{origin:, viewer_protocol:, methods:, compress:, cache_policy:,
33
- # origin_request_policy:}`.
34
- # - `behaviors`: entries of the same shape with a required `path`; the first match wins,
35
- # so order matters.
36
- # - `retain`: true keeps the distribution when the stack is deleted or replaces it.
37
- #
38
- # A cache or origin-request policy is a managed policy's name (`caching_disabled`,
39
- # `caching_optimized`, `all_viewer`, `all_viewer_except_host`, or `none` to omit an origin
40
- # request policy) or the id of a policy in the account. `methods` is `all`, `read` or
41
- # `get_head`.
10
+ # With no `cdn` setting the stack gets `default_yaml`; settings are in the DSL reference.
42
11
  module Cdn
43
12
  module_function
44
13
 
@@ -64,14 +33,6 @@ module Hecks
64
33
  HOSTNAME = /\A(\*\.)?([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z]{2,}\z/
65
34
 
66
35
  # Reads and checks the `cdn` setting.
67
- #
68
- # @param setting [Hash, nil] the world's `cdn` value, or nil when it sets none
69
- # @param default_origin_id [String] the load-balancer origin's id when `origin_id` is not
70
- # set
71
- # @return [Hash{Symbol => Object}, nil] the checked options with defaults applied, or nil
72
- # for none
73
- # @raise [ArgumentError] if an option is unknown, malformed, or names an origin that does
74
- # not exist
75
36
  def normalize(setting, default_origin_id:)
76
37
  return nil if setting.nil?
77
38
 
@@ -87,9 +48,6 @@ module Hecks
87
48
  end
88
49
 
89
50
  # Lists the template parameters the options need.
90
- #
91
- # @param options [Hash, nil] the checked options from `normalize`
92
- # @return [String] flush-left parameter text, or empty
93
51
  def parameters_yaml(options)
94
52
  secret = options && options[:origin_secret]
95
53
  return "" unless secret
@@ -103,11 +61,6 @@ module Hecks
103
61
  end
104
62
 
105
63
  # Renders the distribution for a set of checked options.
106
- #
107
- # @param options [Hash] the checked options from `normalize`
108
- # @param distribution_id [String] the logical id the distribution is given
109
- # @param alb_id [String] the logical id of the load balancer the origin points at
110
- # @return [String] the flush-left resource text ending in a newline
111
64
  def yaml(options, distribution_id:, alb_id:)
112
65
  lines = ["#{distribution_id}:", " Type: AWS::CloudFront::Distribution"]
113
66
  lines.push(" DeletionPolicy: Retain", " UpdateReplacePolicy: Retain") if options[:retain]
@@ -6,17 +6,8 @@ module Hecks
6
6
  module Cdn
7
7
  module_function
8
8
 
9
- # The distribution a stack gets when its world sets no `cdn` options.
10
- #
11
- # Real HTTPS in front of the load balancer's HTTP-only listener, and
12
- # the one safe caching default the generator can offer: every route
13
- # is treated as session-driven, so nothing is cached. The comment
14
- # inside the rendered block explains why, and reaches the generated
15
- # template unchanged.
16
- #
17
- # @param alb_id [String] the logical id of the load balancer
18
- # @param distribution_id [String] the logical id the distribution is given
19
- # @return [String] the flush-left resource text with its comments, ending in a newline
9
+ # The distribution a stack gets when its world sets no `cdn` options: HTTPS in
10
+ # front of the HTTP-only ALB, caching disabled since every route is session-driven.
20
11
  def default_yaml(alb_id:, distribution_id:)
21
12
  <<~DEFAULT
22
13
  # Real HTTPS (the ALB's own Listener above is HTTP-only —
@@ -2,15 +2,8 @@ module Hecks
2
2
  module Projections
3
3
  module Deploy
4
4
  module Fargate
5
- # Validation for the optional settings a `deployed_to("AwsFargate")`
6
- # block accepts beyond the required ones.
7
- #
8
- # `FargateTarget.Declare` in deploy.bluebook owns the baseline
9
- # settings (`cpu`, `memory`, `port`, `database`, `web`). The keys added
10
- # for multi-container stacks are nested shapes (lists of hashes, maps),
11
- # which that aggregate's flat attributes cannot describe, so they are
12
- # checked here. Every check raises `ArgumentError` naming the setting
13
- # it was reading, so a mistake in a `.world` file points at its line.
5
+ # Validation for the optional Fargate settings beyond the baseline ones.
6
+ # Every check raises `ArgumentError` naming the setting it was reading.
14
7
  module Check
15
8
  module_function
16
9
 
@@ -71,7 +64,7 @@ module Hecks
71
64
  "(letters and digits, starting with a letter), got #{value.inspect}"
72
65
  end
73
66
 
74
- # Checks that a value is a name AWS accepts for a container, repository or stack resource.
67
+ # Checks that a value is a name AWS accepts for a container, repository or stack.
75
68
  #
76
69
  # @param value [Object] the name as written in the world file
77
70
  # @param where [String] the setting's name, used in the error message
@@ -116,7 +109,7 @@ module Hecks
116
109
  # @param min [Integer] the fewest entries allowed
117
110
  # @param max [Integer, nil] the most entries allowed, or nil for no limit
118
111
  # @return [Array<String>] the entries as strings
119
- # @raise [ArgumentError] if the value is not a list of strings or its size is out of range
112
+ # @raise [ArgumentError] if the value is not a list of strings or is out of size range
120
113
  def strings!(value, where, min: 0, max: nil)
121
114
  list = value.is_a?(Array) ? value : nil
122
115
  ok = list&.all? { |item| (item.is_a?(String) || item.is_a?(Symbol)) && !item.to_s.empty? }
@@ -128,9 +121,7 @@ module Hecks
128
121
  end
129
122
 
130
123
  # Checks that a value is a map of names to strings and returns it string-keyed.
131
- #
132
- # A `nil` value is kept: for the domain container's environment it
133
- # removes a default variable.
124
+ # A `nil` value is kept: the domain container's env setting removes a variable with it.
134
125
  #
135
126
  # @param value [Object] the map as written in the world file
136
127
  # @param where [String] the setting's name, used in the error message