hecks 3.5.0 → 3.6.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 (1088) hide show
  1. checksums.yaml +4 -4
  2. data/examples/pizzas/bluebook/hecksagon/mock_stripe_payment_adapter.rb +1 -1
  3. data/lib/hecks/adapters/driven/claude_code.rb +11 -7
  4. data/lib/hecks/adapters/driven/d1/connection.rb +90 -0
  5. data/lib/hecks/adapters/driven/d1.rb +48 -314
  6. data/lib/hecks/adapters/driven/folder.rb +20 -10
  7. data/lib/hecks/adapters/driven/google_authentication.rb +18 -4
  8. data/lib/hecks/adapters/driven/governance_authorization.rb +2 -2
  9. data/lib/hecks/adapters/driven/heki/journal.rb +11 -10
  10. data/lib/hecks/adapters/driven/heki/saga_store.rb +4 -6
  11. data/lib/hecks/adapters/driven/heki/sagas.rb +55 -0
  12. data/lib/hecks/adapters/driven/heki.rb +21 -66
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +37 -12
  14. data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
  15. data/lib/hecks/adapters/driven/lambda.rb +1 -8
  16. data/lib/hecks/adapters/driven/memory/outbox_rows.rb +76 -0
  17. data/lib/hecks/adapters/driven/memory/shared_elements/values.rb +117 -0
  18. data/lib/hecks/adapters/driven/memory/shared_elements.rb +10 -97
  19. data/lib/hecks/adapters/driven/memory.rb +3 -65
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +29 -26
  21. data/lib/hecks/adapters/driven/postgres/ddl.rb +50 -0
  22. data/lib/hecks/adapters/driven/postgres/dialect.rb +93 -0
  23. data/lib/hecks/adapters/driven/postgres/events.rb +57 -0
  24. data/lib/hecks/adapters/driven/postgres/journal.rb +127 -0
  25. data/lib/hecks/adapters/driven/postgres/outbox.rb +39 -31
  26. data/lib/hecks/adapters/driven/postgres/repository.rb +190 -0
  27. data/lib/hecks/adapters/driven/postgres/sagas.rb +72 -0
  28. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +13 -41
  29. data/lib/hecks/adapters/driven/postgres.rb +61 -528
  30. data/lib/hecks/adapters/driven/prism.rb +1 -1
  31. data/lib/hecks/adapters/driven/sql_query_builder.rb +45 -53
  32. data/lib/hecks/adapters/driven/sql_value_members.rb +57 -0
  33. data/lib/hecks/adapters/driven/sqlite/codec.rb +32 -29
  34. data/lib/hecks/adapters/driven/sqlite/ddl.rb +68 -0
  35. data/lib/hecks/adapters/driven/sqlite/dialect.rb +55 -0
  36. data/lib/hecks/adapters/driven/sqlite/events.rb +61 -0
  37. data/lib/hecks/adapters/driven/sqlite/journal.rb +125 -0
  38. data/lib/hecks/adapters/driven/sqlite/outbox.rb +98 -0
  39. data/lib/hecks/adapters/driven/sqlite/projection.rb +82 -63
  40. data/lib/hecks/adapters/driven/sqlite/repository.rb +146 -0
  41. data/lib/hecks/adapters/driven/sqlite/sagas.rb +69 -0
  42. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +8 -55
  43. data/lib/hecks/adapters/driven/sqlite.rb +36 -513
  44. data/lib/hecks/adapters/driven/tenant_provisioner.rb +13 -7
  45. data/lib/hecks/adapters/driving/github_webhook.rb +11 -8
  46. data/lib/hecks/behaviors/dsl.rb +17 -12
  47. data/lib/hecks/behaviors/expectations/boot.rb +81 -0
  48. data/lib/hecks/behaviors/expectations/checks.rb +178 -0
  49. data/lib/hecks/behaviors/expectations/dispatching.rb +93 -0
  50. data/lib/hecks/behaviors/expectations/qualify.rb +81 -0
  51. data/lib/hecks/behaviors/expectations.rb +39 -355
  52. data/lib/hecks/behaviors/rspec.rb +12 -12
  53. data/lib/hecks/behaviors/runner.rb +20 -11
  54. data/lib/hecks/bench/cli.rb +16 -13
  55. data/lib/hecks/bench/environment.rb +1 -1
  56. data/lib/hecks/bench/report.rb +11 -7
  57. data/lib/hecks/bench/ruby_runner.rb +13 -8
  58. data/lib/hecks/bench/rust_runner.rb +19 -11
  59. data/lib/hecks/bench/suite.rb +48 -20
  60. data/lib/hecks/bench/workload.rb +42 -31
  61. data/lib/hecks/bluebook/aggregate.rb +15 -21
  62. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +18 -21
  63. data/lib/hecks/bluebook/assembly/build.rb +12 -7
  64. data/lib/hecks/bluebook/assembly/contracts/read_models.rb +70 -0
  65. data/lib/hecks/bluebook/assembly/contracts/rules.rb +84 -0
  66. data/lib/hecks/bluebook/assembly/contracts/sagas.rb +109 -0
  67. data/lib/hecks/bluebook/assembly/contracts/structure.rb +91 -0
  68. data/lib/hecks/bluebook/assembly/contracts.rb +9 -319
  69. data/lib/hecks/bluebook/assembly/marks.rb +9 -8
  70. data/lib/hecks/bluebook/attribute.rb +13 -10
  71. data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -3
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +26 -13
  73. data/lib/hecks/bluebook/chapter.rb +22 -14
  74. data/lib/hecks/bluebook/command.rb +14 -18
  75. data/lib/hecks/bluebook/domain_port.rb +11 -8
  76. data/lib/hecks/bluebook/dsl/aggregate_builder/correction_sealing.rb +78 -0
  77. data/lib/hecks/bluebook/dsl/aggregate_builder/draining.rb +74 -0
  78. data/lib/hecks/bluebook/dsl/aggregate_builder/query_field_sealing.rb +105 -0
  79. data/lib/hecks/bluebook/dsl/aggregate_builder/query_sealing.rb +121 -0
  80. data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +128 -0
  81. data/lib/hecks/bluebook/dsl/aggregate_builder/rules.rb +84 -0
  82. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +61 -249
  83. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +51 -285
  84. data/lib/hecks/bluebook/dsl/attribute_collector/identity_resolution.rb +113 -0
  85. data/lib/hecks/bluebook/dsl/attribute_collector.rb +58 -117
  86. data/lib/hecks/bluebook/dsl/binding_proxy.rb +24 -19
  87. data/lib/hecks/bluebook/dsl/bluebook_builder/pending_givens.rb +109 -0
  88. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +105 -0
  89. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/event_shapes.rb +126 -0
  90. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/hop_tails.rb +79 -0
  91. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +76 -0
  92. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +65 -0
  93. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/query_hops.rb +123 -0
  94. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/references.rb +112 -0
  95. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +126 -0
  96. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +34 -595
  97. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +18 -107
  98. data/lib/hecks/bluebook/dsl/command_builder/implicit_attributes.rb +132 -0
  99. data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +190 -0
  100. data/lib/hecks/bluebook/dsl/command_builder/owner.rb +22 -0
  101. data/lib/hecks/bluebook/dsl/command_builder/rules.rb +57 -0
  102. data/lib/hecks/bluebook/dsl/command_builder.rb +60 -360
  103. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +19 -13
  104. data/lib/hecks/bluebook/dsl/entity_builder/rules.rb +96 -0
  105. data/lib/hecks/bluebook/dsl/entity_builder/scope.rb +25 -0
  106. data/lib/hecks/bluebook/dsl/entity_builder/sealing.rb +94 -0
  107. data/lib/hecks/bluebook/dsl/entity_builder.rb +35 -169
  108. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +53 -24
  109. data/lib/hecks/bluebook/dsl/hecksagon_builder/chapter_scope.rb +133 -0
  110. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +3 -97
  111. data/lib/hecks/bluebook/dsl/identity_declaration.rb +73 -73
  112. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +7 -3
  113. data/lib/hecks/bluebook/dsl/need_word.rb +1 -1
  114. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +34 -29
  115. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +57 -41
  116. data/lib/hecks/bluebook/dsl/query_builder.rb +12 -15
  117. data/lib/hecks/bluebook/dsl/read_model_builder/sealing.rb +116 -0
  118. data/lib/hecks/bluebook/dsl/read_model_builder.rb +25 -102
  119. data/lib/hecks/bluebook/dsl/rule_reference.rb +26 -12
  120. data/lib/hecks/bluebook/dsl/translation_builder.rb +24 -14
  121. data/lib/hecks/bluebook/dsl/value_object_builder.rb +29 -19
  122. data/lib/hecks/bluebook/dsl/word_gate.rb +34 -27
  123. data/lib/hecks/bluebook/entity.rb +13 -17
  124. data/lib/hecks/bluebook/expression/ast_json/emitters.rb +93 -0
  125. data/lib/hecks/bluebook/expression/ast_json/emitters.rb-e +88 -0
  126. data/lib/hecks/bluebook/expression/ast_json.rb +49 -76
  127. data/lib/hecks/bluebook/expression/ast_reader.rb +95 -28
  128. data/lib/hecks/bluebook/expression/canonical_form.rb +6 -26
  129. data/lib/hecks/bluebook/expression/evaluator/parser.rb +62 -0
  130. data/lib/hecks/bluebook/expression/evaluator/scanning.rb +122 -0
  131. data/lib/hecks/bluebook/expression/evaluator.rb +11 -111
  132. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +28 -44
  133. data/lib/hecks/bluebook/expression/resolver/lookups.rb +77 -0
  134. data/lib/hecks/bluebook/expression/resolver/operations.rb +78 -0
  135. data/lib/hecks/bluebook/expression/resolver/parsing.rb +110 -0
  136. data/lib/hecks/bluebook/expression/resolver/scanning.rb +139 -0
  137. data/lib/hecks/bluebook/expression/resolver/values.rb +115 -0
  138. data/lib/hecks/bluebook/expression/resolver.rb +16 -414
  139. data/lib/hecks/bluebook/{hexagon.rb → hecksagon.rb} +22 -14
  140. data/lib/hecks/bluebook/keyword_fields.rb +42 -0
  141. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +7 -6
  142. data/lib/hecks/bluebook/meta_validator/judge/cells.rb +99 -0
  143. data/lib/hecks/bluebook/meta_validator/judge/dispatching.rb +111 -0
  144. data/lib/hecks/bluebook/meta_validator/judge/identity.rb +108 -0
  145. data/lib/hecks/bluebook/meta_validator/judge/walking.rb +141 -0
  146. data/lib/hecks/bluebook/meta_validator/judge.rb +31 -376
  147. data/lib/hecks/bluebook/meta_validator/modes.rb +137 -0
  148. data/lib/hecks/bluebook/meta_validator/plan/category.rb +44 -0
  149. data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +73 -0
  150. data/lib/hecks/bluebook/meta_validator/plan.rb +38 -122
  151. data/lib/hecks/bluebook/meta_validator/readings/fields.rb +100 -0
  152. data/lib/hecks/bluebook/meta_validator/readings.rb +10 -95
  153. data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +89 -0
  154. data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +96 -0
  155. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -151
  156. data/lib/hecks/bluebook/meta_validator/shapes/helpers.rb +83 -0
  157. data/lib/hecks/bluebook/meta_validator/shapes.rb +8 -75
  158. data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +77 -0
  159. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +31 -95
  160. data/lib/hecks/bluebook/meta_validator/translation_judge/rules.rb +74 -0
  161. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +15 -65
  162. data/lib/hecks/bluebook/meta_validator/verdict_cache/tagging.rb +63 -0
  163. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +22 -43
  164. data/lib/hecks/bluebook/meta_validator/world_judge.rb +8 -4
  165. data/lib/hecks/bluebook/meta_validator.rb +59 -175
  166. data/lib/hecks/bluebook/model_check/lifecycle_checks.rb +122 -0
  167. data/lib/hecks/bluebook/model_check/policy_checks.rb +129 -0
  168. data/lib/hecks/bluebook/model_check/saga_checks.rb +134 -0
  169. data/lib/hecks/bluebook/model_check/verbs.rb +69 -0
  170. data/lib/hecks/bluebook/model_check.rb +73 -413
  171. data/lib/hecks/bluebook/pattern_subset/refusals.rb +54 -0
  172. data/lib/hecks/bluebook/pattern_subset/scan.rb +58 -0
  173. data/lib/hecks/bluebook/pattern_subset.rb +93 -134
  174. data/lib/hecks/bluebook/process_manager.rb +10 -9
  175. data/lib/hecks/bluebook/project_discovery.rb +10 -7
  176. data/lib/hecks/bluebook/project_register.rb +42 -41
  177. data/lib/hecks/bluebook/query.rb +19 -12
  178. data/lib/hecks/bluebook/read_model.rb +41 -39
  179. data/lib/hecks/bluebook/smoke_test.rb +51 -36
  180. data/lib/hecks/bluebook/synthesizer.rb +13 -5
  181. data/lib/hecks/bluebook/translation.rb +12 -12
  182. data/lib/hecks/bluebook.rb +1 -1
  183. data/lib/hecks/chapters.rb +32 -16
  184. data/lib/hecks/cli/behaviors.rb +22 -15
  185. data/lib/hecks/cli/check_era.rb +2 -2
  186. data/lib/hecks/cli/command_table.rb +72 -0
  187. data/lib/hecks/cli/console.rb +10 -7
  188. data/lib/hecks/cli/deploy_template_diff.rb +22 -9
  189. data/lib/hecks/cli/document.rb +14 -10
  190. data/lib/hecks/cli/domain_stub.rb +1 -1
  191. data/lib/hecks/cli/domain_writer.rb +1 -1
  192. data/lib/hecks/cli/expression_projection.rb +8 -6
  193. data/lib/hecks/cli/follow.rb +10 -4
  194. data/lib/hecks/cli/interview_aggregate.rb +132 -0
  195. data/lib/hecks/cli/interview_draft.rb +16 -200
  196. data/lib/hecks/cli/interview_record.rb +130 -0
  197. data/lib/hecks/cli/interview_run.rb +19 -8
  198. data/lib/hecks/cli/interview_session/agent_state.rb +70 -0
  199. data/lib/hecks/cli/interview_session/catalog.rb +76 -0
  200. data/lib/hecks/cli/interview_session/manual_findings.rb +48 -0
  201. data/lib/hecks/cli/interview_session/proposals.rb +90 -0
  202. data/lib/hecks/cli/interview_session.rb +8 -205
  203. data/lib/hecks/cli/interview_shape.rb +13 -6
  204. data/lib/hecks/cli/ir.rb +8 -11
  205. data/lib/hecks/cli/launcher_words.rb +168 -0
  206. data/lib/hecks/cli/model_check/examination.rb +93 -0
  207. data/lib/hecks/cli/model_check/sources.rb +57 -0
  208. data/lib/hecks/cli/model_check.rb +28 -134
  209. data/lib/hecks/cli/project_cli/launcher_source.rb +177 -0
  210. data/lib/hecks/cli/project_cli/templates.rb +106 -0
  211. data/lib/hecks/cli/project_cli.rb +57 -236
  212. data/lib/hecks/cli/project_diagrams.rb +26 -4
  213. data/lib/hecks/cli/project_glossary.rb +19 -9
  214. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +29 -13
  215. data/lib/hecks/cli/release.rb +29 -22
  216. data/lib/hecks/cli/release_gem.rb +12 -6
  217. data/lib/hecks/cli/rspec_io_parallel_files.rb +87 -30
  218. data/lib/hecks/cli/rspec_shard_files.rb +24 -9
  219. data/lib/hecks/cli/run.rb +25 -44
  220. data/lib/hecks/cli/run_expectations.rb +63 -0
  221. data/lib/hecks/cli/seed_semantics_corpus.rb +37 -17
  222. data/lib/hecks/cli/smoke_http/checks.rb +66 -0
  223. data/lib/hecks/cli/smoke_http/settings.rb +63 -0
  224. data/lib/hecks/cli/smoke_http/transport.rb +45 -0
  225. data/lib/hecks/cli/smoke_http.rb +8 -142
  226. data/lib/hecks/cli/smoke_test.rb +18 -4
  227. data/lib/hecks/cli/stores.rb +7 -4
  228. data/lib/hecks/cli/stress_concurrency_specs/reporting.rb +44 -0
  229. data/lib/hecks/cli/stress_concurrency_specs/usage.rb +28 -0
  230. data/lib/hecks/cli/stress_concurrency_specs.rb +82 -80
  231. data/lib/hecks/cli.rb +32 -208
  232. data/lib/hecks/codemod/runner.rb +92 -0
  233. data/lib/hecks/codemod/sweep.rb +94 -0
  234. data/lib/hecks/codemod.rb +22 -165
  235. data/lib/hecks/corpus/routes.rb +34 -0
  236. data/lib/hecks/corpus/rust.rb +193 -0
  237. data/lib/hecks/corpus/sources.rb +46 -0
  238. data/lib/hecks/corpus.rb +28 -265
  239. data/lib/hecks/doc/reference/coverage.rb +70 -0
  240. data/lib/hecks/doc/reference/harvester.rb +55 -0
  241. data/lib/hecks/doc/reference/readme.rb +89 -0
  242. data/lib/hecks/doc/reference/rendering.rb +149 -0
  243. data/lib/hecks/doc/reference.rb +14 -273
  244. data/lib/hecks/doors/cli_door/nesting.rb +34 -0
  245. data/lib/hecks/doors/cli_door/shorthand.rb +85 -0
  246. data/lib/hecks/doors/cli_door.rb +23 -95
  247. data/lib/hecks/doors/cli_runner/answers.rb +138 -0
  248. data/lib/hecks/doors/cli_runner/resolution.rb +146 -0
  249. data/lib/hecks/doors/cli_runner/settling.rb +115 -0
  250. data/lib/hecks/doors/cli_runner/streaming.rb +90 -0
  251. data/lib/hecks/doors/cli_runner/suggestions.rb +43 -0
  252. data/lib/hecks/doors/cli_runner.rb +12 -336
  253. data/lib/hecks/doors/command_request.rb +42 -31
  254. data/lib/hecks/doors/handle.rb +32 -30
  255. data/lib/hecks/doors/launcher_options.rb +62 -7
  256. data/lib/hecks/doors/mcp_door/properties.rb +47 -0
  257. data/lib/hecks/doors/mcp_door/tool_calls.rb +113 -0
  258. data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +51 -0
  259. data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +69 -0
  260. data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +97 -0
  261. data/lib/hecks/doors/mcp_door/tool_definitions.rb +15 -0
  262. data/lib/hecks/doors/mcp_door.rb +55 -301
  263. data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +92 -0
  264. data/lib/hecks/doors/mcp_door_scope/env_problems.rb +55 -0
  265. data/lib/hecks/doors/mcp_door_scope/presenter.rb +78 -0
  266. data/lib/hecks/doors/mcp_door_scope.rb +16 -172
  267. data/lib/hecks/doors/ruby_door/aggregate_door.rb +1 -1
  268. data/lib/hecks/doors/ruby_door/chapter.rb +33 -16
  269. data/lib/hecks/doors/ruby_door.rb +14 -11
  270. data/lib/hecks/doors/usage_cache.rb +14 -8
  271. data/lib/hecks/doors.rb +10 -4
  272. data/lib/hecks/embryonaut_bluebook/manifest.rb +11 -3
  273. data/lib/hecks/embryonaut_bluebook/registry/changelog.rb +26 -0
  274. data/lib/hecks/embryonaut_bluebook/registry/versions.rb +27 -0
  275. data/lib/hecks/embryonaut_bluebook/registry.rb +27 -37
  276. data/lib/hecks/embryonaut_bluebook/vendor/acceptance.rb +37 -0
  277. data/lib/hecks/embryonaut_bluebook/vendor.rb +22 -36
  278. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +9 -6
  279. data/lib/hecks/embryonaut_bluebook.rb +16 -11
  280. data/lib/hecks/engine_agreement.rb +24 -17
  281. data/lib/hecks/forms/app/commands.rb +98 -0
  282. data/lib/hecks/forms/app/queries.rb +62 -0
  283. data/lib/hecks/forms/app/records.rb +67 -0
  284. data/lib/hecks/forms/app/responses.rb +46 -0
  285. data/lib/hecks/forms/app.rb +33 -221
  286. data/lib/hecks/forms/banking_presentation.rb +5 -0
  287. data/lib/hecks/forms/command_form_renderer.rb +55 -14
  288. data/lib/hecks/forms/field_controls.rb +95 -0
  289. data/lib/hecks/forms/field_renderer.rb +34 -88
  290. data/lib/hecks/forms/field_shape.rb +9 -34
  291. data/lib/hecks/forms/html.rb +1 -1
  292. data/lib/hecks/forms/index_renderer.rb +14 -9
  293. data/lib/hecks/forms/page.rb +2 -106
  294. data/lib/hecks/forms/page_assets.rb +88 -0
  295. data/lib/hecks/forms/page_script.rb +28 -0
  296. data/lib/hecks/forms/params.rb +17 -8
  297. data/lib/hecks/forms/query_form_renderer.rb +11 -7
  298. data/lib/hecks/forms/record_renderer.rb +28 -19
  299. data/lib/hecks/forms/reference_options.rb +1 -1
  300. data/lib/hecks/forms/text_shape.rb +40 -0
  301. data/lib/hecks/fqn.rb +64 -32
  302. data/lib/hecks/framework.rb +10 -3
  303. data/lib/hecks/freezer.rb +10 -1
  304. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/fragments.rb +61 -0
  305. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/productions.rb +217 -0
  306. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +5 -194
  307. data/lib/hecks/fuzzing/combination_miner.rb +23 -12
  308. data/lib/hecks/fuzzing/concurrent_dispatch/racing.rb +64 -0
  309. data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +66 -0
  310. data/lib/hecks/fuzzing/concurrent_dispatch.rb +31 -107
  311. data/lib/hecks/fuzzing/coverage_campaign.rb +7 -7
  312. data/lib/hecks/fuzzing/differential/wire_comparison.rb +74 -0
  313. data/lib/hecks/fuzzing/differential.rb +59 -84
  314. data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +70 -0
  315. data/lib/hecks/fuzzing/domain_generator/builder/attribute_shapes.rb +105 -0
  316. data/lib/hecks/fuzzing/domain_generator/builder/shapes.rb +97 -0
  317. data/lib/hecks/fuzzing/domain_generator/builder/wiring.rb +128 -0
  318. data/lib/hecks/fuzzing/domain_generator/builder.rb +105 -0
  319. data/lib/hecks/fuzzing/domain_generator/pruning.rb +90 -0
  320. data/lib/hecks/fuzzing/domain_generator/removals.rb +62 -0
  321. data/lib/hecks/fuzzing/domain_generator/rendering.rb +94 -0
  322. data/lib/hecks/fuzzing/domain_generator/tokens.rb +38 -0
  323. data/lib/hecks/fuzzing/domain_generator.rb +7 -555
  324. data/lib/hecks/fuzzing/era_boundary.rb +34 -24
  325. data/lib/hecks/fuzzing/form_census.rb +18 -8
  326. data/lib/hecks/fuzzing/generated_domain_check.rb +23 -11
  327. data/lib/hecks/fuzzing/isolated_boot/copying.rb +62 -0
  328. data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +133 -0
  329. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +102 -0
  330. data/lib/hecks/fuzzing/isolated_boot.rb +25 -252
  331. data/lib/hecks/fuzzing/persistence_parity.rb +5 -5
  332. data/lib/hecks/fuzzing/properties/aggregation_recompute.rb +121 -0
  333. data/lib/hecks/fuzzing/properties/catalog.rb +138 -0
  334. data/lib/hecks/fuzzing/properties/corrections.rb +23 -20
  335. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +64 -185
  336. data/lib/hecks/fuzzing/properties/group_by_recompute.rb +69 -0
  337. data/lib/hecks/fuzzing/properties/guards.rb +76 -108
  338. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +66 -227
  339. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +46 -35
  340. data/lib/hecks/fuzzing/properties/mutation_recompute.rb +162 -0
  341. data/lib/hecks/fuzzing/properties/outbox.rb +41 -24
  342. data/lib/hecks/fuzzing/properties/piece_invariants.rb +61 -0
  343. data/lib/hecks/fuzzing/properties/policy_wiring.rb +140 -0
  344. data/lib/hecks/fuzzing/properties/query_rows.rb +67 -0
  345. data/lib/hecks/fuzzing/properties/querying.rb +69 -90
  346. data/lib/hecks/fuzzing/properties/references.rb +100 -0
  347. data/lib/hecks/fuzzing/properties/tenant_scope.rb +84 -0
  348. data/lib/hecks/fuzzing/properties.rb +6 -119
  349. data/lib/hecks/fuzzing/qa_settings.rb +23 -17
  350. data/lib/hecks/fuzzing/replay/fan_out.rb +78 -0
  351. data/lib/hecks/fuzzing/replay/filters.rb +72 -0
  352. data/lib/hecks/fuzzing/replay/guard_check.rb +88 -0
  353. data/lib/hecks/fuzzing/replay/mutation_trace.rb +117 -0
  354. data/lib/hecks/fuzzing/replay/observation.rb +60 -0
  355. data/lib/hecks/fuzzing/replay/read_only_steps.rb +84 -0
  356. data/lib/hecks/fuzzing/replay/session.rb +151 -0
  357. data/lib/hecks/fuzzing/replay.rb +35 -442
  358. data/lib/hecks/fuzzing/rust_gap_manifest.rb +3 -4
  359. data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +133 -0
  360. data/lib/hecks/fuzzing/self_consistency/sagas.rb +93 -0
  361. data/lib/hecks/fuzzing/self_consistency/value_objects.rb +87 -0
  362. data/lib/hecks/fuzzing/self_consistency.rb +8 -213
  363. data/lib/hecks/fuzzing/sequence_generator/adversary/argument_mutations.rb +116 -0
  364. data/lib/hecks/fuzzing/sequence_generator/adversary/caller_draw.rb +68 -0
  365. data/lib/hecks/fuzzing/sequence_generator/adversary/identity_mutations.rb +62 -0
  366. data/lib/hecks/fuzzing/sequence_generator/adversary/precedence_mutations.rb +126 -0
  367. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +23 -283
  368. data/lib/hecks/fuzzing/sequence_generator/argument_drawing.rb +78 -0
  369. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +69 -53
  370. data/lib/hecks/fuzzing/sequence_generator/identity_shaping.rb +85 -0
  371. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +20 -16
  372. data/lib/hecks/fuzzing/sequence_generator/picker.rb +12 -6
  373. data/lib/hecks/fuzzing/sequence_generator/prefixing.rb +45 -0
  374. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +19 -8
  375. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +43 -144
  376. data/lib/hecks/fuzzing/sequence_generator.rb +65 -63
  377. data/lib/hecks/fuzzing/shrinker.rb +33 -29
  378. data/lib/hecks/fuzzing/target_capabilities.rb +10 -4
  379. data/lib/hecks/fuzzing/value_generator.rb +27 -17
  380. data/lib/hecks/gate/stages.yml +10 -0
  381. data/lib/hecks/grammar/evolve/arguments.rb +90 -0
  382. data/lib/hecks/grammar/evolve/keywords.rb +81 -0
  383. data/lib/hecks/grammar/evolve/seeds.rb +172 -0
  384. data/lib/hecks/grammar/evolve.rb +22 -263
  385. data/lib/hecks/grammar/operators.rb +111 -0
  386. data/lib/hecks/grammar.rb +53 -126
  387. data/lib/hecks/hecks/adapters/bluebook_report.rb +6 -6
  388. data/lib/hecks/hecks/adapters/codebase/codemods.rb +1 -1
  389. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +23 -9
  390. data/lib/hecks/hecks/adapters/codebase/language/edits.rb +75 -0
  391. data/lib/hecks/hecks/adapters/codebase/language.rb +30 -72
  392. data/lib/hecks/hecks/adapters/codebase/promotion/candidates.rb +54 -0
  393. data/lib/hecks/hecks/adapters/codebase/promotion/gate.rb +50 -0
  394. data/lib/hecks/hecks/adapters/codebase/promotion/move.rb +70 -0
  395. data/lib/hecks/hecks/adapters/codebase/promotion/standing.rb +88 -0
  396. data/lib/hecks/hecks/adapters/codebase/promotion/watch.rb +83 -0
  397. data/lib/hecks/hecks/adapters/codebase/promotion.rb +115 -0
  398. data/lib/hecks/hecks/adapters/codebase/publishing.rb +31 -12
  399. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +43 -6
  400. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +16 -5
  401. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +9 -1
  402. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +1 -1
  403. data/lib/hecks/hecks/adapters/codebase/style.rb +1 -1
  404. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +11 -5
  405. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +27 -8
  406. data/lib/hecks/hecks/adapters/console_capture.rb +21 -17
  407. data/lib/hecks/hecks/adapters/cost_explorer.rb +11 -6
  408. data/lib/hecks/hecks/adapters/deploy_plans.rb +3 -3
  409. data/lib/hecks/hecks/adapters/deploy_toolchain/answers.rb +141 -0
  410. data/lib/hecks/hecks/adapters/deploy_toolchain/scripts.rb +95 -0
  411. data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +74 -0
  412. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +21 -239
  413. data/lib/hecks/hecks/adapters/finding_github.rb +2 -2
  414. data/lib/hecks/hecks/adapters/first_admin.rb +22 -8
  415. data/lib/hecks/hecks/adapters/git.rb +18 -5
  416. data/lib/hecks/hecks/adapters/git_refs.rb +144 -0
  417. data/lib/hecks/hecks/adapters/github_rulesets.rb +126 -0
  418. data/lib/hecks/hecks/adapters/host_http.rb +16 -6
  419. data/lib/hecks/hecks/adapters/in_process_boot.rb +9 -5
  420. data/lib/hecks/hecks/adapters/in_process_operations/tailing.rb +61 -0
  421. data/lib/hecks/hecks/adapters/in_process_operations.rb +33 -35
  422. data/lib/hecks/hecks/adapters/journal_store/changes.rb +21 -15
  423. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +29 -12
  424. data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +52 -0
  425. data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +52 -0
  426. data/lib/hecks/hecks/adapters/journal_store/readings.rb +5 -62
  427. data/lib/hecks/hecks/adapters/local_files.rb +27 -10
  428. data/lib/hecks/hecks/adapters/pg_admin/ownership.rb +115 -0
  429. data/lib/hecks/hecks/adapters/pg_admin.rb +14 -87
  430. data/lib/hecks/hecks/adapters/process_pool.rb +54 -22
  431. data/lib/hecks/hecks/adapters/rust_toolchain.rb +12 -4
  432. data/lib/hecks/hecks/adapters/site_toolchain.rb +16 -7
  433. data/lib/hecks/hecks/adapters/terminal.rb +13 -9
  434. data/lib/hecks/hecks/codebase.bluebook +322 -5
  435. data/lib/hecks/hecks/hecks.hecksagon +16 -0
  436. data/lib/hecks/hecks/hecks.world +10 -2
  437. data/lib/hecks/kernel_capabilities/templates.rb +92 -0
  438. data/lib/hecks/kernel_capabilities.rb +18 -85
  439. data/lib/hecks/language/bluebook/vocabulary.bluebook +43 -1
  440. data/lib/hecks/literal/item_splitter.rb +50 -0
  441. data/lib/hecks/literal.rb +29 -38
  442. data/lib/hecks/mcp_stdio_guard.rb +8 -8
  443. data/lib/hecks/naming.rb +9 -3
  444. data/lib/hecks/persistence_legacy_fixture/postgres_stores.rb +81 -0
  445. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +26 -66
  446. data/lib/hecks/persistence_legacy_fixture.rb +13 -10
  447. data/lib/hecks/ports/access_control.rb +13 -10
  448. data/lib/hecks/ports/agent/answers.rb +2 -2
  449. data/lib/hecks/ports/agent.rb +13 -10
  450. data/lib/hecks/ports/authentication.rb +13 -10
  451. data/lib/hecks/ports/authorization.rb +13 -10
  452. data/lib/hecks/ports/clock.rb +13 -10
  453. data/lib/hecks/ports/extraction.rb +13 -12
  454. data/lib/hecks/ports/identity_assignment.rb +13 -10
  455. data/lib/hecks/ports/identity_generation.rb +13 -10
  456. data/lib/hecks/ports/identity_resolution.rb +13 -10
  457. data/lib/hecks/ports/key_vault.rb +13 -10
  458. data/lib/hecks/ports/persistence/append_only.rb +5 -5
  459. data/lib/hecks/ports/persistence/binding_policy.rb +33 -9
  460. data/lib/hecks/ports/persistence/codec_boundary.rb +22 -11
  461. data/lib/hecks/ports/persistence/constants.rb +10 -0
  462. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +18 -16
  463. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +27 -18
  464. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +52 -23
  465. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +14 -8
  466. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +17 -6
  467. data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +58 -0
  468. data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +130 -0
  469. data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +25 -0
  470. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +20 -180
  471. data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +41 -0
  472. data/lib/hecks/ports/persistence/plugins/era/postgres_era/class_methods.rb +105 -0
  473. data/lib/hecks/ports/persistence/plugins/era/postgres_era/dialect.rb +137 -0
  474. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +25 -28
  475. data/lib/hecks/ports/persistence/plugins/era/postgres_era/head_writes.rb +62 -0
  476. data/lib/hecks/ports/persistence/plugins/era/postgres_era/journal.rb +128 -0
  477. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +74 -0
  478. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/chain_sql.rb +169 -0
  479. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +91 -0
  480. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_integrity.rb +99 -0
  481. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +0 -73
  482. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +55 -39
  483. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +51 -222
  484. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/merge_writes.rb +120 -0
  485. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +85 -60
  486. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +97 -181
  487. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +19 -19
  488. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/sql_templates.rb +88 -0
  489. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +77 -118
  490. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +3 -117
  491. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_sql.rb +116 -0
  492. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +3 -1
  493. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/context.rb +38 -0
  494. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +43 -25
  495. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +62 -38
  496. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +21 -16
  497. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +66 -86
  498. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +75 -0
  499. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +27 -9
  500. data/lib/hecks/ports/persistence/plugins/era/postgres_era/query_phases.rb +63 -0
  501. data/lib/hecks/ports/persistence/plugins/era/postgres_era/sagas.rb +78 -0
  502. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +28 -482
  503. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +40 -12
  504. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +22 -15
  505. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +39 -19
  506. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -16
  507. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +48 -25
  508. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +60 -99
  509. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/path_diff.rb +57 -0
  510. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +21 -11
  511. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +13 -4
  512. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +4 -2
  513. data/lib/hecks/ports/persistence/postgres_dump.rb +13 -7
  514. data/lib/hecks/ports/persistence/repository_factory.rb +35 -11
  515. data/lib/hecks/ports/persistence/state_codec.rb +10 -0
  516. data/lib/hecks/ports/persistence.rb +1 -10
  517. data/lib/hecks/ports/projection.rb +34 -21
  518. data/lib/hecks/ports/query/in_memory.rb +16 -8
  519. data/lib/hecks/projection_files/expression_tables.rb +64 -0
  520. data/lib/hecks/projection_files/texts.rb +67 -0
  521. data/lib/hecks/projection_files.rb +19 -103
  522. data/lib/hecks/projections/bootstrap_table.rb +43 -29
  523. data/lib/hecks/projections/deploy/bastion_lines.rb +32 -0
  524. data/lib/hecks/projections/deploy/box/access.rb +73 -0
  525. data/lib/hecks/projections/deploy/box/caddy.rb +87 -0
  526. data/lib/hecks/projections/deploy/box/compose.rb +70 -0
  527. data/lib/hecks/projections/deploy/box/hosting.rb +4 -105
  528. data/lib/hecks/projections/deploy/box/hosting_parts.rb +97 -0
  529. data/lib/hecks/projections/deploy/box/hosting_settings.rb +1 -1
  530. data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
  531. data/lib/hecks/projections/deploy/box/roll_scripts.rb +135 -0
  532. data/lib/hecks/projections/deploy/box/settings/checks.rb +38 -0
  533. data/lib/hecks/projections/deploy/box/settings/containers.rb +123 -0
  534. data/lib/hecks/projections/deploy/box/settings/origin.rb +56 -0
  535. data/lib/hecks/projections/deploy/box/settings/patterns.rb +43 -0
  536. data/lib/hecks/projections/deploy/box/settings/types.rb +72 -0
  537. data/lib/hecks/projections/deploy/box/settings.rb +58 -263
  538. data/lib/hecks/projections/deploy/box/stack_yaml.rb +107 -0
  539. data/lib/hecks/projections/deploy/box/templates/MIGRATION.md.tmpl +39 -0
  540. data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +24 -0
  541. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +41 -1
  542. data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +2 -1
  543. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +2 -1
  544. data/lib/hecks/projections/deploy/box/templates/deploy-usage-services.tmpl +4 -0
  545. data/lib/hecks/projections/deploy/box/templates/deploy-usage-taskdef.tmpl +5 -0
  546. data/lib/hecks/projections/deploy/box/templates/ecr-repository.yaml.tmpl +9 -0
  547. data/lib/hecks/projections/deploy/box/templates/mode-summary-services.tmpl +2 -0
  548. data/lib/hecks/projections/deploy/box/templates/mode-summary-taskdef.tmpl +4 -0
  549. data/lib/hecks/projections/deploy/box/templates/services-block.tmpl +9 -0
  550. data/lib/hecks/projections/deploy/box/templates/tunnel-egress.yaml.tmpl +11 -0
  551. data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
  552. data/lib/hecks/projections/deploy/box.rb +33 -493
  553. data/lib/hecks/projections/deploy/fargate/assembly.rb +13 -142
  554. data/lib/hecks/projections/deploy/fargate/cdn/behaviors.rb +76 -0
  555. data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +112 -0
  556. data/lib/hecks/projections/deploy/fargate/cdn/options.rb +85 -0
  557. data/lib/hecks/projections/deploy/fargate/cdn.rb +23 -215
  558. data/lib/hecks/projections/deploy/fargate/check.rb +16 -6
  559. data/lib/hecks/projections/deploy/fargate/containers/definition_lines.rb +61 -0
  560. data/lib/hecks/projections/deploy/fargate/containers/reading.rb +86 -0
  561. data/lib/hecks/projections/deploy/fargate/containers/rendering.rb +132 -0
  562. data/lib/hecks/projections/deploy/fargate/containers/routing.rb +93 -0
  563. data/lib/hecks/projections/deploy/fargate/containers.rb +10 -286
  564. data/lib/hecks/projections/deploy/fargate/extras/reading.rb +90 -0
  565. data/lib/hecks/projections/deploy/fargate/extras/rendering.rb +81 -0
  566. data/lib/hecks/projections/deploy/fargate/extras.rb +9 -158
  567. data/lib/hecks/projections/deploy/fargate/monitoring/alarms.rb +115 -0
  568. data/lib/hecks/projections/deploy/fargate/monitoring/reading.rb +84 -0
  569. data/lib/hecks/projections/deploy/fargate/monitoring/topic.rb +59 -0
  570. data/lib/hecks/projections/deploy/fargate/monitoring/warmer.rb +90 -0
  571. data/lib/hecks/projections/deploy/fargate/monitoring/warmer_roles.rb +76 -0
  572. data/lib/hecks/projections/deploy/fargate/monitoring.rb +14 -348
  573. data/lib/hecks/projections/deploy/fargate/sections.rb +115 -0
  574. data/lib/hecks/projections/deploy/fargate/settings/ids.rb +55 -0
  575. data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +77 -0
  576. data/lib/hecks/projections/deploy/fargate/settings.rb +17 -104
  577. data/lib/hecks/projections/deploy/fargate/stack/blocks.rb +91 -0
  578. data/lib/hecks/projections/deploy/fargate/stack/readers.rb +87 -0
  579. data/lib/hecks/projections/deploy/fargate/stack/recipes.rb +106 -0
  580. data/lib/hecks/projections/deploy/fargate/stack.rb +146 -0
  581. data/lib/hecks/projections/deploy/fargate/task_sections.rb +56 -0
  582. data/lib/hecks/projections/deploy/fargate/yaml.rb +1 -1
  583. data/lib/hecks/projections/deploy/fargate.rb +51 -756
  584. data/lib/hecks/projections/deploy/lambda/pii.rb +49 -0
  585. data/lib/hecks/projections/deploy/lambda/stack/blocks.rb +118 -0
  586. data/lib/hecks/projections/deploy/lambda/stack/checks.rb +64 -0
  587. data/lib/hecks/projections/deploy/lambda/stack/deploy_chain.rb +119 -0
  588. data/lib/hecks/projections/deploy/lambda/stack/readers.rb +62 -0
  589. data/lib/hecks/projections/deploy/lambda/stack/reading.rb +170 -0
  590. data/lib/hecks/projections/deploy/lambda/stack/reading_web.rb +53 -0
  591. data/lib/hecks/projections/deploy/lambda/stack/recipes.rb +112 -0
  592. data/lib/hecks/projections/deploy/lambda/stack/web.rb +57 -0
  593. data/lib/hecks/projections/deploy/lambda/stack.rb +54 -0
  594. data/lib/hecks/projections/deploy/lambda.rb +77 -1885
  595. data/lib/hecks/projections/deploy/preview/access_yaml.rb +8 -74
  596. data/lib/hecks/projections/deploy/preview/containers.rb +18 -7
  597. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +15 -87
  598. data/lib/hecks/projections/deploy/preview/settings.rb +7 -4
  599. data/lib/hecks/projections/deploy/preview/task_yaml.rb +42 -106
  600. data/lib/hecks/projections/deploy/preview/template.rb +11 -106
  601. data/lib/hecks/projections/deploy/preview/yaml_text.rb +1 -1
  602. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +1 -1
  603. data/lib/hecks/projections/deploy/scripts/settings.rb +14 -6
  604. data/lib/hecks/projections/deploy/scripts.rb +11 -9
  605. data/lib/hecks/projections/deploy/shared/rows.rb +48 -0
  606. data/lib/hecks/projections/deploy/shared.rb +89 -449
  607. data/lib/hecks/projections/deploy/smoke.rb +15 -10
  608. data/lib/hecks/projections/deploy/template_diff/comparer.rb +21 -147
  609. data/lib/hecks/projections/deploy/template_diff/normalizer.rb +60 -0
  610. data/lib/hecks/projections/deploy/template_diff/value_diff.rb +136 -0
  611. data/lib/hecks/projections/deploy/template_diff.rb +8 -3
  612. data/lib/hecks/projections/deploy/templates/fargate/Dockerfile.tmpl +28 -0
  613. data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +63 -0
  614. data/lib/hecks/projections/deploy/templates/fargate/always_params.tmpl +4 -0
  615. data/lib/hecks/projections/deploy/templates/fargate/deploy_plain.tmpl +1 -0
  616. data/lib/hecks/projections/deploy/templates/fargate/deploy_shared.tmpl +11 -0
  617. data/lib/hecks/projections/deploy/templates/fargate/mint_era_own.tmpl +44 -0
  618. data/lib/hecks/projections/deploy/templates/fargate/mint_era_shared.tmpl +8 -0
  619. data/lib/hecks/projections/deploy/templates/fargate/missing_owner.tmpl +9 -0
  620. data/lib/hecks/projections/deploy/templates/fargate/oauth_params.tmpl +7 -0
  621. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_env.tmpl +4 -0
  622. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_policy.tmpl +7 -0
  623. data/lib/hecks/projections/deploy/templates/fargate/owning_params.tmpl +33 -0
  624. data/lib/hecks/projections/deploy/templates/fargate/template.yaml.tmpl +281 -0
  625. data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +218 -0
  626. data/lib/hecks/projections/deploy/templates/lambda/aurora_depends.tmpl +18 -0
  627. data/lib/hecks/projections/deploy/templates/lambda/build_dispatch_none.tmpl +10 -0
  628. data/lib/hecks/projections/deploy/templates/lambda/build_pg.tmpl +15 -0
  629. data/lib/hecks/projections/deploy/templates/lambda/build_plain.tmpl +2 -0
  630. data/lib/hecks/projections/deploy/templates/lambda/build_web.tmpl +11 -0
  631. data/lib/hecks/projections/deploy/templates/lambda/env_blind_guard.tmpl +4 -0
  632. data/lib/hecks/projections/deploy/templates/lambda/mint_era_own.tmpl +122 -0
  633. data/lib/hecks/projections/deploy/templates/lambda/mint_era_shared.tmpl +47 -0
  634. data/lib/hecks/projections/deploy/templates/lambda/missing_owner.tmpl +9 -0
  635. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +14 -0
  636. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_plain.tmpl +3 -0
  637. data/lib/hecks/projections/deploy/templates/lambda/oauth_note.tmpl +8 -0
  638. data/lib/hecks/projections/deploy/templates/lambda/params_oauth.tmpl +13 -0
  639. data/lib/hecks/projections/deploy/templates/lambda/params_shared.tmpl +33 -0
  640. data/lib/hecks/projections/deploy/templates/lambda/pg_native.tmpl +71 -0
  641. data/lib/hecks/projections/deploy/templates/lambda/pii_oac.tmpl +8 -0
  642. data/lib/hecks/projections/deploy/templates/lambda/pii_permission.tmpl +8 -0
  643. data/lib/hecks/projections/deploy/templates/lambda/pii_resources.tmpl +116 -0
  644. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge.tmpl +30 -0
  645. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_oauth.tmpl +12 -0
  646. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_plain.tmpl +7 -0
  647. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_own.tmpl +93 -0
  648. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_shared.tmpl +7 -0
  649. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_env.tmpl +17 -0
  650. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_policy.tmpl +16 -0
  651. data/lib/hecks/projections/deploy/templates/lambda/rust_session_secret.tmpl +13 -0
  652. data/lib/hecks/projections/deploy/templates/lambda/samconfig.toml.tmpl +12 -0
  653. data/lib/hecks/projections/deploy/templates/lambda/shared_note.tmpl +6 -0
  654. data/lib/hecks/projections/deploy/templates/lambda/sync_oauth.tmpl +23 -0
  655. data/lib/hecks/projections/deploy/templates/lambda/template.yaml.tmpl +187 -0
  656. data/lib/hecks/projections/deploy/templates/lambda/translation_own.tmpl +46 -0
  657. data/lib/hecks/projections/deploy/templates/lambda/translation_shared.tmpl +2 -0
  658. data/lib/hecks/projections/deploy/templates/lambda/web_function.tmpl +207 -0
  659. data/lib/hecks/projections/deploy/templates/lambda/web_google_oauth_env.tmpl +12 -0
  660. data/lib/hecks/projections/deploy/templates/lambda/web_no_oauth_env.tmpl +7 -0
  661. data/lib/hecks/projections/deploy/templates/lambda/web_oauth_policy.tmpl +4 -0
  662. data/lib/hecks/projections/deploy/templates/lambda/webhook_secret_resource.tmpl +20 -0
  663. data/lib/hecks/projections/deploy/templates/preview/alb.tmpl +8 -0
  664. data/lib/hecks/projections/deploy/templates/preview/alb_security_group.tmpl +11 -0
  665. data/lib/hecks/projections/deploy/templates/preview/assume_role.tmpl +6 -0
  666. data/lib/hecks/projections/deploy/templates/preview/base_parameters.tmpl +24 -0
  667. data/lib/hecks/projections/deploy/templates/preview/cluster.tmpl +4 -0
  668. data/lib/hecks/projections/deploy/templates/preview/container_secret.tmpl +9 -0
  669. data/lib/hecks/projections/deploy/templates/preview/db_init_script.sh.tmpl +23 -0
  670. data/lib/hecks/projections/deploy/templates/preview/db_init_secrets.tmpl +5 -0
  671. data/lib/hecks/projections/deploy/templates/preview/db_init_task.tmpl +39 -0
  672. data/lib/hecks/projections/deploy/templates/preview/desired_count.tmpl +5 -0
  673. data/lib/hecks/projections/deploy/templates/preview/distribution.tmpl +24 -0
  674. data/lib/hecks/projections/deploy/templates/preview/execution_role.tmpl +16 -0
  675. data/lib/hecks/projections/deploy/templates/preview/header.tmpl +16 -0
  676. data/lib/hecks/projections/deploy/templates/preview/ingress.tmpl +8 -0
  677. data/lib/hecks/projections/deploy/templates/preview/listener.tmpl +9 -0
  678. data/lib/hecks/projections/deploy/templates/preview/listener_rule.tmpl +11 -0
  679. data/lib/hecks/projections/deploy/templates/preview/log_group.tmpl +5 -0
  680. data/lib/hecks/projections/deploy/templates/preview/log_options.tmpl +5 -0
  681. data/lib/hecks/projections/deploy/templates/preview/outputs.tmpl +14 -0
  682. data/lib/hecks/projections/deploy/templates/preview/service.tmpl +17 -0
  683. data/lib/hecks/projections/deploy/templates/preview/session_secret.tmpl +11 -0
  684. data/lib/hecks/projections/deploy/templates/preview/target_group.tmpl +9 -0
  685. data/lib/hecks/projections/deploy/templates/preview/task_definition.tmpl +15 -0
  686. data/lib/hecks/projections/deploy/templates/preview/task_role.tmpl +22 -0
  687. data/lib/hecks/projections/deploy/templates/shared/aurora_db.tmpl +52 -0
  688. data/lib/hecks/projections/deploy/templates/shared/bastion.tmpl +74 -0
  689. data/lib/hecks/projections/deploy/templates/shared/bastion_own_public.tmpl +41 -0
  690. data/lib/hecks/projections/deploy/templates/shared/bastion_reuse_public.tmpl +10 -0
  691. data/lib/hecks/projections/deploy/templates/shared/nat_gateway.tmpl +102 -0
  692. data/lib/hecks/projections/deploy/templates/shared/oauth_egress.tmpl +17 -0
  693. data/lib/hecks/projections/deploy/templates/shared/plain_db.tmpl +16 -0
  694. data/lib/hecks/projections/deploy/templates/shared/vpc_and_database.tmpl +67 -0
  695. data/lib/hecks/projections/deploy/text_template.rb +35 -0
  696. data/lib/hecks/projections/diagrams/dispatch.rb +114 -0
  697. data/lib/hecks/projections/diagrams/statecharts.rb +59 -0
  698. data/lib/hecks/projections/diagrams/structure.rb +114 -0
  699. data/lib/hecks/projections/diagrams.rb +33 -256
  700. data/lib/hecks/projections/glossary/entries.rb +140 -0
  701. data/lib/hecks/projections/glossary/html/page.rb +96 -0
  702. data/lib/hecks/projections/glossary/html/parser.rb +66 -0
  703. data/lib/hecks/projections/glossary/html/sections.rb +78 -0
  704. data/lib/hecks/projections/glossary/html.rb +7 -179
  705. data/lib/hecks/projections/glossary/index.rb +45 -0
  706. data/lib/hecks/projections/glossary/markdown.rb +22 -11
  707. data/lib/hecks/projections/glossary/mermaid.rb +44 -31
  708. data/lib/hecks/projections/glossary/sensitivity.rb +7 -4
  709. data/lib/hecks/projections/glossary/sentences/value_objects.rb +77 -0
  710. data/lib/hecks/projections/glossary/sentences.rb +42 -81
  711. data/lib/hecks/projections/glossary/slugs.rb +33 -0
  712. data/lib/hecks/projections/glossary.rb +22 -190
  713. data/lib/hecks/projections/model.rb +20 -14
  714. data/lib/hecks/projections/rust_vocabulary/arguments/support.rb +33 -0
  715. data/lib/hecks/projections/rust_vocabulary/arguments.rb +171 -0
  716. data/lib/hecks/projections/rust_vocabulary/enum_body.rb +114 -0
  717. data/lib/hecks/projections/rust_vocabulary/tests.rb +144 -0
  718. data/lib/hecks/projections/rust_vocabulary.rb +24 -293
  719. data/lib/hecks/projections/site/admin.rb +15 -9
  720. data/lib/hecks/projections/site/admin_cms/templates/membership.rb +115 -0
  721. data/lib/hecks/projections/site/admin_cms/templates/session_strategy.rb +90 -0
  722. data/lib/hecks/projections/site/admin_cms/templates/sso.rb +101 -0
  723. data/lib/hecks/projections/site/admin_cms/templates/sso_tail.rb +54 -0
  724. data/lib/hecks/projections/site/admin_cms/templates/users.rb +83 -0
  725. data/lib/hecks/projections/site/admin_cms/templates.rb +14 -369
  726. data/lib/hecks/projections/site/admin_cms.rb +15 -9
  727. data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
  728. data/lib/hecks/projections/site/edge/checks.rb +30 -80
  729. data/lib/hecks/projections/site/edge/findings.rb +28 -0
  730. data/lib/hecks/projections/site/edge/route_checks.rb +110 -0
  731. data/lib/hecks/projections/site/edge/row_reader.rb +52 -0
  732. data/lib/hecks/projections/site/edge/rules.rb +28 -26
  733. data/lib/hecks/projections/site/edge.rb +20 -31
  734. data/lib/hecks/projections/site/live_edge.rb +9 -7
  735. data/lib/hecks/projections/site/payload/fields/definitions.rb +90 -0
  736. data/lib/hecks/projections/site/payload/fields/readers.rb +69 -0
  737. data/lib/hecks/projections/site/payload/fields.rb +14 -111
  738. data/lib/hecks/projections/site/payload/lifecycle/text.rb +84 -0
  739. data/lib/hecks/projections/site/payload/lifecycle/text_tail.rb +106 -0
  740. data/lib/hecks/projections/site/payload/lifecycle.rb +8 -166
  741. data/lib/hecks/projections/site/payload/model.rb +22 -22
  742. data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
  743. data/lib/hecks/projections/site/payload/specs.rb +24 -68
  744. data/lib/hecks/projections/site/payload_driver.rb +19 -17
  745. data/lib/hecks/projections/site/root_rows.rb +12 -4
  746. data/lib/hecks/projections/site/routes_ts/helpers.rb +79 -0
  747. data/lib/hecks/projections/site/routes_ts/listings.rb +75 -0
  748. data/lib/hecks/projections/site/routes_ts/navigation.rb +79 -0
  749. data/lib/hecks/projections/site/routes_ts.rb +27 -175
  750. data/lib/hecks/projections/site/site_admin/access.rb +104 -0
  751. data/lib/hecks/projections/site/site_admin/session.rb +127 -0
  752. data/lib/hecks/projections/site/site_admin.rb +12 -219
  753. data/lib/hecks/projections/site/site_cdn.rb +12 -7
  754. data/lib/hecks/projections/site/site_host/dockerfile.rb +75 -0
  755. data/lib/hecks/projections/site/site_host/templates.rb +7 -63
  756. data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
  757. data/lib/hecks/projections/site/site_root.rb +3 -54
  758. data/lib/hecks/projections/site/table/checks.rb +28 -57
  759. data/lib/hecks/projections/site/table/link_builder.rb +14 -5
  760. data/lib/hecks/projections/site/table/navigation_checks.rb +75 -0
  761. data/lib/hecks/projections/site/table/row_builder.rb +31 -53
  762. data/lib/hecks/projections/site/table/row_defaults.rb +65 -0
  763. data/lib/hecks/projections/site/table.rb +9 -5
  764. data/lib/hecks/projections/vocabulary.rb +34 -31
  765. data/lib/hecks/projector/cli_audience.rb +42 -0
  766. data/lib/hecks/projector/cli_projector/claims.rb +149 -0
  767. data/lib/hecks/projector/cli_projector/command_help.rb +65 -0
  768. data/lib/hecks/projector/cli_projector/command_specs.rb +133 -0
  769. data/lib/hecks/projector/cli_projector/listing.rb +100 -0
  770. data/lib/hecks/projector/cli_projector/option_specs.rb +116 -0
  771. data/lib/hecks/projector/cli_projector/query_specs.rb +67 -0
  772. data/lib/hecks/projector/cli_projector/usage.rb +101 -0
  773. data/lib/hecks/projector/cli_projector.rb +15 -532
  774. data/lib/hecks/projector/docs_projector/attributes.rb +78 -0
  775. data/lib/hecks/projector/docs_projector/behaviour.rb +127 -0
  776. data/lib/hecks/projector/docs_projector/closing.rb +40 -0
  777. data/lib/hecks/projector/docs_projector.rb +58 -192
  778. data/lib/hecks/projector/exporter/bindings.rb +174 -0
  779. data/lib/hecks/projector/exporter/translations.rb +127 -0
  780. data/lib/hecks/projector/exporter.rb +8 -279
  781. data/lib/hecks/projector/narrate_projector/commands.rb +108 -0
  782. data/lib/hecks/projector/narrate_projector/reactions.rb +33 -0
  783. data/lib/hecks/projector/narrate_projector.rb +60 -160
  784. data/lib/hecks/projector.rb +22 -13
  785. data/lib/hecks/quality_control/adapters/agent_profile.rb +25 -16
  786. data/lib/hecks/quality_control/adapters/github_checks.rb +42 -6
  787. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +1 -1
  788. data/lib/hecks/quality_control/adapters/github_issues.rb +22 -10
  789. data/lib/hecks/quality_control/cli/qa_discover_external_domains/parsing.rb +54 -0
  790. data/lib/hecks/quality_control/cli/qa_discover_external_domains/reporting.rb +44 -0
  791. data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +119 -0
  792. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +28 -155
  793. data/lib/hecks/quality_control/cli/qa_domain_novelty/verdict.rb +76 -0
  794. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +33 -66
  795. data/lib/hecks/quality_control/cli/qa_generated_domains/arguments.rb +62 -0
  796. data/lib/hecks/quality_control/cli/qa_generated_domains/blueprints.rb +45 -0
  797. data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +107 -0
  798. data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +107 -0
  799. data/lib/hecks/quality_control/cli/qa_generated_domains/reporting.rb +97 -0
  800. data/lib/hecks/quality_control/cli/qa_generated_domains/shrinking.rb +70 -0
  801. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +43 -327
  802. data/lib/hecks/quality_control/cli/qa_log_bug/arguments.rb +55 -0
  803. data/lib/hecks/quality_control/cli/qa_log_bug/proof.rb +65 -0
  804. data/lib/hecks/quality_control/cli/qa_log_bug.rb +18 -81
  805. data/lib/hecks/quality_control/cli/qa_mine_combinations/arguments.rb +54 -0
  806. data/lib/hecks/quality_control/cli/qa_mine_combinations/booting.rb +96 -0
  807. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +45 -109
  808. data/lib/hecks/quality_control/cli/qa_open_pr/arguments.rb +55 -0
  809. data/lib/hecks/quality_control/cli/qa_open_pr/recording.rb +79 -0
  810. data/lib/hecks/quality_control/cli/qa_open_pr/rules.rb +122 -0
  811. data/lib/hecks/quality_control/cli/qa_open_pr.rb +41 -200
  812. data/lib/hecks/quality_control/cli/qa_postgres_migrate/copying.rb +45 -0
  813. data/lib/hecks/quality_control/cli/qa_postgres_migrate/reporting.rb +33 -0
  814. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +37 -63
  815. data/lib/hecks/quality_control/cli/qa_postgres_role/ownership.rb +57 -0
  816. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +66 -71
  817. data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +118 -0
  818. data/lib/hecks/quality_control/cli/qa_pr_check/reporting.rb +54 -0
  819. data/lib/hecks/quality_control/cli/qa_pr_check.rb +28 -145
  820. data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +80 -0
  821. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +13 -86
  822. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/children.rb +80 -0
  823. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/report.rb +125 -0
  824. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +63 -193
  825. data/lib/hecks/quality_control/cli/qa_sweep/checks/boundary.rb +92 -0
  826. data/lib/hecks/quality_control/cli/qa_sweep/checks/engines.rb +92 -0
  827. data/lib/hecks/quality_control/cli/qa_sweep/checks/seeds.rb +86 -0
  828. data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +69 -0
  829. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +10 -248
  830. data/lib/hecks/quality_control/cli/qa_sweep/conclusion.rb +60 -0
  831. data/lib/hecks/quality_control/cli/qa_sweep/depth.rb +61 -0
  832. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +26 -13
  833. data/lib/hecks/quality_control/cli/qa_sweep/finding_report/shrunk.rb +42 -0
  834. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +40 -41
  835. data/lib/hecks/quality_control/cli/qa_sweep/parsing/validation.rb +70 -0
  836. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +35 -65
  837. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +41 -22
  838. data/lib/hecks/quality_control/cli/qa_sweep/scratch.rb +67 -0
  839. data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +94 -0
  840. data/lib/hecks/quality_control/cli/qa_sweep/seed_loop.rb +149 -0
  841. data/lib/hecks/quality_control/cli/qa_sweep/target_setup.rb +115 -0
  842. data/lib/hecks/quality_control/cli/qa_sweep.rb +22 -445
  843. data/lib/hecks/quality_control/cli/qa_tick/output.rb +107 -0
  844. data/lib/hecks/quality_control/cli/qa_tick/preflight.rb +95 -0
  845. data/lib/hecks/quality_control/cli/qa_tick.rb +42 -175
  846. data/lib/hecks/query_ir/formatting.rb +86 -0
  847. data/lib/hecks/query_ir/rules.rb +132 -0
  848. data/lib/hecks/query_ir/touchpoints.rb +104 -0
  849. data/lib/hecks/query_ir.rb +33 -281
  850. data/lib/hecks/query_ir_mcp/tools.rb +68 -0
  851. data/lib/hecks/query_ir_mcp.rb +27 -71
  852. data/lib/hecks/query_specification/common/comparison.rb +25 -5
  853. data/lib/hecks/query_specification/common/dsl.rb +1 -1
  854. data/lib/hecks/query_specification/common/null_policy.rb +9 -6
  855. data/lib/hecks/query_specification/common/options.rb +21 -14
  856. data/lib/hecks/query_specification/field_path.rb +5 -2
  857. data/lib/hecks/query_specification/hop_path.rb +15 -18
  858. data/lib/hecks/release/lane.rb +22 -0
  859. data/lib/hecks/release/runner/clean_tree.rb +2 -2
  860. data/lib/hecks/release/runner/commands.rb +1 -1
  861. data/lib/hecks/release/runner/options.rb +82 -0
  862. data/lib/hecks/release/runner/preflight.rb +12 -7
  863. data/lib/hecks/release/runner/publishing.rb +86 -0
  864. data/lib/hecks/release/runner/tagger.rb +8 -3
  865. data/lib/hecks/release/runner.rb +40 -156
  866. data/lib/hecks/rendering.rb +13 -9
  867. data/lib/hecks/router/door.rb +37 -0
  868. data/lib/hecks/router/namespace_installer.rb +45 -83
  869. data/lib/hecks/router/options_proxy.rb +44 -0
  870. data/lib/hecks/runtime/adapter_lookup.rb +45 -24
  871. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -8
  872. data/lib/hecks/runtime/command_interpreter/delegation.rb +116 -0
  873. data/lib/hecks/runtime/command_interpreter/enforcement.rb +38 -0
  874. data/lib/hecks/runtime/command_interpreter/hydration.rb +139 -0
  875. data/lib/hecks/runtime/command_interpreter/list_mutations.rb +98 -0
  876. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +67 -114
  877. data/lib/hecks/runtime/command_interpreter/persisting.rb +96 -0
  878. data/lib/hecks/runtime/command_interpreter.rb +57 -352
  879. data/lib/hecks/runtime/command_rules/admissibility.rb +64 -147
  880. data/lib/hecks/runtime/command_rules/arithmetic.rb +13 -72
  881. data/lib/hecks/runtime/command_rules/authorization.rb +9 -9
  882. data/lib/hecks/runtime/command_rules/emission.rb +13 -14
  883. data/lib/hecks/runtime/command_rules/guard_state.rb +49 -0
  884. data/lib/hecks/runtime/command_rules/invariants.rb +84 -0
  885. data/lib/hecks/runtime/command_rules/operands.rb +88 -0
  886. data/lib/hecks/runtime/command_rules/references.rb +59 -57
  887. data/lib/hecks/runtime/command_rules/tenant_boundary.rb +69 -0
  888. data/lib/hecks/runtime/dependency_planning/analyzer.rb +90 -0
  889. data/lib/hecks/runtime/dependency_planning/expression_reads.rb +73 -0
  890. data/lib/hecks/runtime/dependency_planning/mutation_analysis.rb +89 -0
  891. data/lib/hecks/runtime/dependency_planning/rule_analysis.rb +82 -0
  892. data/lib/hecks/runtime/dependency_planning.rb +3 -250
  893. data/lib/hecks/runtime/dispatcher/queries.rb +62 -0
  894. data/lib/hecks/runtime/dispatcher/result.rb +55 -0
  895. data/lib/hecks/runtime/dispatcher/routing.rb +107 -0
  896. data/lib/hecks/runtime/dispatcher.rb +64 -209
  897. data/lib/hecks/runtime/entity_element/location.rb +124 -0
  898. data/lib/hecks/runtime/entity_element/mutations.rb +150 -0
  899. data/lib/hecks/runtime/entity_element.rb +5 -177
  900. data/lib/hecks/runtime/entity_interpreter/enforcement.rb +51 -0
  901. data/lib/hecks/runtime/entity_interpreter/locating.rb +62 -0
  902. data/lib/hecks/runtime/entity_interpreter/resolution.rb +42 -0
  903. data/lib/hecks/runtime/entity_interpreter/saving.rb +49 -0
  904. data/lib/hecks/runtime/entity_interpreter.rb +45 -164
  905. data/lib/hecks/runtime/identity.rb +15 -9
  906. data/lib/hecks/runtime/instance.rb +11 -7
  907. data/lib/hecks/runtime/interpreting.rb +16 -8
  908. data/lib/hecks/runtime/invocation.rb +3 -155
  909. data/lib/hecks/runtime/invocation_builder.rb +132 -0
  910. data/lib/hecks/runtime/invocation_facts.rb +87 -0
  911. data/lib/hecks/runtime/loader/boot_steps.rb +96 -0
  912. data/lib/hecks/runtime/loader/described.rb +27 -0
  913. data/lib/hecks/runtime/loader.rb +27 -114
  914. data/lib/hecks/runtime/outbox/consumer_runner.rb +40 -0
  915. data/lib/hecks/runtime/outbox/fanout.rb +82 -0
  916. data/lib/hecks/runtime/outbox/relay.rb +149 -0
  917. data/lib/hecks/runtime/outbox.rb +3 -214
  918. data/lib/hecks/runtime/policy_interpreter/arguments.rb +67 -0
  919. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +96 -0
  920. data/lib/hecks/runtime/policy_interpreter.rb +22 -137
  921. data/lib/hecks/runtime/port_operation_interpreter.rb +18 -17
  922. data/lib/hecks/runtime/query_interpreter/arguments.rb +51 -0
  923. data/lib/hecks/runtime/query_interpreter/entity_rows.rb +82 -0
  924. data/lib/hecks/runtime/query_interpreter/outside_answer.rb +89 -0
  925. data/lib/hecks/runtime/query_interpreter.rb +43 -191
  926. data/lib/hecks/runtime/reaction_invocation/identities.rb +92 -0
  927. data/lib/hecks/runtime/reaction_invocation/target_resolution.rb +88 -0
  928. data/lib/hecks/runtime/reaction_invocation.rb +66 -183
  929. data/lib/hecks/runtime/reaction_outcome.rb +7 -3
  930. data/lib/hecks/runtime/read_model_interpreter/head_ordering.rb +49 -0
  931. data/lib/hecks/runtime/read_model_interpreter/reductions.rb +123 -0
  932. data/lib/hecks/runtime/read_model_interpreter/shaping.rb +100 -0
  933. data/lib/hecks/runtime/read_model_interpreter.rb +71 -214
  934. data/lib/hecks/runtime/reference_hop.rb +11 -11
  935. data/lib/hecks/runtime/refusal_wording.rb +11 -8
  936. data/lib/hecks/runtime/registry/chapter_verification.rb +84 -0
  937. data/lib/hecks/runtime/registry/declarations.rb +17 -0
  938. data/lib/hecks/runtime/registry/durability_warnings.rb +71 -0
  939. data/lib/hecks/runtime/registry/hecksagon_rules.rb +124 -0
  940. data/lib/hecks/runtime/registry/merging.rb +49 -0
  941. data/lib/hecks/runtime/registry/providers.rb +139 -0
  942. data/lib/hecks/runtime/registry/query_verification.rb +144 -0
  943. data/lib/hecks/runtime/registry/read_repository.rb +61 -0
  944. data/lib/hecks/runtime/registry/runtime_state.rb +27 -0
  945. data/lib/hecks/runtime/registry/saga_persistence.rb +12 -8
  946. data/lib/hecks/runtime/registry/verification.rb +45 -389
  947. data/lib/hecks/runtime/registry/world_defaults.rb +3 -3
  948. data/lib/hecks/runtime/registry.rb +58 -296
  949. data/lib/hecks/runtime/remote_dispatcher.rb +47 -31
  950. data/lib/hecks/runtime/saga_interpreter/compensation.rb +90 -0
  951. data/lib/hecks/runtime/saga_interpreter/correlation.rb +19 -10
  952. data/lib/hecks/runtime/saga_interpreter/delivery.rb +147 -0
  953. data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +63 -0
  954. data/lib/hecks/runtime/saga_interpreter/transitions.rb +112 -0
  955. data/lib/hecks/runtime/saga_interpreter.rb +41 -320
  956. data/lib/hecks/runtime/tenant_check.rb +14 -9
  957. data/lib/hecks/runtime/value/admission.rb +28 -19
  958. data/lib/hecks/runtime/value/coercion.rb +55 -404
  959. data/lib/hecks/runtime/value/entity_list_coercion.rb +27 -29
  960. data/lib/hecks/runtime/value/field_checks.rb +57 -100
  961. data/lib/hecks/runtime/value/flags.rb +65 -0
  962. data/lib/hecks/runtime/value/identifiers.rb +64 -0
  963. data/lib/hecks/runtime/value/references.rb +195 -0
  964. data/lib/hecks/runtime/value/shape_checks.rb +61 -0
  965. data/lib/hecks/runtime/value/validation.rb +125 -0
  966. data/lib/hecks/runtime/value.rb +18 -6
  967. data/lib/hecks/rust_build/conformance/surface.rb +75 -0
  968. data/lib/hecks/rust_build/conformance.rb +27 -59
  969. data/lib/hecks/rust_build/conformance_fuzz.rb +26 -15
  970. data/lib/hecks/rust_build/coverage.rb +32 -104
  971. data/lib/hecks/rust_build/coverage_parts/expected.rb +68 -0
  972. data/lib/hecks/rust_build/coverage_parts/printer.rb +75 -0
  973. data/lib/hecks/rust_build/host.rb +23 -13
  974. data/lib/hecks/rust_build/kernel_input.rb +19 -12
  975. data/lib/hecks/rust_build/native_build.rb +19 -15
  976. data/lib/hecks/rust_build/project_rust/domain_loader.rb +75 -0
  977. data/lib/hecks/rust_build/project_rust/root_mod/notes.rb +66 -0
  978. data/lib/hecks/rust_build/project_rust/root_mod.rb +22 -55
  979. data/lib/hecks/rust_build/project_rust/target_ir.rb +74 -0
  980. data/lib/hecks/rust_build/project_rust.rb +21 -89
  981. data/lib/hecks/rust_build/wasm.rb +11 -4
  982. data/lib/hecks/rust_build/wasm_browser.rb +7 -7
  983. data/lib/hecks/rust_build/write_if_changed.rb +3 -6
  984. data/lib/hecks/rust_build.rb +7 -3
  985. data/lib/hecks/storehouse/audit.rb +106 -0
  986. data/lib/hecks/storehouse/callers.rb +73 -0
  987. data/lib/hecks/storehouse/dispatching.rb +149 -0
  988. data/lib/hecks/storehouse/introspection.rb +145 -0
  989. data/lib/hecks/storehouse/querying.rb +78 -0
  990. data/lib/hecks/storehouse.rb +43 -451
  991. data/lib/hecks/tickets/bluebook/tickets.bluebook +29 -0
  992. data/lib/hecks/tools/argument_gate_matrix/dispatching.rb +69 -0
  993. data/lib/hecks/tools/argument_gate_matrix/rows.rb +121 -0
  994. data/lib/hecks/tools/argument_gate_matrix/violations.rb +108 -0
  995. data/lib/hecks/tools/argument_gate_matrix.rb +43 -212
  996. data/lib/hecks/tools/ci_gate_decision.rb +21 -14
  997. data/lib/hecks/tools/ci_gates.rb +40 -26
  998. data/lib/hecks/tools/comment_style/baseline.rb +41 -0
  999. data/lib/hecks/tools/comment_style/caps_words.rb +104 -0
  1000. data/lib/hecks/tools/comment_style/cli.rb +121 -0
  1001. data/lib/hecks/tools/comment_style/dictionary.rb +60 -0
  1002. data/lib/hecks/tools/comment_style/fixing.rb +119 -0
  1003. data/lib/hecks/tools/comment_style/long_blocks.rb +51 -0
  1004. data/lib/hecks/tools/comment_style/masking.rb +94 -0
  1005. data/lib/hecks/tools/comment_style/patterns.rb +61 -0
  1006. data/lib/hecks/tools/comment_style/run.rb +161 -0
  1007. data/lib/hecks/tools/comment_style/signature.rb +59 -0
  1008. data/lib/hecks/tools/comment_style/source_file.rb +105 -0
  1009. data/lib/hecks/tools/comment_style/structure_checks.rb +113 -0
  1010. data/lib/hecks/tools/comment_style/text_checks.rb +67 -0
  1011. data/lib/hecks/tools/comment_style/vocabulary.rb +55 -0
  1012. data/lib/hecks/tools/comment_style/walker.rb +136 -0
  1013. data/lib/hecks/tools/comment_style.rb +17 -1000
  1014. data/lib/hecks/tools/corpus_report.rb +26 -16
  1015. data/lib/hecks/tools/deploy_recipe/targets.rb +61 -0
  1016. data/lib/hecks/tools/deploy_recipe/worlds.rb +114 -0
  1017. data/lib/hecks/tools/deploy_recipe.rb +60 -174
  1018. data/lib/hecks/tools/deploy_recipe_lint/checks.rb +78 -0
  1019. data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +88 -0
  1020. data/lib/hecks/tools/deploy_recipe_lint/makefile.rb +84 -0
  1021. data/lib/hecks/tools/deploy_recipe_lint.rb +29 -192
  1022. data/lib/hecks/tools/drop_implicit_append_fields.rb +20 -12
  1023. data/lib/hecks/tools/era_projection_backfill.rb +50 -33
  1024. data/lib/hecks/tools/era_reattest/reporting.rb +55 -0
  1025. data/lib/hecks/tools/era_reattest.rb +32 -43
  1026. data/lib/hecks/tools/evolve_run/arguments.rb +49 -0
  1027. data/lib/hecks/tools/evolve_run/words.rb +60 -0
  1028. data/lib/hecks/tools/evolve_run.rb +43 -90
  1029. data/lib/hecks/tools/fuzz_sweep/findings.rb +106 -0
  1030. data/lib/hecks/tools/fuzz_sweep/options.rb +69 -0
  1031. data/lib/hecks/tools/fuzz_sweep/pool.rb +74 -0
  1032. data/lib/hecks/tools/fuzz_sweep/reporting.rb +88 -0
  1033. data/lib/hecks/tools/fuzz_sweep.rb +75 -273
  1034. data/lib/hecks/tools/gate.rb +31 -16
  1035. data/lib/hecks/tools/heki_compaction.rb +63 -42
  1036. data/lib/hecks/tools/hoist_local_givens/rewriting.rb +119 -0
  1037. data/lib/hecks/tools/hoist_local_givens.rb +89 -157
  1038. data/lib/hecks/tools/journal_compaction.rb +40 -31
  1039. data/lib/hecks/tools/lanes/files.rb +82 -0
  1040. data/lib/hecks/tools/lanes/live.rb +41 -0
  1041. data/lib/hecks/tools/lanes/rows.rb +45 -0
  1042. data/lib/hecks/tools/lanes/ruleset.rb +44 -0
  1043. data/lib/hecks/tools/lanes/watch_workflow.rb +82 -0
  1044. data/lib/hecks/tools/lanes/workflow.rb +79 -0
  1045. data/lib/hecks/tools/lanes.rb +71 -0
  1046. data/lib/hecks/tools/oidc_manifests.rb +10 -9
  1047. data/lib/hecks/tools/query_ir_run.rb +7 -3
  1048. data/lib/hecks/tools/regeneration_run.rb +40 -26
  1049. data/lib/hecks/tools/rust_comment_style/caps_words.rb +98 -0
  1050. data/lib/hecks/tools/rust_comment_style/fixing.rb +102 -0
  1051. data/lib/hecks/tools/rust_comment_style/masking.rb +85 -0
  1052. data/lib/hecks/tools/rust_comment_style/run.rb +94 -0
  1053. data/lib/hecks/tools/rust_comment_style/source_file.rb +71 -0
  1054. data/lib/hecks/tools/rust_comment_style/structure.rb +79 -0
  1055. data/lib/hecks/tools/rust_comment_style/text_checks.rb +63 -0
  1056. data/lib/hecks/tools/rust_comment_style/tokenizer.rb +102 -0
  1057. data/lib/hecks/tools/rust_comment_style.rb +38 -535
  1058. data/lib/hecks/tools/sequence_script.rb +20 -14
  1059. data/lib/hecks/tools/site_routes/cli.rb +70 -0
  1060. data/lib/hecks/tools/site_routes/root_files.rb +59 -0
  1061. data/lib/hecks/tools/site_routes/templates.rb +77 -0
  1062. data/lib/hecks/tools/site_routes.rb +84 -160
  1063. data/lib/hecks/tools/tail_merge.rb +45 -37
  1064. data/lib/hecks/tools/tenant_provisioning.rb +45 -31
  1065. data/lib/hecks/tools/tools_doc.rb +42 -19
  1066. data/lib/hecks/tools/translation_audit/domain_loading.rb +71 -0
  1067. data/lib/hecks/tools/translation_audit/edges.rb +71 -0
  1068. data/lib/hecks/tools/translation_audit/verdicts.rb +107 -0
  1069. data/lib/hecks/tools/translation_audit.rb +30 -161
  1070. data/lib/hecks/tools/translation_scaffold/reporting.rb +40 -0
  1071. data/lib/hecks/tools/translation_scaffold.rb +77 -60
  1072. data/lib/hecks/tools.rb +1 -0
  1073. data/lib/hecks/vendoring.rb +37 -11
  1074. data/lib/hecks/version.rb +1 -1
  1075. data/lib/hecks/vocabulary.rb +16 -1
  1076. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +7 -9
  1077. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +8 -6
  1078. data/rust/.cargo/mutants.toml +8 -0
  1079. data/rust/host/Cargo.toml +5 -0
  1080. data/rust/host/HECKS_RELEASE +1 -1
  1081. data/rust/host/src/auth.rs +32 -0
  1082. data/rust/host/src/web.rs +2 -3
  1083. data/rust/src/kernel/dispatch.rs +4 -0
  1084. data/rust/src/kernel/dispatch_guard_tests.rs +506 -0
  1085. data/rust/src/kernel/orchestrate.rs +4 -0
  1086. data/rust/src/kernel/orchestrate_guard_tests.rs +708 -0
  1087. metadata +591 -3
  1088. /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
