hecks 3.5.0 → 3.7.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 (1156) 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 +102 -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/prebuilt.rb +44 -0
  163. data/lib/hecks/bluebook/meta_validator/verdict_cache/tagging.rb +63 -0
  164. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +25 -60
  165. data/lib/hecks/bluebook/meta_validator/world_judge.rb +8 -4
  166. data/lib/hecks/bluebook/meta_validator.rb +59 -175
  167. data/lib/hecks/bluebook/model_check/lifecycle_checks.rb +122 -0
  168. data/lib/hecks/bluebook/model_check/policy_checks.rb +129 -0
  169. data/lib/hecks/bluebook/model_check/saga_checks.rb +134 -0
  170. data/lib/hecks/bluebook/model_check/verbs.rb +69 -0
  171. data/lib/hecks/bluebook/model_check.rb +73 -413
  172. data/lib/hecks/bluebook/pattern_subset/refusals.rb +54 -0
  173. data/lib/hecks/bluebook/pattern_subset/scan.rb +58 -0
  174. data/lib/hecks/bluebook/pattern_subset.rb +93 -134
  175. data/lib/hecks/bluebook/process_manager.rb +10 -9
  176. data/lib/hecks/bluebook/project_discovery.rb +10 -7
  177. data/lib/hecks/bluebook/project_register.rb +42 -41
  178. data/lib/hecks/bluebook/query.rb +19 -12
  179. data/lib/hecks/bluebook/read_model.rb +41 -39
  180. data/lib/hecks/bluebook/smoke_test.rb +51 -36
  181. data/lib/hecks/bluebook/synthesizer.rb +13 -5
  182. data/lib/hecks/bluebook/translation.rb +12 -12
  183. data/lib/hecks/bluebook.rb +1 -1
  184. data/lib/hecks/cache_dir.rb +10 -0
  185. data/lib/hecks/chapters.rb +32 -16
  186. data/lib/hecks/cli/behaviors.rb +22 -15
  187. data/lib/hecks/cli/check_era.rb +2 -2
  188. data/lib/hecks/cli/command_table.rb +72 -0
  189. data/lib/hecks/cli/console.rb +10 -7
  190. data/lib/hecks/cli/deploy_template_diff.rb +22 -9
  191. data/lib/hecks/cli/document.rb +14 -10
  192. data/lib/hecks/cli/domain_stub.rb +1 -1
  193. data/lib/hecks/cli/domain_writer.rb +1 -1
  194. data/lib/hecks/cli/expression_projection.rb +8 -6
  195. data/lib/hecks/cli/follow.rb +10 -4
  196. data/lib/hecks/cli/interview_aggregate.rb +132 -0
  197. data/lib/hecks/cli/interview_draft.rb +16 -200
  198. data/lib/hecks/cli/interview_record.rb +130 -0
  199. data/lib/hecks/cli/interview_run.rb +19 -8
  200. data/lib/hecks/cli/interview_session/agent_state.rb +70 -0
  201. data/lib/hecks/cli/interview_session/catalog.rb +76 -0
  202. data/lib/hecks/cli/interview_session/manual_findings.rb +48 -0
  203. data/lib/hecks/cli/interview_session/proposals.rb +90 -0
  204. data/lib/hecks/cli/interview_session.rb +8 -205
  205. data/lib/hecks/cli/interview_shape.rb +13 -6
  206. data/lib/hecks/cli/ir.rb +8 -11
  207. data/lib/hecks/cli/launcher_words.rb +168 -0
  208. data/lib/hecks/cli/model_check/examination.rb +93 -0
  209. data/lib/hecks/cli/model_check/sources.rb +57 -0
  210. data/lib/hecks/cli/model_check.rb +28 -134
  211. data/lib/hecks/cli/project_cli/launcher_source.rb +177 -0
  212. data/lib/hecks/cli/project_cli/templates.rb +106 -0
  213. data/lib/hecks/cli/project_cli.rb +57 -236
  214. data/lib/hecks/cli/project_diagrams.rb +26 -4
  215. data/lib/hecks/cli/project_glossary.rb +19 -9
  216. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +29 -13
  217. data/lib/hecks/cli/release.rb +29 -22
  218. data/lib/hecks/cli/release_gem.rb +12 -6
  219. data/lib/hecks/cli/rspec_io_parallel_files.rb +87 -30
  220. data/lib/hecks/cli/rspec_shard_files.rb +24 -9
  221. data/lib/hecks/cli/run.rb +25 -44
  222. data/lib/hecks/cli/run_expectations.rb +63 -0
  223. data/lib/hecks/cli/seed_semantics_corpus.rb +37 -17
  224. data/lib/hecks/cli/smoke_http/checks.rb +66 -0
  225. data/lib/hecks/cli/smoke_http/settings.rb +63 -0
  226. data/lib/hecks/cli/smoke_http/transport.rb +45 -0
  227. data/lib/hecks/cli/smoke_http.rb +8 -142
  228. data/lib/hecks/cli/smoke_test.rb +18 -4
  229. data/lib/hecks/cli/stores.rb +7 -4
  230. data/lib/hecks/cli/stress_concurrency_specs/reporting.rb +44 -0
  231. data/lib/hecks/cli/stress_concurrency_specs/usage.rb +28 -0
  232. data/lib/hecks/cli/stress_concurrency_specs.rb +82 -80
  233. data/lib/hecks/cli.rb +32 -208
  234. data/lib/hecks/codemod/runner.rb +92 -0
  235. data/lib/hecks/codemod/sweep.rb +94 -0
  236. data/lib/hecks/codemod.rb +22 -165
  237. data/lib/hecks/corpus/routes.rb +34 -0
  238. data/lib/hecks/corpus/rust.rb +193 -0
  239. data/lib/hecks/corpus/sources.rb +46 -0
  240. data/lib/hecks/corpus.rb +28 -265
  241. data/lib/hecks/deploy/bluebook/deploy.bluebook +109 -0
  242. data/lib/hecks/deploy/oidc.json +10 -0
  243. data/lib/hecks/doc/reference/coverage.rb +70 -0
  244. data/lib/hecks/doc/reference/harvester.rb +55 -0
  245. data/lib/hecks/doc/reference/readme.rb +89 -0
  246. data/lib/hecks/doc/reference/rendering.rb +149 -0
  247. data/lib/hecks/doc/reference.rb +14 -273
  248. data/lib/hecks/doors/cli_door/nesting.rb +34 -0
  249. data/lib/hecks/doors/cli_door/shorthand.rb +85 -0
  250. data/lib/hecks/doors/cli_door.rb +23 -95
  251. data/lib/hecks/doors/cli_runner/answers.rb +138 -0
  252. data/lib/hecks/doors/cli_runner/resolution.rb +146 -0
  253. data/lib/hecks/doors/cli_runner/settling.rb +115 -0
  254. data/lib/hecks/doors/cli_runner/streaming.rb +90 -0
  255. data/lib/hecks/doors/cli_runner/suggestions.rb +43 -0
  256. data/lib/hecks/doors/cli_runner.rb +12 -336
  257. data/lib/hecks/doors/command_request.rb +42 -31
  258. data/lib/hecks/doors/handle.rb +32 -30
  259. data/lib/hecks/doors/launcher_options.rb +62 -7
  260. data/lib/hecks/doors/mcp_door/properties.rb +47 -0
  261. data/lib/hecks/doors/mcp_door/tool_calls.rb +113 -0
  262. data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +51 -0
  263. data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +69 -0
  264. data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +97 -0
  265. data/lib/hecks/doors/mcp_door/tool_definitions.rb +15 -0
  266. data/lib/hecks/doors/mcp_door.rb +55 -301
  267. data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +92 -0
  268. data/lib/hecks/doors/mcp_door_scope/env_problems.rb +55 -0
  269. data/lib/hecks/doors/mcp_door_scope/presenter.rb +78 -0
  270. data/lib/hecks/doors/mcp_door_scope.rb +16 -172
  271. data/lib/hecks/doors/ruby_door/aggregate_door.rb +1 -1
  272. data/lib/hecks/doors/ruby_door/chapter.rb +33 -16
  273. data/lib/hecks/doors/ruby_door.rb +14 -11
  274. data/lib/hecks/doors/usage_cache.rb +32 -16
  275. data/lib/hecks/doors.rb +10 -4
  276. data/lib/hecks/embryonaut_bluebook/manifest.rb +11 -3
  277. data/lib/hecks/embryonaut_bluebook/registry/changelog.rb +26 -0
  278. data/lib/hecks/embryonaut_bluebook/registry/versions.rb +27 -0
  279. data/lib/hecks/embryonaut_bluebook/registry.rb +27 -37
  280. data/lib/hecks/embryonaut_bluebook/vendor/acceptance.rb +37 -0
  281. data/lib/hecks/embryonaut_bluebook/vendor.rb +22 -36
  282. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +9 -6
  283. data/lib/hecks/embryonaut_bluebook.rb +16 -11
  284. data/lib/hecks/engine_agreement.rb +24 -17
  285. data/lib/hecks/forms/app/commands.rb +98 -0
  286. data/lib/hecks/forms/app/queries.rb +62 -0
  287. data/lib/hecks/forms/app/records.rb +67 -0
  288. data/lib/hecks/forms/app/responses.rb +46 -0
  289. data/lib/hecks/forms/app.rb +33 -221
  290. data/lib/hecks/forms/banking_presentation.rb +5 -0
  291. data/lib/hecks/forms/command_form_renderer.rb +55 -14
  292. data/lib/hecks/forms/field_controls.rb +95 -0
  293. data/lib/hecks/forms/field_renderer.rb +34 -88
  294. data/lib/hecks/forms/field_shape.rb +9 -34
  295. data/lib/hecks/forms/html.rb +1 -1
  296. data/lib/hecks/forms/index_renderer.rb +14 -9
  297. data/lib/hecks/forms/page.rb +2 -106
  298. data/lib/hecks/forms/page_assets.rb +88 -0
  299. data/lib/hecks/forms/page_script.rb +28 -0
  300. data/lib/hecks/forms/params.rb +17 -8
  301. data/lib/hecks/forms/query_form_renderer.rb +11 -7
  302. data/lib/hecks/forms/record_renderer.rb +28 -19
  303. data/lib/hecks/forms/reference_options.rb +1 -1
  304. data/lib/hecks/forms/text_shape.rb +40 -0
  305. data/lib/hecks/fqn.rb +64 -32
  306. data/lib/hecks/framework.rb +10 -3
  307. data/lib/hecks/freezer.rb +10 -1
  308. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/fragments.rb +61 -0
  309. data/lib/hecks/fuzzing/bounded_exhaustive_expressions/productions.rb +217 -0
  310. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +5 -194
  311. data/lib/hecks/fuzzing/combination_miner.rb +23 -12
  312. data/lib/hecks/fuzzing/concurrent_dispatch/racing.rb +64 -0
  313. data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +66 -0
  314. data/lib/hecks/fuzzing/concurrent_dispatch.rb +31 -107
  315. data/lib/hecks/fuzzing/coverage_campaign.rb +49 -24
  316. data/lib/hecks/fuzzing/differential/wire_comparison.rb +74 -0
  317. data/lib/hecks/fuzzing/differential.rb +59 -84
  318. data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +70 -0
  319. data/lib/hecks/fuzzing/domain_generator/builder/attribute_shapes.rb +105 -0
  320. data/lib/hecks/fuzzing/domain_generator/builder/shapes.rb +97 -0
  321. data/lib/hecks/fuzzing/domain_generator/builder/wiring.rb +128 -0
  322. data/lib/hecks/fuzzing/domain_generator/builder.rb +105 -0
  323. data/lib/hecks/fuzzing/domain_generator/pruning.rb +90 -0
  324. data/lib/hecks/fuzzing/domain_generator/removals.rb +62 -0
  325. data/lib/hecks/fuzzing/domain_generator/rendering.rb +94 -0
  326. data/lib/hecks/fuzzing/domain_generator/tokens.rb +38 -0
  327. data/lib/hecks/fuzzing/domain_generator.rb +7 -555
  328. data/lib/hecks/fuzzing/era_boundary.rb +34 -24
  329. data/lib/hecks/fuzzing/failure_triage.rb +80 -0
  330. data/lib/hecks/fuzzing/form_census/chapter_forms.rb +38 -0
  331. data/lib/hecks/fuzzing/form_census/reference_forms.rb +49 -0
  332. data/lib/hecks/fuzzing/form_census.rb +44 -58
  333. data/lib/hecks/fuzzing/generated_domain_check.rb +23 -11
  334. data/lib/hecks/fuzzing/isolated_boot/copying.rb +62 -0
  335. data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +148 -0
  336. data/lib/hecks/fuzzing/isolated_boot/scratch_schema.rb +27 -0
  337. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +102 -0
  338. data/lib/hecks/fuzzing/isolated_boot.rb +29 -252
  339. data/lib/hecks/fuzzing/mutation/checks.rb +76 -0
  340. data/lib/hecks/fuzzing/mutation/finders.rb +136 -0
  341. data/lib/hecks/fuzzing/mutation/judge.rb +94 -0
  342. data/lib/hecks/fuzzing/mutation/observation.rb +38 -0
  343. data/lib/hecks/fuzzing/mutation/operators.rb +52 -0
  344. data/lib/hecks/fuzzing/mutation/report.rb +78 -0
  345. data/lib/hecks/fuzzing/mutation/run.rb +99 -0
  346. data/lib/hecks/fuzzing/mutation/selection.rb +32 -0
  347. data/lib/hecks/fuzzing/mutation/site.rb +21 -0
  348. data/lib/hecks/fuzzing/mutation/source_map.rb +59 -0
  349. data/lib/hecks/fuzzing/mutation.rb +12 -0
  350. data/lib/hecks/fuzzing/persistence_parity.rb +5 -5
  351. data/lib/hecks/fuzzing/properties/aggregation_recompute.rb +121 -0
  352. data/lib/hecks/fuzzing/properties/catalog.rb +89 -0
  353. data/lib/hecks/fuzzing/properties/corrections.rb +23 -20
  354. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +64 -185
  355. data/lib/hecks/fuzzing/properties/group_by_recompute.rb +69 -0
  356. data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +63 -0
  357. data/lib/hecks/fuzzing/properties/guards.rb +76 -108
  358. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +66 -227
  359. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +46 -35
  360. data/lib/hecks/fuzzing/properties/mutation_recompute.rb +162 -0
  361. data/lib/hecks/fuzzing/properties/outbox.rb +41 -24
  362. data/lib/hecks/fuzzing/properties/piece_invariants.rb +61 -0
  363. data/lib/hecks/fuzzing/properties/policy_wiring.rb +140 -0
  364. data/lib/hecks/fuzzing/properties/query_rows.rb +67 -0
  365. data/lib/hecks/fuzzing/properties/querying.rb +69 -90
  366. data/lib/hecks/fuzzing/properties/read_model_names.rb +50 -0
  367. data/lib/hecks/fuzzing/properties/read_models.rb +138 -0
  368. data/lib/hecks/fuzzing/properties/references.rb +100 -0
  369. data/lib/hecks/fuzzing/properties/role_checks.rb +50 -0
  370. data/lib/hecks/fuzzing/properties/tenant_scope.rb +84 -0
  371. data/lib/hecks/fuzzing/properties.rb +13 -119
  372. data/lib/hecks/fuzzing/qa_settings.rb +23 -17
  373. data/lib/hecks/fuzzing/replay/fan_out.rb +78 -0
  374. data/lib/hecks/fuzzing/replay/filters.rb +72 -0
  375. data/lib/hecks/fuzzing/replay/guard_check.rb +88 -0
  376. data/lib/hecks/fuzzing/replay/mutation_trace.rb +117 -0
  377. data/lib/hecks/fuzzing/replay/observation.rb +60 -0
  378. data/lib/hecks/fuzzing/replay/read_only_steps.rb +84 -0
  379. data/lib/hecks/fuzzing/replay/role_check.rb +49 -0
  380. data/lib/hecks/fuzzing/replay/session.rb +167 -0
  381. data/lib/hecks/fuzzing/replay.rb +36 -442
  382. data/lib/hecks/fuzzing/runtime_coverage.rb +70 -0
  383. data/lib/hecks/fuzzing/rust_gap_manifest.rb +3 -4
  384. data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +133 -0
  385. data/lib/hecks/fuzzing/self_consistency/sagas.rb +93 -0
  386. data/lib/hecks/fuzzing/self_consistency/value_objects.rb +87 -0
  387. data/lib/hecks/fuzzing/self_consistency.rb +8 -213
  388. data/lib/hecks/fuzzing/sequence_generator/adversary/argument_mutations.rb +116 -0
  389. data/lib/hecks/fuzzing/sequence_generator/adversary/caller_draw.rb +68 -0
  390. data/lib/hecks/fuzzing/sequence_generator/adversary/identity_mutations.rb +62 -0
  391. data/lib/hecks/fuzzing/sequence_generator/adversary/precedence_mutations.rb +126 -0
  392. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +23 -283
  393. data/lib/hecks/fuzzing/sequence_generator/argument_drawing.rb +78 -0
  394. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +69 -53
  395. data/lib/hecks/fuzzing/sequence_generator/identity_shaping.rb +85 -0
  396. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +20 -16
  397. data/lib/hecks/fuzzing/sequence_generator/picker.rb +12 -6
  398. data/lib/hecks/fuzzing/sequence_generator/prefixing.rb +45 -0
  399. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +19 -8
  400. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +43 -144
  401. data/lib/hecks/fuzzing/sequence_generator.rb +65 -63
  402. data/lib/hecks/fuzzing/shrinker/value_simplification.rb +64 -0
  403. data/lib/hecks/fuzzing/shrinker.rb +36 -29
  404. data/lib/hecks/fuzzing/target_capabilities.rb +10 -4
  405. data/lib/hecks/fuzzing/value_generator.rb +27 -17
  406. data/lib/hecks/fuzzing.rb +3 -0
  407. data/lib/hecks/gate/stages.yml +11 -1
  408. data/lib/hecks/grammar/evolve/arguments.rb +90 -0
  409. data/lib/hecks/grammar/evolve/keywords.rb +81 -0
  410. data/lib/hecks/grammar/evolve/seeds.rb +172 -0
  411. data/lib/hecks/grammar/evolve.rb +22 -263
  412. data/lib/hecks/grammar/operators.rb +111 -0
  413. data/lib/hecks/grammar.rb +53 -126
  414. data/lib/hecks/hecks/adapters/bluebook_report.rb +6 -6
  415. data/lib/hecks/hecks/adapters/codebase/codemods.rb +1 -1
  416. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +23 -9
  417. data/lib/hecks/hecks/adapters/codebase/language/edits.rb +75 -0
  418. data/lib/hecks/hecks/adapters/codebase/language.rb +30 -72
  419. data/lib/hecks/hecks/adapters/codebase/promotion/candidates.rb +54 -0
  420. data/lib/hecks/hecks/adapters/codebase/promotion/gate.rb +50 -0
  421. data/lib/hecks/hecks/adapters/codebase/promotion/move.rb +70 -0
  422. data/lib/hecks/hecks/adapters/codebase/promotion/standing.rb +88 -0
  423. data/lib/hecks/hecks/adapters/codebase/promotion/watch.rb +83 -0
  424. data/lib/hecks/hecks/adapters/codebase/promotion.rb +115 -0
  425. data/lib/hecks/hecks/adapters/codebase/publishing.rb +31 -12
  426. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +43 -6
  427. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +16 -5
  428. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +9 -1
  429. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +1 -1
  430. data/lib/hecks/hecks/adapters/codebase/style.rb +1 -1
  431. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +11 -5
  432. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +27 -8
  433. data/lib/hecks/hecks/adapters/console_capture.rb +21 -17
  434. data/lib/hecks/hecks/adapters/cost_explorer.rb +11 -6
  435. data/lib/hecks/hecks/adapters/deploy_plans.rb +3 -3
  436. data/lib/hecks/hecks/adapters/deploy_toolchain/answers.rb +142 -0
  437. data/lib/hecks/hecks/adapters/deploy_toolchain/scripts.rb +95 -0
  438. data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +74 -0
  439. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +21 -239
  440. data/lib/hecks/hecks/adapters/finding_github.rb +2 -2
  441. data/lib/hecks/hecks/adapters/first_admin.rb +22 -8
  442. data/lib/hecks/hecks/adapters/git.rb +18 -5
  443. data/lib/hecks/hecks/adapters/git_refs.rb +144 -0
  444. data/lib/hecks/hecks/adapters/github_rulesets.rb +128 -0
  445. data/lib/hecks/hecks/adapters/host_http.rb +16 -6
  446. data/lib/hecks/hecks/adapters/in_process_boot.rb +9 -5
  447. data/lib/hecks/hecks/adapters/in_process_operations/tailing.rb +61 -0
  448. data/lib/hecks/hecks/adapters/in_process_operations.rb +33 -35
  449. data/lib/hecks/hecks/adapters/journal_store/changes.rb +21 -15
  450. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +29 -12
  451. data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +52 -0
  452. data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +52 -0
  453. data/lib/hecks/hecks/adapters/journal_store/readings.rb +5 -62
  454. data/lib/hecks/hecks/adapters/local_files.rb +27 -10
  455. data/lib/hecks/hecks/adapters/pg_admin/ownership.rb +115 -0
  456. data/lib/hecks/hecks/adapters/pg_admin.rb +14 -87
  457. data/lib/hecks/hecks/adapters/process_pool.rb +75 -21
  458. data/lib/hecks/hecks/adapters/rust_toolchain.rb +12 -4
  459. data/lib/hecks/hecks/adapters/site_toolchain.rb +16 -7
  460. data/lib/hecks/hecks/adapters/terminal.rb +13 -9
  461. data/lib/hecks/hecks/codebase.bluebook +322 -5
  462. data/lib/hecks/hecks/custodian.behaviors +6 -0
  463. data/lib/hecks/hecks/custodian.bluebook +37 -0
  464. data/lib/hecks/hecks/hecks.hecksagon +22 -0
  465. data/lib/hecks/hecks/hecks.world +10 -2
  466. data/lib/hecks/kernel_capabilities/templates.rb +92 -0
  467. data/lib/hecks/kernel_capabilities.rb +18 -85
  468. data/lib/hecks/language/bluebook/vocabulary.bluebook +46 -1
  469. data/lib/hecks/literal/item_splitter.rb +50 -0
  470. data/lib/hecks/literal.rb +29 -38
  471. data/lib/hecks/mcp_stdio_guard.rb +8 -8
  472. data/lib/hecks/naming.rb +9 -3
  473. data/lib/hecks/persistence_legacy_fixture/postgres_stores.rb +81 -0
  474. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +26 -66
  475. data/lib/hecks/persistence_legacy_fixture.rb +13 -10
  476. data/lib/hecks/ports/access_control.rb +13 -10
  477. data/lib/hecks/ports/agent/answers.rb +2 -2
  478. data/lib/hecks/ports/agent.rb +13 -10
  479. data/lib/hecks/ports/authentication.rb +13 -10
  480. data/lib/hecks/ports/authorization.rb +13 -10
  481. data/lib/hecks/ports/clock.rb +13 -10
  482. data/lib/hecks/ports/extraction.rb +13 -12
  483. data/lib/hecks/ports/identity_assignment.rb +13 -10
  484. data/lib/hecks/ports/identity_generation.rb +13 -10
  485. data/lib/hecks/ports/identity_resolution.rb +13 -10
  486. data/lib/hecks/ports/key_vault.rb +13 -10
  487. data/lib/hecks/ports/persistence/append_only.rb +5 -5
  488. data/lib/hecks/ports/persistence/binding_policy.rb +33 -9
  489. data/lib/hecks/ports/persistence/codec_boundary.rb +22 -11
  490. data/lib/hecks/ports/persistence/constants.rb +10 -0
  491. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +18 -16
  492. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +27 -18
  493. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +52 -23
  494. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +14 -8
  495. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +17 -6
  496. data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +58 -0
  497. data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +130 -0
  498. data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +25 -0
  499. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +20 -180
  500. data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +41 -0
  501. data/lib/hecks/ports/persistence/plugins/era/postgres_era/class_methods.rb +105 -0
  502. data/lib/hecks/ports/persistence/plugins/era/postgres_era/dialect.rb +137 -0
  503. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +25 -28
  504. data/lib/hecks/ports/persistence/plugins/era/postgres_era/head_writes.rb +62 -0
  505. data/lib/hecks/ports/persistence/plugins/era/postgres_era/journal.rb +128 -0
  506. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +74 -0
  507. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/chain_sql.rb +169 -0
  508. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +91 -0
  509. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_integrity.rb +99 -0
  510. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +0 -73
  511. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +55 -39
  512. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +51 -222
  513. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/merge_writes.rb +120 -0
  514. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +85 -60
  515. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +97 -181
  516. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +19 -19
  517. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/sql_templates.rb +88 -0
  518. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +77 -118
  519. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +3 -117
  520. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_sql.rb +116 -0
  521. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +3 -1
  522. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/context.rb +38 -0
  523. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +43 -25
  524. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +62 -38
  525. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +21 -16
  526. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +66 -86
  527. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +75 -0
  528. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +27 -9
  529. data/lib/hecks/ports/persistence/plugins/era/postgres_era/query_phases.rb +63 -0
  530. data/lib/hecks/ports/persistence/plugins/era/postgres_era/sagas.rb +78 -0
  531. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +28 -482
  532. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +40 -12
  533. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +22 -15
  534. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +39 -19
  535. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -16
  536. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +48 -25
  537. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +60 -99
  538. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/path_diff.rb +57 -0
  539. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +21 -11
  540. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +13 -4
  541. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +4 -2
  542. data/lib/hecks/ports/persistence/postgres_dump.rb +13 -7
  543. data/lib/hecks/ports/persistence/repository_factory.rb +35 -11
  544. data/lib/hecks/ports/persistence/state_codec.rb +10 -0
  545. data/lib/hecks/ports/persistence.rb +1 -10
  546. data/lib/hecks/ports/projection.rb +34 -21
  547. data/lib/hecks/ports/query/in_memory.rb +16 -8
  548. data/lib/hecks/projection_files/expression_tables.rb +64 -0
  549. data/lib/hecks/projection_files/texts.rb +67 -0
  550. data/lib/hecks/projection_files.rb +19 -103
  551. data/lib/hecks/projections/bootstrap_table.rb +43 -29
  552. data/lib/hecks/projections/deploy/bastion_lines.rb +32 -0
  553. data/lib/hecks/projections/deploy/box/access.rb +73 -0
  554. data/lib/hecks/projections/deploy/box/caddy.rb +87 -0
  555. data/lib/hecks/projections/deploy/box/compose.rb +70 -0
  556. data/lib/hecks/projections/deploy/box/hosting.rb +4 -105
  557. data/lib/hecks/projections/deploy/box/hosting_parts.rb +97 -0
  558. data/lib/hecks/projections/deploy/box/hosting_settings.rb +1 -1
  559. data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
  560. data/lib/hecks/projections/deploy/box/roll_scripts.rb +137 -0
  561. data/lib/hecks/projections/deploy/box/settings/checks.rb +38 -0
  562. data/lib/hecks/projections/deploy/box/settings/containers.rb +123 -0
  563. data/lib/hecks/projections/deploy/box/settings/origin.rb +56 -0
  564. data/lib/hecks/projections/deploy/box/settings/patterns.rb +47 -0
  565. data/lib/hecks/projections/deploy/box/settings/types.rb +76 -0
  566. data/lib/hecks/projections/deploy/box/settings.rb +76 -263
  567. data/lib/hecks/projections/deploy/box/shared_database.rb +69 -0
  568. data/lib/hecks/projections/deploy/box/stack_yaml.rb +107 -0
  569. data/lib/hecks/projections/deploy/box/templates/MIGRATION.md.tmpl +39 -0
  570. data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +23 -0
  571. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +42 -2
  572. data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +2 -1
  573. data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +2 -1
  574. data/lib/hecks/projections/deploy/box/templates/deploy-usage-services.tmpl +4 -0
  575. data/lib/hecks/projections/deploy/box/templates/deploy-usage-taskdef.tmpl +5 -0
  576. data/lib/hecks/projections/deploy/box/templates/ecr-repository.yaml.tmpl +9 -0
  577. data/lib/hecks/projections/deploy/box/templates/mode-summary-services.tmpl +2 -0
  578. data/lib/hecks/projections/deploy/box/templates/mode-summary-taskdef.tmpl +4 -0
  579. data/lib/hecks/projections/deploy/box/templates/provision-database.sh.tmpl +97 -0
  580. data/lib/hecks/projections/deploy/box/templates/restore-to-rds.sh.tmpl +4 -2
  581. data/lib/hecks/projections/deploy/box/templates/services-block.tmpl +9 -0
  582. data/lib/hecks/projections/deploy/box/templates/tunnel-egress.yaml.tmpl +11 -0
  583. data/lib/hecks/projections/deploy/box/templates/verify-copy.sh.tmpl +2 -1
  584. data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
  585. data/lib/hecks/projections/deploy/box.rb +43 -491
  586. data/lib/hecks/projections/deploy/fargate/assembly.rb +13 -142
  587. data/lib/hecks/projections/deploy/fargate/cdn/behaviors.rb +76 -0
  588. data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +112 -0
  589. data/lib/hecks/projections/deploy/fargate/cdn/options.rb +85 -0
  590. data/lib/hecks/projections/deploy/fargate/cdn.rb +23 -215
  591. data/lib/hecks/projections/deploy/fargate/check.rb +16 -6
  592. data/lib/hecks/projections/deploy/fargate/containers/definition_lines.rb +61 -0
  593. data/lib/hecks/projections/deploy/fargate/containers/reading.rb +86 -0
  594. data/lib/hecks/projections/deploy/fargate/containers/rendering.rb +132 -0
  595. data/lib/hecks/projections/deploy/fargate/containers/routing.rb +93 -0
  596. data/lib/hecks/projections/deploy/fargate/containers.rb +10 -286
  597. data/lib/hecks/projections/deploy/fargate/extras/reading.rb +90 -0
  598. data/lib/hecks/projections/deploy/fargate/extras/rendering.rb +81 -0
  599. data/lib/hecks/projections/deploy/fargate/extras.rb +9 -158
  600. data/lib/hecks/projections/deploy/fargate/monitoring/alarms.rb +115 -0
  601. data/lib/hecks/projections/deploy/fargate/monitoring/reading.rb +84 -0
  602. data/lib/hecks/projections/deploy/fargate/monitoring/topic.rb +59 -0
  603. data/lib/hecks/projections/deploy/fargate/monitoring/warmer.rb +90 -0
  604. data/lib/hecks/projections/deploy/fargate/monitoring/warmer_roles.rb +76 -0
  605. data/lib/hecks/projections/deploy/fargate/monitoring.rb +14 -348
  606. data/lib/hecks/projections/deploy/fargate/sections.rb +115 -0
  607. data/lib/hecks/projections/deploy/fargate/settings/ids.rb +55 -0
  608. data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +77 -0
  609. data/lib/hecks/projections/deploy/fargate/settings.rb +17 -104
  610. data/lib/hecks/projections/deploy/fargate/stack/blocks.rb +91 -0
  611. data/lib/hecks/projections/deploy/fargate/stack/readers.rb +87 -0
  612. data/lib/hecks/projections/deploy/fargate/stack/recipes.rb +106 -0
  613. data/lib/hecks/projections/deploy/fargate/stack.rb +146 -0
  614. data/lib/hecks/projections/deploy/fargate/task_sections.rb +56 -0
  615. data/lib/hecks/projections/deploy/fargate/yaml.rb +1 -1
  616. data/lib/hecks/projections/deploy/fargate.rb +51 -756
  617. data/lib/hecks/projections/deploy/lambda/pii.rb +49 -0
  618. data/lib/hecks/projections/deploy/lambda/stack/blocks.rb +118 -0
  619. data/lib/hecks/projections/deploy/lambda/stack/checks.rb +64 -0
  620. data/lib/hecks/projections/deploy/lambda/stack/deploy_chain.rb +119 -0
  621. data/lib/hecks/projections/deploy/lambda/stack/readers.rb +62 -0
  622. data/lib/hecks/projections/deploy/lambda/stack/reading.rb +170 -0
  623. data/lib/hecks/projections/deploy/lambda/stack/reading_web.rb +53 -0
  624. data/lib/hecks/projections/deploy/lambda/stack/recipes.rb +112 -0
  625. data/lib/hecks/projections/deploy/lambda/stack/web.rb +57 -0
  626. data/lib/hecks/projections/deploy/lambda/stack.rb +54 -0
  627. data/lib/hecks/projections/deploy/lambda.rb +77 -1885
  628. data/lib/hecks/projections/deploy/preview/access_yaml.rb +8 -74
  629. data/lib/hecks/projections/deploy/preview/containers.rb +18 -7
  630. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +15 -87
  631. data/lib/hecks/projections/deploy/preview/settings.rb +7 -4
  632. data/lib/hecks/projections/deploy/preview/task_yaml.rb +42 -106
  633. data/lib/hecks/projections/deploy/preview/template.rb +11 -106
  634. data/lib/hecks/projections/deploy/preview/yaml_text.rb +1 -1
  635. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +1 -1
  636. data/lib/hecks/projections/deploy/scripts/settings.rb +14 -6
  637. data/lib/hecks/projections/deploy/scripts.rb +11 -9
  638. data/lib/hecks/projections/deploy/shared/rows.rb +48 -0
  639. data/lib/hecks/projections/deploy/shared.rb +89 -449
  640. data/lib/hecks/projections/deploy/shared_database_instance/templates/Makefile.tmpl +11 -0
  641. data/lib/hecks/projections/deploy/shared_database_instance/templates/README.md.tmpl +25 -0
  642. data/lib/hecks/projections/deploy/shared_database_instance/templates/rds.yaml.tmpl +180 -0
  643. data/lib/hecks/projections/deploy/shared_database_instance.rb +106 -0
  644. data/lib/hecks/projections/deploy/smoke.rb +15 -10
  645. data/lib/hecks/projections/deploy/template_diff/comparer.rb +21 -147
  646. data/lib/hecks/projections/deploy/template_diff/normalizer.rb +60 -0
  647. data/lib/hecks/projections/deploy/template_diff/value_diff.rb +136 -0
  648. data/lib/hecks/projections/deploy/template_diff.rb +8 -3
  649. data/lib/hecks/projections/deploy/templates/fargate/Dockerfile.tmpl +28 -0
  650. data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +63 -0
  651. data/lib/hecks/projections/deploy/templates/fargate/always_params.tmpl +4 -0
  652. data/lib/hecks/projections/deploy/templates/fargate/deploy_plain.tmpl +1 -0
  653. data/lib/hecks/projections/deploy/templates/fargate/deploy_shared.tmpl +11 -0
  654. data/lib/hecks/projections/deploy/templates/fargate/mint_era_own.tmpl +44 -0
  655. data/lib/hecks/projections/deploy/templates/fargate/mint_era_shared.tmpl +8 -0
  656. data/lib/hecks/projections/deploy/templates/fargate/missing_owner.tmpl +9 -0
  657. data/lib/hecks/projections/deploy/templates/fargate/oauth_params.tmpl +7 -0
  658. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_env.tmpl +4 -0
  659. data/lib/hecks/projections/deploy/templates/fargate/oauth_task_policy.tmpl +7 -0
  660. data/lib/hecks/projections/deploy/templates/fargate/owning_params.tmpl +33 -0
  661. data/lib/hecks/projections/deploy/templates/fargate/template.yaml.tmpl +281 -0
  662. data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +218 -0
  663. data/lib/hecks/projections/deploy/templates/lambda/aurora_depends.tmpl +18 -0
  664. data/lib/hecks/projections/deploy/templates/lambda/build_dispatch_none.tmpl +10 -0
  665. data/lib/hecks/projections/deploy/templates/lambda/build_pg.tmpl +15 -0
  666. data/lib/hecks/projections/deploy/templates/lambda/build_plain.tmpl +2 -0
  667. data/lib/hecks/projections/deploy/templates/lambda/build_web.tmpl +11 -0
  668. data/lib/hecks/projections/deploy/templates/lambda/env_blind_guard.tmpl +4 -0
  669. data/lib/hecks/projections/deploy/templates/lambda/mint_era_own.tmpl +122 -0
  670. data/lib/hecks/projections/deploy/templates/lambda/mint_era_shared.tmpl +47 -0
  671. data/lib/hecks/projections/deploy/templates/lambda/missing_owner.tmpl +9 -0
  672. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +14 -0
  673. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_plain.tmpl +3 -0
  674. data/lib/hecks/projections/deploy/templates/lambda/oauth_note.tmpl +8 -0
  675. data/lib/hecks/projections/deploy/templates/lambda/params_oauth.tmpl +13 -0
  676. data/lib/hecks/projections/deploy/templates/lambda/params_shared.tmpl +33 -0
  677. data/lib/hecks/projections/deploy/templates/lambda/pg_native.tmpl +71 -0
  678. data/lib/hecks/projections/deploy/templates/lambda/pii_oac.tmpl +8 -0
  679. data/lib/hecks/projections/deploy/templates/lambda/pii_permission.tmpl +8 -0
  680. data/lib/hecks/projections/deploy/templates/lambda/pii_resources.tmpl +116 -0
  681. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge.tmpl +30 -0
  682. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_oauth.tmpl +12 -0
  683. data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_plain.tmpl +7 -0
  684. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_own.tmpl +93 -0
  685. data/lib/hecks/projections/deploy/templates/lambda/rename_schema_shared.tmpl +7 -0
  686. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_env.tmpl +17 -0
  687. data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_policy.tmpl +16 -0
  688. data/lib/hecks/projections/deploy/templates/lambda/rust_session_secret.tmpl +13 -0
  689. data/lib/hecks/projections/deploy/templates/lambda/samconfig.toml.tmpl +12 -0
  690. data/lib/hecks/projections/deploy/templates/lambda/shared_note.tmpl +6 -0
  691. data/lib/hecks/projections/deploy/templates/lambda/sync_oauth.tmpl +23 -0
  692. data/lib/hecks/projections/deploy/templates/lambda/template.yaml.tmpl +187 -0
  693. data/lib/hecks/projections/deploy/templates/lambda/translation_own.tmpl +46 -0
  694. data/lib/hecks/projections/deploy/templates/lambda/translation_shared.tmpl +2 -0
  695. data/lib/hecks/projections/deploy/templates/lambda/web_function.tmpl +207 -0
  696. data/lib/hecks/projections/deploy/templates/lambda/web_google_oauth_env.tmpl +12 -0
  697. data/lib/hecks/projections/deploy/templates/lambda/web_no_oauth_env.tmpl +7 -0
  698. data/lib/hecks/projections/deploy/templates/lambda/web_oauth_policy.tmpl +4 -0
  699. data/lib/hecks/projections/deploy/templates/lambda/webhook_secret_resource.tmpl +20 -0
  700. data/lib/hecks/projections/deploy/templates/preview/alb.tmpl +8 -0
  701. data/lib/hecks/projections/deploy/templates/preview/alb_security_group.tmpl +11 -0
  702. data/lib/hecks/projections/deploy/templates/preview/assume_role.tmpl +6 -0
  703. data/lib/hecks/projections/deploy/templates/preview/base_parameters.tmpl +24 -0
  704. data/lib/hecks/projections/deploy/templates/preview/cluster.tmpl +4 -0
  705. data/lib/hecks/projections/deploy/templates/preview/container_secret.tmpl +9 -0
  706. data/lib/hecks/projections/deploy/templates/preview/db_init_script.sh.tmpl +23 -0
  707. data/lib/hecks/projections/deploy/templates/preview/db_init_secrets.tmpl +5 -0
  708. data/lib/hecks/projections/deploy/templates/preview/db_init_task.tmpl +39 -0
  709. data/lib/hecks/projections/deploy/templates/preview/desired_count.tmpl +5 -0
  710. data/lib/hecks/projections/deploy/templates/preview/distribution.tmpl +24 -0
  711. data/lib/hecks/projections/deploy/templates/preview/execution_role.tmpl +16 -0
  712. data/lib/hecks/projections/deploy/templates/preview/header.tmpl +16 -0
  713. data/lib/hecks/projections/deploy/templates/preview/ingress.tmpl +8 -0
  714. data/lib/hecks/projections/deploy/templates/preview/listener.tmpl +9 -0
  715. data/lib/hecks/projections/deploy/templates/preview/listener_rule.tmpl +11 -0
  716. data/lib/hecks/projections/deploy/templates/preview/log_group.tmpl +5 -0
  717. data/lib/hecks/projections/deploy/templates/preview/log_options.tmpl +5 -0
  718. data/lib/hecks/projections/deploy/templates/preview/outputs.tmpl +14 -0
  719. data/lib/hecks/projections/deploy/templates/preview/service.tmpl +17 -0
  720. data/lib/hecks/projections/deploy/templates/preview/session_secret.tmpl +11 -0
  721. data/lib/hecks/projections/deploy/templates/preview/target_group.tmpl +9 -0
  722. data/lib/hecks/projections/deploy/templates/preview/task_definition.tmpl +15 -0
  723. data/lib/hecks/projections/deploy/templates/preview/task_role.tmpl +22 -0
  724. data/lib/hecks/projections/deploy/templates/shared/aurora_db.tmpl +52 -0
  725. data/lib/hecks/projections/deploy/templates/shared/bastion.tmpl +74 -0
  726. data/lib/hecks/projections/deploy/templates/shared/bastion_own_public.tmpl +41 -0
  727. data/lib/hecks/projections/deploy/templates/shared/bastion_reuse_public.tmpl +10 -0
  728. data/lib/hecks/projections/deploy/templates/shared/nat_gateway.tmpl +102 -0
  729. data/lib/hecks/projections/deploy/templates/shared/oauth_egress.tmpl +17 -0
  730. data/lib/hecks/projections/deploy/templates/shared/plain_db.tmpl +16 -0
  731. data/lib/hecks/projections/deploy/templates/shared/vpc_and_database.tmpl +67 -0
  732. data/lib/hecks/projections/deploy/text_template.rb +35 -0
  733. data/lib/hecks/projections/deploy/vercel/settings.rb +83 -0
  734. data/lib/hecks/projections/deploy/vercel.rb +134 -0
  735. data/lib/hecks/projections/diagrams/dispatch.rb +114 -0
  736. data/lib/hecks/projections/diagrams/statecharts.rb +59 -0
  737. data/lib/hecks/projections/diagrams/structure.rb +114 -0
  738. data/lib/hecks/projections/diagrams.rb +33 -256
  739. data/lib/hecks/projections/glossary/entries.rb +140 -0
  740. data/lib/hecks/projections/glossary/html/page.rb +96 -0
  741. data/lib/hecks/projections/glossary/html/parser.rb +66 -0
  742. data/lib/hecks/projections/glossary/html/sections.rb +78 -0
  743. data/lib/hecks/projections/glossary/html.rb +7 -179
  744. data/lib/hecks/projections/glossary/index.rb +45 -0
  745. data/lib/hecks/projections/glossary/markdown.rb +22 -11
  746. data/lib/hecks/projections/glossary/mermaid.rb +44 -31
  747. data/lib/hecks/projections/glossary/sensitivity.rb +7 -4
  748. data/lib/hecks/projections/glossary/sentences/value_objects.rb +77 -0
  749. data/lib/hecks/projections/glossary/sentences.rb +42 -81
  750. data/lib/hecks/projections/glossary/slugs.rb +33 -0
  751. data/lib/hecks/projections/glossary.rb +22 -190
  752. data/lib/hecks/projections/model.rb +20 -14
  753. data/lib/hecks/projections/rust_vocabulary/arguments/support.rb +33 -0
  754. data/lib/hecks/projections/rust_vocabulary/arguments.rb +171 -0
  755. data/lib/hecks/projections/rust_vocabulary/enum_body.rb +114 -0
  756. data/lib/hecks/projections/rust_vocabulary/tests.rb +144 -0
  757. data/lib/hecks/projections/rust_vocabulary.rb +24 -293
  758. data/lib/hecks/projections/site/admin.rb +15 -9
  759. data/lib/hecks/projections/site/admin_cms/templates/membership.rb +115 -0
  760. data/lib/hecks/projections/site/admin_cms/templates/session_strategy.rb +90 -0
  761. data/lib/hecks/projections/site/admin_cms/templates/sso.rb +101 -0
  762. data/lib/hecks/projections/site/admin_cms/templates/sso_tail.rb +54 -0
  763. data/lib/hecks/projections/site/admin_cms/templates/users.rb +83 -0
  764. data/lib/hecks/projections/site/admin_cms/templates.rb +14 -369
  765. data/lib/hecks/projections/site/admin_cms.rb +15 -9
  766. data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
  767. data/lib/hecks/projections/site/edge/checks.rb +30 -80
  768. data/lib/hecks/projections/site/edge/findings.rb +28 -0
  769. data/lib/hecks/projections/site/edge/route_checks.rb +110 -0
  770. data/lib/hecks/projections/site/edge/row_reader.rb +52 -0
  771. data/lib/hecks/projections/site/edge/rules.rb +28 -26
  772. data/lib/hecks/projections/site/edge.rb +20 -31
  773. data/lib/hecks/projections/site/live_edge.rb +9 -7
  774. data/lib/hecks/projections/site/payload/fields/definitions.rb +90 -0
  775. data/lib/hecks/projections/site/payload/fields/readers.rb +69 -0
  776. data/lib/hecks/projections/site/payload/fields.rb +14 -111
  777. data/lib/hecks/projections/site/payload/lifecycle/text.rb +84 -0
  778. data/lib/hecks/projections/site/payload/lifecycle/text_tail.rb +106 -0
  779. data/lib/hecks/projections/site/payload/lifecycle.rb +8 -166
  780. data/lib/hecks/projections/site/payload/model.rb +22 -22
  781. data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
  782. data/lib/hecks/projections/site/payload/specs.rb +24 -68
  783. data/lib/hecks/projections/site/payload_driver.rb +19 -17
  784. data/lib/hecks/projections/site/root_rows.rb +12 -4
  785. data/lib/hecks/projections/site/routes_ts/helpers.rb +79 -0
  786. data/lib/hecks/projections/site/routes_ts/listings.rb +75 -0
  787. data/lib/hecks/projections/site/routes_ts/navigation.rb +79 -0
  788. data/lib/hecks/projections/site/routes_ts.rb +27 -175
  789. data/lib/hecks/projections/site/site_admin/access.rb +104 -0
  790. data/lib/hecks/projections/site/site_admin/session.rb +127 -0
  791. data/lib/hecks/projections/site/site_admin.rb +12 -219
  792. data/lib/hecks/projections/site/site_cdn.rb +12 -7
  793. data/lib/hecks/projections/site/site_host/dockerfile.rb +75 -0
  794. data/lib/hecks/projections/site/site_host/templates.rb +19 -67
  795. data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
  796. data/lib/hecks/projections/site/site_root.rb +3 -54
  797. data/lib/hecks/projections/site/table/checks.rb +28 -57
  798. data/lib/hecks/projections/site/table/link_builder.rb +14 -5
  799. data/lib/hecks/projections/site/table/navigation_checks.rb +75 -0
  800. data/lib/hecks/projections/site/table/row_builder.rb +31 -53
  801. data/lib/hecks/projections/site/table/row_defaults.rb +65 -0
  802. data/lib/hecks/projections/site/table.rb +9 -5
  803. data/lib/hecks/projections/vocabulary.rb +34 -31
  804. data/lib/hecks/projections.rb +2 -0
  805. data/lib/hecks/projector/cli_audience.rb +42 -0
  806. data/lib/hecks/projector/cli_projector/claims.rb +149 -0
  807. data/lib/hecks/projector/cli_projector/command_help.rb +65 -0
  808. data/lib/hecks/projector/cli_projector/command_specs.rb +133 -0
  809. data/lib/hecks/projector/cli_projector/listing.rb +100 -0
  810. data/lib/hecks/projector/cli_projector/option_specs.rb +116 -0
  811. data/lib/hecks/projector/cli_projector/query_specs.rb +67 -0
  812. data/lib/hecks/projector/cli_projector/usage.rb +101 -0
  813. data/lib/hecks/projector/cli_projector.rb +15 -532
  814. data/lib/hecks/projector/docs_projector/attributes.rb +78 -0
  815. data/lib/hecks/projector/docs_projector/behaviour.rb +127 -0
  816. data/lib/hecks/projector/docs_projector/closing.rb +40 -0
  817. data/lib/hecks/projector/docs_projector.rb +58 -192
  818. data/lib/hecks/projector/exporter/bindings.rb +174 -0
  819. data/lib/hecks/projector/exporter/translations.rb +127 -0
  820. data/lib/hecks/projector/exporter.rb +8 -279
  821. data/lib/hecks/projector/narrate_projector/commands.rb +108 -0
  822. data/lib/hecks/projector/narrate_projector/reactions.rb +33 -0
  823. data/lib/hecks/projector/narrate_projector.rb +60 -160
  824. data/lib/hecks/projector.rb +22 -13
  825. data/lib/hecks/quality_control/adapters/agent_profile.rb +25 -16
  826. data/lib/hecks/quality_control/adapters/github_checks.rb +49 -6
  827. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +1 -1
  828. data/lib/hecks/quality_control/adapters/github_issues.rb +22 -10
  829. data/lib/hecks/quality_control/cli/qa_discover_external_domains/parsing.rb +54 -0
  830. data/lib/hecks/quality_control/cli/qa_discover_external_domains/reporting.rb +44 -0
  831. data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +119 -0
  832. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +28 -155
  833. data/lib/hecks/quality_control/cli/qa_domain_novelty/verdict.rb +76 -0
  834. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +33 -66
  835. data/lib/hecks/quality_control/cli/qa_generated_domains/arguments.rb +62 -0
  836. data/lib/hecks/quality_control/cli/qa_generated_domains/blueprints.rb +45 -0
  837. data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +107 -0
  838. data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +107 -0
  839. data/lib/hecks/quality_control/cli/qa_generated_domains/reporting.rb +97 -0
  840. data/lib/hecks/quality_control/cli/qa_generated_domains/shrinking.rb +70 -0
  841. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +43 -327
  842. data/lib/hecks/quality_control/cli/qa_log_bug/arguments.rb +55 -0
  843. data/lib/hecks/quality_control/cli/qa_log_bug/proof.rb +65 -0
  844. data/lib/hecks/quality_control/cli/qa_log_bug.rb +18 -81
  845. data/lib/hecks/quality_control/cli/qa_mine_combinations/arguments.rb +54 -0
  846. data/lib/hecks/quality_control/cli/qa_mine_combinations/booting.rb +96 -0
  847. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +45 -109
  848. data/lib/hecks/quality_control/cli/qa_open_pr/arguments.rb +55 -0
  849. data/lib/hecks/quality_control/cli/qa_open_pr/recording.rb +79 -0
  850. data/lib/hecks/quality_control/cli/qa_open_pr/rules.rb +122 -0
  851. data/lib/hecks/quality_control/cli/qa_open_pr.rb +41 -200
  852. data/lib/hecks/quality_control/cli/qa_postgres_migrate/copying.rb +45 -0
  853. data/lib/hecks/quality_control/cli/qa_postgres_migrate/reporting.rb +33 -0
  854. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +37 -63
  855. data/lib/hecks/quality_control/cli/qa_postgres_role/ownership.rb +57 -0
  856. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +66 -71
  857. data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +118 -0
  858. data/lib/hecks/quality_control/cli/qa_pr_check/reporting.rb +54 -0
  859. data/lib/hecks/quality_control/cli/qa_pr_check.rb +28 -145
  860. data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +80 -0
  861. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +13 -86
  862. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/children.rb +80 -0
  863. data/lib/hecks/quality_control/cli/qa_sweep/all_mode/report.rb +125 -0
  864. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +63 -193
  865. data/lib/hecks/quality_control/cli/qa_sweep/checks/boundary.rb +92 -0
  866. data/lib/hecks/quality_control/cli/qa_sweep/checks/engines.rb +92 -0
  867. data/lib/hecks/quality_control/cli/qa_sweep/checks/seeds.rb +86 -0
  868. data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +69 -0
  869. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +10 -248
  870. data/lib/hecks/quality_control/cli/qa_sweep/conclusion.rb +60 -0
  871. data/lib/hecks/quality_control/cli/qa_sweep/depth.rb +61 -0
  872. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +27 -13
  873. data/lib/hecks/quality_control/cli/qa_sweep/finding_report/shrunk.rb +42 -0
  874. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +40 -41
  875. data/lib/hecks/quality_control/cli/qa_sweep/parsing/validation.rb +70 -0
  876. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +35 -65
  877. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +41 -22
  878. data/lib/hecks/quality_control/cli/qa_sweep/scratch.rb +67 -0
  879. data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +94 -0
  880. data/lib/hecks/quality_control/cli/qa_sweep/seed_loop.rb +157 -0
  881. data/lib/hecks/quality_control/cli/qa_sweep/target_setup.rb +115 -0
  882. data/lib/hecks/quality_control/cli/qa_sweep.rb +22 -445
  883. data/lib/hecks/quality_control/cli/qa_tick/output.rb +107 -0
  884. data/lib/hecks/quality_control/cli/qa_tick/preflight.rb +95 -0
  885. data/lib/hecks/quality_control/cli/qa_tick.rb +42 -175
  886. data/lib/hecks/query_ir/formatting.rb +86 -0
  887. data/lib/hecks/query_ir/rules.rb +132 -0
  888. data/lib/hecks/query_ir/touchpoints.rb +104 -0
  889. data/lib/hecks/query_ir.rb +33 -281
  890. data/lib/hecks/query_ir_mcp/tools.rb +68 -0
  891. data/lib/hecks/query_ir_mcp.rb +27 -71
  892. data/lib/hecks/query_specification/common/comparison.rb +25 -5
  893. data/lib/hecks/query_specification/common/dsl.rb +1 -1
  894. data/lib/hecks/query_specification/common/null_policy.rb +9 -6
  895. data/lib/hecks/query_specification/common/options.rb +21 -14
  896. data/lib/hecks/query_specification/field_path.rb +5 -2
  897. data/lib/hecks/query_specification/hop_path.rb +15 -18
  898. data/lib/hecks/release/lane.rb +22 -0
  899. data/lib/hecks/release/runner/clean_tree.rb +2 -2
  900. data/lib/hecks/release/runner/commands.rb +1 -1
  901. data/lib/hecks/release/runner/options.rb +82 -0
  902. data/lib/hecks/release/runner/preflight.rb +12 -7
  903. data/lib/hecks/release/runner/publishing.rb +86 -0
  904. data/lib/hecks/release/runner/tagger.rb +8 -3
  905. data/lib/hecks/release/runner.rb +40 -156
  906. data/lib/hecks/rendering.rb +13 -9
  907. data/lib/hecks/router/door.rb +37 -0
  908. data/lib/hecks/router/namespace_installer.rb +45 -83
  909. data/lib/hecks/router/options_proxy.rb +44 -0
  910. data/lib/hecks/runtime/adapter_lookup.rb +45 -24
  911. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -8
  912. data/lib/hecks/runtime/command_interpreter/delegation.rb +116 -0
  913. data/lib/hecks/runtime/command_interpreter/enforcement.rb +38 -0
  914. data/lib/hecks/runtime/command_interpreter/hydration.rb +139 -0
  915. data/lib/hecks/runtime/command_interpreter/list_mutations.rb +98 -0
  916. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +67 -114
  917. data/lib/hecks/runtime/command_interpreter/persisting.rb +96 -0
  918. data/lib/hecks/runtime/command_interpreter.rb +57 -352
  919. data/lib/hecks/runtime/command_rules/admissibility.rb +64 -147
  920. data/lib/hecks/runtime/command_rules/arithmetic.rb +13 -72
  921. data/lib/hecks/runtime/command_rules/authorization.rb +9 -9
  922. data/lib/hecks/runtime/command_rules/emission.rb +13 -14
  923. data/lib/hecks/runtime/command_rules/guard_state.rb +49 -0
  924. data/lib/hecks/runtime/command_rules/invariants.rb +84 -0
  925. data/lib/hecks/runtime/command_rules/operands.rb +88 -0
  926. data/lib/hecks/runtime/command_rules/references.rb +59 -57
  927. data/lib/hecks/runtime/command_rules/tenant_boundary.rb +69 -0
  928. data/lib/hecks/runtime/dependency_planning/analyzer.rb +90 -0
  929. data/lib/hecks/runtime/dependency_planning/expression_reads.rb +73 -0
  930. data/lib/hecks/runtime/dependency_planning/mutation_analysis.rb +89 -0
  931. data/lib/hecks/runtime/dependency_planning/rule_analysis.rb +82 -0
  932. data/lib/hecks/runtime/dependency_planning.rb +3 -250
  933. data/lib/hecks/runtime/dispatcher/queries.rb +62 -0
  934. data/lib/hecks/runtime/dispatcher/result.rb +55 -0
  935. data/lib/hecks/runtime/dispatcher/routing.rb +107 -0
  936. data/lib/hecks/runtime/dispatcher.rb +64 -209
  937. data/lib/hecks/runtime/entity_element/location.rb +124 -0
  938. data/lib/hecks/runtime/entity_element/mutations.rb +150 -0
  939. data/lib/hecks/runtime/entity_element.rb +5 -177
  940. data/lib/hecks/runtime/entity_interpreter/enforcement.rb +51 -0
  941. data/lib/hecks/runtime/entity_interpreter/locating.rb +62 -0
  942. data/lib/hecks/runtime/entity_interpreter/resolution.rb +42 -0
  943. data/lib/hecks/runtime/entity_interpreter/saving.rb +49 -0
  944. data/lib/hecks/runtime/entity_interpreter.rb +45 -164
  945. data/lib/hecks/runtime/identity.rb +15 -9
  946. data/lib/hecks/runtime/instance.rb +11 -7
  947. data/lib/hecks/runtime/interpreting.rb +16 -8
  948. data/lib/hecks/runtime/invocation.rb +3 -155
  949. data/lib/hecks/runtime/invocation_builder.rb +132 -0
  950. data/lib/hecks/runtime/invocation_facts.rb +87 -0
  951. data/lib/hecks/runtime/loader/boot_steps.rb +96 -0
  952. data/lib/hecks/runtime/loader/described.rb +27 -0
  953. data/lib/hecks/runtime/loader.rb +27 -114
  954. data/lib/hecks/runtime/outbox/consumer_runner.rb +40 -0
  955. data/lib/hecks/runtime/outbox/fanout.rb +82 -0
  956. data/lib/hecks/runtime/outbox/relay.rb +149 -0
  957. data/lib/hecks/runtime/outbox.rb +3 -214
  958. data/lib/hecks/runtime/policy_interpreter/arguments.rb +67 -0
  959. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +96 -0
  960. data/lib/hecks/runtime/policy_interpreter.rb +22 -137
  961. data/lib/hecks/runtime/port_operation_interpreter.rb +18 -17
  962. data/lib/hecks/runtime/query_interpreter/arguments.rb +51 -0
  963. data/lib/hecks/runtime/query_interpreter/entity_rows.rb +82 -0
  964. data/lib/hecks/runtime/query_interpreter/outside_answer.rb +89 -0
  965. data/lib/hecks/runtime/query_interpreter.rb +43 -191
  966. data/lib/hecks/runtime/reaction_invocation/identities.rb +92 -0
  967. data/lib/hecks/runtime/reaction_invocation/target_resolution.rb +88 -0
  968. data/lib/hecks/runtime/reaction_invocation.rb +66 -183
  969. data/lib/hecks/runtime/reaction_outcome.rb +7 -3
  970. data/lib/hecks/runtime/read_model_interpreter/head_ordering.rb +49 -0
  971. data/lib/hecks/runtime/read_model_interpreter/reductions.rb +123 -0
  972. data/lib/hecks/runtime/read_model_interpreter/shaping.rb +100 -0
  973. data/lib/hecks/runtime/read_model_interpreter.rb +71 -214
  974. data/lib/hecks/runtime/reference_hop.rb +11 -11
  975. data/lib/hecks/runtime/refusal_wording.rb +11 -8
  976. data/lib/hecks/runtime/registry/chapter_verification.rb +84 -0
  977. data/lib/hecks/runtime/registry/declarations.rb +17 -0
  978. data/lib/hecks/runtime/registry/durability_warnings.rb +71 -0
  979. data/lib/hecks/runtime/registry/hecksagon_rules.rb +124 -0
  980. data/lib/hecks/runtime/registry/merging.rb +49 -0
  981. data/lib/hecks/runtime/registry/providers.rb +139 -0
  982. data/lib/hecks/runtime/registry/query_verification.rb +144 -0
  983. data/lib/hecks/runtime/registry/read_repository.rb +61 -0
  984. data/lib/hecks/runtime/registry/runtime_state.rb +27 -0
  985. data/lib/hecks/runtime/registry/saga_persistence.rb +12 -8
  986. data/lib/hecks/runtime/registry/verification.rb +45 -389
  987. data/lib/hecks/runtime/registry/world_defaults.rb +3 -3
  988. data/lib/hecks/runtime/registry.rb +58 -296
  989. data/lib/hecks/runtime/remote_dispatcher.rb +47 -31
  990. data/lib/hecks/runtime/saga_interpreter/compensation.rb +90 -0
  991. data/lib/hecks/runtime/saga_interpreter/correlation.rb +19 -10
  992. data/lib/hecks/runtime/saga_interpreter/delivery.rb +147 -0
  993. data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +63 -0
  994. data/lib/hecks/runtime/saga_interpreter/transitions.rb +112 -0
  995. data/lib/hecks/runtime/saga_interpreter.rb +41 -320
  996. data/lib/hecks/runtime/tenant_check.rb +14 -9
  997. data/lib/hecks/runtime/value/admission.rb +28 -19
  998. data/lib/hecks/runtime/value/coercion.rb +55 -404
  999. data/lib/hecks/runtime/value/entity_list_coercion.rb +27 -29
  1000. data/lib/hecks/runtime/value/field_checks.rb +57 -100
  1001. data/lib/hecks/runtime/value/flags.rb +65 -0
  1002. data/lib/hecks/runtime/value/identifiers.rb +64 -0
  1003. data/lib/hecks/runtime/value/references.rb +195 -0
  1004. data/lib/hecks/runtime/value/shape_checks.rb +61 -0
  1005. data/lib/hecks/runtime/value/validation.rb +125 -0
  1006. data/lib/hecks/runtime/value.rb +18 -6
  1007. data/lib/hecks/rust_build/conformance/surface.rb +75 -0
  1008. data/lib/hecks/rust_build/conformance.rb +27 -59
  1009. data/lib/hecks/rust_build/conformance_fuzz.rb +26 -15
  1010. data/lib/hecks/rust_build/coverage.rb +32 -104
  1011. data/lib/hecks/rust_build/coverage_parts/expected.rb +68 -0
  1012. data/lib/hecks/rust_build/coverage_parts/printer.rb +75 -0
  1013. data/lib/hecks/rust_build/host.rb +23 -13
  1014. data/lib/hecks/rust_build/kernel_input.rb +19 -12
  1015. data/lib/hecks/rust_build/native_build.rb +48 -16
  1016. data/lib/hecks/rust_build/project_rust/domain_loader.rb +75 -0
  1017. data/lib/hecks/rust_build/project_rust/root_mod/notes.rb +66 -0
  1018. data/lib/hecks/rust_build/project_rust/root_mod.rb +22 -55
  1019. data/lib/hecks/rust_build/project_rust/target_ir.rb +74 -0
  1020. data/lib/hecks/rust_build/project_rust.rb +21 -89
  1021. data/lib/hecks/rust_build/wasm.rb +27 -7
  1022. data/lib/hecks/rust_build/wasm_browser.rb +7 -7
  1023. data/lib/hecks/rust_build/write_if_changed.rb +3 -6
  1024. data/lib/hecks/rust_build.rb +7 -3
  1025. data/lib/hecks/storehouse/audit.rb +106 -0
  1026. data/lib/hecks/storehouse/callers.rb +73 -0
  1027. data/lib/hecks/storehouse/dispatching.rb +149 -0
  1028. data/lib/hecks/storehouse/introspection.rb +145 -0
  1029. data/lib/hecks/storehouse/querying.rb +78 -0
  1030. data/lib/hecks/storehouse.rb +43 -451
  1031. data/lib/hecks/tickets/bluebook/tickets.bluebook +29 -0
  1032. data/lib/hecks/tools/argument_gate_matrix/dispatching.rb +69 -0
  1033. data/lib/hecks/tools/argument_gate_matrix/rows.rb +121 -0
  1034. data/lib/hecks/tools/argument_gate_matrix/violations.rb +108 -0
  1035. data/lib/hecks/tools/argument_gate_matrix.rb +43 -212
  1036. data/lib/hecks/tools/ci_gate_decision.rb +21 -14
  1037. data/lib/hecks/tools/ci_gates.rb +40 -26
  1038. data/lib/hecks/tools/comment_style/baseline.rb +41 -0
  1039. data/lib/hecks/tools/comment_style/caps_words.rb +104 -0
  1040. data/lib/hecks/tools/comment_style/cli.rb +121 -0
  1041. data/lib/hecks/tools/comment_style/dictionary.rb +60 -0
  1042. data/lib/hecks/tools/comment_style/fixing.rb +119 -0
  1043. data/lib/hecks/tools/comment_style/long_blocks.rb +51 -0
  1044. data/lib/hecks/tools/comment_style/masking.rb +94 -0
  1045. data/lib/hecks/tools/comment_style/patterns.rb +61 -0
  1046. data/lib/hecks/tools/comment_style/run.rb +161 -0
  1047. data/lib/hecks/tools/comment_style/signature.rb +59 -0
  1048. data/lib/hecks/tools/comment_style/source_file.rb +105 -0
  1049. data/lib/hecks/tools/comment_style/structure_checks.rb +113 -0
  1050. data/lib/hecks/tools/comment_style/text_checks.rb +67 -0
  1051. data/lib/hecks/tools/comment_style/vocabulary.rb +55 -0
  1052. data/lib/hecks/tools/comment_style/walker.rb +136 -0
  1053. data/lib/hecks/tools/comment_style.rb +17 -1000
  1054. data/lib/hecks/tools/corpus_report.rb +26 -16
  1055. data/lib/hecks/tools/deploy_recipe/generation.rb +59 -0
  1056. data/lib/hecks/tools/deploy_recipe/targets.rb +115 -0
  1057. data/lib/hecks/tools/deploy_recipe/worlds.rb +115 -0
  1058. data/lib/hecks/tools/deploy_recipe.rb +72 -176
  1059. data/lib/hecks/tools/deploy_recipe_lint/checks.rb +78 -0
  1060. data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +88 -0
  1061. data/lib/hecks/tools/deploy_recipe_lint/makefile.rb +84 -0
  1062. data/lib/hecks/tools/deploy_recipe_lint.rb +29 -192
  1063. data/lib/hecks/tools/drop_implicit_append_fields.rb +20 -12
  1064. data/lib/hecks/tools/era_projection_backfill.rb +50 -33
  1065. data/lib/hecks/tools/era_reattest/reporting.rb +55 -0
  1066. data/lib/hecks/tools/era_reattest.rb +32 -43
  1067. data/lib/hecks/tools/evolve_run/arguments.rb +49 -0
  1068. data/lib/hecks/tools/evolve_run/words.rb +60 -0
  1069. data/lib/hecks/tools/evolve_run.rb +43 -90
  1070. data/lib/hecks/tools/fuzz_sweep/findings.rb +106 -0
  1071. data/lib/hecks/tools/fuzz_sweep/options.rb +80 -0
  1072. data/lib/hecks/tools/fuzz_sweep/pool.rb +74 -0
  1073. data/lib/hecks/tools/fuzz_sweep/reporting.rb +110 -0
  1074. data/lib/hecks/tools/fuzz_sweep.rb +91 -272
  1075. data/lib/hecks/tools/gate.rb +31 -16
  1076. data/lib/hecks/tools/heki_compaction.rb +63 -42
  1077. data/lib/hecks/tools/hoist_local_givens/rewriting.rb +119 -0
  1078. data/lib/hecks/tools/hoist_local_givens.rb +89 -157
  1079. data/lib/hecks/tools/journal_compaction.rb +40 -31
  1080. data/lib/hecks/tools/lanes/files.rb +80 -0
  1081. data/lib/hecks/tools/lanes/live.rb +40 -0
  1082. data/lib/hecks/tools/lanes/rows.rb +45 -0
  1083. data/lib/hecks/tools/lanes/ruleset.rb +66 -0
  1084. data/lib/hecks/tools/lanes/watch_workflow.rb +82 -0
  1085. data/lib/hecks/tools/lanes/workflow.rb +79 -0
  1086. data/lib/hecks/tools/lanes.rb +82 -0
  1087. data/lib/hecks/tools/mutation_run.rb +73 -0
  1088. data/lib/hecks/tools/oidc_manifests.rb +10 -9
  1089. data/lib/hecks/tools/query_ir_run.rb +7 -3
  1090. data/lib/hecks/tools/regeneration_run.rb +40 -26
  1091. data/lib/hecks/tools/rust_comment_style/caps_words.rb +98 -0
  1092. data/lib/hecks/tools/rust_comment_style/fixing.rb +102 -0
  1093. data/lib/hecks/tools/rust_comment_style/masking.rb +85 -0
  1094. data/lib/hecks/tools/rust_comment_style/run.rb +94 -0
  1095. data/lib/hecks/tools/rust_comment_style/source_file.rb +71 -0
  1096. data/lib/hecks/tools/rust_comment_style/structure.rb +79 -0
  1097. data/lib/hecks/tools/rust_comment_style/text_checks.rb +63 -0
  1098. data/lib/hecks/tools/rust_comment_style/tokenizer.rb +102 -0
  1099. data/lib/hecks/tools/rust_comment_style.rb +38 -535
  1100. data/lib/hecks/tools/sequence_script.rb +20 -14
  1101. data/lib/hecks/tools/site_routes/cli.rb +70 -0
  1102. data/lib/hecks/tools/site_routes/root_files.rb +59 -0
  1103. data/lib/hecks/tools/site_routes/templates.rb +77 -0
  1104. data/lib/hecks/tools/site_routes.rb +84 -160
  1105. data/lib/hecks/tools/tail_merge.rb +45 -37
  1106. data/lib/hecks/tools/tenant_provisioning.rb +45 -31
  1107. data/lib/hecks/tools/tools_doc.rb +42 -19
  1108. data/lib/hecks/tools/translation_audit/domain_loading.rb +71 -0
  1109. data/lib/hecks/tools/translation_audit/edges.rb +71 -0
  1110. data/lib/hecks/tools/translation_audit/verdicts.rb +107 -0
  1111. data/lib/hecks/tools/translation_audit.rb +30 -161
  1112. data/lib/hecks/tools/translation_scaffold/reporting.rb +40 -0
  1113. data/lib/hecks/tools/translation_scaffold.rb +77 -60
  1114. data/lib/hecks/tools.rb +2 -0
  1115. data/lib/hecks/vendoring.rb +37 -11
  1116. data/lib/hecks/version.rb +1 -1
  1117. data/lib/hecks/vocabulary.rb +18 -1
  1118. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +7 -9
  1119. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +8 -6
  1120. data/prebuilt/945481eefbdb584649d45f256307053558966a868b9c38dee7ee88f8169610f8.marshal +0 -0
  1121. data/prebuilt/a0818e2de67364dc1ab22868b6cbf869c62da6f8d9b924c778fa5cce2e76ee94.marshal +0 -0
  1122. data/prebuilt/verdicts-be73f0df9eee0abe2f4aadc968321c4b919d19d424a3ccfe1777a71dabf7d9e7.json +1 -0
  1123. data/qa/settings.yml +1 -0
  1124. data/rust/.cargo/mutants.toml +8 -0
  1125. data/rust/host/Cargo.toml +5 -0
  1126. data/rust/host/HECKS_RELEASE +1 -1
  1127. data/rust/host/src/api.rs +28 -5
  1128. data/rust/host/src/auth.rs +43 -1
  1129. data/rust/host/src/boundary_fuzz/api.rs +260 -0
  1130. data/rust/host/src/boundary_fuzz/auth.rs +119 -0
  1131. data/rust/host/src/boundary_fuzz/expr_json.rs +158 -0
  1132. data/rust/host/src/boundary_fuzz/ir.rs +78 -0
  1133. data/rust/host/src/boundary_fuzz/server.rs +227 -0
  1134. data/rust/host/src/boundary_fuzz/web.rs +125 -0
  1135. data/rust/host/src/fuzz_support.rs +165 -0
  1136. data/rust/host/src/ir.rs +4 -0
  1137. data/rust/host/src/main.rs +9 -4
  1138. data/rust/host/src/secrets.rs +44 -0
  1139. data/rust/host/src/server.rs +6 -1
  1140. data/rust/host/src/web.rs +14 -5
  1141. data/rust/parser/fuzz/.gitignore +4 -0
  1142. data/rust/parser/fuzz/Cargo.lock +89 -0
  1143. data/rust/parser/fuzz/Cargo.toml +27 -0
  1144. data/rust/parser/fuzz/README.md +19 -0
  1145. data/rust/parser/fuzz/fuzz_targets/chapter.rs +50 -0
  1146. data/rust/parser/fuzz/fuzz_targets/resolve.rs +35 -0
  1147. data/rust/parser/src/parse/command.rs +14 -2
  1148. data/rust/parser/src/parse/mod.rs +25 -0
  1149. data/rust/parser/src/ruby_value.rs +95 -6
  1150. data/rust/src/kernel/dispatch.rs +4 -0
  1151. data/rust/src/kernel/dispatch_guard_tests.rs +506 -0
  1152. data/rust/src/kernel/json.rs +34 -3
  1153. data/rust/src/kernel/orchestrate.rs +4 -0
  1154. data/rust/src/kernel/orchestrate_guard_tests.rs +708 -0
  1155. metadata +640 -3
  1156. /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Hecks
