hecks 3.4.2 → 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 (1099) 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/deploy/bluebook/deploy.bluebook +1510 -3
  240. data/lib/hecks/deploy/bluebook/deploy.hecksagon +57 -0
  241. data/lib/hecks/deploy/oidc.json +225 -0
  242. data/lib/hecks/doc/reference/coverage.rb +70 -0
  243. data/lib/hecks/doc/reference/harvester.rb +55 -0
  244. data/lib/hecks/doc/reference/readme.rb +89 -0
  245. data/lib/hecks/doc/reference/rendering.rb +149 -0
  246. data/lib/hecks/doc/reference.rb +14 -273
  247. data/lib/hecks/doors/cli_door/nesting.rb +34 -0
  248. data/lib/hecks/doors/cli_door/shorthand.rb +85 -0
  249. data/lib/hecks/doors/cli_door.rb +23 -95
  250. data/lib/hecks/doors/cli_runner/answers.rb +138 -0
  251. data/lib/hecks/doors/cli_runner/resolution.rb +146 -0
  252. data/lib/hecks/doors/cli_runner/settling.rb +115 -0
  253. data/lib/hecks/doors/cli_runner/streaming.rb +90 -0
  254. data/lib/hecks/doors/cli_runner/suggestions.rb +43 -0
  255. data/lib/hecks/doors/cli_runner.rb +12 -336
  256. data/lib/hecks/doors/command_request.rb +42 -31
  257. data/lib/hecks/doors/handle.rb +32 -30
  258. data/lib/hecks/doors/launcher_options.rb +62 -7
  259. data/lib/hecks/doors/mcp_door/properties.rb +47 -0
  260. data/lib/hecks/doors/mcp_door/tool_calls.rb +113 -0
  261. data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +51 -0
  262. data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +69 -0
  263. data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +97 -0
  264. data/lib/hecks/doors/mcp_door/tool_definitions.rb +15 -0
  265. data/lib/hecks/doors/mcp_door.rb +55 -301
  266. data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +92 -0
  267. data/lib/hecks/doors/mcp_door_scope/env_problems.rb +55 -0
  268. data/lib/hecks/doors/mcp_door_scope/presenter.rb +78 -0
  269. data/lib/hecks/doors/mcp_door_scope.rb +16 -172
  270. data/lib/hecks/doors/ruby_door/aggregate_door.rb +1 -1
  271. data/lib/hecks/doors/ruby_door/chapter.rb +33 -16
  272. data/lib/hecks/doors/ruby_door.rb +14 -11
  273. data/lib/hecks/doors/usage_cache.rb +14 -8
  274. data/lib/hecks/doors.rb +10 -4
  275. data/lib/hecks/embryonaut_bluebook/manifest.rb +11 -3
  276. data/lib/hecks/embryonaut_bluebook/registry/changelog.rb +26 -0
  277. data/lib/hecks/embryonaut_bluebook/registry/versions.rb +27 -0
  278. data/lib/hecks/embryonaut_bluebook/registry.rb +27 -37
  279. data/lib/hecks/embryonaut_bluebook/vendor/acceptance.rb +37 -0
  280. data/lib/hecks/embryonaut_bluebook/vendor.rb +22 -36
  281. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +9 -6
  282. data/lib/hecks/embryonaut_bluebook.rb +16 -11
  283. data/lib/hecks/engine_agreement.rb +24 -17
  284. data/lib/hecks/forms/app/commands.rb +98 -0
  285. data/lib/hecks/forms/app/queries.rb +62 -0
  286. data/lib/hecks/forms/app/records.rb +67 -0
  287. data/lib/hecks/forms/app/responses.rb +46 -0
  288. data/lib/hecks/forms/app.rb +33 -221
  289. data/lib/hecks/forms/banking_presentation.rb +5 -0
  290. data/lib/hecks/forms/command_form_renderer.rb +55 -14
  291. data/lib/hecks/forms/field_controls.rb +95 -0
  292. data/lib/hecks/forms/field_renderer.rb +34 -88
  293. data/lib/hecks/forms/field_shape.rb +9 -34
  294. data/lib/hecks/forms/html.rb +1 -1
  295. data/lib/hecks/forms/index_renderer.rb +14 -9
  296. data/lib/hecks/forms/page.rb +2 -106
  297. data/lib/hecks/forms/page_assets.rb +88 -0
  298. data/lib/hecks/forms/page_script.rb +28 -0
  299. data/lib/hecks/forms/params.rb +17 -8
  300. data/lib/hecks/forms/query_form_renderer.rb +11 -7
  301. data/lib/hecks/forms/record_renderer.rb +28 -19
  302. data/lib/hecks/forms/reference_options.rb +1 -1
  303. data/lib/hecks/forms/text_shape.rb +40 -0
  304. data/lib/hecks/fqn.rb +64 -32
  305. data/lib/hecks/framework.rb +10 -3
  306. data/lib/hecks/freezer.rb +10 -1
  307. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/fragments.rb +61 -0
  308. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/productions.rb +217 -0
  309. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +5 -194
  310. data/lib/hecks/fuzzing/combination_miner.rb +23 -12
  311. data/lib/hecks/fuzzing/concurrent_dispatch/racing.rb +64 -0
  312. data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +66 -0
  313. data/lib/hecks/fuzzing/concurrent_dispatch.rb +31 -107
  314. data/lib/hecks/fuzzing/coverage_campaign.rb +7 -7
  315. data/lib/hecks/fuzzing/differential/wire_comparison.rb +74 -0
  316. data/lib/hecks/fuzzing/differential.rb +59 -84
  317. data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +70 -0
  318. data/lib/hecks/fuzzing/domain_generator/builder/attribute_shapes.rb +105 -0
  319. data/lib/hecks/fuzzing/domain_generator/builder/shapes.rb +97 -0
  320. data/lib/hecks/fuzzing/domain_generator/builder/wiring.rb +128 -0
  321. data/lib/hecks/fuzzing/domain_generator/builder.rb +105 -0
  322. data/lib/hecks/fuzzing/domain_generator/pruning.rb +90 -0
  323. data/lib/hecks/fuzzing/domain_generator/removals.rb +62 -0
  324. data/lib/hecks/fuzzing/domain_generator/rendering.rb +94 -0
  325. data/lib/hecks/fuzzing/domain_generator/tokens.rb +38 -0
  326. data/lib/hecks/fuzzing/domain_generator.rb +7 -555
  327. data/lib/hecks/fuzzing/era_boundary.rb +34 -24
  328. data/lib/hecks/fuzzing/form_census.rb +18 -8
  329. data/lib/hecks/fuzzing/generated_domain_check.rb +23 -11
  330. data/lib/hecks/fuzzing/isolated_boot/copying.rb +62 -0
  331. data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +133 -0
  332. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +102 -0
  333. data/lib/hecks/fuzzing/isolated_boot.rb +25 -252
  334. data/lib/hecks/fuzzing/persistence_parity.rb +5 -5
  335. data/lib/hecks/fuzzing/properties/aggregation_recompute.rb +121 -0
  336. data/lib/hecks/fuzzing/properties/catalog.rb +138 -0
  337. data/lib/hecks/fuzzing/properties/corrections.rb +23 -20
  338. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +64 -185
  339. data/lib/hecks/fuzzing/properties/group_by_recompute.rb +69 -0
  340. data/lib/hecks/fuzzing/properties/guards.rb +76 -108
  341. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +66 -227
  342. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +46 -35
  343. data/lib/hecks/fuzzing/properties/mutation_recompute.rb +162 -0
  344. data/lib/hecks/fuzzing/properties/outbox.rb +41 -24
  345. data/lib/hecks/fuzzing/properties/piece_invariants.rb +61 -0
  346. data/lib/hecks/fuzzing/properties/policy_wiring.rb +140 -0
  347. data/lib/hecks/fuzzing/properties/query_rows.rb +67 -0
  348. data/lib/hecks/fuzzing/properties/querying.rb +69 -90
  349. data/lib/hecks/fuzzing/properties/references.rb +100 -0
  350. data/lib/hecks/fuzzing/properties/tenant_scope.rb +84 -0
  351. data/lib/hecks/fuzzing/properties.rb +6 -119
  352. data/lib/hecks/fuzzing/qa_settings.rb +23 -17
  353. data/lib/hecks/fuzzing/replay/fan_out.rb +78 -0
  354. data/lib/hecks/fuzzing/replay/filters.rb +72 -0
  355. data/lib/hecks/fuzzing/replay/guard_check.rb +88 -0
  356. data/lib/hecks/fuzzing/replay/mutation_trace.rb +117 -0
  357. data/lib/hecks/fuzzing/replay/observation.rb +60 -0
  358. data/lib/hecks/fuzzing/replay/read_only_steps.rb +84 -0
  359. data/lib/hecks/fuzzing/replay/session.rb +151 -0
  360. data/lib/hecks/fuzzing/replay.rb +35 -442
  361. data/lib/hecks/fuzzing/rust_gap_manifest.rb +3 -4
  362. data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +133 -0
  363. data/lib/hecks/fuzzing/self_consistency/sagas.rb +93 -0
  364. data/lib/hecks/fuzzing/self_consistency/value_objects.rb +87 -0
  365. data/lib/hecks/fuzzing/self_consistency.rb +8 -213
  366. data/lib/hecks/fuzzing/sequence_generator/adversary/argument_mutations.rb +116 -0
  367. data/lib/hecks/fuzzing/sequence_generator/adversary/caller_draw.rb +68 -0
  368. data/lib/hecks/fuzzing/sequence_generator/adversary/identity_mutations.rb +62 -0
  369. data/lib/hecks/fuzzing/sequence_generator/adversary/precedence_mutations.rb +126 -0
  370. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +23 -283
  371. data/lib/hecks/fuzzing/sequence_generator/argument_drawing.rb +78 -0
  372. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +69 -53
  373. data/lib/hecks/fuzzing/sequence_generator/identity_shaping.rb +85 -0
  374. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +20 -16
  375. data/lib/hecks/fuzzing/sequence_generator/picker.rb +12 -6
  376. data/lib/hecks/fuzzing/sequence_generator/prefixing.rb +45 -0
  377. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +19 -8
  378. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +43 -144
  379. data/lib/hecks/fuzzing/sequence_generator.rb +65 -63
  380. data/lib/hecks/fuzzing/shrinker.rb +33 -29
  381. data/lib/hecks/fuzzing/target_capabilities.rb +10 -4
  382. data/lib/hecks/fuzzing/value_generator.rb +27 -17
  383. data/lib/hecks/gate/stages.yml +10 -0
  384. data/lib/hecks/grammar/evolve/arguments.rb +90 -0
  385. data/lib/hecks/grammar/evolve/keywords.rb +81 -0
  386. data/lib/hecks/grammar/evolve/seeds.rb +172 -0
  387. data/lib/hecks/grammar/evolve.rb +22 -263
  388. data/lib/hecks/grammar/operators.rb +111 -0
  389. data/lib/hecks/grammar.rb +53 -126
  390. data/lib/hecks/hecks/adapters/bluebook_report.rb +91 -0
  391. data/lib/hecks/hecks/adapters/codebase/codemods.rb +1 -1
  392. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +23 -9
  393. data/lib/hecks/hecks/adapters/codebase/language/edits.rb +75 -0
  394. data/lib/hecks/hecks/adapters/codebase/language.rb +30 -72
  395. data/lib/hecks/hecks/adapters/codebase/promotion/candidates.rb +54 -0
  396. data/lib/hecks/hecks/adapters/codebase/promotion/gate.rb +50 -0
  397. data/lib/hecks/hecks/adapters/codebase/promotion/move.rb +70 -0
  398. data/lib/hecks/hecks/adapters/codebase/promotion/standing.rb +88 -0
  399. data/lib/hecks/hecks/adapters/codebase/promotion/watch.rb +83 -0
  400. data/lib/hecks/hecks/adapters/codebase/promotion.rb +115 -0
  401. data/lib/hecks/hecks/adapters/codebase/publishing.rb +31 -12
  402. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +43 -6
  403. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +16 -5
  404. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +9 -1
  405. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +1 -1
  406. data/lib/hecks/hecks/adapters/codebase/style.rb +1 -1
  407. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +11 -5
  408. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +27 -8
  409. data/lib/hecks/hecks/adapters/console_capture.rb +21 -17
  410. data/lib/hecks/hecks/adapters/cost_explorer.rb +11 -6
  411. data/lib/hecks/hecks/adapters/deploy_plans.rb +49 -0
  412. data/lib/hecks/hecks/adapters/deploy_toolchain/answers.rb +141 -0
  413. data/lib/hecks/hecks/adapters/deploy_toolchain/scripts.rb +95 -0
  414. data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +74 -0
  415. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +122 -59
  416. data/lib/hecks/hecks/adapters/finding_github.rb +2 -2
  417. data/lib/hecks/hecks/adapters/first_admin.rb +22 -8
  418. data/lib/hecks/hecks/adapters/git.rb +18 -5
  419. data/lib/hecks/hecks/adapters/git_refs.rb +144 -0
  420. data/lib/hecks/hecks/adapters/github_rulesets.rb +126 -0
  421. data/lib/hecks/hecks/adapters/host_http.rb +16 -6
  422. data/lib/hecks/hecks/adapters/in_process_boot.rb +9 -5
  423. data/lib/hecks/hecks/adapters/in_process_operations/tailing.rb +61 -0
  424. data/lib/hecks/hecks/adapters/in_process_operations.rb +39 -37
  425. data/lib/hecks/hecks/adapters/journal_store/changes.rb +21 -15
  426. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +29 -12
  427. data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +52 -0
  428. data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +52 -0
  429. data/lib/hecks/hecks/adapters/journal_store/readings.rb +5 -62
  430. data/lib/hecks/hecks/adapters/local_files.rb +27 -10
  431. data/lib/hecks/hecks/adapters/pg_admin/ownership.rb +115 -0
  432. data/lib/hecks/hecks/adapters/pg_admin.rb +14 -87
  433. data/lib/hecks/hecks/adapters/process_pool.rb +54 -22
  434. data/lib/hecks/hecks/adapters/rust_toolchain.rb +12 -4
  435. data/lib/hecks/hecks/adapters/site_toolchain.rb +19 -10
  436. data/lib/hecks/hecks/adapters/terminal.rb +13 -9
  437. data/lib/hecks/hecks/codebase.bluebook +322 -5
  438. data/lib/hecks/hecks/custodian.bluebook +12 -2
  439. data/lib/hecks/hecks/hecks.hecksagon +73 -0
  440. data/lib/hecks/hecks/hecks.world +15 -3
  441. data/lib/hecks/kernel_capabilities/templates.rb +92 -0
  442. data/lib/hecks/kernel_capabilities.rb +18 -85
  443. data/lib/hecks/language/bluebook/vocabulary.bluebook +43 -1
  444. data/lib/hecks/literal/item_splitter.rb +50 -0
  445. data/lib/hecks/literal.rb +29 -38
  446. data/lib/hecks/mcp_stdio_guard.rb +8 -8
  447. data/lib/hecks/naming.rb +9 -3
  448. data/lib/hecks/persistence_legacy_fixture/postgres_stores.rb +81 -0
  449. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +26 -66
  450. data/lib/hecks/persistence_legacy_fixture.rb +13 -10
  451. data/lib/hecks/ports/access_control.rb +13 -10
  452. data/lib/hecks/ports/agent/answers.rb +2 -2
  453. data/lib/hecks/ports/agent.rb +13 -10
  454. data/lib/hecks/ports/authentication.rb +13 -10
  455. data/lib/hecks/ports/authorization.rb +13 -10
  456. data/lib/hecks/ports/clock.rb +13 -10
  457. data/lib/hecks/ports/extraction.rb +13 -12
  458. data/lib/hecks/ports/identity_assignment.rb +13 -10
  459. data/lib/hecks/ports/identity_generation.rb +13 -10
  460. data/lib/hecks/ports/identity_resolution.rb +13 -10
  461. data/lib/hecks/ports/key_vault.rb +13 -10
  462. data/lib/hecks/ports/persistence/append_only.rb +5 -5
  463. data/lib/hecks/ports/persistence/binding_policy.rb +33 -9
  464. data/lib/hecks/ports/persistence/codec_boundary.rb +22 -11
  465. data/lib/hecks/ports/persistence/constants.rb +10 -0
  466. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +18 -16
  467. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +27 -18
  468. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +52 -23
  469. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +14 -8
  470. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +17 -6
  471. data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +58 -0
  472. data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +130 -0
  473. data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +25 -0
  474. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +20 -180
  475. data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +41 -0
  476. data/lib/hecks/ports/persistence/plugins/era/postgres_era/class_methods.rb +105 -0
  477. data/lib/hecks/ports/persistence/plugins/era/postgres_era/dialect.rb +137 -0
  478. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +25 -28
  479. data/lib/hecks/ports/persistence/plugins/era/postgres_era/head_writes.rb +62 -0
  480. data/lib/hecks/ports/persistence/plugins/era/postgres_era/journal.rb +128 -0
  481. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +74 -0
  482. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/chain_sql.rb +169 -0
  483. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +91 -0
  484. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_integrity.rb +99 -0
  485. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +0 -73
  486. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +55 -39
  487. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +51 -222
  488. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/merge_writes.rb +120 -0
  489. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +85 -60
  490. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +97 -181
  491. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +19 -19
  492. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/sql_templates.rb +88 -0
  493. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +77 -118
  494. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +3 -117
  495. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_sql.rb +116 -0
  496. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +3 -1
  497. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/context.rb +38 -0
  498. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +43 -25
  499. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +62 -38
  500. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +21 -16
  501. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +66 -86
  502. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +75 -0
  503. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +27 -9
  504. data/lib/hecks/ports/persistence/plugins/era/postgres_era/query_phases.rb +63 -0
  505. data/lib/hecks/ports/persistence/plugins/era/postgres_era/sagas.rb +78 -0
  506. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +28 -482
  507. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +40 -12
  508. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +22 -15
  509. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +39 -19
  510. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -16
  511. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +48 -25
  512. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +60 -99
  513. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/path_diff.rb +57 -0
  514. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +21 -11
  515. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +13 -4
  516. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +4 -2
  517. data/lib/hecks/ports/persistence/postgres_dump.rb +13 -7
  518. data/lib/hecks/ports/persistence/repository_factory.rb +35 -11
  519. data/lib/hecks/ports/persistence/state_codec.rb +10 -0
  520. data/lib/hecks/ports/persistence.rb +1 -10
  521. data/lib/hecks/ports/projection.rb +34 -21
  522. data/lib/hecks/ports/query/in_memory.rb +16 -8
  523. data/lib/hecks/projection_files/expression_tables.rb +64 -0
  524. data/lib/hecks/projection_files/texts.rb +67 -0
  525. data/lib/hecks/projection_files.rb +19 -103
  526. data/lib/hecks/projections/bootstrap_table.rb +43 -29
  527. data/lib/hecks/projections/deploy/bastion_lines.rb +32 -0
  528. data/lib/hecks/projections/deploy/box/access.rb +73 -0
  529. data/lib/hecks/projections/deploy/box/caddy.rb +87 -0
  530. data/lib/hecks/projections/deploy/box/compose.rb +70 -0
  531. data/lib/hecks/projections/deploy/box/hosting.rb +16 -108
  532. data/lib/hecks/projections/deploy/box/hosting_parts.rb +97 -0
  533. data/lib/hecks/projections/deploy/box/hosting_settings.rb +1 -1
  534. data/lib/hecks/projections/deploy/box/roll_recipe.rb +62 -0
  535. data/lib/hecks/projections/deploy/box/roll_scripts.rb +135 -0
  536. data/lib/hecks/projections/deploy/box/settings/checks.rb +38 -0
  537. data/lib/hecks/projections/deploy/box/settings/containers.rb +123 -0
  538. data/lib/hecks/projections/deploy/box/settings/origin.rb +56 -0
  539. data/lib/hecks/projections/deploy/box/settings/patterns.rb +43 -0
  540. data/lib/hecks/projections/deploy/box/settings/types.rb +72 -0
  541. data/lib/hecks/projections/deploy/box/settings.rb +58 -263
  542. data/lib/hecks/projections/deploy/box/stack_yaml.rb +107 -0
  543. data/lib/hecks/projections/deploy/box/templates/MIGRATION.md.tmpl +39 -0
  544. data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +24 -0
  545. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +51 -4
  546. data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +4 -3
  547. data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +16 -4
  548. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +8 -7
  549. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef.part +1 -1
  550. data/lib/hecks/projections/deploy/box/templates/deploy-usage-services.tmpl +4 -0
  551. data/lib/hecks/projections/deploy/box/templates/deploy-usage-taskdef.tmpl +5 -0
  552. data/lib/hecks/projections/deploy/box/templates/ecr-repository.yaml.tmpl +9 -0
  553. data/lib/hecks/projections/deploy/box/templates/hosting.mk.tmpl +6 -3
  554. data/lib/hecks/projections/deploy/box/templates/mode-summary-services.tmpl +2 -0
  555. data/lib/hecks/projections/deploy/box/templates/mode-summary-taskdef.tmpl +4 -0
  556. data/lib/hecks/projections/deploy/box/templates/restore-to-rds.sh.tmpl +8 -3
  557. data/lib/hecks/projections/deploy/box/templates/services-block.tmpl +9 -0
  558. data/lib/hecks/projections/deploy/box/templates/tunnel-egress.yaml.tmpl +11 -0
  559. data/lib/hecks/projections/deploy/box/templates/verify-copy.sh.tmpl +2 -2
  560. data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
  561. data/lib/hecks/projections/deploy/box.rb +37 -503
  562. data/lib/hecks/projections/deploy/fargate/assembly.rb +13 -142
  563. data/lib/hecks/projections/deploy/fargate/cdn/behaviors.rb +76 -0
  564. data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +112 -0
  565. data/lib/hecks/projections/deploy/fargate/cdn/options.rb +85 -0
  566. data/lib/hecks/projections/deploy/fargate/cdn.rb +23 -215
  567. data/lib/hecks/projections/deploy/fargate/check.rb +16 -6
  568. data/lib/hecks/projections/deploy/fargate/containers/definition_lines.rb +61 -0
  569. data/lib/hecks/projections/deploy/fargate/containers/reading.rb +86 -0
  570. data/lib/hecks/projections/deploy/fargate/containers/rendering.rb +132 -0
  571. data/lib/hecks/projections/deploy/fargate/containers/routing.rb +93 -0
  572. data/lib/hecks/projections/deploy/fargate/containers.rb +10 -286
  573. data/lib/hecks/projections/deploy/fargate/extras/reading.rb +90 -0
  574. data/lib/hecks/projections/deploy/fargate/extras/rendering.rb +81 -0
  575. data/lib/hecks/projections/deploy/fargate/extras.rb +9 -158
  576. data/lib/hecks/projections/deploy/fargate/monitoring/alarms.rb +115 -0
  577. data/lib/hecks/projections/deploy/fargate/monitoring/reading.rb +84 -0
  578. data/lib/hecks/projections/deploy/fargate/monitoring/topic.rb +59 -0
  579. data/lib/hecks/projections/deploy/fargate/monitoring/warmer.rb +90 -0
  580. data/lib/hecks/projections/deploy/fargate/monitoring/warmer_roles.rb +76 -0
  581. data/lib/hecks/projections/deploy/fargate/monitoring.rb +14 -348
  582. data/lib/hecks/projections/deploy/fargate/sections.rb +115 -0
  583. data/lib/hecks/projections/deploy/fargate/settings/ids.rb +55 -0
  584. data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +77 -0
  585. data/lib/hecks/projections/deploy/fargate/settings.rb +17 -104
  586. data/lib/hecks/projections/deploy/fargate/stack/blocks.rb +91 -0
  587. data/lib/hecks/projections/deploy/fargate/stack/readers.rb +87 -0
  588. data/lib/hecks/projections/deploy/fargate/stack/recipes.rb +106 -0
  589. data/lib/hecks/projections/deploy/fargate/stack.rb +146 -0
  590. data/lib/hecks/projections/deploy/fargate/task_sections.rb +56 -0
  591. data/lib/hecks/projections/deploy/fargate/yaml.rb +1 -1
  592. data/lib/hecks/projections/deploy/fargate.rb +51 -756
  593. data/lib/hecks/projections/deploy/lambda/pii.rb +49 -0
  594. data/lib/hecks/projections/deploy/lambda/stack/blocks.rb +118 -0
  595. data/lib/hecks/projections/deploy/lambda/stack/checks.rb +64 -0
  596. data/lib/hecks/projections/deploy/lambda/stack/deploy_chain.rb +119 -0
  597. data/lib/hecks/projections/deploy/lambda/stack/readers.rb +62 -0
  598. data/lib/hecks/projections/deploy/lambda/stack/reading.rb +170 -0
  599. data/lib/hecks/projections/deploy/lambda/stack/reading_web.rb +53 -0
  600. data/lib/hecks/projections/deploy/lambda/stack/recipes.rb +112 -0
  601. data/lib/hecks/projections/deploy/lambda/stack/web.rb +57 -0
  602. data/lib/hecks/projections/deploy/lambda/stack.rb +54 -0
  603. data/lib/hecks/projections/deploy/lambda.rb +77 -1885
  604. data/lib/hecks/projections/deploy/preview/access_yaml.rb +8 -74
  605. data/lib/hecks/projections/deploy/preview/containers.rb +18 -7
  606. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +15 -87
  607. data/lib/hecks/projections/deploy/preview/settings.rb +7 -4
  608. data/lib/hecks/projections/deploy/preview/task_yaml.rb +42 -106
  609. data/lib/hecks/projections/deploy/preview/template.rb +11 -106
  610. data/lib/hecks/projections/deploy/preview/yaml_text.rb +1 -1
  611. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +1 -1
  612. data/lib/hecks/projections/deploy/scripts/settings.rb +14 -6
  613. data/lib/hecks/projections/deploy/scripts.rb +11 -9
  614. data/lib/hecks/projections/deploy/shared/rows.rb +48 -0
  615. data/lib/hecks/projections/deploy/shared.rb +89 -449
  616. data/lib/hecks/projections/deploy/smoke.rb +15 -10
  617. data/lib/hecks/projections/deploy/template_diff/comparer.rb +21 -147
  618. data/lib/hecks/projections/deploy/template_diff/normalizer.rb +60 -0
  619. data/lib/hecks/projections/deploy/template_diff/value_diff.rb +136 -0
  620. data/lib/hecks/projections/deploy/template_diff.rb +8 -3
  621. data/lib/hecks/projections/deploy/templates/fargate/Dockerfile.tmpl +28 -0
  622. data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +63 -0
  623. data/lib/hecks/projections/deploy/templates/fargate/always_params.tmpl +4 -0
  624. data/lib/hecks/projections/deploy/templates/fargate/deploy_plain.tmpl +1 -0
  625. data/lib/hecks/projections/deploy/templates/fargate/deploy_shared.tmpl +11 -0
  626. data/lib/hecks/projections/deploy/templates/fargate/mint_era_own.tmpl +44 -0
  627. data/lib/hecks/projections/deploy/templates/fargate/mint_era_shared.tmpl +8 -0
  628. data/lib/hecks/projections/deploy/templates/fargate/missing_owner.tmpl +9 -0
  629. data/lib/hecks/projections/deploy/templates/fargate/oauth_params.tmpl +7 -0
  630. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_env.tmpl +4 -0
  631. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_policy.tmpl +7 -0
  632. data/lib/hecks/projections/deploy/templates/fargate/owning_params.tmpl +33 -0
  633. data/lib/hecks/projections/deploy/templates/fargate/template.yaml.tmpl +281 -0
  634. data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +218 -0
  635. data/lib/hecks/projections/deploy/templates/lambda/aurora_depends.tmpl +18 -0
  636. data/lib/hecks/projections/deploy/templates/lambda/build_dispatch_none.tmpl +10 -0
  637. data/lib/hecks/projections/deploy/templates/lambda/build_pg.tmpl +15 -0
  638. data/lib/hecks/projections/deploy/templates/lambda/build_plain.tmpl +2 -0
  639. data/lib/hecks/projections/deploy/templates/lambda/build_web.tmpl +11 -0
  640. data/lib/hecks/projections/deploy/templates/lambda/env_blind_guard.tmpl +4 -0
  641. data/lib/hecks/projections/deploy/templates/lambda/mint_era_own.tmpl +122 -0
  642. data/lib/hecks/projections/deploy/templates/lambda/mint_era_shared.tmpl +47 -0
  643. data/lib/hecks/projections/deploy/templates/lambda/missing_owner.tmpl +9 -0
  644. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +14 -0
  645. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_plain.tmpl +3 -0
  646. data/lib/hecks/projections/deploy/templates/lambda/oauth_note.tmpl +8 -0
  647. data/lib/hecks/projections/deploy/templates/lambda/params_oauth.tmpl +13 -0
  648. data/lib/hecks/projections/deploy/templates/lambda/params_shared.tmpl +33 -0
  649. data/lib/hecks/projections/deploy/templates/lambda/pg_native.tmpl +71 -0
  650. data/lib/hecks/projections/deploy/templates/lambda/pii_oac.tmpl +8 -0
  651. data/lib/hecks/projections/deploy/templates/lambda/pii_permission.tmpl +8 -0
  652. data/lib/hecks/projections/deploy/templates/lambda/pii_resources.tmpl +116 -0
  653. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge.tmpl +30 -0
  654. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_oauth.tmpl +12 -0
  655. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_plain.tmpl +7 -0
  656. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_own.tmpl +93 -0
  657. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_shared.tmpl +7 -0
  658. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_env.tmpl +17 -0
  659. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_policy.tmpl +16 -0
  660. data/lib/hecks/projections/deploy/templates/lambda/rust_session_secret.tmpl +13 -0
  661. data/lib/hecks/projections/deploy/templates/lambda/samconfig.toml.tmpl +12 -0
  662. data/lib/hecks/projections/deploy/templates/lambda/shared_note.tmpl +6 -0
  663. data/lib/hecks/projections/deploy/templates/lambda/sync_oauth.tmpl +23 -0
  664. data/lib/hecks/projections/deploy/templates/lambda/template.yaml.tmpl +187 -0
  665. data/lib/hecks/projections/deploy/templates/lambda/translation_own.tmpl +46 -0
  666. data/lib/hecks/projections/deploy/templates/lambda/translation_shared.tmpl +2 -0
  667. data/lib/hecks/projections/deploy/templates/lambda/web_function.tmpl +207 -0
  668. data/lib/hecks/projections/deploy/templates/lambda/web_google_oauth_env.tmpl +12 -0
  669. data/lib/hecks/projections/deploy/templates/lambda/web_no_oauth_env.tmpl +7 -0
  670. data/lib/hecks/projections/deploy/templates/lambda/web_oauth_policy.tmpl +4 -0
  671. data/lib/hecks/projections/deploy/templates/lambda/webhook_secret_resource.tmpl +20 -0
  672. data/lib/hecks/projections/deploy/templates/preview/alb.tmpl +8 -0
  673. data/lib/hecks/projections/deploy/templates/preview/alb_security_group.tmpl +11 -0
  674. data/lib/hecks/projections/deploy/templates/preview/assume_role.tmpl +6 -0
  675. data/lib/hecks/projections/deploy/templates/preview/base_parameters.tmpl +24 -0
  676. data/lib/hecks/projections/deploy/templates/preview/cluster.tmpl +4 -0
  677. data/lib/hecks/projections/deploy/templates/preview/container_secret.tmpl +9 -0
  678. data/lib/hecks/projections/deploy/templates/preview/db_init_script.sh.tmpl +23 -0
  679. data/lib/hecks/projections/deploy/templates/preview/db_init_secrets.tmpl +5 -0
  680. data/lib/hecks/projections/deploy/templates/preview/db_init_task.tmpl +39 -0
  681. data/lib/hecks/projections/deploy/templates/preview/desired_count.tmpl +5 -0
  682. data/lib/hecks/projections/deploy/templates/preview/distribution.tmpl +24 -0
  683. data/lib/hecks/projections/deploy/templates/preview/execution_role.tmpl +16 -0
  684. data/lib/hecks/projections/deploy/templates/preview/header.tmpl +16 -0
  685. data/lib/hecks/projections/deploy/templates/preview/ingress.tmpl +8 -0
  686. data/lib/hecks/projections/deploy/templates/preview/listener.tmpl +9 -0
  687. data/lib/hecks/projections/deploy/templates/preview/listener_rule.tmpl +11 -0
  688. data/lib/hecks/projections/deploy/templates/preview/log_group.tmpl +5 -0
  689. data/lib/hecks/projections/deploy/templates/preview/log_options.tmpl +5 -0
  690. data/lib/hecks/projections/deploy/templates/preview/outputs.tmpl +14 -0
  691. data/lib/hecks/projections/deploy/templates/preview/service.tmpl +17 -0
  692. data/lib/hecks/projections/deploy/templates/preview/session_secret.tmpl +11 -0
  693. data/lib/hecks/projections/deploy/templates/preview/target_group.tmpl +9 -0
  694. data/lib/hecks/projections/deploy/templates/preview/task_definition.tmpl +15 -0
  695. data/lib/hecks/projections/deploy/templates/preview/task_role.tmpl +22 -0
  696. data/lib/hecks/projections/deploy/templates/shared/aurora_db.tmpl +52 -0
  697. data/lib/hecks/projections/deploy/templates/shared/bastion.tmpl +74 -0
  698. data/lib/hecks/projections/deploy/templates/shared/bastion_own_public.tmpl +41 -0
  699. data/lib/hecks/projections/deploy/templates/shared/bastion_reuse_public.tmpl +10 -0
  700. data/lib/hecks/projections/deploy/templates/shared/nat_gateway.tmpl +102 -0
  701. data/lib/hecks/projections/deploy/templates/shared/oauth_egress.tmpl +17 -0
  702. data/lib/hecks/projections/deploy/templates/shared/plain_db.tmpl +16 -0
  703. data/lib/hecks/projections/deploy/templates/shared/vpc_and_database.tmpl +67 -0
  704. data/lib/hecks/projections/deploy/text_template.rb +35 -0
  705. data/lib/hecks/projections/diagrams/dispatch.rb +114 -0
  706. data/lib/hecks/projections/diagrams/statecharts.rb +59 -0
  707. data/lib/hecks/projections/diagrams/structure.rb +114 -0
  708. data/lib/hecks/projections/diagrams.rb +33 -256
  709. data/lib/hecks/projections/glossary/entries.rb +140 -0
  710. data/lib/hecks/projections/glossary/html/page.rb +96 -0
  711. data/lib/hecks/projections/glossary/html/parser.rb +66 -0
  712. data/lib/hecks/projections/glossary/html/sections.rb +78 -0
  713. data/lib/hecks/projections/glossary/html.rb +7 -179
  714. data/lib/hecks/projections/glossary/index.rb +45 -0
  715. data/lib/hecks/projections/glossary/markdown.rb +22 -11
  716. data/lib/hecks/projections/glossary/mermaid.rb +44 -31
  717. data/lib/hecks/projections/glossary/sensitivity.rb +7 -4
  718. data/lib/hecks/projections/glossary/sentences/value_objects.rb +77 -0
  719. data/lib/hecks/projections/glossary/sentences.rb +42 -81
  720. data/lib/hecks/projections/glossary/slugs.rb +33 -0
  721. data/lib/hecks/projections/glossary.rb +22 -190
  722. data/lib/hecks/projections/model.rb +20 -14
  723. data/lib/hecks/projections/rust_vocabulary/arguments/support.rb +33 -0
  724. data/lib/hecks/projections/rust_vocabulary/arguments.rb +171 -0
  725. data/lib/hecks/projections/rust_vocabulary/enum_body.rb +114 -0
  726. data/lib/hecks/projections/rust_vocabulary/tests.rb +144 -0
  727. data/lib/hecks/projections/rust_vocabulary.rb +24 -293
  728. data/lib/hecks/projections/site/admin.rb +146 -0
  729. data/lib/hecks/projections/site/admin_cms/templates/membership.rb +115 -0
  730. data/lib/hecks/projections/site/admin_cms/templates/session_strategy.rb +90 -0
  731. data/lib/hecks/projections/site/admin_cms/templates/sso.rb +101 -0
  732. data/lib/hecks/projections/site/admin_cms/templates/sso_tail.rb +54 -0
  733. data/lib/hecks/projections/site/admin_cms/templates/users.rb +83 -0
  734. data/lib/hecks/projections/site/admin_cms/templates.rb +33 -0
  735. data/lib/hecks/projections/site/admin_cms.rb +78 -0
  736. data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
  737. data/lib/hecks/projections/site/edge/checks.rb +30 -80
  738. data/lib/hecks/projections/site/edge/findings.rb +28 -0
  739. data/lib/hecks/projections/site/edge/route_checks.rb +110 -0
  740. data/lib/hecks/projections/site/edge/row_reader.rb +52 -0
  741. data/lib/hecks/projections/site/edge/rules.rb +28 -26
  742. data/lib/hecks/projections/site/edge.rb +20 -31
  743. data/lib/hecks/projections/site/live_edge.rb +9 -7
  744. data/lib/hecks/projections/site/payload/fields/definitions.rb +90 -0
  745. data/lib/hecks/projections/site/payload/fields/readers.rb +69 -0
  746. data/lib/hecks/projections/site/payload/fields.rb +137 -0
  747. data/lib/hecks/projections/site/payload/lifecycle/text.rb +84 -0
  748. data/lib/hecks/projections/site/payload/lifecycle/text_tail.rb +106 -0
  749. data/lib/hecks/projections/site/payload/lifecycle.rb +33 -0
  750. data/lib/hecks/projections/site/payload/model.rb +128 -0
  751. data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
  752. data/lib/hecks/projections/site/payload/specs.rb +135 -0
  753. data/lib/hecks/projections/site/payload_driver.rb +95 -0
  754. data/lib/hecks/projections/site/root_rows.rb +67 -0
  755. data/lib/hecks/projections/site/routes_ts/helpers.rb +79 -0
  756. data/lib/hecks/projections/site/routes_ts/listings.rb +75 -0
  757. data/lib/hecks/projections/site/routes_ts/navigation.rb +79 -0
  758. data/lib/hecks/projections/site/routes_ts.rb +27 -175
  759. data/lib/hecks/projections/site/site_admin/access.rb +104 -0
  760. data/lib/hecks/projections/site/site_admin/session.rb +127 -0
  761. data/lib/hecks/projections/site/site_admin.rb +85 -0
  762. data/lib/hecks/projections/site/site_cdn.rb +12 -7
  763. data/lib/hecks/projections/site/site_host/dockerfile.rb +75 -0
  764. data/lib/hecks/projections/site/site_host/templates.rb +109 -0
  765. data/lib/hecks/projections/site/site_host.rb +58 -0
  766. data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
  767. data/lib/hecks/projections/site/site_root.rb +128 -0
  768. data/lib/hecks/projections/site/table/checks.rb +28 -57
  769. data/lib/hecks/projections/site/table/link_builder.rb +14 -5
  770. data/lib/hecks/projections/site/table/navigation_checks.rb +75 -0
  771. data/lib/hecks/projections/site/table/row_builder.rb +31 -53
  772. data/lib/hecks/projections/site/table/row_defaults.rb +65 -0
  773. data/lib/hecks/projections/site/table.rb +9 -5
  774. data/lib/hecks/projections/vocabulary.rb +34 -31
  775. data/lib/hecks/projector/cli_audience.rb +42 -0
  776. data/lib/hecks/projector/cli_projector/claims.rb +149 -0
  777. data/lib/hecks/projector/cli_projector/command_help.rb +65 -0
  778. data/lib/hecks/projector/cli_projector/command_specs.rb +133 -0
  779. data/lib/hecks/projector/cli_projector/listing.rb +100 -0
  780. data/lib/hecks/projector/cli_projector/option_specs.rb +116 -0
  781. data/lib/hecks/projector/cli_projector/query_specs.rb +67 -0
  782. data/lib/hecks/projector/cli_projector/usage.rb +101 -0
  783. data/lib/hecks/projector/cli_projector.rb +15 -532
  784. data/lib/hecks/projector/docs_projector/attributes.rb +78 -0
  785. data/lib/hecks/projector/docs_projector/behaviour.rb +127 -0
  786. data/lib/hecks/projector/docs_projector/closing.rb +40 -0
  787. data/lib/hecks/projector/docs_projector.rb +58 -192
  788. data/lib/hecks/projector/exporter/bindings.rb +174 -0
  789. data/lib/hecks/projector/exporter/translations.rb +127 -0
  790. data/lib/hecks/projector/exporter.rb +8 -279
  791. data/lib/hecks/projector/narrate_projector/commands.rb +108 -0
  792. data/lib/hecks/projector/narrate_projector/reactions.rb +33 -0
  793. data/lib/hecks/projector/narrate_projector.rb +60 -160
  794. data/lib/hecks/projector.rb +22 -13
  795. data/lib/hecks/quality_control/adapters/agent_profile.rb +25 -16
  796. data/lib/hecks/quality_control/adapters/github_checks.rb +42 -6
  797. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +1 -1
  798. data/lib/hecks/quality_control/adapters/github_issues.rb +22 -10
  799. data/lib/hecks/quality_control/cli/qa_discover_external_domains/parsing.rb +54 -0
  800. data/lib/hecks/quality_control/cli/qa_discover_external_domains/reporting.rb +44 -0
  801. data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +119 -0
  802. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +28 -155
  803. data/lib/hecks/quality_control/cli/qa_domain_novelty/verdict.rb +76 -0
  804. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +33 -66
  805. data/lib/hecks/quality_control/cli/qa_generated_domains/arguments.rb +62 -0
  806. data/lib/hecks/quality_control/cli/qa_generated_domains/blueprints.rb +45 -0
  807. data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +107 -0
  808. data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +107 -0
  809. data/lib/hecks/quality_control/cli/qa_generated_domains/reporting.rb +97 -0
  810. data/lib/hecks/quality_control/cli/qa_generated_domains/shrinking.rb +70 -0
  811. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +43 -327
  812. data/lib/hecks/quality_control/cli/qa_log_bug/arguments.rb +55 -0
  813. data/lib/hecks/quality_control/cli/qa_log_bug/proof.rb +65 -0
  814. data/lib/hecks/quality_control/cli/qa_log_bug.rb +18 -81
  815. data/lib/hecks/quality_control/cli/qa_mine_combinations/arguments.rb +54 -0
  816. data/lib/hecks/quality_control/cli/qa_mine_combinations/booting.rb +96 -0
  817. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +45 -109
  818. data/lib/hecks/quality_control/cli/qa_open_pr/arguments.rb +55 -0
  819. data/lib/hecks/quality_control/cli/qa_open_pr/recording.rb +79 -0
  820. data/lib/hecks/quality_control/cli/qa_open_pr/rules.rb +122 -0
  821. data/lib/hecks/quality_control/cli/qa_open_pr.rb +41 -200
  822. data/lib/hecks/quality_control/cli/qa_postgres_migrate/copying.rb +45 -0
  823. data/lib/hecks/quality_control/cli/qa_postgres_migrate/reporting.rb +33 -0
  824. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +37 -63
  825. data/lib/hecks/quality_control/cli/qa_postgres_role/ownership.rb +57 -0
  826. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +66 -71
  827. data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +118 -0
  828. data/lib/hecks/quality_control/cli/qa_pr_check/reporting.rb +54 -0
  829. data/lib/hecks/quality_control/cli/qa_pr_check.rb +28 -145
  830. data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +80 -0
  831. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +13 -86
  832. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/children.rb +80 -0
  833. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/report.rb +125 -0
  834. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +63 -193
  835. data/lib/hecks/quality_control/cli/qa_sweep/checks/boundary.rb +92 -0
  836. data/lib/hecks/quality_control/cli/qa_sweep/checks/engines.rb +92 -0
  837. data/lib/hecks/quality_control/cli/qa_sweep/checks/seeds.rb +86 -0
  838. data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +69 -0
  839. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +10 -248
  840. data/lib/hecks/quality_control/cli/qa_sweep/conclusion.rb +60 -0
  841. data/lib/hecks/quality_control/cli/qa_sweep/depth.rb +61 -0
  842. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +26 -13
  843. data/lib/hecks/quality_control/cli/qa_sweep/finding_report/shrunk.rb +42 -0
  844. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +40 -41
  845. data/lib/hecks/quality_control/cli/qa_sweep/parsing/validation.rb +70 -0
  846. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +35 -65
  847. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +41 -22
  848. data/lib/hecks/quality_control/cli/qa_sweep/scratch.rb +67 -0
  849. data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +94 -0
  850. data/lib/hecks/quality_control/cli/qa_sweep/seed_loop.rb +149 -0
  851. data/lib/hecks/quality_control/cli/qa_sweep/target_setup.rb +115 -0
  852. data/lib/hecks/quality_control/cli/qa_sweep.rb +22 -445
  853. data/lib/hecks/quality_control/cli/qa_tick/output.rb +107 -0
  854. data/lib/hecks/quality_control/cli/qa_tick/preflight.rb +95 -0
  855. data/lib/hecks/quality_control/cli/qa_tick.rb +42 -175
  856. data/lib/hecks/query_ir/formatting.rb +86 -0
  857. data/lib/hecks/query_ir/rules.rb +132 -0
  858. data/lib/hecks/query_ir/touchpoints.rb +104 -0
  859. data/lib/hecks/query_ir.rb +33 -281
  860. data/lib/hecks/query_ir_mcp/tools.rb +68 -0
  861. data/lib/hecks/query_ir_mcp.rb +27 -71
  862. data/lib/hecks/query_specification/common/comparison.rb +25 -5
  863. data/lib/hecks/query_specification/common/dsl.rb +1 -1
  864. data/lib/hecks/query_specification/common/null_policy.rb +9 -6
  865. data/lib/hecks/query_specification/common/options.rb +21 -14
  866. data/lib/hecks/query_specification/field_path.rb +5 -2
  867. data/lib/hecks/query_specification/hop_path.rb +15 -18
  868. data/lib/hecks/release/lane.rb +22 -0
  869. data/lib/hecks/release/runner/clean_tree.rb +2 -2
  870. data/lib/hecks/release/runner/commands.rb +1 -1
  871. data/lib/hecks/release/runner/options.rb +82 -0
  872. data/lib/hecks/release/runner/preflight.rb +12 -7
  873. data/lib/hecks/release/runner/publishing.rb +86 -0
  874. data/lib/hecks/release/runner/tagger.rb +8 -3
  875. data/lib/hecks/release/runner.rb +40 -156
  876. data/lib/hecks/rendering.rb +13 -9
  877. data/lib/hecks/router/door.rb +37 -0
  878. data/lib/hecks/router/namespace_installer.rb +45 -83
  879. data/lib/hecks/router/options_proxy.rb +44 -0
  880. data/lib/hecks/runtime/adapter_lookup.rb +45 -24
  881. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -8
  882. data/lib/hecks/runtime/command_interpreter/delegation.rb +116 -0
  883. data/lib/hecks/runtime/command_interpreter/enforcement.rb +38 -0
  884. data/lib/hecks/runtime/command_interpreter/hydration.rb +139 -0
  885. data/lib/hecks/runtime/command_interpreter/list_mutations.rb +98 -0
  886. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +67 -114
  887. data/lib/hecks/runtime/command_interpreter/persisting.rb +96 -0
  888. data/lib/hecks/runtime/command_interpreter.rb +57 -352
  889. data/lib/hecks/runtime/command_rules/admissibility.rb +64 -147
  890. data/lib/hecks/runtime/command_rules/arithmetic.rb +13 -72
  891. data/lib/hecks/runtime/command_rules/authorization.rb +9 -9
  892. data/lib/hecks/runtime/command_rules/emission.rb +13 -14
  893. data/lib/hecks/runtime/command_rules/guard_state.rb +49 -0
  894. data/lib/hecks/runtime/command_rules/invariants.rb +84 -0
  895. data/lib/hecks/runtime/command_rules/operands.rb +88 -0
  896. data/lib/hecks/runtime/command_rules/references.rb +59 -57
  897. data/lib/hecks/runtime/command_rules/tenant_boundary.rb +69 -0
  898. data/lib/hecks/runtime/dependency_planning/analyzer.rb +90 -0
  899. data/lib/hecks/runtime/dependency_planning/expression_reads.rb +73 -0
  900. data/lib/hecks/runtime/dependency_planning/mutation_analysis.rb +89 -0
  901. data/lib/hecks/runtime/dependency_planning/rule_analysis.rb +82 -0
  902. data/lib/hecks/runtime/dependency_planning.rb +3 -250
  903. data/lib/hecks/runtime/dispatcher/queries.rb +62 -0
  904. data/lib/hecks/runtime/dispatcher/result.rb +55 -0
  905. data/lib/hecks/runtime/dispatcher/routing.rb +107 -0
  906. data/lib/hecks/runtime/dispatcher.rb +64 -209
  907. data/lib/hecks/runtime/entity_element/location.rb +124 -0
  908. data/lib/hecks/runtime/entity_element/mutations.rb +150 -0
  909. data/lib/hecks/runtime/entity_element.rb +5 -177
  910. data/lib/hecks/runtime/entity_interpreter/enforcement.rb +51 -0
  911. data/lib/hecks/runtime/entity_interpreter/locating.rb +62 -0
  912. data/lib/hecks/runtime/entity_interpreter/resolution.rb +42 -0
  913. data/lib/hecks/runtime/entity_interpreter/saving.rb +49 -0
  914. data/lib/hecks/runtime/entity_interpreter.rb +45 -164
  915. data/lib/hecks/runtime/identity.rb +15 -9
  916. data/lib/hecks/runtime/instance.rb +11 -7
  917. data/lib/hecks/runtime/interpreting.rb +16 -8
  918. data/lib/hecks/runtime/invocation.rb +3 -155
  919. data/lib/hecks/runtime/invocation_builder.rb +132 -0
  920. data/lib/hecks/runtime/invocation_facts.rb +87 -0
  921. data/lib/hecks/runtime/loader/boot_steps.rb +96 -0
  922. data/lib/hecks/runtime/loader/described.rb +27 -0
  923. data/lib/hecks/runtime/loader.rb +27 -114
  924. data/lib/hecks/runtime/outbox/consumer_runner.rb +40 -0
  925. data/lib/hecks/runtime/outbox/fanout.rb +82 -0
  926. data/lib/hecks/runtime/outbox/relay.rb +149 -0
  927. data/lib/hecks/runtime/outbox.rb +3 -214
  928. data/lib/hecks/runtime/policy_interpreter/arguments.rb +67 -0
  929. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +96 -0
  930. data/lib/hecks/runtime/policy_interpreter.rb +22 -137
  931. data/lib/hecks/runtime/port_operation_interpreter.rb +18 -17
  932. data/lib/hecks/runtime/query_interpreter/arguments.rb +51 -0
  933. data/lib/hecks/runtime/query_interpreter/entity_rows.rb +82 -0
  934. data/lib/hecks/runtime/query_interpreter/outside_answer.rb +89 -0
  935. data/lib/hecks/runtime/query_interpreter.rb +43 -191
  936. data/lib/hecks/runtime/reaction_invocation/identities.rb +92 -0
  937. data/lib/hecks/runtime/reaction_invocation/target_resolution.rb +88 -0
  938. data/lib/hecks/runtime/reaction_invocation.rb +66 -183
  939. data/lib/hecks/runtime/reaction_outcome.rb +7 -3
  940. data/lib/hecks/runtime/read_model_interpreter/head_ordering.rb +49 -0
  941. data/lib/hecks/runtime/read_model_interpreter/reductions.rb +123 -0
  942. data/lib/hecks/runtime/read_model_interpreter/shaping.rb +100 -0
  943. data/lib/hecks/runtime/read_model_interpreter.rb +71 -214
  944. data/lib/hecks/runtime/reference_hop.rb +11 -11
  945. data/lib/hecks/runtime/refusal_wording.rb +11 -8
  946. data/lib/hecks/runtime/registry/chapter_verification.rb +84 -0
  947. data/lib/hecks/runtime/registry/declarations.rb +17 -0
  948. data/lib/hecks/runtime/registry/durability_warnings.rb +71 -0
  949. data/lib/hecks/runtime/registry/hecksagon_rules.rb +124 -0
  950. data/lib/hecks/runtime/registry/merging.rb +49 -0
  951. data/lib/hecks/runtime/registry/providers.rb +139 -0
  952. data/lib/hecks/runtime/registry/query_verification.rb +144 -0
  953. data/lib/hecks/runtime/registry/read_repository.rb +61 -0
  954. data/lib/hecks/runtime/registry/runtime_state.rb +27 -0
  955. data/lib/hecks/runtime/registry/saga_persistence.rb +12 -8
  956. data/lib/hecks/runtime/registry/verification.rb +45 -389
  957. data/lib/hecks/runtime/registry/world_defaults.rb +3 -3
  958. data/lib/hecks/runtime/registry.rb +58 -296
  959. data/lib/hecks/runtime/remote_dispatcher.rb +47 -31
  960. data/lib/hecks/runtime/saga_interpreter/compensation.rb +90 -0
  961. data/lib/hecks/runtime/saga_interpreter/correlation.rb +19 -10
  962. data/lib/hecks/runtime/saga_interpreter/delivery.rb +147 -0
  963. data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +63 -0
  964. data/lib/hecks/runtime/saga_interpreter/transitions.rb +112 -0
  965. data/lib/hecks/runtime/saga_interpreter.rb +41 -320
  966. data/lib/hecks/runtime/tenant_check.rb +14 -9
  967. data/lib/hecks/runtime/value/admission.rb +28 -19
  968. data/lib/hecks/runtime/value/coercion.rb +55 -404
  969. data/lib/hecks/runtime/value/entity_list_coercion.rb +27 -29
  970. data/lib/hecks/runtime/value/field_checks.rb +57 -100
  971. data/lib/hecks/runtime/value/flags.rb +65 -0
  972. data/lib/hecks/runtime/value/identifiers.rb +64 -0
  973. data/lib/hecks/runtime/value/references.rb +195 -0
  974. data/lib/hecks/runtime/value/shape_checks.rb +61 -0
  975. data/lib/hecks/runtime/value/validation.rb +125 -0
  976. data/lib/hecks/runtime/value.rb +18 -6
  977. data/lib/hecks/rust_build/conformance/surface.rb +75 -0
  978. data/lib/hecks/rust_build/conformance.rb +27 -59
  979. data/lib/hecks/rust_build/conformance_fuzz.rb +26 -15
  980. data/lib/hecks/rust_build/coverage.rb +32 -104
  981. data/lib/hecks/rust_build/coverage_parts/expected.rb +68 -0
  982. data/lib/hecks/rust_build/coverage_parts/printer.rb +75 -0
  983. data/lib/hecks/rust_build/host.rb +23 -13
  984. data/lib/hecks/rust_build/kernel_input.rb +19 -12
  985. data/lib/hecks/rust_build/native_build.rb +19 -15
  986. data/lib/hecks/rust_build/project_rust/domain_loader.rb +75 -0
  987. data/lib/hecks/rust_build/project_rust/root_mod/notes.rb +66 -0
  988. data/lib/hecks/rust_build/project_rust/root_mod.rb +22 -55
  989. data/lib/hecks/rust_build/project_rust/target_ir.rb +74 -0
  990. data/lib/hecks/rust_build/project_rust.rb +21 -89
  991. data/lib/hecks/rust_build/wasm.rb +11 -4
  992. data/lib/hecks/rust_build/wasm_browser.rb +7 -7
  993. data/lib/hecks/rust_build/write_if_changed.rb +3 -6
  994. data/lib/hecks/rust_build.rb +7 -3
  995. data/lib/hecks/site/bluebook/site.bluebook +7 -1
  996. data/lib/hecks/storehouse/audit.rb +106 -0
  997. data/lib/hecks/storehouse/callers.rb +73 -0
  998. data/lib/hecks/storehouse/dispatching.rb +149 -0
  999. data/lib/hecks/storehouse/introspection.rb +145 -0
  1000. data/lib/hecks/storehouse/querying.rb +78 -0
  1001. data/lib/hecks/storehouse.rb +43 -451
  1002. data/lib/hecks/tickets/bluebook/tickets.bluebook +29 -0
  1003. data/lib/hecks/tools/argument_gate_matrix/dispatching.rb +69 -0
  1004. data/lib/hecks/tools/argument_gate_matrix/rows.rb +121 -0
  1005. data/lib/hecks/tools/argument_gate_matrix/violations.rb +108 -0
  1006. data/lib/hecks/tools/argument_gate_matrix.rb +43 -212
  1007. data/lib/hecks/tools/ci_gate_decision.rb +21 -14
  1008. data/lib/hecks/tools/ci_gates.rb +40 -26
  1009. data/lib/hecks/tools/comment_style/baseline.rb +41 -0
  1010. data/lib/hecks/tools/comment_style/caps_words.rb +104 -0
  1011. data/lib/hecks/tools/comment_style/cli.rb +121 -0
  1012. data/lib/hecks/tools/comment_style/dictionary.rb +60 -0
  1013. data/lib/hecks/tools/comment_style/fixing.rb +119 -0
  1014. data/lib/hecks/tools/comment_style/long_blocks.rb +51 -0
  1015. data/lib/hecks/tools/comment_style/masking.rb +94 -0
  1016. data/lib/hecks/tools/comment_style/patterns.rb +61 -0
  1017. data/lib/hecks/tools/comment_style/run.rb +161 -0
  1018. data/lib/hecks/tools/comment_style/signature.rb +59 -0
  1019. data/lib/hecks/tools/comment_style/source_file.rb +105 -0
  1020. data/lib/hecks/tools/comment_style/structure_checks.rb +113 -0
  1021. data/lib/hecks/tools/comment_style/text_checks.rb +67 -0
  1022. data/lib/hecks/tools/comment_style/vocabulary.rb +55 -0
  1023. data/lib/hecks/tools/comment_style/walker.rb +136 -0
  1024. data/lib/hecks/tools/comment_style.rb +17 -1000
  1025. data/lib/hecks/tools/corpus_report.rb +26 -16
  1026. data/lib/hecks/tools/deploy_recipe/targets.rb +61 -0
  1027. data/lib/hecks/tools/deploy_recipe/worlds.rb +114 -0
  1028. data/lib/hecks/tools/deploy_recipe.rb +60 -174
  1029. data/lib/hecks/tools/deploy_recipe_lint/checks.rb +78 -0
  1030. data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +88 -0
  1031. data/lib/hecks/tools/deploy_recipe_lint/makefile.rb +84 -0
  1032. data/lib/hecks/tools/deploy_recipe_lint.rb +29 -192
  1033. data/lib/hecks/tools/drop_implicit_append_fields.rb +20 -12
  1034. data/lib/hecks/tools/era_projection_backfill.rb +50 -33
  1035. data/lib/hecks/tools/era_reattest/reporting.rb +55 -0
  1036. data/lib/hecks/tools/era_reattest.rb +32 -43
  1037. data/lib/hecks/tools/evolve_run/arguments.rb +49 -0
  1038. data/lib/hecks/tools/evolve_run/words.rb +60 -0
  1039. data/lib/hecks/tools/evolve_run.rb +43 -90
  1040. data/lib/hecks/tools/fuzz_sweep/findings.rb +106 -0
  1041. data/lib/hecks/tools/fuzz_sweep/options.rb +69 -0
  1042. data/lib/hecks/tools/fuzz_sweep/pool.rb +74 -0
  1043. data/lib/hecks/tools/fuzz_sweep/reporting.rb +88 -0
  1044. data/lib/hecks/tools/fuzz_sweep.rb +75 -273
  1045. data/lib/hecks/tools/gate.rb +31 -16
  1046. data/lib/hecks/tools/heki_compaction.rb +63 -42
  1047. data/lib/hecks/tools/hoist_local_givens/rewriting.rb +119 -0
  1048. data/lib/hecks/tools/hoist_local_givens.rb +89 -157
  1049. data/lib/hecks/tools/journal_compaction.rb +40 -31
  1050. data/lib/hecks/tools/lanes/files.rb +82 -0
  1051. data/lib/hecks/tools/lanes/live.rb +41 -0
  1052. data/lib/hecks/tools/lanes/rows.rb +45 -0
  1053. data/lib/hecks/tools/lanes/ruleset.rb +44 -0
  1054. data/lib/hecks/tools/lanes/watch_workflow.rb +82 -0
  1055. data/lib/hecks/tools/lanes/workflow.rb +79 -0
  1056. data/lib/hecks/tools/lanes.rb +71 -0
  1057. data/lib/hecks/tools/oidc_manifests.rb +10 -9
  1058. data/lib/hecks/tools/query_ir_run.rb +7 -3
  1059. data/lib/hecks/tools/regeneration_run.rb +40 -26
  1060. data/lib/hecks/tools/rust_comment_style/caps_words.rb +98 -0
  1061. data/lib/hecks/tools/rust_comment_style/fixing.rb +102 -0
  1062. data/lib/hecks/tools/rust_comment_style/masking.rb +85 -0
  1063. data/lib/hecks/tools/rust_comment_style/run.rb +94 -0
  1064. data/lib/hecks/tools/rust_comment_style/source_file.rb +71 -0
  1065. data/lib/hecks/tools/rust_comment_style/structure.rb +79 -0
  1066. data/lib/hecks/tools/rust_comment_style/text_checks.rb +63 -0
  1067. data/lib/hecks/tools/rust_comment_style/tokenizer.rb +102 -0
  1068. data/lib/hecks/tools/rust_comment_style.rb +38 -535
  1069. data/lib/hecks/tools/sequence_script.rb +20 -14
  1070. data/lib/hecks/tools/site_routes/cli.rb +70 -0
  1071. data/lib/hecks/tools/site_routes/root_files.rb +59 -0
  1072. data/lib/hecks/tools/site_routes/templates.rb +77 -0
  1073. data/lib/hecks/tools/site_routes.rb +102 -108
  1074. data/lib/hecks/tools/tail_merge.rb +45 -37
  1075. data/lib/hecks/tools/tenant_provisioning.rb +45 -31
  1076. data/lib/hecks/tools/tools_doc.rb +42 -19
  1077. data/lib/hecks/tools/translation_audit/domain_loading.rb +71 -0
  1078. data/lib/hecks/tools/translation_audit/edges.rb +71 -0
  1079. data/lib/hecks/tools/translation_audit/verdicts.rb +107 -0
  1080. data/lib/hecks/tools/translation_audit.rb +30 -161
  1081. data/lib/hecks/tools/translation_scaffold/reporting.rb +40 -0
  1082. data/lib/hecks/tools/translation_scaffold.rb +77 -60
  1083. data/lib/hecks/tools.rb +1 -0
  1084. data/lib/hecks/vendoring.rb +37 -11
  1085. data/lib/hecks/version.rb +1 -1
  1086. data/lib/hecks/vocabulary.rb +16 -1
  1087. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +7 -9
  1088. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +8 -6
  1089. data/rust/.cargo/mutants.toml +8 -0
  1090. data/rust/host/Cargo.toml +5 -0
  1091. data/rust/host/HECKS_RELEASE +1 -1
  1092. data/rust/host/src/auth.rs +32 -0
  1093. data/rust/host/src/web.rs +2 -3
  1094. data/rust/src/kernel/dispatch.rs +4 -0
  1095. data/rust/src/kernel/dispatch_guard_tests.rs +506 -0
  1096. data/rust/src/kernel/orchestrate.rs +4 -0
  1097. data/rust/src/kernel/orchestrate_guard_tests.rs +708 -0
  1098. metadata +607 -3
  1099. /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