@@ -27,6 +27,28 @@ module Hecks
27
27
  # projected from is still being built (`MetaValidator.bootstrapping?`).
28
28
  RUBY
29
29
 
30
+ # The generated file, with `@@CALLS@@` and `@@RESOLVES@@` standing for the table rows.
31
+ TEMPLATE = <<~RUBY.freeze
32
+ #{HEADER}
33
+ module Hecks
34
+ module Bluebook
35
+ module DSL
36
+ module BootstrapTable
37
+ # [context, word] => the method a word's whole call forwards to.
38
+ CALLS = {
39
+ @@CALLS@@
40
+ }.freeze
41
+
42
+ # [word, context] => the RuleReference primitive a bare reference resolves through.
43
+ RESOLVES = {
44
+ @@RESOLVES@@
45
+ }.freeze
46
+ end
47
+ end
48
+ end
49
+ end
50
+ RUBY
51
+
30
52
  module_function
31
53
 
32
54
  # Projects the bootstrap fallback table; both arguments are ignored (the table is
@@ -56,12 +78,18 @@ module Hecks
56
78
  def calls(rows = live_keywords)
57
79
  rows.reject { |row| row[:calls].to_s.empty? }
58
80
  .group_by { |row| [row[:context], row[:word]] }
59
- .to_h do |key, same_word|
60
- targets = same_word.map { |row| row[:calls] }.uniq
61
- raise Conflict, "#{key.inspect} names more than one method: #{targets.join(', ')}" if targets.size > 1
81
+ .to_h { |key, same_word| [key, single_target(key, same_word)] }
82
+ end
62
83
 
