hecks 2.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +11 -0
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +18 -99
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres.rb +145 -134
  25. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  26. data/lib/hecks/adapters/driven/prism.rb +7 -30
  27. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  28. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  29. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  30. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  31. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  32. data/lib/hecks/adapters/driven/tenant_provisioner.rb +15 -37
  33. data/lib/hecks/adapters/driven.rb +5 -36
  34. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  35. data/lib/hecks/behaviors/dsl.rb +7 -25
  36. data/lib/hecks/behaviors/expectations.rb +32 -142
  37. data/lib/hecks/behaviors/ir.rb +7 -20
  38. data/lib/hecks/behaviors/rspec.rb +6 -17
  39. data/lib/hecks/behaviors/runner.rb +10 -34
  40. data/lib/hecks/behaviors.rb +4 -8
  41. data/lib/hecks/bluebook/aggregate.rb +9 -75
  42. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  43. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  44. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  45. data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
  46. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  47. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  48. data/lib/hecks/bluebook/assembly.rb +6 -45
  49. data/lib/hecks/bluebook/attribute.rb +12 -61
  50. data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
  51. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  52. data/lib/hecks/bluebook/behaviour/chapter.rb +17 -42
  53. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  54. data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
  55. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  56. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  57. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  58. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  59. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  60. data/lib/hecks/bluebook/behaviour/read_model.rb +38 -26
  61. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  62. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  63. data/lib/hecks/bluebook/capabilities.rb +17 -49
  64. data/lib/hecks/bluebook/chapter.rb +10 -48
  65. data/lib/hecks/bluebook/command.rb +23 -81
  66. data/lib/hecks/bluebook/domain_port.rb +14 -63
  67. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  68. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  69. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  70. data/lib/hecks/bluebook/dsl/binding_proxy.rb +17 -65
  71. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
  72. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
  73. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
  74. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  75. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  76. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
  77. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  78. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  79. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -189
  80. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  81. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  82. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  83. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  84. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  85. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  86. data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
  87. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  88. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  89. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  90. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  91. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  92. data/lib/hecks/bluebook/dsl/world_builder.rb +19 -106
  93. data/lib/hecks/bluebook/entity.rb +13 -71
  94. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  95. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  96. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  97. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  98. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  99. data/lib/hecks/bluebook/expression/resolver.rb +37 -660
  100. data/lib/hecks/bluebook/hexagon.rb +5 -28
  101. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  102. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  103. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  104. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  105. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  106. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  107. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
  108. data/lib/hecks/bluebook/meta_validator/shapes.rb +54 -268
  109. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -308
  110. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  111. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  112. data/lib/hecks/bluebook/meta_validator.rb +79 -349
  113. data/lib/hecks/bluebook/model_check/client_profile.rb +10 -91
  114. data/lib/hecks/bluebook/model_check.rb +102 -600
  115. data/lib/hecks/bluebook/pattern_subset.rb +11 -69
  116. data/lib/hecks/bluebook/process_manager.rb +13 -83
  117. data/lib/hecks/bluebook/project_loader.rb +3 -39
  118. data/lib/hecks/bluebook/project_register.rb +12 -60
  119. data/lib/hecks/bluebook/query.rb +9 -48
  120. data/lib/hecks/bluebook/read_model.rb +57 -81
  121. data/lib/hecks/bluebook/reference.rb +7 -41
  122. data/lib/hecks/bluebook/smoke_test.rb +8 -98
  123. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  124. data/lib/hecks/bluebook/translation.rb +26 -62
  125. data/lib/hecks/bluebook/value_object.rb +11 -36
  126. data/lib/hecks/bluebook.rb +5 -22
  127. data/lib/hecks/cache_dir.rb +84 -0
  128. data/lib/hecks/cli/document.rb +86 -0
  129. data/lib/hecks/cli/ir.rb +45 -0
  130. data/lib/hecks/cli/mcp.rb +31 -0
  131. data/lib/hecks/cli/mcp_door.rb +366 -0
  132. data/lib/hecks/cli/model_check.rb +203 -0
  133. data/lib/hecks/cli/project_cli.rb +90 -0
  134. data/lib/hecks/cli/project_diagrams.rb +36 -0
  135. data/lib/hecks/cli/run.rb +173 -0
  136. data/lib/hecks/cli/smoke_test.rb +45 -0
  137. data/lib/hecks/cli/stores.rb +53 -0
  138. data/lib/hecks/cli.rb +160 -0
  139. data/lib/hecks/construct.rb +8 -34
  140. data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
  141. data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
  142. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  143. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  144. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  145. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  146. data/lib/hecks/embryonaut_bluebook.rb +4 -71
  147. data/lib/hecks/facade/cli_door.rb +24 -106
  148. data/lib/hecks/facade/cli_runner.rb +28 -172
  149. data/lib/hecks/facade/command_request.rb +13 -33
  150. data/lib/hecks/facade/handle.rb +34 -121
  151. data/lib/hecks/facade/json_door.rb +31 -146
  152. data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
  153. data/lib/hecks/facade/surface/chapter.rb +10 -54
  154. data/lib/hecks/facade/surface.rb +8 -23
  155. data/lib/hecks/facade.rb +10 -25
  156. data/lib/hecks/forms/app.rb +15 -70
  157. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  158. data/lib/hecks/forms/field_renderer.rb +17 -156
  159. data/lib/hecks/forms/field_shape.rb +30 -222
  160. data/lib/hecks/forms/html.rb +12 -47
  161. data/lib/hecks/forms/index_renderer.rb +1 -4
  162. data/lib/hecks/forms/page.rb +3 -9
  163. data/lib/hecks/forms/params.rb +14 -60
  164. data/lib/hecks/forms/port_argument.rb +2 -19
  165. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  166. data/lib/hecks/forms/record_renderer.rb +8 -75
  167. data/lib/hecks/forms/record_table.rb +7 -50
  168. data/lib/hecks/forms/reference_options.rb +3 -30
  169. data/lib/hecks/forms/value_object_shape.rb +8 -35
  170. data/lib/hecks/forms.rb +5 -33
  171. data/lib/hecks/fqn.rb +5 -12
  172. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  173. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  174. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  175. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  176. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  177. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  178. data/lib/hecks/framework.rb +11 -80
  179. data/lib/hecks/freezer.rb +5 -39
  180. data/lib/hecks/grammar/expression.bluebook +15 -40
  181. data/lib/hecks/grammar/translation.bluebook +3 -6
  182. data/lib/hecks/grammar.rb +16 -41
  183. data/lib/hecks/ir.rb +14 -83
  184. data/lib/hecks/language/adapter.bluebook +2 -7
  185. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  186. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  187. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
  188. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  189. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  190. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  191. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  192. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  193. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  194. data/lib/hecks/language/bluebook/query.bluebook +12 -43
  195. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  196. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  197. data/lib/hecks/language/bluebook/vocabulary.bluebook +98 -197
  198. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  199. data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
  200. data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
  201. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  202. data/lib/hecks/language/oidc.json +35 -0
  203. data/lib/hecks/language/port.bluebook +4 -17
  204. data/lib/hecks/language/translation/translation.bluebook +3 -9
  205. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  206. data/lib/hecks/language/world/wiring.bluebook +1 -3
  207. data/lib/hecks/language/world/world.bluebook +5 -7
  208. data/lib/hecks/literal.rb +8 -50
  209. data/lib/hecks/mcp_door_scope.rb +95 -0
  210. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  211. data/lib/hecks/naming.rb +29 -137
  212. data/lib/hecks/ports/access_control.rb +7 -23
  213. data/lib/hecks/ports/agent/answers.rb +5 -23
  214. data/lib/hecks/ports/agent.rb +47 -172
  215. data/lib/hecks/ports/authentication.rb +12 -39
  216. data/lib/hecks/ports/authorization.rb +16 -43
  217. data/lib/hecks/ports/clock.rb +5 -45
  218. data/lib/hecks/ports/extraction.rb +7 -12
  219. data/lib/hecks/ports/identity_assignment.rb +8 -29
  220. data/lib/hecks/ports/identity_generation.rb +6 -29
  221. data/lib/hecks/ports/identity_resolution.rb +2 -10
  222. data/lib/hecks/ports/key_vault.rb +9 -45
  223. data/lib/hecks/ports/persistence/append_only.rb +62 -65
  224. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  225. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  226. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  227. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  228. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
  229. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
  231. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +7 -26
  232. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
  233. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  241. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
  242. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  243. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  244. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  245. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  246. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  247. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
  248. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  249. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
  250. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  251. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  252. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  253. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  254. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  255. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  256. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
  257. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +22 -122
  258. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  259. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  260. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  261. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  262. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  263. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  264. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  265. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  266. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  267. data/lib/hecks/ports/persistence/state_codec.rb +23 -103
  268. data/lib/hecks/ports/persistence.rb +7 -14
  269. data/lib/hecks/ports/projection.rb +42 -84
  270. data/lib/hecks/ports/query/in_memory.rb +10 -58
  271. data/lib/hecks/ports/query/ordering.rb +11 -32
  272. data/lib/hecks/ports/query.rb +14 -37
  273. data/lib/hecks/ports.rb +2 -8
  274. data/lib/hecks/projections/bootstrap_table.rb +11 -43
  275. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  276. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  277. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  278. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  279. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  280. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  281. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  282. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  283. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  284. data/lib/hecks/projections/deploy/fargate.rb +35 -202
  285. data/lib/hecks/projections/deploy/lambda.rb +151 -679
  286. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  287. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  288. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  289. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  290. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  291. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  292. data/lib/hecks/projections/deploy/preview/template.rb +2 -58
  293. data/lib/hecks/projections/deploy/preview.rb +2 -67
  294. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  295. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  296. data/lib/hecks/projections/deploy/shared.rb +47 -146
  297. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  298. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  299. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  300. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  301. data/lib/hecks/projections/diagrams.rb +20 -582
  302. data/lib/hecks/projections/glossary/html.rb +14 -130
  303. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  304. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  305. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  306. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  307. data/lib/hecks/projections/glossary.rb +30 -222
  308. data/lib/hecks/projections/ir.rb +3 -10
  309. data/lib/hecks/projections/model/deviations.rb +15 -42
  310. data/lib/hecks/projections/model.rb +12 -51
  311. data/lib/hecks/projections/oidc.rb +12 -56
  312. data/lib/hecks/projections/parser_table.rb +9 -28
  313. data/lib/hecks/projections/reference.rb +9 -16
  314. data/lib/hecks/projections/rust_vocabulary.rb +12 -250
  315. data/lib/hecks/projections/shape.rb +3 -29
  316. data/lib/hecks/projections/statements.rb +7 -86
  317. data/lib/hecks/projections/vocabulary.rb +6 -22
  318. data/lib/hecks/projections.rb +2 -16
  319. data/lib/hecks/projector/cli_projector.rb +60 -375
  320. data/lib/hecks/projector/docs_projector.rb +10 -201
  321. data/lib/hecks/projector/exporter.rb +46 -138
  322. data/lib/hecks/projector/ir_projector.rb +2 -9
  323. data/lib/hecks/projector/narrate_projector.rb +15 -189
  324. data/lib/hecks/projector/target.rb +13 -76
  325. data/lib/hecks/projector.rb +30 -121
  326. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  327. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  328. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  329. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  330. data/lib/hecks/query_specification/common/options.rb +2 -6
  331. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  332. data/lib/hecks/query_specification/field_path.rb +37 -77
  333. data/lib/hecks/query_specification/hop_path.rb +12 -76
  334. data/lib/hecks/release/gem_pin.rb +2 -26
  335. data/lib/hecks/release/runner/ci_publisher.rb +93 -0
  336. data/lib/hecks/release/runner/commands.rb +66 -0
  337. data/lib/hecks/release/runner/console.rb +52 -0
  338. data/lib/hecks/release/runner/gem_publisher.rb +43 -0
  339. data/lib/hecks/release/runner/git.rb +48 -0
  340. data/lib/hecks/release/runner/npm_publisher.rb +75 -0
  341. data/lib/hecks/release/runner/preflight.rb +104 -0
  342. data/lib/hecks/release/runner/published.rb +55 -0
  343. data/lib/hecks/release/runner/tagger.rb +80 -0
  344. data/lib/hecks/release/runner.rb +215 -0
  345. data/lib/hecks/rendering.rb +4 -26
  346. data/lib/hecks/router/namespace_installer.rb +12 -36
  347. data/lib/hecks/router.rb +4 -8
  348. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  349. data/lib/hecks/runtime/boot_gates.rb +3 -18
  350. data/lib/hecks/runtime/caller.rb +19 -59
  351. data/lib/hecks/runtime/capability_graph.rb +5 -21
  352. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  353. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
  354. data/lib/hecks/runtime/command_interpreter.rb +125 -307
  355. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  356. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  357. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  358. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  359. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  360. data/lib/hecks/runtime/dependency_planning.rb +30 -102
  361. data/lib/hecks/runtime/dispatcher.rb +82 -241
  362. data/lib/hecks/runtime/entity_element.rb +40 -462
  363. data/lib/hecks/runtime/entity_interpreter.rb +65 -220
  364. data/lib/hecks/runtime/errors.rb +32 -115
  365. data/lib/hecks/runtime/event.rb +3 -25
  366. data/lib/hecks/runtime/identity.rb +18 -154
  367. data/lib/hecks/runtime/instance.rb +18 -150
  368. data/lib/hecks/runtime/interpreting.rb +11 -70
  369. data/lib/hecks/runtime/invocation.rb +28 -164
  370. data/lib/hecks/runtime/loader.rb +48 -186
  371. data/lib/hecks/runtime/outbox.rb +38 -261
  372. data/lib/hecks/runtime/policy_interpreter.rb +38 -200
  373. data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
  374. data/lib/hecks/runtime/query_interpreter.rb +45 -187
  375. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  376. data/lib/hecks/runtime/read_model_interpreter.rb +139 -208
  377. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  378. data/lib/hecks/runtime/reference_hop.rb +8 -81
  379. data/lib/hecks/runtime/refusal_wording.rb +8 -89
  380. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  381. data/lib/hecks/runtime/registry/verification.rb +52 -225
  382. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  383. data/lib/hecks/runtime/registry.rb +103 -244
  384. data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
  385. data/lib/hecks/runtime/routing.rb +4 -15
  386. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  387. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  388. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  389. data/lib/hecks/runtime/tenant_check.rb +6 -68
  390. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  391. data/lib/hecks/runtime/value/admission.rb +16 -67
  392. data/lib/hecks/runtime/value/coercion.rb +155 -641
  393. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  394. data/lib/hecks/runtime/value.rb +12 -84
  395. data/lib/hecks/runtime.rb +17 -65
  396. data/lib/hecks/storehouse.rb +146 -567
  397. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
  398. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  399. data/lib/hecks/vendoring/git_environment.rb +2 -8
  400. data/lib/hecks/vendoring/git_source.rb +4 -10
  401. data/lib/hecks/vendoring.rb +7 -46
  402. data/lib/hecks/version.rb +3 -14
  403. data/lib/hecks/vocabulary.rb +5 -0
  404. data/lib/hecks.rb +32 -82
  405. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  406. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  407. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  408. metadata +30 -59
  409. data/lib/hecks/bench/cli.rb +0 -74
  410. data/lib/hecks/bench/environment.rb +0 -100
  411. data/lib/hecks/bench/postgres_probe.rb +0 -41
  412. data/lib/hecks/bench/report.rb +0 -116
  413. data/lib/hecks/bench/ruby_runner.rb +0 -151
  414. data/lib/hecks/bench/run.rb +0 -55
  415. data/lib/hecks/bench/rust_runner.rb +0 -165
  416. data/lib/hecks/bench/stats.rb +0 -75
  417. data/lib/hecks/bench/suite.rb +0 -172
  418. data/lib/hecks/bench/workload.rb +0 -137
  419. data/lib/hecks/bench.rb +0 -28
  420. data/lib/hecks/codemod.rb +0 -443
  421. data/lib/hecks/corpus.rb +0 -479
  422. data/lib/hecks/doc/reference.rb +0 -585
  423. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -684
  424. data/lib/hecks/fuzzing/combination_miner.rb +0 -178
  425. data/lib/hecks/fuzzing/concurrent_dispatch.rb +0 -469
  426. data/lib/hecks/fuzzing/coverage_campaign.rb +0 -161
  427. data/lib/hecks/fuzzing/differential.rb +0 -192
  428. data/lib/hecks/fuzzing/domain_generator.rb +0 -871
  429. data/lib/hecks/fuzzing/era_boundary.rb +0 -154
  430. data/lib/hecks/fuzzing/form_census.rb +0 -285
  431. data/lib/hecks/fuzzing/generated_domain_check.rb +0 -171
  432. data/lib/hecks/fuzzing/invalid_value_generator.rb +0 -125
  433. data/lib/hecks/fuzzing/isolated_boot.rb +0 -658
  434. data/lib/hecks/fuzzing/nondeterministic.rb +0 -79
  435. data/lib/hecks/fuzzing/persistence_parity.rb +0 -253
  436. data/lib/hecks/fuzzing/properties/corrections.rb +0 -125
  437. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +0 -688
  438. data/lib/hecks/fuzzing/properties/guards.rb +0 -398
  439. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +0 -399
  440. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +0 -137
  441. data/lib/hecks/fuzzing/properties/outbox.rb +0 -180
  442. data/lib/hecks/fuzzing/properties/querying.rb +0 -260
  443. data/lib/hecks/fuzzing/properties.rb +0 -267
  444. data/lib/hecks/fuzzing/qa_settings.rb +0 -164
  445. data/lib/hecks/fuzzing/replay.rb +0 -930
  446. data/lib/hecks/fuzzing/rotation_priority.rb +0 -114
  447. data/lib/hecks/fuzzing/rust_gap_manifest.rb +0 -139
  448. data/lib/hecks/fuzzing/self_consistency.rb +0 -825
  449. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +0 -532
  450. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +0 -171
  451. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +0 -127
  452. data/lib/hecks/fuzzing/sequence_generator/picker.rb +0 -116
  453. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +0 -138
  454. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +0 -344
  455. data/lib/hecks/fuzzing/sequence_generator.rb +0 -311
  456. data/lib/hecks/fuzzing/shrinker.rb +0 -309
  457. data/lib/hecks/fuzzing/structural_skips.rb +0 -53
  458. data/lib/hecks/fuzzing/sweep_depth.rb +0 -61
  459. data/lib/hecks/fuzzing/target_capabilities.rb +0 -255
  460. data/lib/hecks/fuzzing/value_generator.rb +0 -340
  461. data/lib/hecks/fuzzing.rb +0 -23
  462. data/lib/hecks/grammar/evolve.rb +0 -524
  463. data/lib/hecks/query_ir.rb +0 -482
