hecks 3.10.0 → 3.12.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 (542) hide show
  1. checksums.yaml +4 -4
  2. data/examples/pizzas/bluebook/pizzas.bluebook +29 -0
  3. data/examples/pizzas/bluebook/pizzas.hecksagon +7 -0
  4. data/exe/hecks +4 -4
  5. data/lib/hecks/adapters/driven/d1.rb +2 -10
  6. data/lib/hecks/adapters/driven/heki.adapter +1 -1
  7. data/lib/hecks/adapters/driven/heki.rb +2 -12
  8. data/lib/hecks/adapters/driven/lambda.adapter +1 -1
  9. data/lib/hecks/adapters/driven/lambda.rb +3 -18
  10. data/lib/hecks/adapters/driven/postgres.rb +4 -11
  11. data/lib/hecks/adapters/driven/sqlite.adapter +1 -1
  12. data/lib/hecks/adapters/driven/sqlite.rb +2 -10
  13. data/lib/hecks/adapters/driving/admission.rb +46 -0
  14. data/lib/hecks/adapters/driving/cli/nesting.rb +36 -0
  15. data/lib/hecks/adapters/driving/cli/shorthand.rb +88 -0
  16. data/lib/hecks/adapters/driving/cli.rb +127 -0
  17. data/lib/hecks/adapters/driving/cli_runner/answers.rb +160 -0
  18. data/lib/hecks/adapters/driving/cli_runner/resolution.rb +158 -0
  19. data/lib/hecks/adapters/driving/cli_runner/settling.rb +120 -0
  20. data/lib/hecks/adapters/driving/cli_runner/streaming.rb +93 -0
  21. data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +47 -0
  22. data/lib/hecks/adapters/driving/cli_runner.rb +70 -0
  23. data/lib/hecks/adapters/driving/command_request.rb +121 -0
  24. data/lib/hecks/adapters/driving/handle.rb +214 -0
  25. data/lib/hecks/adapters/driving/json.rb +136 -0
  26. data/lib/hecks/adapters/driving/launcher_options.rb +267 -0
  27. data/lib/hecks/adapters/driving/mcp/properties.rb +49 -0
  28. data/lib/hecks/adapters/driving/mcp/tool_calls.rb +116 -0
  29. data/lib/hecks/adapters/driving/mcp/tool_definitions/auditing.rb +53 -0
  30. data/lib/hecks/adapters/driving/mcp/tool_definitions/calling.rb +71 -0
  31. data/lib/hecks/adapters/driving/mcp/tool_definitions/reading.rb +99 -0
  32. data/lib/hecks/adapters/driving/mcp/tool_definitions.rb +18 -0
  33. data/lib/hecks/adapters/driving/mcp.rb +159 -0
  34. data/lib/hecks/adapters/driving/mcp_guide_cache.rb +78 -0
  35. data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +97 -0
  36. data/lib/hecks/adapters/driving/mcp_scope/env_problems.rb +69 -0
  37. data/lib/hecks/adapters/driving/mcp_scope/presenter.rb +83 -0
  38. data/lib/hecks/adapters/driving/mcp_scope.rb +213 -0
  39. data/lib/hecks/adapters/driving/newcomer.rb +50 -0
  40. data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +171 -0
  41. data/lib/hecks/adapters/driving/ruby/chapter.rb +91 -0
  42. data/lib/hecks/adapters/driving/ruby.rb +83 -0
  43. data/lib/hecks/adapters/driving/usage_cache.rb +144 -0
  44. data/lib/hecks/{doors.rb → adapters/driving.rb} +10 -6
  45. data/lib/hecks/behaviors/expectations/boot.rb +1 -1
  46. data/lib/hecks/bench/ruby_runner.rb +1 -1
  47. data/lib/hecks/bluebook/ask_resolution.rb +130 -0
  48. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +8 -2
  49. data/lib/hecks/bluebook/assembly/contracts/read_models.rb +1 -1
  50. data/lib/hecks/bluebook/assembly/contracts/rules.rb +4 -2
  51. data/lib/hecks/bluebook/assembly/contracts/structure.rb +3 -1
  52. data/lib/hecks/bluebook/assembly/marks.rb +4 -15
  53. data/lib/hecks/bluebook/assembly/scalars.rb +39 -0
  54. data/lib/hecks/bluebook/attribute.rb +1 -1
  55. data/lib/hecks/bluebook/behaviour/command.rb +13 -8
  56. data/lib/hecks/bluebook/behaviour/policy.rb +30 -0
  57. data/lib/hecks/bluebook/capabilities/attribute_values.rb +72 -0
  58. data/lib/hecks/bluebook/capabilities.rb +91 -9
  59. data/lib/hecks/bluebook/domain_port.rb +16 -4
  60. data/lib/hecks/bluebook/dsl/adapter_builder.rb +18 -6
  61. data/lib/hecks/bluebook/dsl/binding_proxy.rb +13 -0
  62. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/computed_sources.rb +98 -0
  63. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/fan_out_rows.rb +42 -0
  64. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +14 -2
  65. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +69 -3
  66. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +17 -10
  67. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +5 -0
  68. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
  69. data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +8 -1
  70. data/lib/hecks/bluebook/dsl/command_builder/operands.rb +121 -0
  71. data/lib/hecks/bluebook/dsl/command_builder.rb +2 -0
  72. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +10 -1
  73. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +45 -2
  74. data/lib/hecks/bluebook/dsl/policy_builder.rb +47 -10
  75. data/lib/hecks/bluebook/dsl/rule_reference.rb +7 -4
  76. data/lib/hecks/bluebook/dsl/world_builder.rb +1 -1
  77. data/lib/hecks/bluebook/expression/ast_json/emitters.rb +6 -0
  78. data/lib/hecks/bluebook/expression/ast_json.rb +9 -6
  79. data/lib/hecks/bluebook/expression/ast_reader.rb +14 -9
  80. data/lib/hecks/bluebook/expression/projection.json +36 -0
  81. data/lib/hecks/bluebook/expression/resolver/operations.rb +31 -0
  82. data/lib/hecks/bluebook/expression/resolver/parsing.rb +38 -5
  83. data/lib/hecks/bluebook/expression/resolver/scanning.rb +22 -5
  84. data/lib/hecks/bluebook/expression/resolver/values.rb +10 -0
  85. data/lib/hecks/bluebook/expression/resolver.rb +20 -1
  86. data/lib/hecks/bluebook/hecksagon.rb +23 -3
  87. data/lib/hecks/bluebook/lifecycle.rb +22 -3
  88. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +13 -1
  89. data/lib/hecks/bluebook/meta_validator/modes.rb +4 -1
  90. data/lib/hecks/bluebook/meta_validator/readings.rb +24 -1
  91. data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +2 -1
  92. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +6 -3
  93. data/lib/hecks/bluebook/meta_validator/shapes.rb +5 -0
  94. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +1 -1
  95. data/lib/hecks/bluebook/meta_validator.rb +12 -12
  96. data/lib/hecks/bluebook/model_check/ask_checks.rb +71 -0
  97. data/lib/hecks/bluebook/model_check/policy_checks.rb +2 -1
  98. data/lib/hecks/bluebook/model_check/reference_checks.rb +70 -0
  99. data/lib/hecks/bluebook/model_check.rb +8 -2
  100. data/lib/hecks/bluebook/policy.rb +4 -2
  101. data/lib/hecks/bluebook/smoke_test.rb +1 -1
  102. data/lib/hecks/bluebook/synthesizer.rb +2 -0
  103. data/lib/hecks/bluebook.rb +2 -0
  104. data/lib/hecks/cli/command_table.rb +1 -1
  105. data/lib/hecks/cli/console.rb +2 -1
  106. data/lib/hecks/cli/document.rb +1 -1
  107. data/lib/hecks/cli/launcher_words.rb +4 -4
  108. data/lib/hecks/cli/mcp.rb +4 -4
  109. data/lib/hecks/cli/project_cli/launcher_source.rb +2 -2
  110. data/lib/hecks/cli/project_cli/templates.rb +5 -5
  111. data/lib/hecks/cli/project_cli.rb +9 -6
  112. data/lib/hecks/cli/run.rb +2 -2
  113. data/lib/hecks/cli/smoke_http/checks.rb +4 -1
  114. data/lib/hecks/cli/smoke_http/transport.rb +3 -3
  115. data/lib/hecks/cli/smoke_http.rb +3 -0
  116. data/lib/hecks/codemod.rb +5 -2
  117. data/lib/hecks/corpus/routes.rb +7 -0
  118. data/lib/hecks/corpus/rust.rb +3 -2
  119. data/lib/hecks/deploy/bluebook/deploy.bluebook +34 -4
  120. data/lib/hecks/doc/reference/rendering.rb +6 -3
  121. data/lib/hecks/forms/app/commands.rb +8 -7
  122. data/lib/hecks/forms/app/queries.rb +2 -1
  123. data/lib/hecks/forms/app.rb +1 -1
  124. data/lib/hecks/forms/record_renderer.rb +1 -1
  125. data/lib/hecks/framework/bluebook/privacy.bluebook +11 -0
  126. data/lib/hecks/fuzzing/concurrent_dispatch.rb +4 -1
  127. data/lib/hecks/fuzzing/failure_triage.rb +2 -1
  128. data/lib/hecks/fuzzing/mutation/run.rb +11 -4
  129. data/lib/hecks/fuzzing/properties/catalog.rb +6 -4
  130. data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +18 -11
  131. data/lib/hecks/fuzzing/properties/guards.rb +1 -1
  132. data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +1 -1
  133. data/lib/hecks/fuzzing/self_consistency.rb +6 -2
  134. data/lib/hecks/fuzzing/shrinker.rb +3 -1
  135. data/lib/hecks/fuzzing/value_generator.rb +19 -5
  136. data/lib/hecks/gate/stages.yml +33 -7
  137. data/lib/hecks/grammar/evolve.rb +1 -1
  138. data/lib/hecks/grammar/expression_operators.json +372 -0
  139. data/lib/hecks/grammar/operators.rb +3 -1
  140. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +10 -10
  141. data/lib/hecks/hecks/adapters/codebase/inspection/rubycritic.rb +35 -0
  142. data/lib/hecks/hecks/adapters/codebase/inspection.rb +104 -0
  143. data/lib/hecks/hecks/adapters/codebase/publishing.rb +2 -1
  144. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +12 -2
  145. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +2 -1
  146. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +1 -1
  147. data/lib/hecks/hecks/adapters/cost_explorer.rb +8 -5
  148. data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +2 -1
  149. data/lib/hecks/hecks/adapters/finding_github.rb +13 -6
  150. data/lib/hecks/hecks/adapters/first_admin.rb +2 -2
  151. data/lib/hecks/hecks/adapters/github_rulesets.rb +6 -3
  152. data/lib/hecks/hecks/adapters/in_process_boot.rb +1 -1
  153. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +1 -1
  154. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +10 -20
  155. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +28 -5
  156. data/lib/hecks/hecks/adapters/local_files.rb +2 -2
  157. data/lib/hecks/hecks/adapters/rehearsal/audit_report.rb +107 -0
  158. data/lib/hecks/hecks/adapters/rehearsal/census.rb +71 -0
  159. data/lib/hecks/hecks/adapters/rehearsal/declaration.rb +133 -0
  160. data/lib/hecks/hecks/adapters/rehearsal/environment.rb +83 -0
  161. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +142 -0
  162. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +96 -0
  163. data/lib/hecks/hecks/adapters/rehearsal/postgres_census.rb +100 -0
  164. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +69 -0
  165. data/lib/hecks/hecks/adapters/rehearsal/postgres_store.rb +133 -0
  166. data/lib/hecks/hecks/adapters/rehearsal/rows.rb +41 -0
  167. data/lib/hecks/hecks/adapters/rehearsal/rust_audit.rb +83 -0
  168. data/lib/hecks/hecks/adapters/rehearsal/subject.rb +104 -0
  169. data/lib/hecks/hecks/adapters/rehearsal.rb +54 -0
  170. data/lib/hecks/hecks/adapters/rehearsal_store.adapter +7 -0
  171. data/lib/hecks/hecks/adapters/rehearsal_store.rb +81 -0
  172. data/lib/hecks/hecks/adapters/terminal.rb +13 -11
  173. data/lib/hecks/hecks/codebase.behaviors +13 -1
  174. data/lib/hecks/hecks/codebase.bluebook +239 -5
  175. data/lib/hecks/hecks/custodian.behaviors +24 -6
  176. data/lib/hecks/hecks/custodian.bluebook +6 -1227
  177. data/lib/hecks/hecks/deploy.behaviors +1 -1
  178. data/lib/hecks/hecks/deploy.world +1 -3
  179. data/lib/hecks/hecks/hecks.behaviors +1 -1
  180. data/lib/hecks/hecks/hecks.hecksagon +53 -18
  181. data/lib/hecks/hecks/hecks.world +13 -10
  182. data/lib/hecks/hecks/rehearsal.bluebook +477 -0
  183. data/lib/hecks/hecks/site.behaviors +1 -1
  184. data/lib/hecks/hecks/site.world +0 -1
  185. data/lib/hecks/hecks/tooling.bluebook +1238 -0
  186. data/lib/hecks/indifferent_key.rb +20 -0
  187. data/lib/hecks/language/adapter.bluebook +13 -3
  188. data/lib/hecks/language/bluebook/aggregate.bluebook +23 -0
  189. data/lib/hecks/language/bluebook/bluebook.behaviors +23 -0
  190. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -0
  191. data/lib/hecks/language/bluebook/entity.bluebook +18 -0
  192. data/lib/hecks/language/bluebook/policy.behaviors +19 -0
  193. data/lib/hecks/language/bluebook/policy.bluebook +9 -1
  194. data/lib/hecks/language/bluebook/query.bluebook +1 -1
  195. data/lib/hecks/language/bluebook/vocabulary.bluebook +63 -4
  196. data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -1
  197. data/lib/hecks/language/hecksagon/hecksagon.bluebook +22 -0
  198. data/lib/hecks/language/oidc.json +10 -0
  199. data/lib/hecks/language/port.bluebook +4 -4
  200. data/lib/hecks/literal.rb +12 -3
  201. data/lib/hecks/ports/key_vault.rb +7 -2
  202. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +21 -10
  203. data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +4 -2
  204. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +2 -1
  205. data/lib/hecks/ports/persistence/repository_factory.rb +6 -3
  206. data/lib/hecks/projection_files/expression_tables.rb +7 -2
  207. data/lib/hecks/projections/deploy/box/compose.rb +6 -4
  208. data/lib/hecks/projections/deploy/box/edge.rb +62 -0
  209. data/lib/hecks/projections/deploy/box/logging.rb +99 -0
  210. data/lib/hecks/projections/deploy/box/roll_scripts.rb +16 -8
  211. data/lib/hecks/projections/deploy/box/settings/cdn.rb +40 -0
  212. data/lib/hecks/projections/deploy/box/settings/logs.rb +40 -0
  213. data/lib/hecks/projections/deploy/box/settings/patterns.rb +11 -0
  214. data/lib/hecks/projections/deploy/box/settings/types.rb +16 -1
  215. data/lib/hecks/projections/deploy/box/settings.rb +6 -2
  216. data/lib/hecks/projections/deploy/box/stack_yaml.rb +5 -2
  217. data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +16 -0
  218. data/lib/hecks/projections/deploy/box/templates/box.yaml.tmpl +8 -4
  219. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +32 -0
  220. data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +1 -1
  221. data/lib/hecks/projections/deploy/box/templates/edge.mk.tmpl +17 -0
  222. data/lib/hecks/projections/deploy/box/templates/edge.yaml.tmpl +65 -0
  223. data/lib/hecks/projections/deploy/box/templates/log-group.yaml.tmpl +12 -0
  224. data/lib/hecks/projections/deploy/box/templates/log-policy.yaml.tmpl +7 -0
  225. data/lib/hecks/projections/deploy/box/templates/render-compose-taskdef.sh.tmpl +5 -4
  226. data/lib/hecks/projections/deploy/box/templates/render-compose.sh.tmpl +5 -4
  227. data/lib/hecks/projections/deploy/box.rb +15 -3
  228. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  229. data/lib/hecks/projections/deploy/shared.rb +5 -2
  230. data/lib/hecks/projections/model/deviations.rb +2 -2
  231. data/lib/hecks/projections/model.rb +2 -2
  232. data/lib/hecks/projections/oidc.rb +13 -1
  233. data/lib/hecks/projections/shape.rb +5 -2
  234. data/lib/hecks/projections/site/cms_editor/attributes.rb +26 -6
  235. data/lib/hecks/projections/site/cms_editor/blocks.rb +157 -0
  236. data/lib/hecks/projections/site/cms_editor/checks.rb +14 -1
  237. data/lib/hecks/projections/site/cms_editor/clearing.rb +70 -0
  238. data/lib/hecks/projections/site/cms_editor/color.rb +124 -0
  239. data/lib/hecks/projections/site/cms_editor/composition.rb +42 -0
  240. data/lib/hecks/projections/site/cms_editor/destructive.rb +61 -0
  241. data/lib/hecks/projections/site/cms_editor/drafts.rb +102 -0
  242. data/lib/hecks/projections/site/cms_editor/hints.rb +74 -0
  243. data/lib/hecks/projections/site/cms_editor/icons.rb +86 -0
  244. data/lib/hecks/projections/site/cms_editor/key_kinds.rb +31 -0
  245. data/lib/hecks/projections/site/cms_editor/limits.rb +72 -0
  246. data/lib/hecks/projections/site/cms_editor/media.rb +1 -1
  247. data/lib/hecks/projections/site/cms_editor/moment.rb +34 -0
  248. data/lib/hecks/projections/site/cms_editor/palette.rb +115 -0
  249. data/lib/hecks/projections/site/cms_editor/pickers.rb +85 -0
  250. data/lib/hecks/projections/site/cms_editor/preview.rb +91 -0
  251. data/lib/hecks/projections/site/cms_editor/relations.rb +92 -0
  252. data/lib/hecks/projections/site/cms_editor/scale_checks.rb +66 -0
  253. data/lib/hecks/projections/site/cms_editor/scheduling.rb +150 -0
  254. data/lib/hecks/projections/site/cms_editor/schema.rb +96 -19
  255. data/lib/hecks/projections/site/cms_editor/setting.rb +52 -9
  256. data/lib/hecks/projections/site/cms_editor/targets.rb +86 -0
  257. data/lib/hecks/projections/site/cms_editor/templates/package.json.tmpl +18 -1
  258. data/lib/hecks/projections/site/cms_editor/templates/src/app.ts.tmpl +251 -57
  259. data/lib/hecks/projections/site/cms_editor/templates/src/assets.ts.tmpl +98 -0
  260. data/lib/hecks/projections/site/cms_editor/templates/src/auth/membership.ts.tmpl +32 -24
  261. data/lib/hecks/projections/site/cms_editor/templates/src/browser/app.css.tmpl +412 -0
  262. data/lib/hecks/projections/site/cms_editor/templates/src/browser/autosave.js.tmpl +144 -0
  263. data/lib/hecks/projections/site/cms_editor/templates/src/browser/blocks.js.tmpl +500 -0
  264. data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_doc.js.tmpl +175 -0
  265. data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_editor.js.tmpl +418 -0
  266. data/lib/hecks/projections/site/cms_editor/templates/src/browser/epoch.js.tmpl +61 -0
  267. data/lib/hecks/projections/site/cms_editor/templates/src/browser/forms.js.tmpl +210 -0
  268. data/lib/hecks/projections/site/cms_editor/templates/src/browser/lists.js.tmpl +40 -0
  269. data/lib/hecks/projections/site/cms_editor/templates/src/browser/main.js.tmpl +26 -0
  270. data/lib/hecks/projections/site/cms_editor/templates/src/browser/media_picker.js.tmpl +232 -0
  271. data/lib/hecks/projections/site/cms_editor/templates/src/browser/moments.js.tmpl +73 -0
  272. data/lib/hecks/projections/site/cms_editor/templates/src/browser/pickers.js.tmpl +152 -0
  273. data/lib/hecks/projections/site/cms_editor/templates/src/browser/preview.js.tmpl +98 -0
  274. data/lib/hecks/projections/site/cms_editor/templates/src/browser/shell.js.tmpl +140 -0
  275. data/lib/hecks/projections/site/cms_editor/templates/src/browser/toast.js.tmpl +66 -0
  276. data/lib/hecks/projections/site/cms_editor/templates/src/choices.ts.tmpl +99 -0
  277. data/lib/hecks/projections/site/cms_editor/templates/src/commands.ts.tmpl +78 -24
  278. data/lib/hecks/projections/site/cms_editor/templates/src/config.ts.tmpl +6 -0
  279. data/lib/hecks/projections/site/cms_editor/templates/src/flash.ts.tmpl +52 -0
  280. data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +19 -2
  281. data/lib/hecks/projections/site/cms_editor/templates/src/media/handler.ts.tmpl +31 -8
  282. data/lib/hecks/projections/site/cms_editor/templates/src/names.ts.tmpl +36 -0
  283. data/lib/hecks/projections/site/cms_editor/templates/src/schema.ts.tmpl +131 -2
  284. data/lib/hecks/projections/site/cms_editor/templates/src/ui/availability.ts.tmpl +15 -0
  285. data/lib/hecks/projections/site/cms_editor/templates/src/ui/block_list.js.tmpl +213 -0
  286. data/lib/hecks/projections/site/cms_editor/templates/src/ui/blocks.ts.tmpl +275 -0
  287. data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_model.js.tmpl +8 -5
  288. data/lib/hecks/projections/site/cms_editor/templates/src/ui/detail.ts.tmpl +88 -0
  289. data/lib/hecks/projections/site/cms_editor/templates/src/ui/dialogs.ts.tmpl +43 -0
  290. data/lib/hecks/projections/site/cms_editor/templates/src/ui/fields.ts.tmpl +229 -34
  291. data/lib/hecks/projections/site/cms_editor/templates/src/ui/html.ts.tmpl +40 -81
  292. data/lib/hecks/projections/site/cms_editor/templates/src/ui/icons.ts.tmpl +15 -0
  293. data/lib/hecks/projections/site/cms_editor/templates/src/ui/input.ts.tmpl +29 -12
  294. data/lib/hecks/projections/site/cms_editor/templates/src/ui/links.ts.tmpl +100 -0
  295. data/lib/hecks/projections/site/cms_editor/templates/src/ui/moments.ts.tmpl +44 -0
  296. data/lib/hecks/projections/site/cms_editor/templates/src/ui/outline.ts.tmpl +53 -17
  297. data/lib/hecks/projections/site/cms_editor/templates/src/ui/pages.ts.tmpl +178 -88
  298. data/lib/hecks/projections/site/cms_editor/templates/src/ui/paging.ts.tmpl +82 -0
  299. data/lib/hecks/projections/site/cms_editor/templates/src/ui/pickers.ts.tmpl +110 -0
  300. data/lib/hecks/projections/site/cms_editor/templates/src/ui/preview.ts.tmpl +87 -0
  301. data/lib/hecks/projections/site/cms_editor/templates/src/ui/related.ts.tmpl +97 -0
  302. data/lib/hecks/projections/site/cms_editor/templates/src/ui/schedule.ts.tmpl +160 -0
  303. data/lib/hecks/projections/site/cms_editor/templates/src/ui/shell.ts.tmpl +211 -0
  304. data/lib/hecks/projections/site/cms_editor/templates/src/ui/table.ts.tmpl +151 -0
  305. data/lib/hecks/projections/site/cms_editor/templates/src/ui/theme.js.tmpl +16 -0
  306. data/lib/hecks/projections/site/cms_editor/templates/src/ui/values.ts.tmpl +69 -0
  307. data/lib/hecks/projections/site/cms_editor/templates/src/ui/words.ts.tmpl +97 -0
  308. data/lib/hecks/projections/site/cms_editor/templates/src/ui/world.ts.tmpl +35 -0
  309. data/lib/hecks/projections/site/cms_editor/templates/tsconfig.json.tmpl +2 -1
  310. data/lib/hecks/projections/site/cms_editor/theme.rb +29 -0
  311. data/lib/hecks/projections/site/cms_editor/theme_checks.rb +57 -0
  312. data/lib/hecks/projections/site/cms_editor.rb +49 -23
  313. data/lib/hecks/projections/site/role_probe.rb +2 -0
  314. data/lib/hecks/projections/site/site_root/workflow.rb +5 -0
  315. data/lib/hecks/projector/cli_audience.rb +22 -1
  316. data/lib/hecks/projector/cli_projector/listing.rb +1 -1
  317. data/lib/hecks/projector/cli_projector/option_specs.rb +1 -1
  318. data/lib/hecks/projector/cli_projector/usage.rb +15 -4
  319. data/lib/hecks/projector/docs_projector/closing.rb +1 -1
  320. data/lib/hecks/projector/docs_projector.rb +1 -1
  321. data/lib/hecks/projector/exporter/bindings.rb +40 -10
  322. data/lib/hecks/projector/exporter/capability_values.rb +55 -0
  323. data/lib/hecks/projector/narrate_projector/reactions.rb +1 -1
  324. data/lib/hecks/projector/target.rb +11 -0
  325. data/lib/hecks/projector.rb +32 -5
  326. data/lib/hecks/quality_control/adapters/github_checks.rb +12 -8
  327. data/lib/hecks/quality_control/adapters/github_issues.rb +8 -4
  328. data/lib/hecks/quality_control/cli/qa_open_pr.rb +2 -2
  329. data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +1 -1
  330. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +1 -1
  331. data/lib/hecks/quality_control/cli/qa_sweep.rb +1 -1
  332. data/lib/hecks/quality_control/quality_control.bluebook +6 -2
  333. data/lib/hecks/release/approval.rb +64 -0
  334. data/lib/hecks/router/{door.rb → aggregate_reader.rb} +5 -4
  335. data/lib/hecks/router/namespace_installer.rb +16 -16
  336. data/lib/hecks/router.rb +1 -1
  337. data/lib/hecks/runtime/best_effort.rb +22 -0
  338. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -2
  339. data/lib/hecks/runtime/command_interpreter.rb +3 -2
  340. data/lib/hecks/runtime/command_rules/emission.rb +1 -1
  341. data/lib/hecks/runtime/dispatcher.rb +4 -4
  342. data/lib/hecks/runtime/entity_element/location.rb +1 -1
  343. data/lib/hecks/runtime/event.rb +5 -0
  344. data/lib/hecks/runtime/identity.rb +7 -6
  345. data/lib/hecks/runtime/interpreting.rb +2 -1
  346. data/lib/hecks/runtime/invocation_builder.rb +1 -1
  347. data/lib/hecks/runtime/loader/boot_steps.rb +8 -5
  348. data/lib/hecks/runtime/loader.rb +10 -10
  349. data/lib/hecks/runtime/policy_interpreter/arguments.rb +7 -4
  350. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +3 -3
  351. data/lib/hecks/runtime/policy_interpreter.rb +6 -6
  352. data/lib/hecks/runtime/port_operation_interpreter.rb +1 -1
  353. data/lib/hecks/runtime/reaction_invocation.rb +1 -1
  354. data/lib/hecks/runtime/rebuild_sweep.rb +11 -1
  355. data/lib/hecks/runtime/registry/ask_verification.rb +35 -0
  356. data/lib/hecks/runtime/registry/hecksagon_rules.rb +10 -0
  357. data/lib/hecks/runtime/registry/merging.rb +1 -1
  358. data/lib/hecks/runtime/registry/providers.rb +16 -0
  359. data/lib/hecks/runtime/registry/read_repository.rb +6 -4
  360. data/lib/hecks/runtime/registry/verification.rb +4 -1
  361. data/lib/hecks/runtime/registry/world_defaults.rb +29 -0
  362. data/lib/hecks/runtime/registry.rb +1 -1
  363. data/lib/hecks/runtime/saga_interpreter/compensation.rb +1 -1
  364. data/lib/hecks/runtime/saga_interpreter/delivery.rb +4 -4
  365. data/lib/hecks/runtime/saga_interpreter/transitions.rb +1 -1
  366. data/lib/hecks/runtime/saga_interpreter.rb +3 -3
  367. data/lib/hecks/runtime/tenant_check.rb +5 -4
  368. data/lib/hecks/runtime/value/coercion.rb +2 -2
  369. data/lib/hecks/runtime/value/validation.rb +16 -4
  370. data/lib/hecks/runtime.rb +9 -9
  371. data/lib/hecks/rust_build/host.rb +11 -4
  372. data/lib/hecks/rust_build/prebuilt_binary.rb +101 -0
  373. data/lib/hecks/rust_build/project_rust/target_ir.rb +1 -1
  374. data/lib/hecks/rust_build/wasm.rb +1 -1
  375. data/lib/hecks/rust_build/wasm_browser.rb +1 -1
  376. data/lib/hecks/rust_build.rb +11 -0
  377. data/lib/hecks/served_options.rb +53 -0
  378. data/lib/hecks/site/bluebook/site.bluebook +1 -0
  379. data/lib/hecks/storehouse/audit.rb +1 -1
  380. data/lib/hecks/storehouse/dispatching.rb +8 -6
  381. data/lib/hecks/storehouse/introspection.rb +2 -2
  382. data/lib/hecks/storehouse/querying.rb +6 -4
  383. data/lib/hecks/storehouse.rb +4 -4
  384. data/lib/hecks/tools/ci_gate_decision.rb +35 -0
  385. data/lib/hecks/tools/ci_gates.rb +20 -1
  386. data/lib/hecks/tools/comment_style/source_file.rb +4 -1
  387. data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +4 -1
  388. data/lib/hecks/tools/lanes/files.rb +8 -0
  389. data/lib/hecks/tools/lanes/prebuilt_workflow.rb +81 -0
  390. data/lib/hecks/tools/lanes/rows.rb +6 -0
  391. data/lib/hecks/tools/lanes.rb +1 -0
  392. data/lib/hecks/tools/oidc_manifests.rb +4 -5
  393. data/lib/hecks/tools/regeneration_run.rb +11 -4
  394. data/lib/hecks/tools/release_only.rb +111 -0
  395. data/lib/hecks/tools/site_routes/editor_files.rb +12 -5
  396. data/lib/hecks/tools/tenant_provisioning.rb +2 -2
  397. data/lib/hecks/tools/tools_doc.rb +4 -4
  398. data/lib/hecks/version.rb +1 -1
  399. data/lib/hecks/vocabulary.rb +19 -5
  400. data/lib/hecks.rb +15 -15
  401. data/lib/rubocop/cop/hecks/env_dump.rb +69 -0
  402. data/lib/rubocop/cop/hecks/monotonic_duration.rb +53 -0
  403. data/lib/rubocop/cop/hecks/no_wall_clock_in_runtime.rb +34 -0
  404. data/lib/rubocop/cop/hecks/raw_shell_interpolation.rb +79 -0
  405. data/lib/rubocop/cop/hecks/sleep_in_spec.rb +34 -0
  406. data/lib/rubocop/cop/hecks/swallowed_rescue.rb +37 -0
  407. data/lib/rubocop/cop/hecks/symbol_string_key_mix.rb +50 -0
  408. data/lib/rubocop/cop/hecks/untyped_raise.rb +37 -0
  409. data/prebuilt/9ee54e2f0d4d6d3fe046827779b221e02de665fba911a048ae5dd8b8fbfb7d90.marshal +0 -0
  410. data/prebuilt/d74a00e996222c1d8b676d5959092effc46b4dc59e0555f3bf9554ac58e3094a.marshal +0 -0
  411. data/prebuilt/verdicts-df19f35868d3284a70f55e42dcef87ef4e65e6a678e5135f72e1f6cff4c1357b.json +1 -0
  412. data/rust/.gitignore +6 -0
  413. data/rust/Cargo.toml +6 -0
  414. data/rust/build/src/binding_pass.rs +103 -0
  415. data/rust/build/src/cargo_sync.rs +6 -0
  416. data/rust/build/src/lineage_pass.rs +3 -3
  417. data/rust/build/src/main.rs +17 -5
  418. data/rust/build/src/pipeline.rs +48 -5
  419. data/rust/build/src/seams_pass.rs +123 -0
  420. data/rust/build/src/translation_pass.rs +167 -0
  421. data/rust/codegen/src/asks.rs +103 -0
  422. data/rust/codegen/src/commands.rs +13 -8
  423. data/rust/codegen/src/constraints.rs +25 -0
  424. data/rust/codegen/src/domain_generator.rs +2 -0
  425. data/rust/codegen/src/expr_emitter.rs +13 -0
  426. data/rust/codegen/src/json_codec.rs +54 -15
  427. data/rust/codegen/src/main.rs +1 -0
  428. data/rust/codegen/src/mutations.rs +128 -3
  429. data/rust/codegen/src/queries.rs +11 -2
  430. data/rust/codegen/src/reactions.rs +1 -1
  431. data/rust/codegen/src/types.rs +166 -8
  432. data/rust/host/HECKS_RELEASE +1 -1
  433. data/rust/host/src/api.rs +4 -4
  434. data/rust/host/src/bin/validate_harness.rs +43 -0
  435. data/rust/host/src/boundary_fuzz/expr_json.rs +2 -2
  436. data/rust/host/src/boundary_fuzz/ir.rs +1 -0
  437. data/rust/host/src/boundary_fuzz/server.rs +1 -1
  438. data/rust/host/src/checkout.rs +35 -19
  439. data/rust/host/src/commerce_ir.rs +408 -2
  440. data/rust/host/src/expr_json.rs +118 -0
  441. data/rust/host/src/extension.rs +13 -1
  442. data/rust/host/src/lib.rs +1 -0
  443. data/rust/host/src/mint.rs +1 -1
  444. data/rust/host/src/payments/tests.rs +27 -1
  445. data/rust/host/src/payments.rs +12 -4
  446. data/rust/host/src/platform_signin/attack_tests.rs +1100 -0
  447. data/rust/host/src/platform_signin/config.rs +512 -0
  448. data/rust/host/src/platform_signin/cookie.rs +237 -0
  449. data/rust/host/src/platform_signin/extension.rs +190 -0
  450. data/rust/host/src/platform_signin/fetcher.rs +322 -0
  451. data/rust/host/src/platform_signin/handler.rs +251 -0
  452. data/rust/host/src/platform_signin/handler_tests.rs +554 -0
  453. data/rust/host/src/platform_signin/jti.rs +196 -0
  454. data/rust/host/src/platform_signin/jwks.rs +542 -0
  455. data/rust/host/src/platform_signin/jws.rs +249 -0
  456. data/rust/host/src/platform_signin/known_answer_tests.rs +237 -0
  457. data/rust/host/src/platform_signin/mapping_tests.rs +254 -0
  458. data/rust/host/src/platform_signin/mod.rs +75 -0
  459. data/rust/host/src/platform_signin/mode_tests.rs +382 -0
  460. data/rust/host/src/platform_signin/pages.rs +204 -0
  461. data/rust/host/src/platform_signin/query.rs +233 -0
  462. data/rust/host/src/platform_signin/session.rs +151 -0
  463. data/rust/host/src/platform_signin/settings.rs +385 -0
  464. data/rust/host/src/platform_signin/strict_json.rs +351 -0
  465. data/rust/host/src/platform_signin/test_support.rs +235 -0
  466. data/rust/host/src/platform_signin/ttl_tests.rs +94 -0
  467. data/rust/host/src/platform_signin/verify.rs +604 -0
  468. data/rust/host/src/platform_signin/wiring_support.rs +319 -0
  469. data/rust/host/src/query_step.rs +22 -4
  470. data/rust/host/src/reference_validate.rs +653 -108
  471. data/rust/host/src/resend.rs +2 -0
  472. data/rust/host/src/server.rs +19 -6
  473. data/rust/host/src/ui_schema.rs +132 -5
  474. data/rust/host/src/web/newsletter.rs +7 -8
  475. data/rust/host/src/web/newsletter_send.rs +38 -13
  476. data/rust/host/src/web/registrations.rs +229 -26
  477. data/rust/host/src/web.rs +53 -9
  478. data/rust/parser/src/emit.rs +38 -6
  479. data/rust/parser/src/expr/ast_json.rs +7 -1
  480. data/rust/parser/src/expr/resolver.rs +171 -6
  481. data/rust/parser/src/ir.rs +7 -0
  482. data/rust/parser/src/keywords.rs +24 -0
  483. data/rust/parser/src/main.rs +3 -0
  484. data/rust/parser/src/parse/aggregate.rs +2 -1
  485. data/rust/parser/src/parse/chapter.rs +2 -2
  486. data/rust/parser/src/parse/command.rs +2 -0
  487. data/rust/parser/src/parse/hecksagon.rs +5 -2
  488. data/rust/parser/src/parse/lifecycle.rs +81 -0
  489. data/rust/parser/src/parse/mod.rs +15 -1
  490. data/rust/parser/src/parse/policy.rs +13 -2
  491. data/rust/parser/src/parse/value_object.rs +34 -17
  492. data/rust/parser/src/ruby_value.rs +1 -1
  493. data/rust/src/exemplar/commands.rs +4 -4
  494. data/rust/src/exemplar/constraints.rs +1 -1
  495. data/rust/src/exemplar/json.rs +43 -1
  496. data/rust/src/kernel/cli.rs +7 -5
  497. data/rust/src/kernel/dispatch.rs +2 -2
  498. data/rust/src/kernel/dispatch_guard_tests.rs +1 -1
  499. data/rust/src/kernel/expr.rs +66 -3
  500. data/rust/src/kernel/expression_operators/arithmetic.rs +130 -5
  501. data/rust/src/kernel/expression_operators/text.rs +26 -2
  502. data/rust/src/kernel/json.rs +15 -0
  503. data/rust/src/kernel/mod.rs +1 -1
  504. data/rust/src/kernel/orchestrate.rs +54 -5
  505. data/rust/src/kernel/orchestrate_guard_tests.rs +67 -0
  506. data/rust/src/kernel/pattern.rs +60 -0
  507. data/rust/src/kernel/reference_lookup.rs +90 -7
  508. metadata +178 -38
  509. data/lib/hecks/doors/cli_door/nesting.rb +0 -34
  510. data/lib/hecks/doors/cli_door/shorthand.rb +0 -85
  511. data/lib/hecks/doors/cli_door.rb +0 -124
  512. data/lib/hecks/doors/cli_runner/answers.rb +0 -138
  513. data/lib/hecks/doors/cli_runner/resolution.rb +0 -146
  514. data/lib/hecks/doors/cli_runner/settling.rb +0 -115
  515. data/lib/hecks/doors/cli_runner/streaming.rb +0 -90
  516. data/lib/hecks/doors/cli_runner/suggestions.rb +0 -43
  517. data/lib/hecks/doors/cli_runner.rb +0 -66
  518. data/lib/hecks/doors/command_request.rb +0 -119
  519. data/lib/hecks/doors/handle.rb +0 -208
  520. data/lib/hecks/doors/json_door.rb +0 -132
  521. data/lib/hecks/doors/launcher_options.rb +0 -247
  522. data/lib/hecks/doors/mcp_door/properties.rb +0 -47
  523. data/lib/hecks/doors/mcp_door/tool_calls.rb +0 -113
  524. data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +0 -51
  525. data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +0 -69
  526. data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +0 -97
  527. data/lib/hecks/doors/mcp_door/tool_definitions.rb +0 -15
  528. data/lib/hecks/doors/mcp_door.rb +0 -156
  529. data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +0 -92
  530. data/lib/hecks/doors/mcp_door_scope/env_problems.rb +0 -55
  531. data/lib/hecks/doors/mcp_door_scope/presenter.rb +0 -78
  532. data/lib/hecks/doors/mcp_door_scope.rb +0 -201
  533. data/lib/hecks/doors/mcp_guide_cache.rb +0 -75
  534. data/lib/hecks/doors/ruby_door/aggregate_door.rb +0 -162
  535. data/lib/hecks/doors/ruby_door/chapter.rb +0 -89
  536. data/lib/hecks/doors/ruby_door.rb +0 -80
  537. data/lib/hecks/doors/usage_cache.rb +0 -139
  538. data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_widget.js.tmpl +0 -282
  539. data/lib/hecks/projections/site/cms_editor/templates/src/ui/media_picker.js.tmpl +0 -109
  540. data/prebuilt/c28d6d9db14eea3e17161e9d9c262efee30b256cf97693a7cfd552bce24b2f7f.marshal +0 -0
  541. data/prebuilt/cb375cba61ca0dbe8ddb9739c306510fe05e5f4b7a9b6955caff8224c63ea0e0.marshal +0 -0
  542. data/prebuilt/verdicts-d6d584ad43b5f3cebf88aafbbdbf024c38574acf18e06adffbc555f7786b1c2f.json +0 -1