63
- [key, targets.first.to_sym]
64
- end
84
+ # @param key [Array<String>] a `[context, word]`
85
+ # @param same_word [Array<Hash{Symbol => String}>] the rows declaring that word
86
+ # @return [Symbol] the one method they all name
87
+ # @raise [Projections::BootstrapTable::Conflict] if they name different methods
88
+ def single_target(key, same_word)
89
+ targets = same_word.map { |row| row[:calls] }.uniq
90
+ raise Conflict, "#{key.inspect} names more than one method: #{targets.join(", ")}" if targets.size > 1
91
+
92
+ targets.first.to_sym
65
93
  end
66
94
 
67
95
  # `[word, context] => { resolves_via:, disambiguator: }`, in RuleReference's key order.
@@ -84,31 +112,17 @@ module Hecks
84
112
  def render(_bluebook)
85
113
  rows = live_keywords
86
114
  calls_lines = calls(rows).map { |key, target| " #{key.inspect} => #{target.inspect}" }
87
- resolves_lines = resolves(rows).map do |key, rule|
88
- fields = rule.map { |name, value| "#{name}: #{value.inspect}" }.join(", ")
89
- " #{key.inspect} => { #{fields} }.freeze"
90
- end
115
+ resolves_lines = resolves(rows).map { |key, rule| resolves_line(key, rule) }
91
116
 