6
+ module RustBuild
7
+ class ProjectRust
8
+ # The target domain's IR, with the binding facts that ride beside it (they are not shape
9
+ # facts, so `bluebook.to_h` never mentions them).
10
+ class TargetIr
11
+ # The optional attachments `rust/host` reads from `ir.json`, each omitted when nothing
12
+ # attached provides it: exporter method, then the key it is written under.
13
+ SEAMS = %i[authorization membership identity newsletter newsletter_issues payments
14
+ registrations payment_connection].freeze
15
+
16
+ # Round-trips a value through JSON so generators see the string-keyed shape a real
17
+ # `ir.json` carries, never live Ruby symbols.
18
+ #
19
+ # @param payload [Object] a JSON-compatible value
20
+ # @return [Object] the same value with symbol keys, as parsed from JSON
21
+ def self.json_shaped(payload) = JSON.parse(JSON.generate(payload), symbolize_names: true)
22
+
23
+ # @param registry [Hecks::Runtime::Registry] the loaded registry
24
+ # @param domain_name [String] the target bluebook's name
25
+ # @param bluebook_dir [String] the target's `bluebook/` directory
26
+ def initialize(registry, domain_name, bluebook_dir)
27
+ @registry = registry
28
+ @domain_name = domain_name
29
+ @bluebook_dir = bluebook_dir
30
+ end
31
+
32
+ # @return [Hash{Symbol => Object}] the IR the generator reads
33
+ # @raise [Failure] when the domain provides membership but not identity
34
+ def call
35
+ exporter = Hecks::Projector::Exporter
36
+ ir = shaped(exporter.call(@registry).fetch(@domain_name))
37
+ ir[:lineage] = shaped(exporter.lineage(@registry, @domain_name))
38
+ ir[:persistence] = shaped(exporter.persistence(@registry, @domain_name))
39
+ add_seams(ir, exporter)
40
+ add_edges_and_source(ir)
41
+ ir
42
+ end
43
+
44
+ private
45
+
46
+ def shaped(payload) = self.class.json_shaped(payload)
47
+
48
+ def add_seams(document, exporter)
49
+ seams = SEAMS.to_h { |seam| [seam, exporter.public_send(seam, @registry, @domain_name)] }
50
+ seams.each { |seam, value| document[seam] = shaped(value) unless value.empty? }
51
+ return unless !seams[:membership].empty? && seams[:identity].empty?
52
+
53
+ raise Failure, "#{@domain_name} provides membership but not identity — rust/host Google sign-in " \
54
+ "cannot register or link an identity from ir.json. Attach Identity " \
55
+ "(`attaches \"Identity\"` plus a sibling Hecks.hecksagon \"Identity\") so the " \
56
+ "hecksagon, not a deploy-time guess, names the identity verbs."
57
+ end
58
+
59
+ # Edges carry their own precompiled SQL, so a boot-time mint only executes it. Committed
60
+ # approvals sit beside the edges. The source text is verbatim: the era's integrity digest is
61
+ # the SHA256 of it, not of anything re-derived from the parsed IR.
62
+ def add_edges_and_source(document)
63
+ edges = Hecks::Projector::Exporter.translations(@registry).select { |edge| edge[:domain] == @domain_name }
64
+ document[:translations] = shaped(edges)
65
+ approvals = Hecks::Translation::ApprovalFile.read_all(@bluebook_dir)
66
+ document[:approvals] = shaped(approvals) unless approvals.empty?
67
+ document[:source_text] = Hecks::Runtime::EraCheck.source_text_for(
68
+ @registry.bluebooks.fetch(@domain_name), @bluebook_dir, registry: @registry
69
+ )
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -22,11 +22,6 @@ module Hecks
22
22
  # The era plugin is required unconditionally so the generator works for any domain, lineage