@@ -780,6 +780,7 @@ Hecks.bluebook "Deploy" do
780
780
  attribute :skip, Switch, optional: true
781
781
  attribute :async, Switch, optional: true
782
782
  attribute :dry_run, Switch, optional: true
783
+ attribute :after, Origin, default: { value: "alone" }
783
784
  attribute :report, Report, optional: true
784
785
  attribute :refusal, Report, optional: true
785
786
  identified_by :run
@@ -801,6 +802,11 @@ Hecks.bluebook "Deploy" do
801
802
  attribute :value, String, pattern: '^[A-Za-z0-9_-]+(:[0-9]+)?$'
802
803
  end
803
804
 
805
+ # What requested the smoke: `alone` for a person, else the roll whose record takes the outcome.
806
+ value_object "Origin" do
807
+ attribute :value, String, pattern: '^(alone|service_roll|box_roll)$'
808
+ end
809
+
804
810
  value_object "Switch" do
805
811
  attribute :value, Boolean
806
812
  end
@@ -830,6 +836,7 @@ Hecks.bluebook "Deploy" do
830
836
  attribute :skip, Switch, optional: true
831
837
  attribute :async, Switch, optional: true
832
838
  attribute :dry_run, Switch, optional: true
839
+ attribute :after, Origin, default: { value: "alone" }
833
840
 