92
- <<~RUBY
93
- #{HEADER}
94
- module Hecks
95
- module Bluebook
96
- module DSL
97
- module BootstrapTable
98
- # [context, word] => the method a word's whole call forwards to.
99
- CALLS = {
100
- #{calls_lines.join(",\n")}
101
- }.freeze
102
-
103
- # [word, context] => the RuleReference primitive a bare reference resolves through.
104
- RESOLVES = {
105
- #{resolves_lines.join(",\n")}
106
- }.freeze
107
- end
108
- end
109
- end
110
- end
111
- RUBY
117
+ TEMPLATE.sub("@@CALLS@@") { calls_lines.join(",\n") }.sub("@@RESOLVES@@") { resolves_lines.join(",\n") }
118
+ end
119
+
120
+ # @param key [Array<String>] a `[word, context]`
121
+ # @param rule [Hash{Symbol => String}] its `resolves_via:` and `disambiguator:` columns
122
+ # @return [String] its entry in the `RESOLVES` literal
123
+ def resolves_line(key, rule)
124
+ fields = rule.map { |name, value| "#{name}: #{value.inspect}" }.join(", ")
125
+ " #{key.inspect} => { #{fields} }.freeze"
112
126
  end
113
127
  end
114
128
  end
@@ -0,0 +1,32 @@
1
+ module Hecks
2
+ module Projections
3
+ module Deploy
4
+ # The Makefile lines that read a stack's outputs for the temporary bastion: one `$(eval ...)`
5
+ # per output, and the `--parameter-overrides` the bastion stack is deployed with. Included
6
+ # into a stack object that answers `stack_outputs` and `bastion_parameters`.
7
+ module BastionLines
8
+ # @return [String] one `$(eval VAR := $(shell aws cloudformation describe-stacks ...))` per
9
+ # output, tab-separated for a Makefile recipe
10
+ def eval_lines
11
+ stack_outputs.map { |output| eval_line(output) }.join("\n\t")
12
+ end
13
+
14
+ # @return [String] `Name=$(VAR)` for each bastion parameter, space-separated
15
+ def parameter_overrides
16
+ outputs = stack_outputs
17
+ bastion_parameters.map do |parameter|
18
+ source = outputs.find { |output| output[:key] == parameter[:from_output] }
19
+ "#{parameter[:name]}=$(#{source[:var]})"
20
+ end.join(" ")
21
+ end
22
+
23
+ private
24
+
25
+ def eval_line(output)
26
+ "$(eval #{output[:var]} := $(shell aws cloudformation describe-stacks --stack-name $(STACK) " \
27
+ "--query \"Stacks[0].Outputs[?OutputKey=='#{output[:key]}'].OutputValue\" --output text))"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ module Hecks
2
+ module Projections
3
+ module Deploy
4
+ module Box
5
+ # The IAM statements of the box's role: the S3 buckets it reads and writes and the Secrets
6
+ # Manager secrets it reads and overwrites. Mixed into `Box`, which supplies `template`.
7
+ module Access
8
+ SECRET_ARN = "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:".freeze
9
+
10
+ # The role's S3 policy: every declared bucket readable, and writable only on a production
11
+ # box, so a rehearsal never changes the real objects.
12
+ #
13
+ # @param plan [Settings::Plan] the resolved settings
14
+ # @return [String] a policy list item, indented into the role's `Policies`, or nothing
15
+ def s3_policy(plan)
16
+ return "" if plan.s3_buckets.empty?
17
+
18
+ "#{s3_rows(plan.s3_buckets).map { |row| " #{row}" }.join("\n")}\n"
19
+ end
20
+
21
+ # @param resources [Array<String>] the bucket and object ARNs a box may read
22
+ # @return [Array<String>] the policy's head and its read statement, relative to `Policies`
23
+ def s3_read_rows(resources)
24
+ ["- PolicyName: s3-access", " PolicyDocument:", " Version: \"2012-10-17\"", " Statement:",
25
+ " - Effect: Allow", " Action: [s3:GetObject, s3:ListBucket]", " Resource:"] +
26
+ resources.map { |r| " - !Sub \"#{r}\"" }
27
+ end
28
+
29
+ # @param resources [Array<String>] the object ARNs a production box may write
30
+ # @return [Array<String>] the production-only write statement, relative to `Policies`
31
+ def s3_write_rows(resources)
32
+ [" - !If", " - IsProduction", " - Effect: Allow",
33
+ " Action: [s3:PutObject, s3:DeleteObject]", " Resource:"] +
34
+ resources.map { |r| " - !Sub \"#{r}\"" } + [" - !Ref AWS::NoValue"]
35
+ end
36
+
37
+ # One Secrets Manager statement resource per prefix. A name without a trailing `*` gets
38
+ # `-*` for the random suffix AWS appends to every secret ARN.
39
+ #
40
+ # @param plan [Settings::Plan] the resolved settings
41
+ # @return [String] YAML list items, one per prefix, ending in a newline
42
+ def secret_resources(plan)
43
+ named = [plan.origin_secret, plan.tunnel_service&.token_secret].compact
44
+ arns = (plan.secret_prefixes + named).map { |name| name.end_with?("*") ? name : "#{name}-*" }
45
+ arns.uniq.map { |pattern| "#{" " * 18}- !Sub \"#{SECRET_ARN}#{pattern}\"\n" }.join.chomp
46
+ end
47
+
48
+ # The statement that lets a production box overwrite the secrets named as writable.
49
+ #
50
+ # @param plan [Settings::Plan] the resolved settings
51
+ # @return [String] a policy statement for the role, or nothing when none are declared
52
+ def writable_secrets(plan)
53
+ return "" if plan.writable_secrets.empty?
54
+
55
+ arns = plan.writable_secrets.map { |name| name.end_with?("*") ? name : "#{name}-*" }.uniq
56
+ resources = arns.map { |pattern| "#{" " * 20}- !Sub \"#{SECRET_ARN}#{pattern}\"\n" }.join
57
+ template("writable-secrets.yaml.tmpl", "RESOURCES" => resources.chomp).chomp
58
+ end
59
+
60
+ private
61
+
62
+ def s3_rows(buckets)
63
+ rows = s3_read_rows(buckets.flat_map { |b| [s3_arn(b.name), s3_arn("#{b.name}/*")] })
64
+ writes = buckets.select(&:write).map { |b| s3_arn("#{b.name}/*") }
65
+ writes.empty? ? rows : rows + s3_write_rows(writes)
66
+ end
67
+
68
+ def s3_arn(path) = "arn:${AWS::Partition}:s3:::#{path}"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,87 @@
1
+ module Hecks
2
+ module Projections
3
+ module Deploy
4
+ module Box
5
+ # The proxy's `Caddyfile`: an optional origin-secret guard, one block per route and a
6
+ # default for everything else. Mixed into `Box`, which supplies `template` and the
7
+ # constants.
8
+ module Caddy
9
+ # The proxy's configuration: an optional origin-secret guard, one block per route and a
10
+ # default for everything else.
11
+ #
12
+ # @param plan [Settings::Plan] the resolved settings
13
+ # @return [String] the Caddyfile
14
+ def caddyfile(plan)
15
+ guarded = !plan.origin_header.nil?
16
+ site =
17
+ if guarded
18
+ "\t@origin header #{plan.origin_header} {$ORIGIN_SECRET}\n\n\thandle @origin {\n" \
19
+ "#{indent(indent(route_blocks(plan)))}\t}\n\n\thandle {\n\t\trespond \"Forbidden\" 403\n\t}\n"
20
+ else
21
+ indent(route_blocks(plan))
22
+ end
23
+ "#{caddy_header(plan)}#{caddy_global(guarded)}\n:80 {\n#{site}}\n\n#{CADDY_EXTRA}"
24
+ end
25
+
26
+ # @param plan [Settings::Plan] the resolved settings
27
+ # @return [String] the `handle` blocks for each route, then the default
28
+ def route_blocks(plan)
29
+ routes = plan.routes.each_with_index.map { |route, i| route_block(plan, route, i + 1) }
30
+ "#{routes.join}handle {\n#{upstream(plan.default.port)}}\n"
31
+ end
32
+
33
+ # One upstream. A request that arrives while its container is being replaced
34
+ # waits, and is tried again every quarter second for up to 15 seconds, so a
35
+ # deploy shows a visitor a slow page instead of a 502.
36
+ #
37
+ # @param port [Integer] the container's port
38
+ # @return [String] the `reverse_proxy` block, one tab in, ending in a newline
39
+ def upstream(port)
40
+ "\treverse_proxy 127.0.0.1:#{port} {\n\t\tlb_try_duration 15s\n\t\tlb_try_interval 250ms\n\t}\n"
41
+ end
42
+
43
+ # @param plan [Settings::Plan] the resolved settings
44
+ # @return [String] the comment that opens the Caddyfile
45
+ def caddy_header(plan)
46
+ origin =
47
+ if plan.origin_header
48
+ "Only requests that carry #{plan.origin_header} with the origin secret are proxied;\n" \
49
+ "# everything else gets a flat 403.\n"
50
+ else
51
+ "Every request is proxied.\n"
52
+ end
53
+ "# #{plan.infra_name}'s proxy. #{origin}"
54
+ end
55
+
56
+ # With a guard, the proxy trusts every source: a request that reaches a `handle` block has
57
+ # already proved it came through the CDN by presenting the secret, and everything else is
58
+ # refused. Caddy then keeps the client address the CDN put in X-Forwarded-For.
59
+ #
60
+ # @param guarded [Boolean] whether an origin secret guards the site
61
+ # @return [String] the global options block
62
+ def caddy_global(guarded)
63
+ options = "\t# No certificate for the :80 site. disable_redirects, not off, so a listener a rehearsal\n" \
64
+ "\t# mounts under caddy-extra can still ask for `tls internal`.\n" \
65
+ "\tauto_https disable_redirects\n\tadmin off\n"
66
+ return "{\n#{options}}\n" unless guarded
67
+
68
+ "{\n#{options}\tservers {\n\t\ttrusted_proxies static 0.0.0.0/0 ::/0\n\t}\n}\n"
69
+ end
70
+
71
+ # @param text [String] lines to indent one level with a tab
72
+ # @return [String] the text, each non-blank line prefixed with a tab
73
+ def indent(text)
74
+ text.lines.map { |line| line.strip.empty? ? line : "\t#{line}" }.join
75
+ end
76
+
77
+ private
78
+
79
+ def route_block(plan, route, number)
80
+ port = plan.containers.find { |c| c.name == route.container }.port
81
+ "@r#{number} path #{route.paths.join(" ")}\nhandle @r#{number} {\n#{upstream(port)}}\n\n"
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,70 @@
1
+ require "json"
2
+
3
+ module Hecks
4
+ module Projections
5
+ module Deploy
6
+ module Box
7
+ # What the box's Compose file is rendered from: the script that renders it and the
8
+ # `services.json` it reads. Mixed into `Box`, which supplies `template`.
9
+ module Compose
10
+ # @param plan [Settings::Plan] the resolved settings
11
+ # @param region [String] the validated region
12
+ # @return [String] the script that renders the Compose file, from `services.json` or from
13
+ # an ECS task definition when the world names one
14
+ def render_compose_sh(plan, region)
15
+ if plan.task_definition
16
+ template("render-compose-taskdef.sh.tmpl", "STACK" => plan.infra_name, "FAMILY" => plan.task_definition,
17
+ "PROXY_IMAGE" => plan.proxy_image)
18
+ else
19
+ template("render-compose.sh.tmpl", "STACK" => plan.infra_name, "REGION" => region,
20
+ "DB_NAME" => plan.database_name, "PROXY_IMAGE" => plan.proxy_image)
21
+ end
22
+ end
23
+
24
+ # The compose source: one entry per container, plus the origin secret the proxy checks.
25
+ #
26
+ # @param plan [Settings::Plan] the resolved settings
27
+ # @return [String] `services.json`
28
+ def services_json(plan)
29
+ services = plan.containers.to_h { |c| [c.name, service_entry(plan, c)] }
30
+ document = { "services" => services, "origin" => origin_entry(plan) }
31
+ document["task_definition"] = plan.task_definition if plan.task_definition
32
+ document["tunnel"] = tunnel_entry(plan.tunnel_service) if plan.tunnel_service
33
+ # An empty object prints as `{}` or `{` newline `}`, depending on the json gem.
34
+ "#{JSON.pretty_generate(document).gsub(/\{\s*\}/, "{}")}\n"
35
+ end
36
+
37
+ # A container's entry. With a task definition the image, environment and secrets are read
38
+ # from it at deploy time, so only the name and port are written here.
39
+ #
40
+ # @param plan [Settings::Plan] the resolved settings
41
+ # @param container [Settings::Container] the container
42
+ # @return [Hash{String => Object}] its entry in `services.json`
43
+ def service_entry(plan, container)
44
+ entry = { "name" => container.name, "port" => container.port }
45
+ return entry if plan.task_definition
46
+
47
+ { "name" => container.name, "repository" => container.repository, "port" => container.port,
48
+ "env" => container.env, "secrets" => container.secrets }
49
+ end
50
+
51
+ # @param tunnel [Settings::Tunnel] the declared tunnel service
52
+ # @return [Hash{String => Object}] its entry in `services.json`
53
+ def tunnel_entry(tunnel)
54
+ { "url" => "http://127.0.0.1:#{tunnel.port}", "token_secret" => tunnel.token_secret, "image" => tunnel.image }
55
+ end
56
+
57
+ private
58
+
59
+ def origin_entry(plan)
60
+ return nil unless plan.origin_secret
61
+
62
+ origin = { "header" => plan.origin_header, "secret" => plan.origin_secret }
63
+ origin["env"] = plan.origin_env if plan.origin_env.any?
64
+ origin
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,5 +1,6 @@
1
1
  require "shellwords"