23
23
  # capable or not; `pg` stays lazy inside it, so nothing here opens a database connection.
24
24
  class ProjectRust
25
- # The optional attachments `rust/host` reads from `ir.json`, each omitted when nothing
26
- # attached provides it: exporter method, then the key it is written under.
27
- SEAMS = %i[authorization membership identity newsletter newsletter_issues payments
28
- registrations payment_connection].freeze
29
-
30
25
  # @param argv [Array<String>] the domain's directory
31
26
  # @return [Integer] the exit status
32
27
  # @raise [Failure] when the domain's name cannot be a Rust module and Cargo feature name
@@ -59,110 +54,45 @@ module Hecks
59
54
  "be used as-is — it has to double as a Rust module identifier and a Cargo feature " \
60
55
  "name, and this one is either not a plain lowercase identifier, is a Rust keyword, " \
61
56
  "or collides with a reserved Cargo.toml key " \
62
- "(#{DomainName::CARGO_RESERVED.join(', ')}). " \
57
+ "(#{DomainName::CARGO_RESERVED.join(", ")}). " \
63
58
  "Rename the domain directory."
64
59
  end
65
60
 
66
61
  def generate
67
- load_registry
68
- @rust_dir = ENV.fetch("HECKS_RUST_DIR", File.join(RustBuild::ROOT, "rust"))
69
- @out_root = File.join(@rust_dir, "src/generated")
70
- FileUtils.mkdir_p(@out_root)
71
- build_target_ir
62
+ loader = DomainLoader.new(@domain).call
63
+ @registry = loader.registry
64
+ @domain_name = loader.domain_name
65
+ prepare_output
66
+ @ir = TargetIr.new(@registry, @domain_name, loader.bluebook_dir).call
72
67
  FileUtils.rm_rf(File.join(@out_root, "active"))