@@ -1,7 +1,7 @@
1
1
  Hecks.behaviors "Deploy" do
2
2
  vision "A recipe, a lint, a comparison or a projection is recorded as requested before anything outside is asked."
3
3
 
4
- loads "hecks.bluebook", "custodian.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "deploy.world", "environments/memory.world"
4
+ loads "hecks.bluebook", "custodian.bluebook", "tooling.bluebook", "rehearsal.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "deploy.world", "environments/memory.world"
5
5
 
6
6
  test "Project keeps a domain that has no world file as a faulted recipe" do
7
7
  tests "Project", on: "Recipe"
@@ -6,7 +6,5 @@
6
6
  # `run_keys` mints the `run` key of a recipe, a lint, a comparison or a manifest projection, and
7
7
  # `--wait` reports a faulted, flagged, drifted or refused run as exit 1.
8
8
  Hecks.world "Deploy" do
9
- launcher "Launcher", run_keys: true,
10
- failure_states: %w[flagged failed drifted unreachable refused faulted halted stopped
11
- abandoned red needs_fix]
9
+ launcher "Launcher", run_keys: true
12
10
  end
@@ -1,7 +1,7 @@
1
1
  Hecks.behaviors "Hecks" do
2
2
  vision "A release moves tagged, published, verified; the grammar cache moves fresh, stale, fresh."