834
841
  sets :project
835
842
  sets :script
@@ -838,6 +845,7 @@ Hecks.bluebook "Deploy" do
838
845
  sets :skip
839
846
  sets :async
840
847
  sets :dry_run
848
+ sets :after
841
849
 
842
850
  emits "SmokeRequested"
843
851
  end
@@ -847,8 +855,10 @@ Hecks.bluebook "Deploy" do
847
855
 
848
856
  reference_to SmokeRun
849
857
  attribute :report, Report
858
+ attribute :after, Origin, default: { value: "alone" }
850
859
 
851
860
  sets :report
861
+ sets :after
852
862
 
853
863
  emits "SmokePassed"
854
864
  end
@@ -858,8 +868,10 @@ Hecks.bluebook "Deploy" do
858
868
 
859
869
  reference_to SmokeRun
860
870
  attribute :refusal, Report
871
+ attribute :after, Origin, default: { value: "alone" }
861
872
 
862
873
  sets :refusal
874
+ sets :after
863
875
 
864
876
  emits "SmokeFlagged"
865
877
  end
@@ -880,17 +892,1512 @@ Hecks.bluebook "Deploy" do
880
892
 
881
893
  policy "SmokeWhenRequested" do
882
894
  on "SmokeRun.SmokeRequested"