73
68
  generate_with_codegen
74
69
  write_root_mod
75
70
  sync_cargo_features
76
71
  end
77
72
 
73
+ def prepare_output
74
+ @rust_dir = ENV.fetch("HECKS_RUST_DIR", File.join(RustBuild::ROOT, "rust"))
75
+ @out_root = File.join(@rust_dir, "src/generated")
76
+ FileUtils.mkdir_p(@out_root)
77
+ end
78
+
78
79
  # `hecks-codegen` is the generator; this process only builds the IR it reads from the live
79
80
  # registry, so a domain's persistence, seams, translations and source text reach `ir.json`.
80
81
  def generate_with_codegen
81
82
  meta = Hecks::Projector::Exporter.call(Hecks::Bluebook::MetaValidator.grammar_registry).fetch("Bluebook")
82
- vendored = @registry.hecksagons.values.flat_map(&:vendored_packages)
83
- chapters = (@registry.bluebooks.keys - [@domain_name]).map do |name|
84
- ir = Hecks::Projector::Exporter.call(@registry).fetch(name)
85
- CodegenRun::Chapter.new(name.downcase, "#{@domain} (#{attachment(name, vendored)})", json_shaped(ir))
86
- end
87
83
  CodegenRun.new(
88
- rust_dir: @rust_dir, out_root: @out_root, meta: json_shaped(meta), chapters: chapters,
84
+ rust_dir: @rust_dir, out_root: @out_root, meta: TargetIr.json_shaped(meta), chapters: chapters,
89
85
  target: CodegenRun::Chapter.new(@mod_name, @domain, @ir)
90
86
  ).call