3
3
 
4
- loads "hecks.bluebook", "custodian.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "environments/memory.world"
4
+ loads "hecks.bluebook", "custodian.bluebook", "tooling.bluebook", "rehearsal.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "environments/memory.world"
5
5
 
6
6
  test "Tag records a version as tagged" do
7
7
  tests "Tag", on: "Release"
@@ -108,31 +108,31 @@ Hecks.hecksagon "Hecks" do
108
108
  answers_query "Digest"
109
109
  end
110
110
 
111
- Hecks::Door.port "Workspace" do
112
- asks "Write", to: Door do
113
- attribute :run, DoorKey
114
- answers "DoorAnswered"
115
- refuses "DoorRefused"
111
+ Hecks::Launch.port "Workspace" do
112
+ asks "Write", to: Launch do
113
+ attribute :run, LaunchKey
114
+ answers "LaunchAnswered"
115
+ refuses "LaunchRefused"
116
116
  end
117
117
 
118
- asks "Scaffold", to: Door do
119
- attribute :run, DoorKey
120
- answers "DoorAnswered"
121
- refuses "DoorRefused"
118
+ asks "Scaffold", to: Launch do
119
+ attribute :run, LaunchKey
120
+ answers "LaunchAnswered"
121
+ refuses "LaunchRefused"
122
122
  end