2
2
  require_relative "../scripts"
3
+ require_relative "hosting_parts"
3
4
 
4
5
  module Hecks
5
6
  module Projections
@@ -10,6 +11,8 @@ module Hecks
10
11
  # Container names, repositories, parameters and stacks come from the resolved plan, never
11
12
  # from this file.
12
13
  module Hosting
14
+ extend HostingParts
15
+
13
16
  module_function
14
17
 
15
18
  # Adds the hosting scripts to a box file map when the world opts in.
@@ -63,116 +66,12 @@ module Hecks
63
66
  # @param region [String] the validated AWS region
64
67
  # @return [String] `smoke-after-deploy.sh`
65
68
  def smoke_after_deploy_sh(plan, region)
66
- hosting = plan.hosting
67
- image_stack = hosting.stack
69
+ image_stack = plan.hosting.stack
68
70
  Box.template("smoke-after-deploy.sh.tmpl",
69
71
  "STACK" => plan.infra_name, "SETTINGS" => smoke_constants(plan, region),
70
72
  "SETTLE_CHECKS" => settle_checks(plan),
71
73
  "IMAGE_STACK_WAIT" => image_stack ? ", stack #{image_stack}" : "")
72
74
  end
73
-
74
- # @param plan [Settings::Plan] the resolved settings
75
- # @return [String] the sentence that says what the roll puts on the box
76
- def mode_summary(plan)
77
- if plan.task_definition
78
- <<~TEXT.gsub(/^/, "# ").chomp
79
- It then sets the stack's matching image-tag parameter (UsePreviousValue for every other
80
- one, and it checks that only that one changed), reads the task definition the stack
81
- registers, refuses to roll it unless it carries the pushed image, and rolls it with
82
- deploy-box.sh.
83
- TEXT
84
- else
85
- <<~TEXT.gsub(/^/, "# ").chomp
86
- It then rolls the box with deploy-box.sh, naming the new tag for this container and the
87
- tag the box runs now for every other one.
88
- TEXT
89
- end
90
- end
91
-
92
- # @param plan [Settings::Plan] the resolved settings
93
- # @return [String] the comment lines that list what "settled" means
94
- def settle_checks(plan)
95
- stacks = plan.hosting.stack ? "the box stack and the #{plan.hosting.stack} stack are" : "the box stack is"
96
- checks = ["#{stacks} CREATE_COMPLETE or UPDATE_COMPLETE, never rolled back or failed;",
97
- "every container and the proxy of the box's Compose project is up and has stayed up;"]
98
- if plan.task_definition
99
- checks << "each container runs the image of the task definition it was rolled from (the latest " \
100
- "#{plan.task_definition} unless TASKDEF says otherwise)."
101
- end
102
- checks.map { |line| "# - #{line}" }.join("\n")
103
- end
104
-
105
- def deploy_constants(plan, region)
106
- lines = { "REGION" => region }
107
- if plan.task_definition
108
- lines["FAMILY"] = plan.task_definition
109
- lines["IMAGE_STACK"] = plan.hosting.stack
110
- else
111
- lines["BOX_STACK"] = plan.box_stack
112
- lines["BOX_DIR"] = "/opt/#{plan.infra_name}"
113
- end
114
- constants(lines)
115
- end
116
-
117
- def smoke_constants(plan, region)
118
- hosting = plan.hosting
119
- watched = [plan.box_stack, hosting.stack].compact
120
- constants(
121
- "REGION" => region, "BOX_STACK" => plan.box_stack, "BOX_DIR" => "/opt/#{plan.infra_name}",
122
- "WATCHED_STACKS" => watched.join(" "),
123
- "EXPECTED_SERVICES" => (plan.containers.map(&:name) + ["caddy"]).join(" ")
124
- ).concat("\n#{smoke_defaults(plan)}")
125
- end
126
-
127
- def smoke_defaults(plan)
128
- hosting = plan.hosting
129
- [
130
- "TASK_DEFINITION=\"${TASKDEF:-#{plan.task_definition}}\"",
131
- "REPO=\"${REPO:-#{hosting.smoke_repo}}\"",
132
- "WORKFLOW=\"${WORKFLOW:-#{hosting.smoke_workflow}}\"",
133
- "SMOKE_REF=\"${SMOKE_REF:-#{hosting.smoke_ref}}\""
134
- ].join("\n")
135
- end
136
-
137
- def constants(values)
138
- values.map { |name, value| "#{name}=#{Shellwords.escape(value)}" }.join("\n")
139
- end
140
-
141
- # One case arm per container that sets the repository and image-tag parameter to use, and
142
- # the list of names the script accepts.
143
- def services_block(plan)
144
- arms = plan.containers.map do |container|
145
- setting =
146
- if plan.task_definition
147
- "CFN_PARAM_KEY=#{Shellwords.escape(container.tag_parameter)}"
148
- else
149
- "ECR_REPOSITORY=#{Shellwords.escape(container.repository)}"
150
- end
151
- " #{Shellwords.escape(container.name)}) #{setting} ;;"
152
- end
153
- <<~BASH.chomp
154
- SERVICES='#{plan.containers.map(&:name).join(' ')}'
155
-
156
- # Sets the container's settings for one service, or exits.
157
- resolve_service() {
158
- case "$1" in
159
- #{arms.join("\n")}
160
- *) echo "unknown service '$1', must be one of: ${SERVICES}" >&2; exit 2 ;;
161
- esac
162
- }
163
- BASH
164
- end
165
-
166
- def repository_step(plan)
167
- plan.task_definition ? "#{part('deploy-service.taskdef.part')}\n\n" : ""
168
- end
169
-
170
- def part(file)
171
- file ? File.read(File.join(Box::TEMPLATE_DIR, file)).chomp : ""
172
- end
173
-
174
- private_class_method :deploy_constants, :smoke_constants, :smoke_defaults, :constants,
175
- :services_block, :part, :repository_step, :settle_checks
176
75
  end