91
87
  end
92
88
 
93
- # Round-trips a value through JSON so generators see the string-keyed shape a real `ir.json`
94
- # carries, never live Ruby symbols.
95
- def json_shaped(payload) = JSON.parse(JSON.generate(payload), symbolize_names: true)
96
-
97
- # `root:` is the domain's own directory: a domain that declares `attaches ... from: :vendor`
98
- # resolves its vendored chapters beneath it.
99
- def load_registry
100
- @registry = Hecks::Runtime::Registry.new(root: File.expand_path(@domain))
101
- Hecks.with_registry(@registry) do
102
- lib = File.expand_path("..", __dir__)
103
- %w[ports/persistence.port ports/extraction.port adapters/driven/memory.adapter
104
- adapters/driven/prism.adapter adapters/driven/postgres_era.adapter].each do |file|
105
- Kernel.load(File.join(lib, file))
106
- end
107
- @bluebook_dir = File.join(@domain, "bluebook")
108
- Hecks::Adapters::Folder.new.load_bluebooks(@bluebook_dir)
109
- load_siblings
110
- load_environment
111
- end
112
- @domain_name = @registry.bluebooks.keys.first
113
- end
114
-
115
- # Translation edges, hecksagons (whose `attaches` loads a framework chapter into the
116
- # same registry) and worlds (whose `default_adapter` binds what a hecksagon leaves out), in
117
- # the order the language loads them.
118
- def load_siblings
119
- Dir[File.join(@bluebook_dir, "translations", "*.bluebook")].each { |file| Kernel.load(file) }
120
- Dir.glob(File.join(@bluebook_dir, "*.hecksagon")).each { |file| Kernel.load(file) }
121
- Dir.glob(File.join(@bluebook_dir, "*.world")).each { |file| Kernel.load(file) }
122
- end
123
-
124
- # Production is the default environment when `environments/production.hecksagon` exists
125
- # (`rust/host` is the production runtime); `HECKS_PROJECT_ENVIRONMENT` overrides it.
126
- def load_environment
127
- environment = ENV.fetch("HECKS_PROJECT_ENVIRONMENT") do
128
- File.exist?(File.join(@bluebook_dir, "environments", "production.hecksagon")) ? "production" : nil
129
- end
130
- return if environment.nil? || environment.empty?
131
-
132
- folder = Hecks::Adapters::Folder.new
133
- folder.load_each(@bluebook_dir, [File.join("environments", "#{environment}.hecksagon")])
134
- folder.load_each(@bluebook_dir, [File.join("environments", "#{environment}.world")])
135
- end
136
-
137
- # The target's IR, with the binding facts that ride beside it (they are not shape facts, so
138
- # `bluebook.to_h` never mentions them).
139
- def build_target_ir
140
- exporter = Hecks::Projector::Exporter
141
- @ir = json_shaped(exporter.call(@registry).fetch(@domain_name))
142
- @ir[:lineage] = json_shaped(exporter.lineage(@registry, @domain_name))
143
- @ir[:persistence] = json_shaped(exporter.persistence(@registry, @domain_name))
144
- seams = SEAMS.to_h { |seam| [seam, exporter.public_send(seam, @registry, @domain_name)] }
145
- seams.each { |seam, value| @ir[seam] = json_shaped(value) unless value.empty? }
146
- if !seams[:membership].empty? && seams[:identity].empty?
147
- raise Failure, "#{@domain_name} provides membership but not identity — rust/host Google sign-in " \
148
- "cannot register or link an identity from ir.json. Attach Identity " \
149
- "(`attaches \"Identity\"` plus a sibling Hecks.hecksagon \"Identity\") so the " \
150
- "hecksagon, not a deploy-time guess, names the identity verbs."
89
+ def chapters
90
+ vendored = @registry.hecksagons.values.flat_map(&:vendored_packages)
91
+ (@registry.bluebooks.keys - [@domain_name]).map do |name|
92
+ ir = Hecks::Projector::Exporter.call(@registry).fetch(name)
93
+ label = "#{@domain} (#{attachment(name, vendored)})"
94
+ CodegenRun::Chapter.new(name.downcase, label, TargetIr.json_shaped(ir))
151
95
  end