123
123
  end
124
124
 
125
- Hecks::Door.port "Terminal" do
126
- asks "Serve", to: Door do
127
- attribute :run, DoorKey
128
- answers "DoorAnswered"
129
- refuses "DoorRefused"
125
+ Hecks::Launch.port "Terminal" do
126
+ asks "Serve", to: Launch do
127
+ attribute :run, LaunchKey
128
+ answers "LaunchAnswered"
129
+ refuses "LaunchRefused"
130
130
  end
131
131
 
132
- asks "Converse", to: Door do
133
- attribute :run, DoorKey
134
- answers "DoorAnswered"
135
- refuses "DoorRefused"
132
+ asks "Converse", to: Launch do
133
+ attribute :run, LaunchKey
134
+ answers "LaunchAnswered"
135
+ refuses "LaunchRefused"
136
136
  end
137
137
  end
138
138
 
@@ -303,6 +303,20 @@ Hecks.hecksagon "Hecks" do
303
303
  answers_query "ReportRustComments"
304
304
  end
305
305
 
306
+ Hecks::InspectionRun.port "SourceTree" do
307
+ asks "Examine", to: InspectionRun do
308
+ attribute :run, RunKey
309
+ answers "InspectionExamined"
310
+ refuses "InspectionRefused"
311
+ end
312
+
313
+ asks "Perform", to: InspectionRun do
314
+ attribute :run, RunKey
315
+ answers "InspectionAnswered"
316
+ refuses "InspectionRefused"
317
+ end
318
+ end
319
+
306
320
  Hecks::CodemodRun.port "SourceTree" do