@@ -8,109 +8,8 @@ require_relative "fargate/assembly"
8
8
  module Hecks
9
9
  module Projections
10
10
  module Deploy
11
- # The AWS Fargate deploy target. An export
12
- # (`Projector::Target#projects_as`'s own `needs_world: true`), the
13
- # same shape `Lambda` is — it reads a domain's own
14
- # `deployed_to("AwsFargate")` `.world` settings, not only its
15
- # declaration.
16
- #
17
- # `bin/project_deploy` finds and boots the domain's own chapter and
18
- # its `.world`/`.hecksagon` bindings, calls this through
19
- # `Projector.call(:aws_fargate, bluebook:, options:, world:)`, and
20
- # writes the returned tree.
21
- #
22
- # ## What this generates
23
- #
24
- # A plain CloudFormation stack — an `AWS::ECR::Repository`, an
25
- # `AWS::ECS::TaskDefinition` (`RequiresCompatibilities: [FARGATE]`,
26
- # `NetworkMode: awsvpc`) running one container built from the
27
- # domain's own `rust/host`, an `AWS::ECS::Service` behind an
28
- # Application Load Balancer fronted by an `AWS::CloudFront::
29
- # Distribution` (real HTTPS, and a `DefaultCacheBehavior` pinned to
30
- # Managed-CachingDisabled — see that resource's own comment for
31
- # why nothing more permissive is a safe default here), and
32
- # least-privilege task execution/task roles — plus the same private
33
- # VPC/RDS-or-Aurora instance and temporary era-minting bastion
34
- # `Lambda` generates, via `Shared`.
35
- #
36
- # No SAM: this is deployed with plain `aws cloudformation deploy`,
37
- # never `sam deploy`, so there is no `samconfig.toml` here. A
38
- # `Dockerfile` packages `rust/host`'s own compiled binary — built by
39
- # the generated Makefile before `docker build` ever runs, the same
40
- # "build outside the container, ship the artifact" shape a
41
- # tebako-pressed Ruby binary's Dockerfile already uses.
42
- #
43
- # ## What this assumes, and does not build
44
- #
45
- # `rust/host` runs as a long-lived HTTP server on this domain's own
46
- # `port` here, not as a Lambda custom-runtime process (`bootstrap`,
47
- # `Lambda`'s own binary): `HECKS_SERVE_MODE: "1"` (below, in
48
- # `ContainerDefinitions[0].Environment`) is `rust/host/src/main.rs`'s
49
- # own top-of-`main` switch into `server.rs`'s axum-based server,
50
- # which answers this stack's own `GET /` health check with a bare,
51
- # dispatch-free `200` and routes every other request through the
52
- # same per-invocation dispatch logic the Lambda target's `bootstrap`
53
- # binary already runs — see `server.rs`'s own header for the
54
- # concurrency reasoning (the boot-time Postgres client is already
55
- # `Arc<Mutex<...>>`-shared, and already anticipated exactly this,
56
- # per `dispatch.rs`'s own comment on `handle`'s locking).
57
- #
58
- # Sidecars and ARM64 are generated, not assumed: the Dockerfile
59
- # COPYs `#{domain_name}.wasm`/`.ir.json` next to the host binary,
60
- # the task sets `HECKS_WASM_PATH`/`HECKS_IR_PATH`, RuntimePlatform
61
- # is ARM64, and the Makefile cross-compiles with
62
- # aarch64-unknown-linux-gnu (plus the GNU cross-linker on macOS).
63
- # A Shared-mode ALB sits in OwningPublicSubnetAId/BId — the private
64
- # pair is unreachable from the internet (found live on a
65
- # shared-database stack). SessionSecret is always minted: HECKS_SERVE_MODE
66
- # always runs web.rs, which panics on an empty SESSION_SECRET.
67
- #
68
- # ## Settings beyond the baseline
69
- #
70
- # `region`, `cpu`, `memory`, `port`, `database`, `web`, `stack_name`, `stack_prefix`,
71
- # `schema`, `desired_count`, `owner` and `owner_stack` are the baseline settings. A world
72
- # that sets none of the keys below renders the single-container stack described above,
73
- # unchanged. Each key is optional, checked before anything is rendered, and refused with its
74
- # own name when malformed; the module named beside it holds the full shape.
75
- #
76
- # - `domain_container`: renames the domain container, its repository, image-tag parameter
77
- # and health path (`Containers`).
78
- # - `containers`: adds containers to the same task, each with a repository, port, health
79
- # path, environment and secrets (`Containers`).
80
- # - `default_container`: the container the listener forwards to when no route matches
81
- # (`Containers`).
82
- # - `routes`: sends path patterns to a container through listener rules, with priorities
83
- # (`Containers`).
84
- # - `logical_ids`: fixes the logical id of each resource so an existing stack's ids are
85
- # reproduced (`Settings`).
86
- # - `names`: fixes the AWS name of the cluster, log group, service, load balancer, task
87
- # family, the load balancer's security group description, and the task role's database
88
- # policy name (`Settings`).
89
- # - `cdn`: aliases, certificate, behaviors and cache policies, an origin secret header,
90
- # S3 origins and retention (`Cdn`).
91
- # - `alerts`: a `SNS` topic, an email subscription, alarms and a synthetic check
92
- # (`Monitoring`).
93
- # - `buckets`, `generated_secrets` and `session_secret`: extra S3 buckets, generated
94
- # secrets and the session secret's name (`Extras`).
95
- # - `task_policies` and `execution_policies`: extra IAM policies on the task role and the
96
- # execution role (`Extras`).
97
- # - `parameters` and `outputs`: extra template parameters and outputs (`Extras`).
98
- # - `execute_command`: enables `aws ecs execute-command` and grants the task role its SSM
99
- # actions (`Settings`).
100
- # - `health_check_grace_period`: seconds `ECS` ignores failing health checks after a task
101
- # starts (`Settings`).
102
- # - `deregistration_delay`: seconds a target group drains a target (`Settings`).
103
- # - `desired_count_parameter`: makes the desired count a template parameter (`Settings`).
104
- # - `domain_env`: extra environment for the domain container; a name the generator sets
105
- # is replaced, and a nil value removes it (`Settings`).
106
- # - `execution_role_database_grant`: false leaves the database secret out of the execution
107
- # role (`Settings`).
108
- # - `install_dir` and `build_context_dir`: where the Dockerfile installs the host and its
109
- # sidecars, and where it copies them from (`Settings`).
110
- # - `db_name_parameter`: for `database "Shared"`, a parameter naming the shared database
111
- # (`Settings`).
112
- #
113
- # Per-branch preview stacks and the deploy and smoke scripts are not generated here.
11
+ # The AWS Fargate deploy target for `deployed_to("AwsFargate")`: renders a
12
+ # CloudFormation stack (ECR, ECS, ALB, CloudFront) plus the shared VPC/RDS `Shared` builds.
114
13
  module Fargate