152
- add_edges_and_source
153
- end
154
-
155
- # Edges carry their own precompiled SQL, so a boot-time mint only executes it. Committed
156
- # approvals sit beside the edges. The source text is verbatim: the era's integrity digest is
157
- # the SHA256 of it, not of anything re-derived from the parsed IR.
158
- def add_edges_and_source
159
- edges = Hecks::Projector::Exporter.translations(@registry).select { |edge| edge[:domain] == @domain_name }
160
- @ir[:translations] = json_shaped(edges)
161
- approvals = Hecks::Translation::ApprovalFile.read_all(@bluebook_dir)
162
- @ir[:approvals] = json_shaped(approvals) unless approvals.empty?
163
- @ir[:source_text] = Hecks::Runtime::EraCheck.source_text_for(
164
- @registry.bluebooks.fetch(@domain_name), @bluebook_dir, registry: @registry
165
- )
166
96
  end
167
97
 
168
98
  # How the target attached a chapter, across every hecksagon the registry loaded: a chapter a
@@ -230,3 +160,5 @@ end
230
160
 
231
161
  require_relative "project_rust/root_mod"
232
162
  require_relative "project_rust/codegen_run"
163
+ require_relative "project_rust/domain_loader"
164
+ require_relative "project_rust/target_ir"
@@ -15,10 +15,15 @@ module Hecks
15
15
  # `wasmtime run rust/dist/<domain>.wasm < script.json`, and the domain's `ir.json` beside it,