307
321
  asks "Examine", to: CodemodRun do
308
322
  attribute :run, RunKey
@@ -386,6 +400,27 @@ Hecks.hecksagon "Hecks" do
386
400
  end
387
401
  end
388
402
 
403
+ # Rehearsal: what a client's domain does against a copy of its data. A rehearsal keeps nothing,
404
+ # so the aggregate is bound to Memory whatever the world's default adapter is, and its report is
405
+ # what the caller is handed. The RehearsalStore port is the copy the subject's own `.world`
406
+ # names (`rehearsed_by`): asking it to survey prepares the copy and loads the domain against
407
+ # it, asking it to examine runs the mint's audit over it and drops it. No era is written.
408
+ Hecks::RehearsalRun.persisted_by("Memory")
409
+
410
+ Hecks::RehearsalRun.port "RehearsalStore" do
411
+ asks "Survey", to: RehearsalRun do
412
+ attribute :run, RunKey
413
+ answers "StoreSurveyed"
414
+ refuses "StoreRefused"
415
+ end
416
+
417
+ asks "Examine", to: RehearsalRun do
418
+ attribute :run, RunKey
419
+ answers "StoreExamined"
420
+ refuses "ExamineRefused"
421
+ end
422
+ end
423
+
389
424
  # Deploy, attached above: its bluebook loads without deploy.hecksagon, so the outside its