115
14
  extend Projector::Target
116
15
 
@@ -118,20 +17,13 @@ module Hecks
118
17
 
119
18
  module_function
120
19
 
121
- # Generates `template.yaml`, `Makefile`, `Dockerfile`, and (unless
122
- # this domain borrows another domain's RDS instance)
123
- # `bastion.yaml` for one domain's `deployed_to("AwsFargate")`
124
- # deploy target.
20
+ # Generates `template.yaml`, `Makefile`, `Dockerfile`, and — unless
21
+ # this domain borrows another domain's RDS instance — `bastion.yaml`.
125
22
  #
126
- # @param bluebook [Bluebook::Behaviour::Chapter] the domain's own booted chapter;
127
- # establishes admission, see `Lambda.call`'s own comment on why generation
128
- # itself reads `options[:cross_domain_registry]` instead
129
- # @param options [Hash] generation options — see `Lambda.call`'s own `@option`
130
- # tags; identical shape, this target reads the same keys
131
- # @return [Hash{String => String}] `"template.yaml"`, `"Makefile"`, `"Dockerfile"`,
132
- # and — unless this domain declares `database "Shared"` — `"bastion.yaml"`
133
- # @raise [ArgumentError] if the domain's own deploy settings conflict, or
134
- # `deploy.bluebook`'s own `FargateTarget.Declare` refuses them
23
+ # @param bluebook [Bluebook::Behaviour::Chapter] the domain's own booted chapter
24
+ # @param options [Hash] generation options; same shape as `Lambda.call`'s
25
+ # @return [Hash{String => String}] the generated file contents, keyed by filename
26
+ # @raise [ArgumentError] if the domain's deploy settings conflict
135
27
  def call(bluebook:, options: {})