16
16
  # which `rust/host` reads at runtime. `HECKS_RUST_DIR` names the workspace to build in and
17
17
  # `CARGO_TARGET_DIR` where build output goes, beside the workspace by default.
18
+ # `HECKS_WASM_PROFILE=dev` builds without `--release`: a much faster compile, for tests that
19
+ # only run the module, not for one that ships.
18
20
  module Wasm
19
21
  # The Cargo target the module is built for.
20
22
  TARGET = "wasm32-wasip1"
21
23
 
24
+ # The Cargo flags and the `target/<target>/` directory of each build profile.
25
+ PROFILES = { "release" => { flags: ["--release"], dir: "release" }, "dev" => { flags: [], dir: "debug" } }.freeze
26
+
22
27
  module_function
23
28
 
24
29
  # @param argv [Array<String>] the domain's directory
@@ -31,15 +36,18 @@ module Hecks
31
36
  require_target!
32
37
  rust_dir = RustBuild.rust_dir
33
38
  scratch = scratch_copy(rust_dir)
34
- puts "== regenerating #{scratch}/src/generated/ for #{domain} =="
35
- status = RustBuild.with_env("HECKS_RUST_DIR" => scratch) { ProjectRust.call([domain]) }
36
- raise Failure, "project_rust failed for #{domain}" unless status.zero?
37
-
39
+ regenerate(scratch, domain)
38
40
  compile(scratch)
39
41
  publish(scratch, rust_dir, File.basename(domain))
40
42
  0
41
43
  end
42
44
 
45
+ def regenerate(scratch, domain)
46
+ puts "== regenerating #{scratch}/src/generated/ for #{domain} =="
47
+ status = RustBuild.with_env("HECKS_RUST_DIR" => scratch) { ProjectRust.call([domain]) }
48
+ raise Failure, "project_rust failed for #{domain}" unless status.zero?
49
+ end
50
+
43
51
  # With the Rust parser and codegen, `hecks-build` runs the same steps and writes the same
44
52
  # outputs.
45
53
  def build_with_rust(domain)
@@ -80,20 +88,32 @@ module Hecks
80
88
  # `rustup run`, not bare `cargo`: a `cargo` earlier on PATH may never have seen
81
89
  # `rustup target add` and fail with "can't find crate for `std`".
82
90
  def compile(scratch)
83
- puts "== cargo build --release --target #{TARGET} =="
91
+ flags = profile.fetch(:flags)
92
+ puts "== cargo build #{flags.join(" ")} --target #{TARGET} =="
84
93
  target_dir = ENV.fetch("CARGO_TARGET_DIR", File.join(RustBuild.rust_dir, "target"))