390
425
  # commands reach is named here as well. TenantProvisioning writes a tenant's overlay world;
391
426
  # DeployToolchain generates and checks a recipe and projects the OIDC manifests.
@@ -22,12 +22,13 @@
22
22
  # edge is written only when such a change is made.
23
23
  #
24
24
  # **launcher** switches on the opt-in parts of the generated `hecks` launcher (see
25
- # `Doors::LauncherOptions`): `run_keys` mints a `run` key for a creating command given none,
26
- # `failure_states` are the lifecycle states `--wait` reports as exit 1 (every failure state the
27
- # chapter's lifecycles declare), `names` gives a command the launcher name clients type,
25
+ # `Adapters::Driving::LauncherOptions`): `run_keys` mints a `run` key for a creating command given none,
26
+ # `names` gives a command the launcher name clients type,
28
27
  # `settled` names the commands that always wait for their reactions, as if `--wait` were given, so a
29
28
  # refusal is an exit status and a reason on standard error (`package.vendor`, which a script runs
30
- # for its outcome), `executable` is where `hecks project_cli` writes this chapter's launcher (the
29
+ # for its outcome), `unknown_runs` names the questions about one run that refuse a run the process
30
+ # does not hold, as unknown, not as an empty list (`rehearsal_run.rehearsal_outcome`: a run is kept
31
+ # by the process that made it, so `request` waits and prints the whole outcome), `executable` is where `hecks project_cli` writes this chapter's launcher (the
31
32
  # gem's `exe/hecks`), `streams` lists the questions `--stream` may tail (`Follow`), `memory_commands` names
32
33
  # the commands that launcher runs on the Memory environment unless `HECKS_ENVIRONMENT` is set (so
33
34
  # `hecks console` needs no database), and `legacy` names the commands it hands to `Hecks::CLI` in the
@@ -35,29 +36,31 @@
35
36
  # checkout runs (Codebase, and releasing hecks itself): the help leaves them out anywhere else and
36
37
  # `--maintainer` lists them; `chapters` names the attached chapters the help points at, one line each
37
38
  # (`hecks deploy`), and `maintainer_chapters` the language's own, added inside a checkout.
39
+ # `newcomer` names the only commands the help lists in a folder holding no bluebook yet
40
+ # (`hecks --all` lists the rest), so a first run shows how to start and nothing else.
38
41
  Hecks.world "Hecks" do
39
42
  realm "Hecks"
40
43
  default_adapter "PostgresEra"
41
44
  default_database ENV.fetch("HECKS_DATABASE", "postgres://hecks@localhost/hecks")
42
45
  launcher "Launcher", run_keys: true,
43
- failure_states: %w[flagged failed drifted unreachable refused faulted halted stopped
44
- abandoned red needs_fix],
45
46
  settled: %w[package.vendor package.revendor package.release
46
47
  operation.bootstrap_admin smoke_run.run
47
48
  service_roll.run box_roll.run data_copy.restore
48
49
  data_copy.verify bluebook_diff.run preview_run.name
49
50
  preview_run.url preview_run.list preview_run.deploy
50
51
  preview_run.destroy preview_run.login companion_roll.run
51
- handover.clear],
52
- names: { "mcp" => "door.serve_mcp", "console" => "operation.open_console", "init" => "door.init",
53
- "interview" => "door.interview", "package.check" => "registry.check",
52
+ handover.clear rehearsal_run.request],
53
+ unknown_runs: %w[rehearsal_run.rehearsal_outcome],
54
+ names: { "mcp" => "launch.serve_mcp", "console" => "operation.open_console", "init" => "launch.init",
55
+ "interview" => "launch.interview", "package.check" => "registry.check",
54
56
  "package.digest" => "registry.digest",
55
57
  "package.release" => "registry.release" },
56
58
  streams: %w[Follow],
57
59
  executable: "exe/hecks",