136
28
  world = options.fetch(:world)
137
29
  domain = options.fetch(:domain_dir)
@@ -145,8 +37,7 @@ module Hecks
145
37
 
146
38
  deploy_settings = world.for_verb("deployed_to")
147
39
 
148
- # Same override `Lambda.call` applies, for the same reason — see
149
- # that method's own comment.
40
+ # Same tenant override `Lambda.call` applies; see that method's comment.
150
41
  if tenant_options[:tenant]
151
42
  base_stack_name = deploy_settings[:stack_name] || domain_name
152
43
  deploy_settings = deploy_settings.merge(stack_name: "#{base_stack_name}-#{tenant_options[:tenant]}",
@@ -185,11 +76,9 @@ module Hecks
185
76
  aurora = database == "Aurora"
186
77
  shared = database == "Shared"
187
78
  rust_web = target.state[:web].value == "Rust"
188
- # Same file-presence convention Lambda uses: `.env.local` is the
189
- # domain's own gitignored secrets file; `make sync-google-oauth`
190
- # (Lambda) owns the secret's lifecycle. Fargate only needs to
191
- # *declare* GOOGLE_OAUTH_SECRET_ID + a redirect URI parameter —
192
- # the secret itself is never a stack resource.
79
+ # Same `.env.local` convention `Lambda` uses; `make sync-google-oauth`
80
+ # owns the secret's lifecycle. Fargate only declares
81
+ # GOOGLE_OAUTH_SECRET_ID — the secret itself is never a stack resource.
193
82
  google_oauth_present = rust_web &&
194
83
  File.exist?(File.join(domain, ".env.local")) &&
195
84
  File.read(File.join(domain, ".env.local")).match?(/^GOOGLE_CLIENT_ID=\S/)
@@ -201,12 +90,9 @@ module Hecks
201
90
  chapter.policies.select(&:target_domain).map(&:target_domain)
202
91
  }.uniq.sort