85
- RustBuild.command!("rustup", "run", "stable", "cargo", "build", "--release", "--target", TARGET,
94
+ RustBuild.command!("rustup", "run", "stable", "cargo", "build", *flags, "--target", TARGET,
86
95
  chdir: scratch, env: { "CARGO_TARGET_DIR" => target_dir })
87
96
  end
88
97
 
98
+ # @return [Hash] the flags and directory of the profile `HECKS_WASM_PROFILE` names
99
+ # @raise [Failure] when the name is not `release` or `dev`
100
+ def profile
101
+ name = ENV.fetch("HECKS_WASM_PROFILE", "release")
102
+ PROFILES.fetch(name) { raise Failure, "HECKS_WASM_PROFILE=#{name} is not release or dev" }
103
+ end
104
+
89
105
  def publish(scratch, rust_dir, name)
90
106
  dist = File.join(rust_dir, "dist")
91
107
  FileUtils.mkdir_p(dist)
92
108
  target_dir = ENV.fetch("CARGO_TARGET_DIR", File.join(rust_dir, "target"))
93
109
  out = File.join(dist, "#{name}.wasm")
94
- FileUtils.cp(File.join(target_dir, TARGET, "release", "rust.wasm"), out)
110
+ FileUtils.cp(File.join(target_dir, TARGET, profile.fetch(:dir), "rust.wasm"), out)
95
111
  puts "wrote #{out}"
96
112
  puts %(run it: wasmtime run #{out} < script.json)
113
+ publish_sidecar(scratch, dist, name)
114
+ end
115
+
116
+ def publish_sidecar(scratch, dist, name)
97
117
  sidecar = File.join(scratch, "src", "generated", name, "ir.json")
98
118
  return unless File.exist?(sidecar)
99
119
 
@@ -29,16 +29,12 @@ module Hecks
29
29
  domain = argv.first or raise Failure, "usage: hecks build_browser_wasm <domain>"
30
30
  rust_dir = RustBuild.rust_dir
31
31
  web_dir = File.join(rust_dir, "web")
32
- name = File.basename(domain)
33
32
  require_target!
34
33
  require_cli!(web_dir)
35
34
  scratch = scratch_copy(rust_dir)
36
- puts "== regenerating #{scratch}/src/generated/ for #{domain} =="
37
- status = RustBuild.with_env("HECKS_RUST_DIR" => scratch) { ProjectRust.call([domain]) }
38
- raise Failure, "project_rust failed for #{domain}" unless status.zero?
39
-
35
+ Wasm.regenerate(scratch, domain)
40
36
  compile(File.join(scratch, "web"), web_dir)
41
- bind(web_dir, name)
37
+ bind(web_dir, File.basename(domain))
42
38
  0
43
39
  end
44
40
 
@@ -99,7 +95,11 @@ module Hecks
99
95
  puts "== wasm-bindgen --target web =="
100
96
  RustBuild.command!("wasm-bindgen", "--target", "web", "--out-dir", out_dir, "--out-name", name, built)
101
97
  puts "wrote #{out_dir}/"
102
- puts <<~MSG
98
+ puts browser_usage(name)
99
+ end
100
+
101
+ def browser_usage(name)
102
+ <<~MSG
103
103
  use it in a browser:
104
104
  <script type="module">
105
105
  import init, { dispatch } from "./#{name}.js";
@@ -71,12 +71,9 @@ module Hecks
71
71
  tmp = "#{path}.tmp-#{Process.pid}-#{rand(1_000_000)}"
72
72
  begin
73
73
  File.open(tmp, "w", &)
74
- if File.exist?(path) && FileUtils.compare_file(tmp, path)
75
- false
76
- else
77
- FileUtils.mv(tmp, path)
78
- true
79
- end
74
+ changed = !(File.exist?(path) && FileUtils.compare_file(tmp, path))
75
+ FileUtils.mv(tmp, path) if changed
76
+ changed
80
77
  ensure
81
78
  FileUtils.rm_f(tmp)
82
79
  end
@@ -80,7 +80,7 @@ module Hecks
80
80
  options[:chdir] = chdir if chdir
81
81
  return if system(env, *command, **options)
82
82
 
83
- raise Failure, "`#{command.join(' ')}` failed#{" in #{chdir}" if chdir}"
83
+ raise Failure, "`#{command.join(" ")}` failed#{" in #{chdir}" if chdir}"
84
84
  end
85
85
 
86
86
  # Runs a tool and holds what it printed.
@@ -127,10 +127,14 @@ module Hecks
127
127
  $stdout, $stderr = saved
128
128
  end
129
129
 
130
- def finish(tool, argv)
130
+ def load_tool(tool)
131
131
  file, constant = TOOLS.fetch(tool)
132
132
  require_relative file
133
- RustBuild.const_get(constant).call(argv)
133
+ RustBuild.const_get(constant)
134
+ end
135
+
136
+ def finish(tool, argv)
137
+ load_tool(tool).call(argv)
134
138
  rescue Failure => e
135
139
  warn e.message
136
140
  1
@@ -0,0 +1,106 @@
1
+ module Hecks
2
+ module Storehouse
3
+ # The bus's own JSONL audit log: writing a line for each dispatch, query and state call, and
4
+ # reading it back as a tail or as the events it announced. Extended onto `Storehouse`.
5
+ module Audit
6
+ # The caller-supplied fields of an audit line, in the order the line spells them.
7
+ AUDIT_FIELDS = %i[verb summary source role actor_id].freeze
8
+
9
+ # Kept under Hecks::CacheDir, not the domain directory (part of the domain's
10
+ # own state) or the gem directory (read-only once installed).
11
+ # :nodoc:
12
+ def log_root = Hecks::CacheDir.path("storehouse")
13
+
14
+ # :nodoc:
15
+ def log_path(domain_name)
16
+ File.join(log_root, "#{domain_name.to_s.gsub(/[^A-Za-z0-9_-]/, "_")}.jsonl")
17
+ end
18
+
19
+ # Never fails a real call because its own audit log couldn't be written —
20
+ # a full disk silences follow, not the dispatch/query/state call itself.
21
+ #
22
+ # @param entry [Hash] the line's `verb:`, `summary:`, `source:`, `role:` and `actor_id:`
23
+ # :nodoc:
24
+ def record!(domain_name, tool:, outcome:, **entry)
25
+ return unless domain_name
26
+
27
+ line = { time: Time.now.utc.iso8601, tool: tool }.merge(AUDIT_FIELDS.to_h { |field| [field, entry[field]] })
28
+ .merge(outcome.slice(:ok, :id, :error, :events)).compact
29
+ FileUtils.mkdir_p(log_root)
30
+ File.open(log_path(domain_name), "a") { |f| f.puts(JSON.generate(line)) }
31
+ rescue StandardError
32
+ nil
33
+ end
34
+
35
+ # Tails this bus's own dispatch/query/state audit log — a pull-based
36
+ # substitute for a push subscription, since a stdio door answers one
37
+ # request at a time with no channel to push through.
38
+ #
39
+ # @param runtime [Runtime::Registry] the booted domain to tail
40
+ # @param limit [Integer, #to_i] how many recent log entries to return
41
+ # @return [Hash] :ok, :domain, :entries; or the refused shape
42
+ def follow(runtime:, limit: 20)
43
+ bluebook = bluebook_for(runtime)
44
+ entries = log_lines(bluebook.name).last([limit.to_i, 1].max)
45
+
46
+ ok(domain: bluebook.name, entries: entries)
47
+ rescue *refusal_classes => e
48
+ refused(e)
49
+ end
50
+
51
+ # :nodoc:
52
+ def log_lines(domain_name)
53
+ path = log_path(domain_name)
54
+ return [] unless File.exist?(path)
55
+
56
+ File.readlines(path).map { |line| JSON.parse(line, symbolize_names: true) }
57
+ end
58
+
59
+ # What actually happened, with payloads, to one aggregate or record — read
60
+ # off this bus's own audit log (a dispatch's announced events), not a full
61
+ # event-sourcing replay. aggregate: narrows the search; id: (requires
62
+ # aggregate:) narrows further to one record.
63
+ #
64
+ # @param runtime [Runtime::Registry] the booted domain to search
65
+ # @param aggregate [String, Symbol, nil] narrows the search to one aggregate
66
+ # @param id [String, Object, nil] narrows further to one record; requires aggregate
67
+ # @param limit [Integer, #to_i, nil] how many recent matching events to
68
+ # return; nil returns every one found
69
+ # @return [Hash] :ok, :domain, :events; or the refused shape
70
+ # @raise [Runtime::TypeMismatch] if id is given without aggregate
71
+ def events(runtime:, aggregate: nil, id: nil, limit: nil)
72
+ if id && !aggregate
73
+ raise Runtime::TypeMismatch, "id: requires aggregate: too — an id alone is not unique across aggregates"
74
+ end
75
+
76
+ bluebook = bluebook_for(runtime)
77
+ fqn = aggregate ? "#{bluebook.name}::#{aggregate_ir!(bluebook, aggregate).hecks_name}" : nil
78
+
79
+ ok(domain: bluebook.name, events: matching_events(bluebook, fqn, id, limit))
80
+ rescue *refusal_classes => e
81
+ refused(e)
82
+ end
83
+
84
+ # :nodoc:
85
+ def matching_events(bluebook, fqn, id, limit)
86
+ found = log_lines(bluebook.name).filter_map { |entry| entry_events(entry, fqn, id) }.flatten(1)
87
+ limit ? found.last(limit.to_i) : found
88
+ end
89
+
90
+ # :nodoc:
91
+ def entry_events(entry, fqn, id)
92
+ return unless entry[:tool] == "dispatch" && entry[:ok] && entry[:events]
93
+ return unless targets?(entry, fqn, id)
94
+
95
+ entry[:events].map { |event| event.merge(time: entry[:time], verb: entry[:verb], id: entry[:id]) }
96
+ end
97
+
98
+ # @return [Boolean] whether the audit entry is about the aggregate and record asked for
99
+ def targets?(entry, fqn, id)
100
+ return false if fqn && !entry[:verb].to_s.start_with?("#{fqn}.")
101
+
102
+ !(id && entry[:id] != id)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,73 @@
1
+ module Hecks
2
+ module Storehouse
3
+ # The checks on who is calling and what a call may carry: its options, summary, source and
4
+ # role. Extended onto `Storehouse`.
5
+ module Callers
6
+ # Refuses an option a call does not take, as a method without that keyword would.
7
+ #
8
+ # @param options [Hash] the keywords the caller passed
9
+ # @param allowed [Array<Symbol>] the keywords the call takes
10
+ # @raise [ArgumentError] naming the first one not in `allowed`
11
+ # :nodoc:
12
+ def check_options!(options, allowed)
13
+ unknown = options.keys - allowed
14
+ raise ArgumentError, "unknown keyword: #{unknown.first.inspect}" unless unknown.empty?
15
+ end
16
+
17
+ # The checks every dispatch and query makes before it reads anything: a summary, a known
18
+ # source,
19
+ # and a role to go with an actor.
20
+ # :nodoc:
21
+ def validate_caller_fields!(request)
22
+ require_summary!(request.summary)
23
+ valid_source!(request.source)
24
+ valid_caller!(request.role, request.actor_id)
25
+ end
26
+
27
+ # Required on dispatch/query/state: what makes an audit row legible later.
28
+ # :nodoc:
29
+ def require_summary!(summary)
30
+ return unless summary.nil? || summary.to_s.strip.empty?
31
+
32
+ raise Runtime::TypeMismatch,
33
+ "a one-line summary: is required on dispatch/query/state — it is what makes an audit row legible later"
34
+ end
35
+
36
+ # :nodoc:
37
+ def valid_source!(source)
38
+ return if source.nil? || SOURCE_TAGS.include?(source.to_s)
39
+
40
+ raise Runtime::TypeMismatch, "source: #{source.inspect} is not one of #{SOURCE_TAGS.join(", ")}"
41
+ end
42
+
43
+ # actor_id without role would silently bind nothing rather than a real
44
+ # caller — refusing here beats a caller thinking it identified itself.
45
+ # :nodoc:
46
+ def valid_caller!(role, actor_id)
47
+ return unless actor_id && role.nil?
48
+
49
+ raise Runtime::TypeMismatch, "actor_id: requires role: too — a caller names WHO through WHICH role they hold"
50
+ end
51
+
52
+ # Binds role/actor_id for the block's duration via Hecks.as_caller; role: nil
53
+ # runs the block unbound (query's own authorization does not depend on it).
54
+ # :nodoc:
55
+ def with_caller(role, actor_id, &)
56
+ return yield if role.nil?
57
+
58
+ Hecks.as_caller(role: role, actor_id: actor_id, &)
59
+ end
60
+
61
+ # A caller who omits role: would otherwise reach a role-gated command
62
+ # unchecked (refuse_role_mismatch no-ops with no bound caller) — refuse here instead.
63
+ # :nodoc:
64
+ def require_caller_for_role_gated!(spec, role)
65
+ return unless spec[:role_gated] && role.nil?
66
+
67
+ raise Runtime::Unauthorized,
68
+ "#{spec[:command]} requires role: #{spec[:role].inspect} — this command is role-gated and no caller " \
69
+ "(role:/actor_id:) is bound; dispatching it unbound is refused, not silently unchecked"
70
+ end
71
+ end
72
+ end
73
+ end