177
76
  end
178
77
  end
@@ -0,0 +1,97 @@
1
+ require "shellwords"
2
+
3
+ module Hecks
4
+ module Projections
5
+ module Deploy
6
+ module Box
7
+ # The pieces `Hosting` splices into its scripts: the settings each script starts with, the
8
+ # service case arms and the sentences that say what a roll does. Extended onto `Hosting`.
9
+ module HostingParts
10
+ # @param plan [Settings::Plan] the resolved settings
11
+ # @return [String] the sentence that says what the roll puts on the box
12
+ def mode_summary(plan)
13
+ file = plan.task_definition ? "mode-summary-taskdef.tmpl" : "mode-summary-services.tmpl"
14
+ Box.template(file, {}).gsub(/^/, "# ").chomp
15
+ end
16
+
17
+ private
18
+
19
+ # @param plan [Settings::Plan] the resolved settings
20
+ # @return [String] the comment lines that list what "settled" means
21
+ def settle_checks(plan)
22
+ stacks = plan.hosting.stack ? "the box stack and the #{plan.hosting.stack} stack are" : "the box stack is"
23
+ checks = ["#{stacks} CREATE_COMPLETE or UPDATE_COMPLETE, never rolled back or failed;",
24
+ "every container and the proxy of the box's Compose project is up and has stayed up;"]
25
+ if plan.task_definition
26
+ checks << "each container runs the image of the task definition it was rolled from (the latest " \
27
+ "#{plan.task_definition} unless TASKDEF says otherwise)."
28
+ end
29
+ checks.map { |line| "# - #{line}" }.join("\n")
30
+ end
31
+
32
+ def deploy_constants(plan, region)
33
+ lines = { "REGION" => region }
34
+ if plan.task_definition
35
+ lines["FAMILY"] = plan.task_definition
36
+ lines["IMAGE_STACK"] = plan.hosting.stack
37
+ else
38
+ lines["BOX_STACK"] = plan.box_stack
39
+ lines["BOX_DIR"] = "/opt/#{plan.infra_name}"
40
+ end
41
+ constants(lines)
42
+ end
43
+
44
+ def smoke_constants(plan, region)
45
+ hosting = plan.hosting
46
+ watched = [plan.box_stack, hosting.stack].compact
47
+ constants(
48
+ "REGION" => region, "BOX_STACK" => plan.box_stack, "BOX_DIR" => "/opt/#{plan.infra_name}",
49
+ "WATCHED_STACKS" => watched.join(" "),
50
+ "EXPECTED_SERVICES" => (plan.containers.map(&:name) + ["caddy"]).join(" ")
51
+ ).concat("\n#{smoke_defaults(plan)}")
52
+ end
53
+
54
+ def smoke_defaults(plan)
55
+ hosting = plan.hosting
56
+ [
57
+ "TASK_DEFINITION=\"${TASKDEF:-#{plan.task_definition}}\"",
58
+ "REPO=\"${REPO:-#{hosting.smoke_repo}}\"",
59
+ "WORKFLOW=\"${WORKFLOW:-#{hosting.smoke_workflow}}\"",
60
+ "SMOKE_REF=\"${SMOKE_REF:-#{hosting.smoke_ref}}\""
61
+ ].join("\n")
62
+ end
63
+
64
+ def constants(values)
65
+ values.map { |name, value| "#{name}=#{Shellwords.escape(value)}" }.join("\n")
66
+ end
67
+
68
+ # One case arm per container that sets the repository and image-tag parameter to use, and
69
+ # the list of names the script accepts.
70
+ def services_block(plan)
71
+ arms = plan.containers.map { |container| service_arm(plan, container) }
72
+ Box.template("services-block.tmpl", "NAMES" => plan.containers.map(&:name).join(" "),
73
+ "ARMS" => arms.join("\n")).chomp
74
+ end
75
+
76
+ def service_arm(plan, container)
77
+ setting =
78
+ if plan.task_definition
79
+ "CFN_PARAM_KEY=#{Shellwords.escape(container.tag_parameter)}"
80
+ else
81
+ "ECR_REPOSITORY=#{Shellwords.escape(container.repository)}"
82
+ end
83
+ " #{Shellwords.escape(container.name)}) #{setting} ;;"
84
+ end
85
+
86
+ def repository_step(plan)
87
+ plan.task_definition ? "#{part("deploy-service.taskdef.part")}\n\n" : ""
88
+ end
89
+
90
+ def part(file)
91
+ file ? File.read(File.join(Box::TEMPLATE_DIR, file)).chomp : ""
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -38,7 +38,7 @@ module Hecks
38
38
 
39
39
  unless flag
40
40
  stray = WORDS.select { |word| settings.key?(word) }
41
- raise ArgumentError, "#{stray.join(', ')} only apply with hosting_scripts true" unless stray.empty?
41
+ raise ArgumentError, "#{stray.join(", ")} only apply with hosting_scripts true" unless stray.empty?
42
42
 
43
43
  return nil
44
44
  end
@@ -20,7 +20,7 @@ module Hecks
20
20
  args = plan.task_definition ? "$(if $(TASKDEF),taskdef=$(TASKDEF))" : "$(if $(TAGS),tags=\"$(TAGS)\")"
21
21
  direct = "bash ./deploy-box.sh $(#{variable})"
22
22
  direct += " || exit $$?; TASKDEF=\"$(TASKDEF)\" bash ./smoke-after-deploy.sh" if plan.hosting
23
- "\t#{call(command: 'box_roll.run', args: args, direct: direct)}"
23
+ "\t#{call(command: "box_roll.run", args: args, direct: direct)}"
24
24
  end
25
25
 
26
26
  # @param command [String] the Deploy command, such as `box_roll.run`