203
92
 
204
- # **The storehouse** — identical borrowing `Lambda.call` supports for
205
- # `database "Shared"`; see that method's own comment for the full
206
- # reasoning. `owner`/`owner_stack` stay Ruby-level `deploy_settings`
207
- # reads, never validated `FargateTarget` attributes, for the same
208
- # reason: which domain owns the shared instance is a deploy-time
209
- # wiring fact, not a business invariant.
93
+ # Same "Shared" borrowing `Lambda.call` supports; see that method's
94
+ # comment. `owner`/`owner_stack` stay plain `deploy_settings` reads,
95
+ # never validated attributes — ownership is a deploy-time wiring fact.
210
96
  if shared
211
97
  owner_domain_name = deploy_settings[:owner] or raise ArgumentError, <<~MSG
212
98
  #{world_file}'s deployed_to("AwsFargate") declares database "Shared" but no owner. Add one, e.g.:
@@ -254,25 +140,14 @@ module Hecks
254
140
  secret_intrinsic = aurora ? "!Ref #{db_id}Secret" : "!GetAtt #{db_ref_id}.MasterUserSecret.SecretArn"
255
141
  db_secret_ref = shared ? "OwningDatabaseSecretArn" : secret_sub
256
142
 
257
- # A Fargate service is reached through an Application Load
258
- # Balancer sitting in a public subnet, not invoked directly the
259
- # way a Lambda Function URL is — this domain always needs real
260
- # internet-facing infrastructure (the `ALB`'s own ingress, and
261
- # egress for an `ECR` image pull/CloudWatch Logs/Secrets Manager),
262
- # unlike `Lambda`'s own NAT Gateway, which is opt-in
263
- # (`google_oauth_present`) because a plain dispatch Lambda needs
264
- # no internet access at all. `Shared.vpc_and_database_yaml`'s
265
- # `google_oauth_present:` parameter is exactly this "does this
266
- # domain need its own NAT Gateway/public subnet" question,
267
- # unconditionally true here.
143
+ # Always true here: unlike Lambda's opt-in NAT Gateway, a Fargate task
144
+ # always needs internet-facing infra (ALB ingress, ECR/Logs/Secrets
145
+ # egress), so `Shared.vpc_and_database_yaml`'s NAT Gateway is unconditional.
268
146
  network_needs_internet = true