58
- maintainer: %w[LanguageRun KernelRun ConformanceRun RegenerationRun GateRun StyleRun
60
+ maintainer: %w[LanguageRun KernelRun ConformanceRun RegenerationRun GateRun StyleRun InspectionRun
59
61
  CodemodRun TestSuiteRun CorpusRun PublishingRun PromotionRun Release
60
62
  SyntaxBootCache],
63
+ newcomer: %w[launch.init launch.interview operation.open_console],
61
64
  chapters: %w[Deploy Governance Tenancy Site Tickets QualityControl],
62
65
  maintainer_chapters: %w[Bluebook Hecksagon World Adapter Port Translation Expression],
63
66
  memory_commands: %w[console init interview],
@@ -0,0 +1,477 @@
1
+ Hecks.bluebook "Hecks" do
2
+ # Rehearsal: operating a domain, in the Operations module (ADR 0096). Whether a domain at a pin
3
+ # would mint its next era against a copy of its real data, and what the mint would refuse.
4
+ #
5
+ # A rehearsal is a run like the Codebase `*Run`s: it is requested, the outside is asked, and the
6
+ # facts it brought back are judged by the givens and reactions below. It differs from them in
7
+ # two ways. It acts on a client's domain, not on this checkout, so it needs no hecks checkout
8
+ # and sits with Custodian, not Codebase. And it keeps nothing: the aggregate is bound to Memory
9
+ # in hecks.hecksagon, and what it found is its report, returned to the caller.
10
+ #
11
+ # Where the data it reads comes from is the subject's own `.world` (`rehearsed_by`), never an
12
+ # argument. The RehearsalStore port prepares that copy, loads the domain against it, runs the
13
+ # mint's audit over it without writing an era, and drops it, so the copy never outlives the run
14
+ # whichever way the chain of reactions ends.
15
+
16
+ aggregate "RehearsalRun" do
17
+ description "One rehearsal of a domain's next era against a copy of its data: what a mint would do, and what it would refuse."
18
+
19
+ attribute :run, RunKey
20
+ attribute :domain, DomainPath
21
+ attribute :pin, Pin, optional: true
22
+ attribute :host_version, HostVersion, optional: true
23
+ attribute :store, StoreKind, optional: true
24
+ attribute :mode, StoreMode, optional: true
25
+ attribute :environment_loaded, EnvironmentLoaded, optional: true
26
+ attribute :schema_used, SchemaRead, optional: true
27
+ attribute :eras_held, Count, optional: true
28
+ attribute :journal_entries, Count, optional: true
29
+ attribute :head_rows, Count, optional: true
30
+ attribute :census, list_of(HeldCount), optional: true
31
+ attribute :copy_empty, Switch, optional: true
32
+ attribute :copy_note, Report, optional: true
33
+ attribute :booted, Switch, optional: true
34
+ attribute :before, ShapeLabel, optional: true
35
+ attribute :after, ShapeLabel, optional: true
36
+ attribute :minting, Minting, optional: true
37
+ attribute :edge_present, Switch, optional: true
38
+ attribute :edge_approved, Switch, optional: true
39
+ attribute :refused_rows, list_of(RefusedRow), optional: true
40
+ attribute :refusal_total, Count, optional: true
41
+ attribute :audited, Switch, optional: true
42
+ attribute :rows_examined, Count, optional: true
43
+ attribute :rust_rows_examined, Count, optional: true
44
+ attribute :aggregates_examined, Count, optional: true
45
+ attribute :reason, Report, optional: true
46
+ attribute :parity, Parity, optional: true
47
+ attribute :unchecked, list_of(Limit), optional: true
48
+ attribute :verdict, Verdict, optional: true
49
+ attribute :released, Switch, optional: true
50
+ attribute :kept, Report, optional: true
51
+ attribute :boot_error, Report, optional: true
52
+ attribute :refusal, Report, optional: true
53
+ identified_by :run
54
+
55
+ value_object "RunKey" do
56
+ attribute :value, String, pattern: '[^ \t\n\r]'
57
+
58
+ invariant("a rehearsal is named") { !value.to_s.empty? }
59
+ end
60
+
61
+ # The domain's directory: where its bluebooks and its `.world` stand.
62
+ value_object "DomainPath" do
63
+ attribute :value, String, pattern: '[^\t\n\r]'
64
+ end
65
+
66
+ # The Hecks the rehearsal must run on: a release (`3.9.0`) or a commit, whole or a prefix.
67
+ value_object "Pin" do
68
+ attribute :value, String, pattern: '^[0-9a-f]{7,40}$|^[0-9]+[.][0-9]+[.][0-9]+'
69
+ end
70
+
71
+ value_object "HostVersion" do
72
+ attribute :value, String, pattern: '[^ \t\n\r]'
73
+ end
74
+
75
+ # Which strategy the subject's world named for the copy of its data.
76
+ value_object "StoreKind" do
77
+ attribute :value, String, one_of: ["memory", "postgres"]
78
+
79
+ invariant("a store is one the language names") { ["memory", "postgres"].include?(value) }
80
+ end
81
+
82
+ # What the copy holds: nothing, a restored dump, or a copy somebody else made, read as it is.
83
+ value_object "StoreMode" do
84
+ attribute :value, String, one_of: ["empty", "dump", "readonly_copy"]
85
+
86
+ invariant("a mode is empty, dump or readonly_copy") { ["empty", "dump", "readonly_copy"].include?(value) }
87
+ end
88
+
89
+ # The environment overlay the subject was loaded under and where that was decided: `world`
90
+ # (its `rehearsed_by` named one), `HECKS_PROJECT_ENVIRONMENT`, `default` (production, because
91
+ # its overlay exists, as the host build does) or `none`. A domain's binds are usually declared
92
+ # in that overlay, so a rehearsal that loaded another one rehearsed another domain.
93
+ value_object "EnvironmentLoaded" do
94
+ attribute :name, String
95
+ attribute :source, String, pattern: '^(world|HECKS_PROJECT_ENVIRONMENT|default|none)$'
96
+ attribute :file, String
97
+ end
98
+
99
+ # The Postgres schema the copy was read in, where that was decided (`world`, `HECKS_SCHEMA`,
100
+ # `derived` from the domain's name, `default` public, or `memory` for a document) and whether
101
+ # the copy has it.
102
+ value_object "SchemaRead" do
103
+ attribute :name, String
104
+ attribute :source, String, pattern: '^(world|HECKS_SCHEMA|derived|default|memory)$'
105
+ attribute :present, Boolean
106
+ end
107
+
108
+ # One aggregate's rows in the copy: what its head table holds and the records its journal's
109
+ # latest entries hold. The audit reads the journal, so a difference is shown, not refused.
110
+ value_object "HeldCount" do
111
+ attribute :aggregate, String
112
+ attribute :head, Integer
113
+ attribute :journal, Integer
114
+ end
115
+
116
+ value_object "Switch" do
117
+ attribute :value, Boolean
118
+ end
119
+
120
+ value_object "Count" do
121
+ attribute :value, Integer
122
+
123
+ invariant("a count is not negative") { value >= 0 }
124
+ end
125
+
126
+ # The first six hex digits of a storage shape's digest, or `none` when no era is held.
127
+ value_object "ShapeLabel" do
128
+ attribute :value, String, pattern: '^[0-9a-f]{6}$|^none$'
129
+ end
130
+
131
+ # Which era a mint would hold: none (the shape stands), the first, or the next.
132
+ value_object "Minting" do
133
+ attribute :value, String, one_of: ["none", "first", "next"]
134
+
135
+ invariant("a mint is none, first or next") { ["none", "first", "next"].include?(value) }
136
+ end
137
+
138
+ # One stored record the mint's audit would refuse, named `Aggregate#id`, with the rule that
139
+ # refused it (a value the new types or invariants refuse, a state the lifecycle never reaches,
140
+ # a reference the edge cannot carry) and the audit's own wording.
141
+ value_object "RefusedRow" do
142
+ attribute :aggregate, String
143
+ attribute :id, String
144
+ attribute :rule, String, pattern: '^(value|lifecycle|reference)$'
145
+ attribute :wording, String
146
+ end
147
+
148
+ # How the other engine's audit stood: not run, in agreement with this one, or not.
149
+ value_object "Parity" do
150
+ attribute :engine, String
151
+ attribute :status, String, pattern: '^(not_run|agree|differ)$'
152
+ attribute :note, String
153
+ end
154
+
155
+ # One thing a rehearsal did not check, and why. A rehearsal states its limits.
156
+ value_object "Limit" do
157
+ attribute :what, String
158
+ attribute :why, String
159
+ end
160
+
161
+ # The five things a rehearsal can conclude. A would_mint of `minting: none` says the shape
162
+ # stands and nothing would be minted at all. `empty_copy` says the copy held no row of the
163
+ # domain, so nothing was rehearsed and no answer about the data is given.
164
+ value_object "Verdict" do
165
+ attribute :value, String, one_of: ["would_mint", "would_refuse", "needs_edge", "cannot_boot", "empty_copy"]
166
+
167
+ invariant("a verdict is one the rehearsal names") do
168
+ ["would_mint", "would_refuse", "needs_edge", "cannot_boot", "empty_copy"].include?(value)
169
+ end
170
+ end
171
+
172
+ value_object "Report" do
173
+ attribute :value, String
174
+ end
175
+
176
+ # Only the first rows are held, so a domain with a million stale rows is a report, not a
177
+ # flood; the total says how many there were.
178
+ invariant("no more than fifty refused rows are held") { refused_rows.unset? || refused_rows.size <= 50 }
179
+ invariant("the total counts at least the rows held") do
180
+ refused_rows.unset? || refusal_total.unset? || refusal_total.value >= refused_rows.size
181
+ end
182
+ invariant("a rehearsal that would mint holds no refused row") do
183
+ verdict.unset? || verdict.value != "would_mint" || refusal_total.unset? || refusal_total.value == 0
184
+ end
185
+ invariant("only a domain that booted would mint") do
186
+ verdict.unset? || verdict.value != "would_mint" || booted.unset? || booted.value
187
+ end
188
+ invariant("a copy that holds nothing is never judged to mint") do
189
+ verdict.unset? || verdict.value != "would_mint" || copy_empty.unset? || !copy_empty.value
190
+ end
191
+ invariant("an empty_copy verdict is given for a copy that holds nothing") do
192
+ verdict.unset? || verdict.value != "empty_copy" || (!copy_empty.unset? && copy_empty.value)
193
+ end
194
+ invariant("only a mint of the next era audits stored rows") do
195
+ audited.unset? || !audited.value || minting.unset? || minting.value == "next"
196
+ end
197
+ invariant("a mint of the next era that would go through states how many rows were examined") do
198
+ verdict.unset? || verdict.value != "would_mint" || minting.unset? || minting.value != "next" || !rows_examined.unset?
199
+ end
200
+ invariant("a clean verdict that examined no row says so in what it did not check") do
201
+ verdict.unset? || verdict.value != "would_mint" || audited.unset? || audited.value ||
202
+ (!unchecked.unset? && unchecked.any? { |limit| limit.what == "the stored rows" })
203
+ end
204
+
205
+ # `requested` is the rehearsal and its store being prepared; `booted` the domain loaded and
206
+ # its shape read; `audited` the mint's audit run over the data. `judged` is a rehearsal whose
207
+ # answer is that the mint would go through, `withheld` one whose answer is that it would not
208
+ # (the verdict says which way), `refused` one that was never run because the request or the
209
+ # store was not admitted, and `failed` one that broke after it began.
210
+ lifecycle :status, default: "requested" do
211
+ mark :failure, "withheld", "refused", "failed"
212
+ transition "Boot" => "booted", from: "requested"
213
+ transition "Audit" => "audited", from: "booted"
214
+ transition "Judge" => "judged", from: "audited"
215
+ transition "Withhold" => "withheld", from: %w[requested booted audited]
216
+ transition "Refuse" => "refused", from: "requested"
217
+ transition "Fail" => "failed", from: %w[requested booted audited]
218
+ end
219
+
220
+ command "Request" do
221
+ role "Operator"
222
+ goal "Rehearse a domain's next era against the copy of its data its world names, say whether a mint would go through, and print the whole outcome"
223
+
224
+ attribute :run, RunKey
225
+ attribute :domain, DomainPath
226
+ attribute :pin, Pin, optional: true
227
+
228
+ sets :run
229
+ sets :domain
230
+ sets :pin
231
+
232
+ emits RehearsalRequested
233
+ end
234
+
235
+ # What the subject reported once it was loaded against the prepared copy.
236
+ command "Boot" do
237
+ role "System"
238
+ goal "Record that the domain loaded, the shape it stands at and the era a mint would hold"
239
+
240
+ reference_to RehearsalRun
241
+ attribute :booted, Switch
242
+ attribute :host_version, HostVersion
243
+ attribute :store, StoreKind
244
+ attribute :mode, StoreMode
245
+ attribute :before, ShapeLabel
246
+ attribute :after, ShapeLabel
247
+ attribute :minting, Minting
248
+ attribute :environment_loaded, EnvironmentLoaded
249
+ attribute :schema_used, SchemaRead
250
+ attribute :eras_held, Count
251
+ attribute :journal_entries, Count
252
+ attribute :head_rows, Count
253
+ attribute :census, list_of(HeldCount)
254
+ attribute :copy_empty, Switch
255
+ attribute :copy_note, Report
256
+ attribute :released, Switch, optional: true
257
+ attribute :kept, Report, optional: true
258
+
259
+ given("the domain loaded") { booted.value }
260
+
261
+ sets :booted
262
+ sets :host_version
263
+ sets :store
264
+ sets :mode
265
+ sets :before
266
+ sets :after
267
+ sets :minting
268
+ sets :environment_loaded
269
+ sets :schema_used
270
+ sets :eras_held
271
+ sets :journal_entries
272
+ sets :head_rows
273
+ sets :census
274
+ sets :copy_empty
275
+ sets :copy_note
276
+ sets :released
277
+ sets :kept
278
+
279
+ emits RehearsalBooted
280
+ end
281
+
282
+ # The mint's own three layers and its edge, approval and coverage rules, run over the copy.
283
+ command "Audit" do
284
+ role "System"
285
+ goal "Record whether an edge leads to the shape and is approved, and every row the mint's audit would refuse"
286
+
287
+ reference_to RehearsalRun
288
+ attribute :minting, Minting
289
+ attribute :edge_present, Switch
290
+ attribute :edge_approved, Switch
291
+ attribute :refused_rows, list_of(RefusedRow), optional: true
292
+ attribute :refusal_total, Count
293
+ attribute :audited, Switch
294
+ attribute :rows_examined, Count
295
+ attribute :rust_rows_examined, Count
296
+ attribute :aggregates_examined, Count
297
+ attribute :reason, Report
298
+ attribute :parity, Parity
299
+ attribute :unchecked, list_of(Limit)
300
+ attribute :released, Switch
301
+ attribute :kept, Report, optional: true
302
+
303
+ sets :minting
304
+ sets :edge_present
305
+ sets :edge_approved
306
+ sets :refused_rows
307
+ sets :refusal_total
308
+ sets :audited
309
+ sets :rows_examined
310
+ sets :rust_rows_examined
311
+ sets :aggregates_examined
312
+ sets :reason
313
+ sets :parity
314
+ sets :unchecked
315
+ sets :released
316
+ sets :kept
317
+
318
+ emits RehearsalAudited
319
+ end
320
+
321
+ command "Judge" do
322
+ role "System"
323
+ goal "Record that the mint would go through: the domain booted, an edge leads on where one is needed, and nothing is refused"
324
+
325
+ reference_to RehearsalRun
326
+ attribute :verdict, Verdict
327
+ attribute :refusal_total, Count
328
+ attribute :edge_present, Switch
329
+ attribute :edge_approved, Switch
330
+
331
+ given("a rehearsal that finds a refused row would not mint") { refusal_total.value == 0 }
332
+ given("a rehearsal judged to mint names that verdict") { verdict.value == "would_mint" }
333
+
334
+ sets :verdict
335
+
336
+ emits RehearsalJudged
337
+ end
338
+
339
+ command "Withhold" do
340
+ role "System"
341
+ goal "Record that the mint would not go through, which of the three ways, and what it would say"
342
+
343
+ reference_to RehearsalRun
344
+ attribute :verdict, Verdict
345
+ attribute :refusal, Report
346
+
347
+ given("a withheld rehearsal names how the mint would stop") { verdict.value != "would_mint" }
348
+
349
+ sets :verdict
350
+ sets :refusal
351
+
352
+ emits RehearsalWithheld
353
+ end
354
+
355
+ command "Refuse" do
356
+ role "System"
357
+ goal "Record that the rehearsal was not run: the subject, the pin or the store was not admitted, and why"
358
+
359
+ reference_to RehearsalRun
360
+ attribute :refusal, Report
361
+
362
+ sets :refusal
363
+
364
+ emits RehearsalRefused
365
+ end
366
+
367
+ command "Fail" do
368
+ role "System"
369
+ goal "Record that the rehearsal broke after it began, and why"
370
+
371
+ reference_to RehearsalRun
372
+ attribute :refusal, Report
373
+
374
+ sets :refusal
375
+
376
+ emits RehearsalFailed
377
+ end
378
+
379
+ query "RehearsalOutcome" do
380
+ description "How one rehearsal ended: its status and verdict, and every fact it brought back. A run is kept by the process that made it, so a run this process does not hold is refused as unknown; `request` waits for its reactions and prints the whole outcome."
381
+ attribute :run, RunKey
382
+ where(run: :run)
383
+ order_by :run
384
+ end
385
+
386
+ query "Withheld" do
387
+ description "Every rehearsal of this process whose answer was that the mint would not go through."
388
+ where(status: "withheld")
389
+ order_by :run
390
+ end
391
+ end
392
+
393
+ policy "SurveyWhenRehearsalRequested" do
394
+ on "RehearsalRun.RehearsalRequested"
395
+ ask :survey, with: { run: :run }
396
+ end
397
+
398
+ policy "RefuseWhenStoreNotAdmitted" do
399
+ on "RehearsalRun.StoreRefused"
400
+ trigger RehearsalRun::Refuse, with: { refusal: :refusal }
401
+ end
402
+ policy "RecordBootWhenStoreSurveyed" do
403
+ on "RehearsalRun.StoreSurveyed"
404
+ where { booted.value }
405
+ trigger RehearsalRun::Boot, with: { booted: :booted, host_version: :host_version, store: :store, mode: :mode,
406
+ before: :before, after: :after, minting: :minting,
407
+ environment_loaded: :environment_loaded, schema_used: :schema_used,
408
+ eras_held: :eras_held, journal_entries: :journal_entries,
409
+ head_rows: :head_rows, census: :census, copy_empty: :copy_empty,
410
+ copy_note: :copy_note, released: :released, kept: :kept }
411
+ end
412
+
413
+ # A copy that holds none of the domain's rows is not rehearsed: there is nothing to audit, and a
414
+ # clean answer over it would be a confident wrong one. The survey has already dropped it.
415
+ policy "WithholdWhenTheCopyHoldsNothing" do
416
+ on "RehearsalRun.RehearsalBooted"
417
+ where { copy_empty.value }
418
+ trigger RehearsalRun::Withhold, with: { verdict: "empty_copy", refusal: :copy_note }
419
+ end
420
+
421
+ # A domain that does not load is an answer, not a breakdown: it is what the mint would be
422
+ # stopped by, so it is judged, not failed.
423
+ policy "WithholdWhenSubjectDoesNotBoot" do
424
+ on "RehearsalRun.StoreSurveyed"
425
+ where { !booted.value }
426
+ trigger RehearsalRun::Withhold, with: { verdict: "cannot_boot", refusal: :boot_error }
427
+ end
428
+
429
+ policy "FailWhenExaminationRefused" do
430
+ on "RehearsalRun.ExamineRefused"
431
+ trigger RehearsalRun::Fail, with: { refusal: :refusal }
432
+ end
433
+
434
+ policy "ExamineWhenBooted" do
435
+ on "RehearsalRun.RehearsalBooted"
436
+ where { !copy_empty.value }
437
+ ask :examine, with: { run: :run }
438
+ end
439
+
440
+ policy "RecordAuditWhenStoreExamined" do
441
+ on "RehearsalRun.StoreExamined"
442
+ trigger RehearsalRun::Audit, with: { minting: :minting, edge_present: :edge_present, edge_approved: :edge_approved,
443
+ refused_rows: :refused_rows, refusal_total: :refusal_total,
444
+ audited: :audited, rows_examined: :rows_examined,
445
+ rust_rows_examined: :rust_rows_examined,
446
+ aggregates_examined: :aggregates_examined, reason: :reason,
447
+ parity: :parity, unchecked: :unchecked,
448
+ released: :released, kept: :kept }
449
+ end
450
+
451
+ policy "JudgeWhenNothingWouldStopTheMint" do
452
+ on "RehearsalRun.RehearsalAudited"
453
+ where do
454
+ (minting.value != "next" || edge_present.value) && refusal_total.value == 0 &&
455
+ (minting.value != "next" || edge_approved.value)
456
+ end
457
+ trigger RehearsalRun::Judge, with: { verdict: "would_mint", refusal_total: :refusal_total,
458
+ edge_present: :edge_present, edge_approved: :edge_approved }
459
+ end
460
+
461
+ policy "WithholdWhenNoEdgeLeadsOn" do
462
+ on "RehearsalRun.RehearsalAudited"
463
+ where { minting.value == "next" && !edge_present.value }
464
+ trigger RehearsalRun::Withhold, with: { verdict: "needs_edge",
465
+ refusal: "no translation edge leads the held era to this shape" }
466
+ end
467
+
468
+ policy "WithholdWhenTheMintWouldRefuse" do
469
+ on "RehearsalRun.RehearsalAudited"
470
+ where do
471
+ (minting.value != "next" || edge_present.value) &&
472
+ (refusal_total.value > 0 || (minting.value == "next" && !edge_approved.value))
473
+ end
474
+ trigger RehearsalRun::Withhold, with: { verdict: "would_refuse",
475
+ refusal: "the mint would refuse: see the refused rows and the edge's approval" }
476
+ end
477
+ end
@@ -1,7 +1,7 @@
1
1
  Hecks.behaviors "Site" do
2
2
  vision "A projection of a site's route table is recorded as requested before anything outside is asked."
3
3
 
4
- loads "hecks.bluebook", "custodian.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "site.world", "environments/memory.world"
4
+ loads "hecks.bluebook", "custodian.bluebook", "tooling.bluebook", "rehearsal.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "site.world", "environments/memory.world"
5
5
 
6
6
  test "ProjectSite keeps a project that has no bluebook as a faulted projection" do
7
7
  tests "ProjectSite", on: "SiteProjection"