883
- trigger SmokeRun::DeployToolchain::Smoke, with: { run: :run }
895
+ trigger SmokeRun::DeployToolchain::Smoke, with: { run: :run, after: :after }
884
896
  end
885
897
 
886
898
  policy "RecordThePassedSmoke" do
887
899
  on "SmokeRun.SmokeAnswered"
888
- trigger SmokeRun::Pass, with: { report: :report }
900
+ trigger SmokeRun::Pass, with: { report: :report, after: :after }
889
901
  end
890
902
 
891
903
  policy "RecordTheFlaggedSmoke" do
892
904
  on "SmokeRun.SmokeRefused"
893
- trigger SmokeRun::Flag, with: { refusal: :refusal }
905
+ trigger SmokeRun::Flag, with: { refusal: :refusal, after: :after }
906
+ end
907
+
908
+ aggregate "ServiceRoll" do
909
+ description "One roll of a single service onto the app box: the generated deploy-service script run, and how it ended."
910
+
911
+ attribute :project, Location
912
+ attribute :script, Location, optional: true
913
+ attribute :run, RunKey
914
+ attribute :service, ServiceName
915
+ attribute :existing_tag, ImageTag, optional: true
916
+ attribute :local_image, ImageName, optional: true
917
+ attribute :skip_smoke, Switch, optional: true
918
+ attribute :taskdef, TaskDefinition, optional: true
919
+ attribute :tag, ImageTag, optional: true
920
+ attribute :report, Report, optional: true
921
+ attribute :smoke, Report, optional: true
922
+ attribute :refusal, Report, optional: true
923
+
924
+ identified_by :run
925
+
926
+ value_object "RunKey" do
927
+ attribute :value, String, pattern: '[^ \t\n\r]'
928
+
929
+ invariant("a run is named") { !value.to_s.empty? }
930
+ end
931
+
932
+ value_object "Location" do
933
+ attribute :value, String, pattern: '[^\t\n\r]'
934
+
935
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
936
+ end
937
+
938
+ # A task definition family, or family:revision, as the generated script takes it in TASKDEF.
939
+ value_object "TaskDefinition" do
940
+ attribute :value, String, pattern: '^[A-Za-z0-9_-]+(:[0-9]+)?$'
941
+ end
942
+
943
+ # A container name from the world: lower case words joined by hyphens or underscores.
944
+ value_object "ServiceName" do
945
+ attribute :value, String, pattern: '^[a-z0-9][a-z0-9_-]*$'
946
+ end
947
+
948
+ # An ECR image tag, as the script's EXISTING_TAG takes it.
949
+ value_object "ImageTag" do
950
+ attribute :value, String, pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'
951
+ end
952
+
953
+ # A local image reference to push, as the script's LOCAL_IMAGE takes it.
954
+ value_object "ImageName" do
955
+ attribute :value, String, pattern: '^[^ \t\n\r]+$'
956
+ end
957
+
958
+ value_object "Switch" do
959
+ attribute :value, Boolean
960
+ end
961
+
962
+ value_object "Report" do
963
+ attribute :value, String
964
+ end
965
+
966
+ lifecycle :status, default: "requested" do
967
+ transition "Complete" => "rolled", from: "requested"
968
+ transition "Flag" => "flagged", from: "requested"
969
+ transition "Verify" => "verified", from: "rolled"
970
+ transition "FlagSmoke" => "flagged", from: "rolled"
971
+ end
972
+
973
+ # `hecks deploy service_roll.run <project> service=<name> [existing_tag=<tag>] [local_image=<ref>]
974
+ # [skip_smoke=true] [script=<path>]`. Runs the project's generated `deploy-service.sh`: push the
975
+ # local image under a fresh tag (or reuse `existing_tag`), set the stack's tag parameter, roll
976
+ # the box. A policy then requests a `SmokeRun`, unless `skip_smoke=true`. Exit 1 when flagged,
977
+ # with the script's status (2 unknown service, 30 to 38 a refused step, 40 to 42 the box roll's).
978
+
979
+ command "Run" do
980
+ goal "Roll one service's local image onto the box and record whether it took (exit 1 when flagged: 2 unknown service, 30-38 a refused step, 40-42 the box roll)"
981
+
982
+ attribute :project, Location
983
+ attribute :script, Location, optional: true
984
+ attribute :run, RunKey
985
+ attribute :service, ServiceName
986
+ attribute :existing_tag, ImageTag, optional: true
987
+ attribute :local_image, ImageName, optional: true
988
+ attribute :skip_smoke, Switch, optional: true
989
+
990
+ sets :project
991
+ sets :script
992
+ sets :run
993
+ sets :service
994
+ sets :existing_tag
995
+ sets :local_image
996
+ sets :skip_smoke
997
+
998
+ emits "ServiceRollRequested"
999
+ end
1000
+
1001
+ command "Complete" do
1002
+ goal "Record that the service rolled, with the task definition and tag it rolled"
1003
+
1004
+ reference_to ServiceRoll
1005
+ attribute :report, Report
1006
+ attribute :taskdef, TaskDefinition, optional: true
1007
+ attribute :tag, ImageTag, optional: true
1008
+ attribute :smoke, Report, optional: true
1009
+
1010
+ sets :report
1011
+ sets :taskdef
1012
+ sets :tag
1013
+ sets :smoke
1014
+
1015
+ emits "ServiceRollCompleted"
1016
+ end
1017
+
1018
+ command "Flag" do
1019
+ goal "Record that the roll failed or could not start, with the script's status and what it said"
1020
+
1021
+ reference_to ServiceRoll
1022
+ attribute :refusal, Report
1023
+
1024
+ sets :refusal
1025
+
1026
+ emits "ServiceRollFlagged"
1027
+ end
1028
+
1029
+ command "Verify" do
1030
+ goal "Record that the smoke the roll requested passed"
1031
+
1032
+ reference_to ServiceRoll
1033
+ attribute :smoke, Report
1034
+
1035
+ sets :smoke
1036
+
1037
+ emits "ServiceRollVerified"
1038
+ end
1039
+
1040
+ command "FlagSmoke" do
1041
+ goal "Record that the roll took but the smoke it requested did not pass, and why"
1042
+
1043
+ reference_to ServiceRoll
1044
+ attribute :smoke, Report
1045
+ attribute :refusal, Report
1046
+
1047
+ sets :smoke
1048
+ sets :refusal
1049
+
1050
+ emits "ServiceRollSmokeFlagged"
1051
+ end
1052
+
1053
+ query "Verdict" do
1054
+ description "What one roll found: its status, and the report or the reason it was flagged."
1055
+ attribute :run, RunKey
1056
+ where(run: :run)
1057
+ order_by :run
1058
+ end
1059
+
1060
+ query "Flagged" do
1061
+ description "Every roll that failed or could not start."
1062
+ where(status: "flagged")
1063
+ order_by :run
1064
+ end
1065
+ end
1066
+
1067
+ policy "RollServiceWhenRequested" do
1068
+ on "ServiceRoll.ServiceRollRequested"
1069
+ trigger ServiceRoll::DeployToolchain::RollService, with: { run: :run }
1070
+ end
1071
+
1072
+ policy "RecordTheRolledService" do
1073
+ on "ServiceRoll.ServiceRollAnswered"
1074
+ trigger ServiceRoll::Complete,
1075
+ with: { report: :report, taskdef: :taskdef, tag: :tag, smoke: :smoke }
1076
+ end
1077
+
1078
+ policy "RecordTheFlaggedServiceRoll" do
1079
+ on "ServiceRoll.ServiceRollRefused"
1080
+ trigger ServiceRoll::Flag, with: { refusal: :refusal }
1081
+ end
1082
+
1083
+ # Declared after RecordTheRolledService: the roll is recorded before its smoke is requested, and the
1084
+ # smoke is requested from the answer itself because a reaction chain is bounded.
1085
+ policy "SmokeAfterServiceRoll" do
1086
+ on "ServiceRoll.ServiceRollAnswered"
1087
+ where { run_smoke.value }
1088
+ trigger SmokeRun::Run, with: { project: :project, run: :run, taskdef: :taskdef, after: :kind }
1089
+ end
1090
+
1091
+ policy "VerifyServiceRollOnPassedSmoke" do
1092
+ on "SmokeRun.SmokePassed"
1093
+ where { after.value == "service_roll" }
1094
+ trigger ServiceRoll::Verify, with: { service_roll: :run, smoke: :report }
1095
+ end
1096
+
1097
+ policy "FlagServiceRollOnFlaggedSmoke" do
1098
+ on "SmokeRun.SmokeFlagged"
1099
+ where { after.value == "service_roll" }
1100
+ trigger ServiceRoll::FlagSmoke, with: { service_roll: :run, smoke: :refusal, refusal: :refusal }
1101
+ end
1102
+
1103
+ aggregate "BoxRoll" do
1104
+ description "One roll of the whole app box: the generated deploy-box script run, and how it ended."
1105
+
1106
+ attribute :project, Location
1107
+ attribute :script, Location, optional: true
1108
+ attribute :run, RunKey
1109
+ attribute :taskdef, TaskDefinition, optional: true
1110
+ attribute :tags, Tags, optional: true
1111
+ attribute :skip_smoke, Switch, optional: true
1112
+ attribute :report, Report, optional: true
1113
+ attribute :smoke, Report, optional: true
1114
+ attribute :refusal, Report, optional: true
1115
+
1116
+ identified_by :run
1117
+
1118
+ value_object "RunKey" do
1119
+ attribute :value, String, pattern: '[^ \t\n\r]'
1120
+
1121
+ invariant("a run is named") { !value.to_s.empty? }
1122
+ end
1123
+
1124
+ value_object "Location" do
1125
+ attribute :value, String, pattern: '[^\t\n\r]'
1126
+
1127
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
1128
+ end
1129
+
1130
+ # A task definition family, or family:revision, as the generated script takes it in TASKDEF.
1131
+ value_object "TaskDefinition" do
1132
+ attribute :value, String, pattern: '^[A-Za-z0-9_-]+(:[0-9]+)?$'
1133
+ end
1134
+
1135
+ # `name=tag` pairs separated by spaces, as a project without a task definition names its images.
1136
+ value_object "Tags" do
1137
+ attribute :value, String, pattern: '^[A-Za-z0-9_-]+=[A-Za-z0-9_.-]+( [A-Za-z0-9_-]+=[A-Za-z0-9_.-]+)*$'
1138
+ end
1139
+
1140
+ value_object "Switch" do
1141
+ attribute :value, Boolean
1142
+ end
1143
+
1144
+ value_object "Report" do
1145
+ attribute :value, String
1146
+ end
1147
+
1148
+ lifecycle :status, default: "requested" do
1149
+ transition "Complete" => "rolled", from: "requested"
1150
+ transition "Flag" => "flagged", from: "requested"
1151
+ transition "Verify" => "verified", from: "rolled"
1152
+ transition "FlagSmoke" => "flagged", from: "rolled"
1153
+ end
1154
+
1155
+ # `hecks deploy box_roll.run <project> [taskdef=<family[:rev]> | tags="name=tag ..."]
1156
+ # [skip_smoke=true] [script=<path>]`.
1157
+ # Runs the project's generated `deploy-box.sh`: render the Compose files, push them to the box over
1158
+ # SSM, start the containers and check them. A policy then requests a `SmokeRun`, unless
1159
+ # `skip_smoke=true`. Exit 1 when flagged, with the script's status (40 no instance, 41 the roll
1160
+ # failed, 42 the box unhealthy).
1161
+
1162
+ command "Run" do
1163
+ goal "Roll the app box and record whether it came up healthy (exit 1 when flagged: 40 no instance, 41 roll failed, 42 box unhealthy)"
1164
+
1165
+ attribute :project, Location
1166
+ attribute :script, Location, optional: true
1167
+ attribute :run, RunKey
1168
+ attribute :taskdef, TaskDefinition, optional: true
1169
+ attribute :tags, Tags, optional: true
1170
+ attribute :skip_smoke, Switch, optional: true
1171
+
1172
+ sets :project
1173
+ sets :script
1174
+ sets :run
1175
+ sets :taskdef
1176
+ sets :tags
1177
+ sets :skip_smoke
1178
+
1179
+ emits "BoxRollRequested"
1180
+ end
1181
+
1182
+ command "Complete" do
1183
+ goal "Record that the box rolled and answered healthy, and what the script said"
1184
+
1185
+ reference_to BoxRoll
1186
+ attribute :report, Report
1187
+ attribute :taskdef, TaskDefinition, optional: true
1188
+ attribute :smoke, Report, optional: true
1189
+
1190
+ sets :report
1191
+ sets :taskdef
1192
+ sets :smoke
1193
+
1194
+ emits "BoxRollCompleted"
1195
+ end
1196
+
1197
+ command "Flag" do
1198
+ goal "Record that the roll failed or could not start, with the script's status and what it said"
1199
+
1200
+ reference_to BoxRoll
1201
+ attribute :refusal, Report
1202
+
1203
+ sets :refusal
1204
+
1205
+ emits "BoxRollFlagged"
1206
+ end
1207
+
1208
+ command "Verify" do
1209
+ goal "Record that the smoke the roll requested passed"
1210
+
1211
+ reference_to BoxRoll
1212
+ attribute :smoke, Report
1213
+
1214
+ sets :smoke
1215
+
1216
+ emits "BoxRollVerified"
1217
+ end
1218
+
1219
+ command "FlagSmoke" do
1220
+ goal "Record that the roll took but the smoke it requested did not pass, and why"
1221
+
1222
+ reference_to BoxRoll
1223
+ attribute :smoke, Report
1224
+ attribute :refusal, Report
1225
+
1226
+ sets :smoke
1227
+ sets :refusal
1228
+
1229
+ emits "BoxRollSmokeFlagged"
1230
+ end
1231
+
1232
+ query "Verdict" do
1233
+ description "What one roll found: its status, and the report or the reason it was flagged."
1234
+ attribute :run, RunKey
1235
+ where(run: :run)
1236
+ order_by :run
1237
+ end
1238
+
1239
+ query "Flagged" do
1240
+ description "Every roll that failed or could not start."
1241
+ where(status: "flagged")
1242
+ order_by :run
1243
+ end
1244
+ end
1245
+
1246
+ policy "RollBoxWhenRequested" do
1247
+ on "BoxRoll.BoxRollRequested"
1248
+ trigger BoxRoll::DeployToolchain::RollBox, with: { run: :run }
1249
+ end
1250
+
1251
+ policy "RecordTheRolledBox" do
1252
+ on "BoxRoll.BoxRollAnswered"
1253
+ trigger BoxRoll::Complete, with: { report: :report, taskdef: :taskdef, smoke: :smoke }
1254
+ end
1255
+
1256
+ policy "RecordTheFlaggedBoxRoll" do
1257
+ on "BoxRoll.BoxRollRefused"
1258
+ trigger BoxRoll::Flag, with: { refusal: :refusal }
1259
+ end
1260
+
1261
+ policy "SmokeAfterBoxRoll" do
1262
+ on "BoxRoll.BoxRollAnswered"
1263
+ where { run_smoke.value }
1264
+ trigger SmokeRun::Run, with: { project: :project, run: :run, taskdef: :taskdef, after: :kind }
1265
+ end
1266
+
1267
+ policy "VerifyBoxRollOnPassedSmoke" do
1268
+ on "SmokeRun.SmokePassed"
1269
+ where { after.value == "box_roll" }
1270
+ trigger BoxRoll::Verify, with: { box_roll: :run, smoke: :report }
1271
+ end
1272
+
1273
+ policy "FlagBoxRollOnFlaggedSmoke" do
1274
+ on "SmokeRun.SmokeFlagged"
1275
+ where { after.value == "box_roll" }
1276
+ trigger BoxRoll::FlagSmoke, with: { box_roll: :run, smoke: :refusal, refusal: :refusal }
1277
+ end
1278
+
1279
+ aggregate "DataCopy" do
1280
+ description "One copy of a project's data from the old database into RDS: the generated restore-to-rds script run, and how it ended."
1281
+
1282
+ attribute :project, Location
1283
+ attribute :script, Location, optional: true
1284
+ attribute :run, RunKey
1285
+ attribute :bastion, Bastion
1286
+ attribute :source, Host
1287
+ attribute :source_secret, Secret
1288
+ attribute :target, Host
1289
+ attribute :target_secret, Secret
1290
+ attribute :source_db, DatabaseName, default: { value: "" }
1291
+ attribute :target_db, DatabaseName, default: { value: "" }
1292
+ attribute :force, Switch, optional: true
1293
+ attribute :confirm, Switch, optional: true
1294
+ attribute :dry_run, Switch, optional: true
1295
+ attribute :skip_verify, Switch, optional: true
1296
+ attribute :report, Report, optional: true
1297
+ attribute :verification, Report, optional: true
1298
+ attribute :refusal, Report, optional: true
1299
+
1300
+ identified_by :run
1301
+
1302
+ value_object "RunKey" do
1303
+ attribute :value, String, pattern: '[^ \t\n\r]'
1304
+
1305
+ invariant("a run is named") { !value.to_s.empty? }
1306
+ end
1307
+
1308
+ value_object "Location" do
1309
+ attribute :value, String, pattern: '[^\t\n\r]'
1310
+
1311
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
1312
+ end
1313
+
1314
+ # The bastion's EC2 instance id, which both databases are reached through.
1315
+ value_object "Bastion" do
1316
+ attribute :value, String, pattern: '^i-[0-9a-f]+$'
1317
+ end
1318
+
1319
+ value_object "Host" do
1320
+ attribute :value, String, pattern: '^[A-Za-z0-9][A-Za-z0-9.-]*$'
1321
+ end
1322
+
1323
+ # A Secrets Manager id or ARN; the script reads the password from it, so no value travels here.
1324
+ value_object "Secret" do
1325
+ attribute :value, String, pattern: '^[^ \t\n\r]+$'
1326
+ end
1327
+
1328
+ # A database's name; empty leaves it to the generated script's own default.
1329
+ value_object "DatabaseName" do
1330
+ attribute :value, String, pattern: '^[A-Za-z0-9_]*$'
1331
+ end
1332
+
1333
+ value_object "Switch" do
1334
+ attribute :value, Boolean
1335
+ end
1336
+
1337
+ value_object "Report" do
1338
+ attribute :value, String
1339
+ end
1340
+
1341
+ lifecycle :status, default: "requested" do
1342
+ transition "Complete" => "restored", from: "requested"
1343
+ transition "Plan" => "planned", from: "requested"
1344
+ transition "Flag" => "flagged", from: "requested"
1345
+ transition "Confirm" => "verified", from: ["requested", "restored"]
1346
+ transition "Drift" => "drifted", from: ["requested", "restored"]
1347
+ transition "FlagVerification" => "flagged", from: ["requested", "restored"]
1348
+ end
1349
+
1350
+ # `hecks deploy data_copy.restore <project> bastion=<i-...> source=<host> source_secret=<id>
1351
+ # target=<host> target_secret=<id> [source_db=] [target_db=] [force=true] [confirm=true]
1352
+ # [dry_run=true] [skip_verify=true] [script=<path>]`. Runs the project's generated
1353
+ # `restore-to-rds.sh`, which overwrites the target database's schemas, so it refuses unless
1354
+ # `confirm=true` (the refusal names what would be overwritten); `dry_run=true` prints the plan
1355
+ # and runs nothing. A policy then requests a `CopyVerification` under the same run key unless
1356
+ # `skip_verify=true`. Exit 1 when flagged or drifted, with the script's status in the reason.
1357
+ command "Restore" do
1358
+ goal "Copy a project's schemas into RDS and record whether the copy matches (exit 1 when flagged or drifted: 60 old client, 61 target has the schema, 62 restore errors)"
1359
+
1360
+ attribute :project, Location
1361
+ attribute :script, Location, optional: true
1362
+ attribute :run, RunKey
1363
+ attribute :bastion, Bastion
1364
+ attribute :source, Host
1365
+ attribute :source_secret, Secret
1366
+ attribute :target, Host
1367
+ attribute :target_secret, Secret
1368
+ attribute :source_db, DatabaseName, default: { value: "" }
1369
+ attribute :target_db, DatabaseName, default: { value: "" }
1370
+ attribute :force, Switch, optional: true
1371
+ attribute :confirm, Switch, optional: true
1372
+ attribute :dry_run, Switch, optional: true
1373
+ attribute :skip_verify, Switch, optional: true
1374
+
1375
+ sets :project
1376
+ sets :script
1377
+ sets :run
1378
+ sets :bastion
1379
+ sets :source
1380
+ sets :source_secret
1381
+ sets :target
1382
+ sets :target_secret
1383
+ sets :source_db
1384
+ sets :target_db
1385
+ sets :force
1386
+ sets :confirm
1387
+ sets :dry_run
1388
+ sets :skip_verify
1389
+
1390
+ emits "DataCopyRequested"
1391
+ end
1392
+
1393
+ # `hecks deploy data_copy.verify <project> bastion= source= source_secret= target= target_secret=
1394
+ # [source_db=] [target_db=] [script=<path>]`. Compares the two databases with the project's
1395
+ # generated `verify-copy.sh` (structure and exact row counts of every table, nothing unpopulated),
1396
+ # read-only on both, without a restore. A policy requests the `CopyVerification` and its outcome
1397
+ # lands here, the same way it does after a restore. Exit 1 when `drifted` or `flagged`.
1398
+ command "Verify" do
1399
+ goal "Compare two databases without a restore and record whether they match (exit 1 when drifted: 50, or flagged: could not compare)"
1400
+
1401
+ attribute :project, Location
1402
+ attribute :script, Location, optional: true
1403
+ attribute :run, RunKey
1404
+ attribute :bastion, Bastion
1405
+ attribute :source, Host
1406
+ attribute :source_secret, Secret
1407
+ attribute :target, Host
1408
+ attribute :target_secret, Secret
1409
+ attribute :source_db, DatabaseName, default: { value: "" }
1410
+ attribute :target_db, DatabaseName, default: { value: "" }
1411
+
1412
+ sets :project
1413
+ sets :script
1414
+ sets :run
1415
+ sets :bastion
1416
+ sets :source
1417
+ sets :source_secret
1418
+ sets :target
1419
+ sets :target_secret
1420
+ sets :source_db
1421
+ sets :target_db
1422
+
1423
+ emits "DataCopyVerifyRequested"
1424
+ end
1425
+
1426
+ command "Complete" do
1427
+ goal "Record that the copy ran, and what the script said"
1428
+
1429
+ reference_to DataCopy
1430
+ attribute :report, Report
1431
+
1432
+ sets :report
1433
+
1434
+ emits "DataCopyCompleted"
1435
+ end
1436
+
1437
+ command "Plan" do
1438
+ goal "Record the plan a dry run printed: what would be copied and overwritten, with nothing run"
1439
+
1440
+ reference_to DataCopy
1441
+ attribute :report, Report
1442
+
1443
+ sets :report
1444
+
1445
+ emits "DataCopyPlanned"
1446
+ end
1447
+
1448
+ command "Flag" do
1449
+ goal "Record that the copy was refused or failed, with the script's status and what it said"
1450
+
1451
+ reference_to DataCopy
1452
+ attribute :refusal, Report
1453
+
1454
+ sets :refusal
1455
+
1456
+ emits "DataCopyFlagged"
1457
+ end
1458
+
1459
+ command "Confirm" do
1460
+ goal "Record that the verification the copy requested found both databases identical"
1461
+
1462
+ reference_to DataCopy
1463
+ attribute :verification, Report
1464
+
1465
+ sets :verification
1466
+
1467
+ emits "DataCopyVerified"
1468
+ end
1469
+
1470
+ command "Drift" do
1471
+ goal "Record that the verification the copy requested found the databases differ, and where"
1472
+
1473
+ reference_to DataCopy
1474
+ attribute :verification, Report
1475
+ attribute :refusal, Report
1476
+
1477
+ sets :verification
1478
+ sets :refusal
1479
+
1480
+ emits "DataCopyDrifted"
1481
+ end
1482
+
1483
+ command "FlagVerification" do
1484
+ goal "Record that the copy ran but its verification could not be made, and why"
1485
+
1486
+ reference_to DataCopy
1487
+ attribute :verification, Report
1488
+ attribute :refusal, Report
1489
+
1490
+ sets :verification
1491
+ sets :refusal
1492
+
1493
+ emits "DataCopyVerificationFlagged"
1494
+ end
1495
+
1496
+ query "Verdict" do
1497
+ description "What one copy found: its status, the report, and the reason it was flagged or drifted."
1498
+ attribute :run, RunKey
1499
+ where(run: :run)
1500
+ order_by :run
1501
+ end
1502
+
1503
+ query "Flagged" do
1504
+ description "Every copy that was refused, failed or could not be verified."
1505
+ where(status: "flagged")
1506
+ order_by :run
1507
+ end
1508
+
1509
+ query "Drifted" do
1510
+ description "Every copy whose verification found the two databases differ."
1511
+ where(status: "drifted")
1512
+ order_by :run
1513
+ end
1514
+ end
1515
+
1516
+ policy "CopyDataWhenRequested" do
1517
+ on "DataCopy.DataCopyRequested"
1518
+ trigger DataCopy::DeployToolchain::CopyData, with: { run: :run }
1519
+ end
1520
+
1521
+ policy "RecordTheCopiedData" do
1522
+ on "DataCopy.DataCopyAnswered"
1523
+ where { !planned.value }
1524
+ trigger DataCopy::Complete, with: { report: :report }
1525
+ end
1526
+
1527
+ policy "RecordTheCopyPlan" do
1528
+ on "DataCopy.DataCopyAnswered"
1529
+ where { planned.value }
1530
+ trigger DataCopy::Plan, with: { report: :report }
1531
+ end
1532
+
1533
+ policy "RecordTheFlaggedCopy" do
1534
+ on "DataCopy.DataCopyRefused"
1535
+ trigger DataCopy::Flag, with: { refusal: :refusal }
1536
+ end
1537
+
1538
+ # Declared after RecordTheCopiedData: the copy is recorded before its verification is requested,
1539
+ # and the request comes from the answer itself because a reaction chain is bounded.
1540
+ policy "VerifyAfterCopy" do
1541
+ on "DataCopy.DataCopyAnswered"
1542
+ where { run_verify.value }
1543
+ trigger CopyVerification::Run,
1544
+ with: { project: :project, run: :run, bastion: :bastion, source: :source,
1545
+ source_secret: :source_secret, target: :target, target_secret: :target_secret,
1546
+ source_db: :source_db, target_db: :target_db }
1547
+ end
1548
+
1549
+ policy "VerifyWhenRequested" do
1550
+ on "DataCopy.DataCopyVerifyRequested"
1551
+ trigger CopyVerification::Run,
1552
+ with: { project: :project, run: :run, bastion: :bastion, source: :source,
1553
+ source_secret: :source_secret, target: :target, target_secret: :target_secret,
1554
+ source_db: :source_db, target_db: :target_db }
1555
+ end
1556
+
1557
+ policy "VerifyDataCopyOnMatch" do
1558
+ on "CopyVerification.CopyMatched"
1559
+ trigger DataCopy::Confirm, with: { data_copy: :run, verification: :report }
1560
+ end
1561
+
1562
+ policy "DriftDataCopyOnDifference" do
1563
+ on "CopyVerification.CopyDrifted"
1564
+ trigger DataCopy::Drift, with: { data_copy: :run, verification: :report, refusal: :report }
1565
+ end
1566
+
1567
+ policy "FlagDataCopyOnUnverified" do
1568
+ on "CopyVerification.CopyUnverified"
1569
+ trigger DataCopy::FlagVerification, with: { data_copy: :run, verification: :refusal, refusal: :refusal }
1570
+ end
1571
+
1572
+ aggregate "CopyVerification" do
1573
+ description "One comparison of two databases holding a project's schemas: the generated verify-copy script run, and what it found."
1574
+
1575
+ attribute :project, Location
1576
+ attribute :script, Location, optional: true
1577
+ attribute :run, RunKey
1578
+ attribute :bastion, Bastion
1579
+ attribute :source, Host
1580
+ attribute :source_secret, Secret
1581
+ attribute :target, Host
1582
+ attribute :target_secret, Secret
1583
+ attribute :source_db, DatabaseName, default: { value: "" }
1584
+ attribute :target_db, DatabaseName, default: { value: "" }
1585
+ attribute :report, Report, optional: true
1586
+ attribute :refusal, Report, optional: true
1587
+ identified_by :run
1588
+
1589
+ value_object "RunKey" do
1590
+ attribute :value, String, pattern: '[^ \t\n\r]'
1591
+
1592
+ invariant("a run is named") { !value.to_s.empty? }
1593
+ end
1594
+
1595
+ value_object "Location" do
1596
+ attribute :value, String, pattern: '[^\t\n\r]'
1597
+
1598
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
1599
+ end
1600
+
1601
+ value_object "Bastion" do
1602
+ attribute :value, String, pattern: '^i-[0-9a-f]+$'
1603
+ end
1604
+
1605
+ value_object "Host" do
1606
+ attribute :value, String, pattern: '^[A-Za-z0-9][A-Za-z0-9.-]*$'
1607
+ end
1608
+
1609
+ value_object "Secret" do
1610
+ attribute :value, String, pattern: '^[^ \t\n\r]+$'
1611
+ end
1612
+
1613
+ # A database's name; empty leaves it to the generated script's own default.
1614
+ value_object "DatabaseName" do
1615
+ attribute :value, String, pattern: '^[A-Za-z0-9_]*$'
1616
+ end
1617
+
1618
+ value_object "Report" do
1619
+ attribute :value, String
1620
+ end
1621
+
1622
+ lifecycle :status, default: "requested" do
1623
+ transition "Match" => "verified", from: "requested"
1624
+ transition "Differ" => "drifted", from: "requested"
1625
+ transition "Flag" => "flagged", from: "requested"
1626
+ end
1627
+
1628
+ # Runs the project's generated `verify-copy.sh`: structure and exact row counts of every table,
1629
+ # nothing unpopulated. Read-only on both databases. A `DataCopy` requests it, by `data_copy.verify`
1630
+ # or after a restore, and takes its outcome by the shared run key.
1631
+ command "Run" do
1632
+ goal "Compare two databases and record whether they match (exit 1 when drifted: 50 differ, or flagged: could not compare)"
1633
+
1634
+ attribute :project, Location
1635
+ attribute :script, Location, optional: true
1636
+ attribute :run, RunKey
1637
+ attribute :bastion, Bastion
1638
+ attribute :source, Host
1639
+ attribute :source_secret, Secret
1640
+ attribute :target, Host
1641
+ attribute :target_secret, Secret
1642
+ attribute :source_db, DatabaseName, default: { value: "" }
1643
+ attribute :target_db, DatabaseName, default: { value: "" }
1644
+
1645
+ sets :project
1646
+ sets :script
1647
+ sets :run
1648
+ sets :bastion
1649
+ sets :source
1650
+ sets :source_secret
1651
+ sets :target
1652
+ sets :target_secret
1653
+ sets :source_db
1654
+ sets :target_db
1655
+
1656
+ emits "CopyVerificationRequested"
1657
+ end
1658
+
1659
+ command "Match" do
1660
+ goal "Record that both databases hold the same structure and row counts"
1661
+
1662
+ reference_to CopyVerification
1663
+ attribute :report, Report
1664
+
1665
+ sets :report
1666
+
1667
+ emits "CopyMatched"
1668
+ end
1669
+
1670
+ command "Differ" do
1671
+ goal "Record that the databases differ, with what the script printed"
1672
+
1673
+ reference_to CopyVerification
1674
+ attribute :report, Report
1675
+
1676
+ sets :report
1677
+
1678
+ emits "CopyDrifted"
1679
+ end
1680
+
1681
+ command "Flag" do
1682
+ goal "Record that the comparison could not be made, and why"
1683
+
1684
+ reference_to CopyVerification
1685
+ attribute :refusal, Report
1686
+
1687
+ sets :refusal
1688
+
1689
+ emits "CopyUnverified"
1690
+ end
1691
+
1692
+ query "Verdict" do
1693
+ description "What one comparison found: its status, and the report or the reason it was flagged."
1694
+ attribute :run, RunKey
1695
+ where(run: :run)
1696
+ order_by :run
1697
+ end
1698
+
1699
+ query "Drifted" do
1700
+ description "Every comparison that found the databases differ."
1701
+ where(status: "drifted")
1702
+ order_by :run
1703
+ end
1704
+
1705
+ query "Flagged" do
1706
+ description "Every comparison that could not be made."
1707
+ where(status: "flagged")
1708
+ order_by :run
1709
+ end
1710
+ end
1711
+
1712
+ policy "CompareCopyWhenRequested" do
1713
+ on "CopyVerification.CopyVerificationRequested"
1714
+ trigger CopyVerification::DeployToolchain::CompareCopy, with: { run: :run }
1715
+ end
1716
+
1717
+ policy "RecordTheMatchingCopy" do
1718
+ on "CopyVerification.CopyVerificationAnswered"
1719
+ where { !drifted.value }
1720
+ trigger CopyVerification::Match, with: { report: :report }
1721
+ end
1722
+
1723
+ policy "RecordTheDriftedCopy" do
1724
+ on "CopyVerification.CopyVerificationAnswered"
1725
+ where { drifted.value }
1726
+ trigger CopyVerification::Differ, with: { report: :report }
1727
+ end
1728
+
1729
+ policy "RecordTheUnverifiedCopy" do
1730
+ on "CopyVerification.CopyVerificationRefused"
1731
+ trigger CopyVerification::Flag, with: { refusal: :refusal }
1732
+ end
1733
+
1734
+ aggregate "BluebookDiff" do
1735
+ description "One report of which bluebook releases a deploy changes: the running image's bluebooks against the ones about to ship."
1736
+
1737
+ attribute :project, Location
1738
+ attribute :script, Location, optional: true
1739
+ attribute :run, RunKey
1740
+ attribute :old, Location, optional: true
1741
+ attribute :new, Location, optional: true
1742
+ attribute :report, Report, optional: true
1743
+ attribute :refusal, Report, optional: true
1744
+ identified_by :run
1745
+
1746
+ value_object "RunKey" do
1747
+ attribute :value, String, pattern: '[^ \t\n\r]'
1748
+
1749
+ invariant("a run is named") { !value.to_s.empty? }
1750
+ end
1751
+
1752
+ value_object "Location" do
1753
+ attribute :value, String, pattern: '[^\t\n\r]'
1754
+
1755
+ invariant("a project, script or file is named by its path") { !value.to_s.empty? }
1756
+ end
1757
+
1758
+ value_object "Report" do
1759
+ attribute :value, String
1760
+ end
1761
+
1762
+ # No outcome is a failure: a report that could not be made is `unavailable`, never `flagged`
1763
+ # (only a malformed request is), because the era check gates a deploy, not this report.
1764
+ lifecycle :status, default: "requested" do
1765
+ transition "Match" => "unchanged", from: "requested"
1766
+ transition "Differ" => "changed", from: "requested"
1767
+ transition "Withhold" => "unavailable", from: "requested"
1768
+ transition "Flag" => "flagged", from: "requested"
1769
+ end
1770
+
1771
+ # `hecks deploy bluebook_diff.run <project> [old=<json> new=<json>] [script=<path>]`. With
1772
+ # `old` and `new` (two `hecks package.verify` outputs) the comparison is made here, offline.
1773
+ # With neither, the project's `bluebooks-diff.sh` reads the running image's bluebooks from the
1774
+ # registry (read-only) and the local image's, and its report is classified. It never fails:
1775
+ # `unchanged`, `changed` or `unavailable` (a lookup failed, or the script is missing). Only
1776
+ # giving one of `old` and `new` is refused, as `flagged`.
1777
+ command "Run" do
1778
+ goal "Report which bluebook releases a deploy changes and record it (never a failure: unchanged, changed or unavailable)"
1779
+
1780
+ attribute :project, Location
1781
+ attribute :script, Location, optional: true
1782
+ attribute :run, RunKey
1783
+ attribute :old, Location, optional: true
1784
+ attribute :new, Location, optional: true
1785
+
1786
+ sets :project
1787
+ sets :script
1788
+ sets :run
1789
+ sets :old
1790
+ sets :new
1791
+
1792
+ emits "BluebookDiffRequested"
1793
+ end
1794
+
1795
+ command "Match" do
1796
+ goal "Record that the deploy changes no bluebook"
1797
+
1798
+ reference_to BluebookDiff
1799
+ attribute :report, Report
1800
+
1801
+ sets :report
1802
+
1803
+ emits "BluebooksUnchanged"
1804
+ end
1805
+
1806
+ command "Differ" do
1807
+ goal "Record the bluebooks the deploy adds, removes, re-versions or changes in content"
1808
+
1809
+ reference_to BluebookDiff
1810
+ attribute :report, Report
1811
+
1812
+ sets :report
1813
+
1814
+ emits "BluebooksChanged"
1815
+ end
1816
+
1817
+ command "Withhold" do
1818
+ goal "Record that the report could not be made, and why; the deploy carries on"
1819
+
1820
+ reference_to BluebookDiff
1821
+ attribute :report, Report
1822
+
1823
+ sets :report
1824
+
1825
+ emits "BluebookDiffUnavailable"
1826
+ end
1827
+
1828
+ command "Flag" do
1829
+ goal "Record that the request was malformed (only one of old and new), and why"
1830
+
1831
+ reference_to BluebookDiff
1832
+ attribute :refusal, Report
1833
+
1834
+ sets :refusal
1835
+
1836
+ emits "BluebookDiffFlagged"
1837
+ end
1838
+
1839
+ query "Verdict" do
1840
+ description "What one report found: its status and the report."
1841
+ attribute :run, RunKey
1842
+ where(run: :run)
1843
+ order_by :run
1844
+ end
1845
+
1846
+ query "Changed" do
1847
+ description "Every report that found a bluebook release changed."
1848
+ where(status: "changed")
1849
+ order_by :run
1850
+ end
1851
+ end
1852
+
1853
+ policy "DiffWhenRequested" do
1854
+ on "BluebookDiff.BluebookDiffRequested"
1855
+ trigger BluebookDiff::DeployToolchain::CompareBluebooks, with: { run: :run }
1856
+ end
1857
+
1858
+ policy "RecordTheUnchangedBluebooks" do
1859
+ on "BluebookDiff.BluebookDiffAnswered"
1860
+ where { outcome.value == "unchanged" }
1861
+ trigger BluebookDiff::Match, with: { report: :report }
1862
+ end
1863
+
1864
+ policy "RecordTheChangedBluebooks" do
1865
+ on "BluebookDiff.BluebookDiffAnswered"
1866
+ where { outcome.value == "changed" }
1867
+ trigger BluebookDiff::Differ, with: { report: :report }
1868
+ end
1869
+
1870
+ policy "RecordTheUnavailableDiff" do
1871
+ on "BluebookDiff.BluebookDiffAnswered"
1872
+ where { outcome.value == "unavailable" }
1873
+ trigger BluebookDiff::Withhold, with: { report: :report }
1874
+ end
1875
+
1876
+ policy "RecordTheFlaggedDiff" do
1877
+ on "BluebookDiff.BluebookDiffRefused"
1878
+ trigger BluebookDiff::Flag, with: { refusal: :refusal }
1879
+ end
1880
+
1881
+ aggregate "PreviewRun" do
1882
+ description "One run of a project's preview script: the per-branch preview stack named, found, listed, deployed, destroyed or signed in to, and how it ended."
1883
+
1884
+ attribute :project, Location
1885
+ attribute :script, Location, optional: true
1886
+ attribute :run, RunKey
1887
+ attribute :action, Action
1888
+ attribute :branch, Branch, optional: true
1889
+ attribute :confirm, Switch, optional: true
1890
+ attribute :dry_run, Switch, optional: true
1891
+ attribute :report, Report, optional: true
1892
+ attribute :refusal, Report, optional: true
1893
+ identified_by :run
1894
+
1895
+ value_object "RunKey" do
1896
+ attribute :value, String, pattern: '[^ \t\n\r]'
1897
+
1898
+ invariant("a run is named") { !value.to_s.empty? }
1899
+ end
1900
+
1901
+ value_object "Location" do
1902
+ attribute :value, String, pattern: '[^\t\n\r]'
1903
+
1904
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
1905
+ end
1906
+
1907
+ # What the script is asked to do; each command sets its own.
1908
+ value_object "Action" do
1909
+ attribute :value, String, pattern: '^(name|url|list|deploy|destroy|login)$'
1910
+ end
1911
+
1912
+ # A git branch name. A preview is never of a production branch.
1913
+ value_object "Branch" do
1914
+ attribute :value, String, pattern: '^[^ \t\n\r]+$'
1915
+
1916
+ invariant("a preview is never of main or master") { value != "main" && value != "master" }
1917
+ end
1918
+
1919
+ value_object "Switch" do
1920
+ attribute :value, Boolean
1921
+ end
1922
+
1923
+ value_object "Report" do
1924
+ attribute :value, String
1925
+ end
1926
+
1927
+ lifecycle :status, default: "requested" do
1928
+ transition "RecordName" => "named", from: "requested"
1929
+ transition "RecordUrl" => "located", from: "requested"
1930
+ transition "RecordList" => "listed", from: "requested"
1931
+ transition "RecordDeploy" => "deployed", from: "requested"
1932
+ transition "RecordDestroy" => "destroyed", from: "requested"
1933
+ transition "RecordLogin" => "signed_in", from: "requested"
1934
+ transition "Plan" => "planned", from: "requested"
1935
+ transition "Flag" => "flagged", from: "requested"
1936
+ end
1937
+
1938
+ # `hecks deploy preview_run.<name|url|list|deploy|destroy|login> <project> [branch=<name>]
1939
+ # [confirm=true] [dry_run=true] [script=<path>]`. Runs the project's `preview.sh` with that
1940
+ # verb; the script derives every name from the branch (the checked-out one unless `branch=`),
1941
+ # refuses `main` and `master`, and only touches stacks under its own prefix. `name`, `url` and
1942
+ # `list` read; `deploy`, `destroy` and `login` write to AWS or read its secrets, so they refuse
1943
+ # unless `confirm=true`, and `dry_run=true` prints the plan and runs nothing. Exit 1 when
1944
+ # flagged, with the script's status (1: it refused or failed) in the reason.
1945
+ command "Name" do
1946
+ goal "Print the names a branch's preview would have, from the project's preview script (no AWS call)"
1947
+
1948
+ attribute :project, Location
1949
+ attribute :script, Location, optional: true
1950
+ attribute :run, RunKey
1951
+ attribute :action, Action, default: { value: "name" }
1952
+ attribute :branch, Branch, optional: true
1953
+ attribute :confirm, Switch, optional: true
1954
+ attribute :dry_run, Switch, optional: true
1955
+
1956
+ sets :project
1957
+ sets :script
1958
+ sets :run
1959
+ sets :action
1960
+ sets :branch
1961
+ sets :confirm
1962
+ sets :dry_run
1963
+
1964
+ emits "PreviewNameRequested"
1965
+ end
1966
+
1967
+ command "Url" do
1968
+ goal "Print a branch's preview URL, read from its stack"
1969
+
1970
+ attribute :project, Location
1971
+ attribute :script, Location, optional: true
1972
+ attribute :run, RunKey
1973
+ attribute :action, Action, default: { value: "url" }
1974
+ attribute :branch, Branch, optional: true
1975
+ attribute :confirm, Switch, optional: true
1976
+ attribute :dry_run, Switch, optional: true
1977
+
1978
+ sets :project
1979
+ sets :script
1980
+ sets :run
1981
+ sets :action
1982
+ sets :branch
1983
+ sets :confirm
1984
+ sets :dry_run
1985
+
1986
+ emits "PreviewUrlRequested"
1987
+ end
1988
+
1989
+ command "List" do
1990
+ goal "List every preview stack that exists, read from AWS"
1991
+
1992
+ attribute :project, Location
1993
+ attribute :script, Location, optional: true
1994
+ attribute :run, RunKey
1995
+ attribute :action, Action, default: { value: "list" }
1996
+ attribute :branch, Branch, optional: true
1997
+ attribute :confirm, Switch, optional: true
1998
+ attribute :dry_run, Switch, optional: true
1999
+
2000
+ sets :project
2001
+ sets :script
2002
+ sets :run
2003
+ sets :action
2004
+ sets :branch
2005
+ sets :confirm
2006
+ sets :dry_run
2007
+
2008
+ emits "PreviewListRequested"
2009
+ end
2010
+
2011
+ command "Deploy" do
2012
+ goal "Create or update a branch's preview from the images built locally (writes to AWS; refuses unless confirm=true)"
2013
+
2014
+ attribute :project, Location
2015
+ attribute :script, Location, optional: true
2016
+ attribute :run, RunKey
2017
+ attribute :action, Action, default: { value: "deploy" }
2018
+ attribute :branch, Branch, optional: true
2019
+ attribute :confirm, Switch, optional: true
2020
+ attribute :dry_run, Switch, optional: true
2021
+
2022
+ sets :project
2023
+ sets :script
2024
+ sets :run
2025
+ sets :action
2026
+ sets :branch
2027
+ sets :confirm
2028
+ sets :dry_run
2029
+
2030
+ emits "PreviewDeployRequested"
2031
+ end
2032
+
2033
+ command "Destroy" do
2034
+ goal "Tear a branch's preview stack down (writes to AWS; refuses unless confirm=true)"
2035
+
2036
+ attribute :project, Location
2037
+ attribute :script, Location, optional: true
2038
+ attribute :run, RunKey
2039
+ attribute :action, Action, default: { value: "destroy" }
2040
+ attribute :branch, Branch, optional: true
2041
+ attribute :confirm, Switch, optional: true
2042
+ attribute :dry_run, Switch, optional: true
2043
+
2044
+ sets :project
2045
+ sets :script
2046
+ sets :run
2047
+ sets :action
2048
+ sets :branch
2049
+ sets :confirm
2050
+ sets :dry_run
2051
+
2052
+ emits "PreviewDestroyRequested"
2053
+ end
2054
+
2055
+ command "Login" do
2056
+ goal "Mint a line that signs the deployer in to a preview as its first admin (reads its session secret; refuses unless confirm=true)"
2057
+
2058
+ attribute :project, Location
2059
+ attribute :script, Location, optional: true
2060
+ attribute :run, RunKey
2061
+ attribute :action, Action, default: { value: "login" }
2062
+ attribute :branch, Branch, optional: true
2063
+ attribute :confirm, Switch, optional: true
2064
+ attribute :dry_run, Switch, optional: true
2065
+
2066
+ sets :project
2067
+ sets :script
2068
+ sets :run
2069
+ sets :action
2070
+ sets :branch
2071
+ sets :confirm
2072
+ sets :dry_run
2073
+
2074
+ emits "PreviewLoginRequested"
2075
+ end
2076
+
2077
+ command "RecordName" do
2078
+ goal "Record the names the script printed"
2079
+
2080
+ reference_to PreviewRun
2081
+ attribute :report, Report
2082
+
2083
+ sets :report
2084
+
2085
+ emits "PreviewNamed"
2086
+ end
2087
+
2088
+ command "RecordUrl" do
2089
+ goal "Record the preview URL the script printed"
2090
+
2091
+ reference_to PreviewRun
2092
+ attribute :report, Report
2093
+
2094
+ sets :report
2095
+
2096
+ emits "PreviewLocated"
2097
+ end
2098
+
2099
+ command "RecordList" do
2100
+ goal "Record the preview stacks the script listed"
2101
+
2102
+ reference_to PreviewRun
2103
+ attribute :report, Report
2104
+
2105
+ sets :report
2106
+
2107
+ emits "PreviewListed"
2108
+ end
2109
+
2110
+ command "RecordDeploy" do
2111
+ goal "Record that the preview was created or updated, and what the script said"
2112
+
2113
+ reference_to PreviewRun
2114
+ attribute :report, Report
2115
+
2116
+ sets :report
2117
+
2118
+ emits "PreviewDeployed"
2119
+ end
2120
+
2121
+ command "RecordDestroy" do
2122
+ goal "Record that the preview was torn down, and what the script said"
2123
+
2124
+ reference_to PreviewRun
2125
+ attribute :report, Report
2126
+
2127
+ sets :report
2128
+
2129
+ emits "PreviewDestroyed"
2130
+ end
2131
+
2132
+ command "RecordLogin" do
2133
+ goal "Record that the sign-in line was minted, and where the script put it"
2134
+
2135
+ reference_to PreviewRun
2136
+ attribute :report, Report
2137
+
2138
+ sets :report
2139
+
2140
+ emits "PreviewSignedIn"
2141
+ end
2142
+
2143
+ command "Plan" do
2144
+ goal "Record the plan a dry run printed: what would run and where, with nothing run"
2145
+
2146
+ reference_to PreviewRun
2147
+ attribute :report, Report
2148
+
2149
+ sets :report
2150
+
2151
+ emits "PreviewPlanned"
2152
+ end
2153
+
2154
+ command "Flag" do
2155
+ goal "Record that the run was refused or failed, with the script's status and what it said"
2156
+
2157
+ reference_to PreviewRun
2158
+ attribute :refusal, Report
2159
+
2160
+ sets :refusal
2161
+
2162
+ emits "PreviewFlagged"
2163
+ end
2164
+
2165
+ query "Verdict" do
2166
+ description "What one run found: its status, the report, and the reason it was flagged."
2167
+ attribute :run, RunKey
2168
+ where(run: :run)
2169
+ order_by :run
2170
+ end
2171
+
2172
+ query "Flagged" do
2173
+ description "Every preview run that was refused or failed."
2174
+ where(status: "flagged")
2175
+ order_by :run
2176
+ end
2177
+ end
2178
+
2179
+ policy "RunPreviewWhenNameRequested" do
2180
+ on "PreviewRun.PreviewNameRequested"
2181
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2182
+ end
2183
+
2184
+ policy "RunPreviewWhenUrlRequested" do
2185
+ on "PreviewRun.PreviewUrlRequested"
2186
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2187
+ end
2188
+
2189
+ policy "RunPreviewWhenListRequested" do
2190
+ on "PreviewRun.PreviewListRequested"
2191
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2192
+ end
2193
+
2194
+ policy "RunPreviewWhenDeployRequested" do
2195
+ on "PreviewRun.PreviewDeployRequested"
2196
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2197
+ end
2198
+
2199
+ policy "RunPreviewWhenDestroyRequested" do
2200
+ on "PreviewRun.PreviewDestroyRequested"
2201
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2202
+ end
2203
+
2204
+ policy "RunPreviewWhenLoginRequested" do
2205
+ on "PreviewRun.PreviewLoginRequested"
2206
+ trigger PreviewRun::DeployToolchain::RunPreview, with: { run: :run }
2207
+ end
2208
+
2209
+ policy "RecordThePreviewName" do
2210
+ on "PreviewRun.PreviewRunAnswered"
2211
+ where { outcome.value == "named" }
2212
+ trigger PreviewRun::RecordName, with: { report: :report }
2213
+ end
2214
+
2215
+ policy "RecordThePreviewUrl" do
2216
+ on "PreviewRun.PreviewRunAnswered"
2217
+ where { outcome.value == "located" }
2218
+ trigger PreviewRun::RecordUrl, with: { report: :report }
2219
+ end
2220
+
2221
+ policy "RecordThePreviewList" do
2222
+ on "PreviewRun.PreviewRunAnswered"
2223
+ where { outcome.value == "listed" }
2224
+ trigger PreviewRun::RecordList, with: { report: :report }
2225
+ end
2226
+
2227
+ policy "RecordTheDeployedPreview" do
2228
+ on "PreviewRun.PreviewRunAnswered"
2229
+ where { outcome.value == "deployed" }
2230
+ trigger PreviewRun::RecordDeploy, with: { report: :report }
2231
+ end
2232
+
2233
+ policy "RecordTheDestroyedPreview" do
2234
+ on "PreviewRun.PreviewRunAnswered"
2235
+ where { outcome.value == "destroyed" }
2236
+ trigger PreviewRun::RecordDestroy, with: { report: :report }
2237
+ end
2238
+
2239
+ policy "RecordThePreviewLogin" do
2240
+ on "PreviewRun.PreviewRunAnswered"
2241
+ where { outcome.value == "signed_in" }
2242
+ trigger PreviewRun::RecordLogin, with: { report: :report }
2243
+ end
2244
+
2245
+ policy "RecordThePreviewPlan" do
2246
+ on "PreviewRun.PreviewRunAnswered"
2247
+ where { outcome.value == "planned" }
2248
+ trigger PreviewRun::Plan, with: { report: :report }
2249
+ end
2250
+
2251
+ policy "RecordTheFlaggedPreview" do
2252
+ on "PreviewRun.PreviewRunRefused"
2253
+ trigger PreviewRun::Flag, with: { refusal: :refusal }
2254
+ end
2255
+
2256
+ aggregate "CompanionRoll" do
2257
+ description "One roll of a companion Compose project (a second project beside the app's) onto the box: the project's deploy script run, and how it ended."
2258
+
2259
+ attribute :project, Location
2260
+ attribute :script, Location, optional: true
2261
+ attribute :run, RunKey
2262
+ attribute :companion, Companion, default: { value: "umami" }
2263
+ attribute :taskdef, TaskDefinition
2264
+ attribute :confirm, Switch, optional: true
2265
+ attribute :dry_run, Switch, optional: true
2266
+ attribute :report, Report, optional: true
2267
+ attribute :refusal, Report, optional: true
2268
+ identified_by :run
2269
+
2270
+ value_object "RunKey" do
2271
+ attribute :value, String, pattern: '[^ \t\n\r]'
2272
+
2273
+ invariant("a run is named") { !value.to_s.empty? }
2274
+ end
2275
+
2276
+ value_object "Location" do
2277
+ attribute :value, String, pattern: '[^\t\n\r]'
2278
+
2279
+ invariant("a project or script is named by its path") { !value.to_s.empty? }
2280
+ end
2281
+
2282
+ # The companion's name; its script is `deploy-<companion>.sh`.
2283
+ value_object "Companion" do
2284
+ attribute :value, String, pattern: '^[a-z0-9][a-z0-9-]*$'
2285
+ end
2286
+
2287
+ # A task definition revision (or family) the companion's image and settings are read from.
2288
+ value_object "TaskDefinition" do
2289
+ attribute :value, String, pattern: '^[A-Za-z0-9_-]+(:[0-9]+)?$'
2290
+ end
2291
+
2292
+ value_object "Switch" do
2293
+ attribute :value, Boolean
2294
+ end
2295
+
2296
+ value_object "Report" do
2297
+ attribute :value, String
2298
+ end
2299
+
2300
+ lifecycle :status, default: "requested" do
2301
+ transition "Complete" => "rolled", from: "requested"
2302
+ transition "Plan" => "planned", from: "requested"
2303
+ transition "Flag" => "flagged", from: "requested"
2304
+ end
2305
+
2306
+ # `hecks deploy companion_roll.run <project> taskdef=<family:rev> [companion=umami] [confirm=true]
2307
+ # [dry_run=true] [script=<path>]`. Runs the project's `deploy-<companion>.sh`, which reads the
2308
+ # companion's image and settings from the task definition, sends a Compose project and its secret
2309
+ # references to the box over SSM (secret values never travel; the box resolves them), starts it
2310
+ # beside the app's project, and checks it on the box. It writes to the box, so it refuses unless
2311
+ # `confirm=true`; `dry_run=true` prints the plan and runs nothing. Exit 1 when flagged.
2312
+ command "Run" do
2313
+ goal "Roll a companion Compose project onto the box and record the check on the box (refuses unless confirm=true)"
2314
+
2315
+ attribute :project, Location
2316
+ attribute :script, Location, optional: true
2317
+ attribute :run, RunKey
2318
+ attribute :companion, Companion, default: { value: "umami" }
2319
+ attribute :taskdef, TaskDefinition
2320
+ attribute :confirm, Switch, optional: true
2321
+ attribute :dry_run, Switch, optional: true
2322
+
2323
+ sets :project
2324
+ sets :script
2325
+ sets :run
2326
+ sets :companion
2327
+ sets :taskdef
2328
+ sets :confirm
2329
+ sets :dry_run
2330
+
2331
+ emits "CompanionRollRequested"
2332
+ end
2333
+
2334
+ command "Complete" do
2335
+ goal "Record that the companion rolled and passed its check on the box, and what the script printed"
2336
+
2337
+ reference_to CompanionRoll
2338
+ attribute :report, Report
2339
+
2340
+ sets :report
2341
+
2342
+ emits "CompanionRolled"
2343
+ end
2344
+
2345
+ command "Plan" do
2346
+ goal "Record the plan a dry run printed: what would be rolled and where, with nothing run"
2347
+
2348
+ reference_to CompanionRoll
2349
+ attribute :report, Report
2350
+
2351
+ sets :report
2352
+
2353
+ emits "CompanionRollPlanned"
2354
+ end
2355
+
2356
+ command "Flag" do
2357
+ goal "Record that the roll was refused, or the companion did not roll or is not healthy, and why"
2358
+
2359
+ reference_to CompanionRoll
2360
+ attribute :refusal, Report
2361
+
2362
+ sets :refusal
2363
+
2364
+ emits "CompanionRollFlagged"
2365
+ end
2366
+
2367
+ query "Verdict" do
2368
+ description "What one roll found: its status, the report, and the reason it was flagged."
2369
+ attribute :run, RunKey
2370
+ where(run: :run)
2371
+ order_by :run
2372
+ end
2373
+
2374
+ query "Flagged" do
2375
+ description "Every companion roll that was refused, did not roll or was not healthy."
2376
+ where(status: "flagged")
2377
+ order_by :run
2378
+ end
2379
+ end
2380
+
2381
+ policy "RollCompanionWhenRequested" do
2382
+ on "CompanionRoll.CompanionRollRequested"
2383
+ trigger CompanionRoll::DeployToolchain::RollCompanion, with: { run: :run }
2384
+ end
2385
+
2386
+ policy "RecordTheRolledCompanion" do
2387
+ on "CompanionRoll.CompanionRollAnswered"
2388
+ where { !planned.value }
2389
+ trigger CompanionRoll::Complete, with: { report: :report }
2390
+ end
2391
+
2392
+ policy "RecordTheCompanionPlan" do
2393
+ on "CompanionRoll.CompanionRollAnswered"
2394
+ where { planned.value }
2395
+ trigger CompanionRoll::Plan, with: { report: :report }
2396
+ end
2397
+
2398
+ policy "RecordTheFlaggedCompanionRoll" do
2399
+ on "CompanionRoll.CompanionRollRefused"
2400
+ trigger CompanionRoll::Flag, with: { refusal: :refusal }
894
2401
  end
895
2402
 
896
2403
  aggregate "TemplateComparison" do