269
147
 
270
- # Never created at all when `shared` — the compute-side security
271
- # group `Shared.vpc_and_database_yaml` would otherwise declare is
272
- # skipped along with the rest of this domain's own VPC (same as
273
- # `Lambda.call`'s own Shared-mode `VpcConfig`); the `ECS` task and
274
- # the `ALB`-ingress rule both reach through the borrowed owner's
275
- # own security group instead.
148
+ # Never created when `shared` — this domain's own VPC (and its compute
149
+ # security group) is skipped entirely; the task and ALB-ingress rule
150
+ # reach through the borrowed owner's security group instead.
276
151
  compute_security_group_ref = shared ? "!Ref OwningSecurityGroupId" : "!Ref #{ids[:compute_prefix]}SecurityGroup"
277
152
 
278
153
  # `logical_id` stays the derived name in prose (descriptions, comments);
@@ -321,10 +196,9 @@ module Hecks
321
196
  Type: String
322
197
  Default: ""
323
198
  OAUTHPARAMS
324
- # Built outside the template heredoc so Layout/HeredocIndentation
325
- # cannot re-indent YAML that must match SessionSecretRead / env.
326
- # First interpolated line sits at the `\#{...}` column; later lines
327
- # get that same left pad (lambda.rb's own OAUTHPOLICY pattern).
199
+ # Built outside the heredoc so re-indenting the template can't shift
200
+ # this YAML out of sync with SessionSecretRead/env — same pattern
201
+ # as `Lambda`'s own `OAUTHPOLICY`.
328
202
  oauth_task_policy_yaml = google_oauth_present ? <<~OAUTHPOLICY.rstrip : ""
329
203
  - PolicyName: GoogleOauthSecretRead
330
204
  PolicyDocument:
@@ -666,25 +540,13 @@ module Hecks
666
540
  # TMPL:extra_outputs
667
541
  YAML
668
542
 
669
- # Spliced in after the heredoc renders, not interpolated inside
670
- # it — `Lambda.call`'s own comment on `# TMPL:cross_domain_lambda_policies`
671
- # explains why: a `<<~` heredoc's own dedent is computed from its
672
- # raw source, before any `#{...}` evaluates, so a multi-line
673
- # value substituted in at runtime is not reindented by the
674
- # enclosing heredoc a second time — hand-computing a matching
675
- # prefix in advance drifts out of sync the moment anything
676
- # upstream shifts this template's own baseline indentation
677
- # (confirmed the hard way, writing this: the first version
678
- # hardcoded the raw source column instead of the marker's own
679
- # actual rendered one, and every subsequent line landed twice as
680
- # deep as it should have). A plain `String#sub` after the fact,
681
- # capturing the marker's own real indentation, has no such
682
- # interaction with the text it replaces into.
543
+ # Spliced in after the heredoc renders, not interpolated inside it —
544
+ # `<<~` dedents from raw source before `#{...}` evaluates, so a
545
+ # multi-line value can't be reindented a second time by the heredoc.
683
546
  template_yaml = template_yaml.sub(/^([ \t]*)# TMPL:db_env\n/) { db_env_yaml(shared: shared, owner_db_name: owner_db_name, db_ref_id: db_ref_id, db_name: db_name, secret_sub: secret_sub, hecks_schema: hecks_schema, db_name_ref: db_name_ref, base: $1) }
684
- # A multi-line block is indented by the marker's own rendered column, never a
685
- # hand-computed one: the heredoc above is dedented after its interpolations
686
- # evaluate, so a column counted in the source ran twelve too deep and made the
687
- # Google sign-in blocks invalid YAML.
547
+ # Indented by the marker's own rendered column, never a hand-computed
548
+ # one — the heredoc dedents after interpolation, so a source-counted
549
+ # column lands at the wrong depth.
688
550
  template_yaml = Yaml.splice(template_yaml, "oauth_task_policy", "#{oauth_task_policy_yaml}\n")
689
551
  template_yaml = Yaml.splice(template_yaml, "oauth_task_env", "#{oauth_task_env_yaml}\n")
690
552
  template_yaml = template_yaml.sub(/^([ \t]*)# TMPL:cross_domain_fargate_policies\n/) {
@@ -877,27 +739,8 @@ module Hecks
877
739
  stack_name: stack_name, region: region)
878
740
  end
879
741
 
880
- # Renders the container's own `DB_HOST`/`DB_NAME`/`DB_SECRET_ARN`
881
- # (and, when set, `HECKS_SCHEMA`) `Environment` entries — the
882
- # borrowed-owner values for a Shared-mode domain, this domain's
883
- # own RDS/Aurora endpoint otherwise. See `call`'s own comment on
884
- # `# TMPL:db_env` for why this is spliced in after the enclosing
885
- # template renders, not interpolated inline.
886
- #
887
- # @param shared [Boolean] whether this domain borrows another domain's
888
- # RDS instance
889
- # @param owner_db_name [String, nil] the owning domain's own database name,
890
- # used only when `shared`
891
- # @param db_ref_id [String] the logical id `.Endpoint` resolves against
892
- # @param db_name [String] this domain's own database identifier
893
- # @param secret_sub [String] the `${...}`-ready identifier for this domain's
894
- # own database secret
895
- # @param hecks_schema [String, nil] the Postgres schema to set, or nil for none
896
- # @param db_name_ref [String, nil] an intrinsic (such as `!Ref Param`) that names the shared
897
- # database in place of `owner_db_name`, or nil to write the name itself
898
- # @param base [String] the marker line's own rendered indentation whitespace
899
- # @return [String] the rendered `ContainerDefinitions[0].Environment` entries,
900
- # ending in exactly one trailing newline
742
+ # Renders DB_HOST/DB_NAME/DB_SECRET_ARN — spliced in after `call`'s
743
+ # template heredoc renders; see its `# TMPL:db_env` comment for why.
901
744
  def db_env_yaml(shared:, owner_db_name:, db_ref_id:, db_name:, secret_sub:, hecks_schema:, base:, db_name_ref: nil)
902
745
  lines =
903
746
  if shared
@@ -924,19 +767,9 @@ module Hecks
924
767
  lines.map { |line| "#{base}#{line}" }.join("\n") + "\n"
925
768
  end
926
769
 
927
- # Renders the cross-domain policy's own least-privilege invoke
928
- # grant as a plain `AWS::IAM::Role` `Policies` list entry — the
929
- # `PolicyName`/`PolicyDocument` shape that resource type requires,
930
- # unlike the bare `{Statement: [...]}` shorthand
931
- # `Shared.cross_domain_invoke_policy_yaml` renders for SAM's own
932
- # `AWS::Serverless::Function.Policies` property. Not called at all
933
- # when `targets` is empty — see `call`'s own `# TMPL:cross_domain_fargate_policies`
934
- # splice.
935
- #
936
- # @param targets [Array<String>] the domain names this stack's `across:` targets
937
- # declare
938
- # @param base [String] the marker line's own rendered indentation whitespace
939
- # @return [String] one `Policies` list entry, ending in exactly one trailing newline
770
+ # Renders one `AWS::IAM::Role` `Policies` entry per cross-domain target —
771
+ # the shape that resource type requires, unlike the bare shorthand
772
+ # `Shared.cross_domain_invoke_policy_yaml` renders for SAM.
940
773
  def cross_domain_fargate_policy_yaml(targets, base)
941
774
  resources = targets.map { |target|
942
775
  "#{base} - !Sub \"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:hecks-#{target.downcase}\""