hecks 6.0.0 → 7.0.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 (754) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +19 -12
  3. data/lib/hecks/adapters/driven/claude_code.rb +2 -2
  4. data/lib/hecks/adapters/driven/folder.rb +10 -1
  5. data/lib/hecks/adapters/driven/folder_overlay.rb +15 -0
  6. data/lib/hecks/adapters/driven/heki.rb +1 -1
  7. data/lib/hecks/adapters/driven/in_process_key_vault.rb +1 -1
  8. data/lib/hecks/adapters/driven/memory/outbox_rows.rb +2 -2
  9. data/lib/hecks/adapters/driven/postgres/name_guard.rb +25 -0
  10. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -3
  11. data/lib/hecks/adapters/driven/postgres/repository.rb +1 -1
  12. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +1 -1
  13. data/lib/hecks/adapters/driven/postgres.rb +3 -0
  14. data/lib/hecks/adapters/driven/postgres_era/boot.rb +28 -16
  15. data/lib/hecks/adapters/driven/postgres_era/class_methods.rb +27 -7
  16. data/lib/hecks/adapters/driven/postgres_era/dialect.rb +10 -5
  17. data/lib/hecks/adapters/driven/postgres_era/field_cache_provisioner.rb +39 -0
  18. data/lib/hecks/adapters/driven/postgres_era/journal.rb +52 -13
  19. data/lib/hecks/adapters/driven/postgres_era/lineage/chain_sql.rb +29 -49
  20. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_sql.rb +73 -0
  21. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.json +10 -0
  22. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.rb +65 -0
  23. data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename.rb +77 -25
  24. data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename_state.rb +108 -0
  25. data/lib/hecks/adapters/driven/postgres_era/lineage/era_integrity.rb +11 -6
  26. data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +63 -5
  27. data/lib/hecks/adapters/driven/postgres_era/lineage/layered_sql.rb +64 -0
  28. data/lib/hecks/adapters/driven/postgres_era/lineage/ledger_reset.rb +150 -0
  29. data/lib/hecks/adapters/driven/postgres_era/lineage/mint_provisioning.rb +85 -0
  30. data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +11 -7
  31. data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +11 -5
  32. data/lib/hecks/adapters/driven/postgres_era/lineage/split_sql.rb +76 -0
  33. data/lib/hecks/adapters/driven/postgres_era/lineage/sql_templates.rb +9 -0
  34. data/lib/hecks/adapters/driven/postgres_era/lineage.rb +10 -2
  35. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/context.rb +23 -3
  36. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +3 -1
  37. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/disposable_ledger.rb +119 -0
  38. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolution.rb +219 -0
  39. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +68 -71
  40. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/held_era.rb +68 -0
  41. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/ledger_change.rb +63 -0
  42. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
  43. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_decision.rb +163 -0
  44. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_request.rb +24 -0
  45. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +59 -21
  46. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/refusals.rb +24 -11
  47. data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +40 -6
  48. data/lib/hecks/adapters/driven/postgres_era/shared_tables.rb +32 -0
  49. data/lib/hecks/adapters/driven/postgres_era.adapter +12 -0
  50. data/lib/hecks/adapters/driven/postgres_era.rb +25 -10
  51. data/lib/hecks/adapters/driven/prism.rb +0 -1
  52. data/lib/hecks/adapters/driven/sql_query_builder.rb +1 -0
  53. data/lib/hecks/adapters/driven/sqlite/dispatch_claims.rb +1 -1
  54. data/lib/hecks/adapters/driven/sqlite/name_guard.rb +25 -0
  55. data/lib/hecks/adapters/driven/sqlite/outbox.rb +2 -2
  56. data/lib/hecks/adapters/driven/sqlite/repository.rb +1 -1
  57. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +20 -0
  58. data/lib/hecks/adapters/driven/sqlite.rb +9 -1
  59. data/lib/hecks/adapters/driven/tenant_provisioner.rb +1 -1
  60. data/lib/hecks/adapters/driven/worktree_overlay.rb +117 -0
  61. data/lib/hecks/adapters/driving/cli/shorthand.rb +5 -1
  62. data/lib/hecks/adapters/driving/cli.rb +1 -1
  63. data/lib/hecks/adapters/driving/cli_runner/answers.rb +77 -22
  64. data/lib/hecks/adapters/driving/cli_runner/bang_rule.rb +35 -0
  65. data/lib/hecks/adapters/driving/cli_runner/completion_words.rb +36 -0
  66. data/lib/hecks/adapters/driving/cli_runner/json_words.rb +55 -0
  67. data/lib/hecks/adapters/driving/cli_runner/name_index.rb +63 -0
  68. data/lib/hecks/adapters/driving/cli_runner/read_context.rb +32 -0
  69. data/lib/hecks/adapters/driving/cli_runner/renamed_names.rb +49 -0
  70. data/lib/hecks/adapters/driving/cli_runner/resolution.rb +43 -17
  71. data/lib/hecks/adapters/driving/cli_runner/resume_words.rb +63 -0
  72. data/lib/hecks/adapters/driving/cli_runner/run_reference.rb +66 -0
  73. data/lib/hecks/adapters/driving/cli_runner/run_replay.rb +118 -0
  74. data/lib/hecks/adapters/driving/cli_runner/search_words.rb +35 -0
  75. data/lib/hecks/adapters/driving/cli_runner/settling.rb +6 -5
  76. data/lib/hecks/adapters/driving/cli_runner/streaming.rb +11 -10
  77. data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +1 -1
  78. data/lib/hecks/adapters/driving/cli_runner/tour_words.rb +77 -0
  79. data/lib/hecks/adapters/driving/cli_runner/verb_names.rb +36 -4
  80. data/lib/hecks/adapters/driving/cli_runner/verbosity.rb +75 -0
  81. data/lib/hecks/adapters/driving/cli_runner.rb +106 -7
  82. data/lib/hecks/adapters/driving/context_line.rb +85 -0
  83. data/lib/hecks/adapters/driving/exit_status.rb +31 -0
  84. data/lib/hecks/adapters/driving/launcher_options.rb +7 -5
  85. data/lib/hecks/adapters/driving/mcp/progress_sink.rb +45 -0
  86. data/lib/hecks/adapters/driving/mcp/tool_calls.rb +7 -5
  87. data/lib/hecks/adapters/driving/mcp.rb +25 -5
  88. data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +40 -7
  89. data/lib/hecks/adapters/driving/mcp_scope.rb +8 -7
  90. data/lib/hecks/adapters/driving/ruby/aggregate_module/hooks.rb +154 -0
  91. data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +64 -93
  92. data/lib/hecks/adapters/driving/usage_log.rb +146 -0
  93. data/lib/hecks/adapters/driving/write_guard.rb +55 -0
  94. data/lib/hecks/adapters/driving.rb +0 -1
  95. data/lib/hecks/behaviors/dsl.rb +5 -1
  96. data/lib/hecks/behaviors/expectations/boot.rb +0 -1
  97. data/lib/hecks/bluebook/acknowledgements.rb +1 -1
  98. data/lib/hecks/bluebook/aggregate.rb +21 -18
  99. data/lib/hecks/bluebook/assembly/contracts/sagas.rb +2 -0
  100. data/lib/hecks/bluebook/assembly/contracts/structure.rb +18 -13
  101. data/lib/hecks/bluebook/behaviour/aggregate.rb +27 -3
  102. data/lib/hecks/bluebook/command.rb +16 -5
  103. data/lib/hecks/bluebook/declaration.rb +32 -4
  104. data/lib/hecks/bluebook/domain_port.rb +7 -3
  105. data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +0 -2
  106. data/lib/hecks/bluebook/dsl/aggregate_builder/renaming.rb +25 -0
  107. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +3 -0
  108. data/lib/hecks/bluebook/dsl/attribute_collector.rb +0 -1
  109. data/lib/hecks/bluebook/dsl/audience_word.rb +40 -0
  110. data/lib/hecks/bluebook/dsl/bluebook_builder/metadata.rb +56 -0
  111. data/lib/hecks/bluebook/dsl/bluebook_builder/modules.rb +80 -0
  112. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +51 -0
  113. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +1 -0
  114. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +17 -34
  115. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +8 -0
  116. data/lib/hecks/bluebook/dsl/command_builder.rb +13 -3
  117. data/lib/hecks/bluebook/dsl/entity_builder.rb +0 -2
  118. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +6 -4
  119. data/lib/hecks/bluebook/dsl/kinds.rb +53 -0
  120. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +9 -2
  121. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +25 -15
  122. data/lib/hecks/bluebook/dsl/translation_builder.rb +16 -1
  123. data/lib/hecks/bluebook/dsl/word_gate.rb +1 -1
  124. data/lib/hecks/bluebook/dsl.rb +1 -0
  125. data/lib/hecks/bluebook/meta_validator/judge/identity.rb +9 -4
  126. data/lib/hecks/bluebook/meta_validator/plan/category.rb +10 -2
  127. data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +9 -0
  128. data/lib/hecks/bluebook/meta_validator/plan.rb +2 -1
  129. data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +3 -1
  130. data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +7 -0
  131. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +7 -2
  132. data/lib/hecks/bluebook/meta_validator/shapes.rb +3 -0
  133. data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +1 -1
  134. data/lib/hecks/bluebook/model_check/aggregate_checks.rb +27 -0
  135. data/lib/hecks/bluebook/model_check/ask_checks.rb +25 -0
  136. data/lib/hecks/bluebook/model_check/reaction_chains.rb +114 -0
  137. data/lib/hecks/bluebook/model_check/reaction_cycles.rb +53 -0
  138. data/lib/hecks/bluebook/model_check/reaction_depth_checks.rb +58 -0
  139. data/lib/hecks/bluebook/model_check/reaction_walk.rb +62 -0
  140. data/lib/hecks/bluebook/model_check.rb +5 -27
  141. data/lib/hecks/bluebook/process_manager.rb +20 -3
  142. data/lib/hecks/bluebook/translation.rb +5 -3
  143. data/lib/hecks/bluebook/translation_plan.rb +9 -2
  144. data/lib/hecks/ci_pipeline/adapters/ci_cache.adapter +7 -0
  145. data/lib/hecks/ci_pipeline/adapters/ci_cache.rb +39 -0
  146. data/lib/hecks/ci_pipeline/adapters/ci_runner.adapter +7 -0
  147. data/lib/hecks/ci_pipeline/adapters/ci_runner.rb +55 -0
  148. data/lib/hecks/ci_pipeline/ci_pipeline.behaviors +322 -0
  149. data/lib/hecks/ci_pipeline/ci_pipeline.bluebook +938 -0
  150. data/lib/hecks/ci_pipeline/ci_pipeline.hecksagon +12 -0
  151. data/lib/hecks/ci_pipeline/ci_pipeline.ports.hecksagon +16 -0
  152. data/lib/hecks/ci_speed/adapters/ci_reader.adapter +7 -0
  153. data/lib/hecks/ci_speed/adapters/ci_reader.rb +141 -0
  154. data/lib/hecks/ci_speed/adapters/local_runner/answer.rb +41 -0
  155. data/lib/hecks/ci_speed/adapters/local_runner/catalog.rb +89 -0
  156. data/lib/hecks/ci_speed/adapters/local_runner/checkouts.rb +89 -0
  157. data/lib/hecks/ci_speed/adapters/local_runner/launcher.rb +69 -0
  158. data/lib/hecks/ci_speed/adapters/local_runner/load_average.rb +38 -0
  159. data/lib/hecks/ci_speed/adapters/local_runner/refs.rb +39 -0
  160. data/lib/hecks/ci_speed/adapters/local_runner/refused.rb +11 -0
  161. data/lib/hecks/ci_speed/adapters/local_runner/verdict.rb +71 -0
  162. data/lib/hecks/ci_speed/adapters/local_runner.adapter +7 -0
  163. data/lib/hecks/ci_speed/adapters/local_runner.rb +168 -0
  164. data/lib/hecks/ci_speed/adapters/replayed_runner.rb +39 -0
  165. data/lib/hecks/ci_speed/ci_speed.behaviors +341 -0
  166. data/lib/hecks/ci_speed/ci_speed.bluebook +1073 -0
  167. data/lib/hecks/ci_speed/ci_speed.hecksagon +11 -0
  168. data/lib/hecks/ci_speed/ci_speed.ports.hecksagon +21 -0
  169. data/lib/hecks/ci_workflows/ci_workflows.behaviors +13 -0
  170. data/lib/hecks/ci_workflows/ci_workflows.bluebook +173 -0
  171. data/lib/hecks/ci_workflows/ci_workflows.hecksagon +15 -0
  172. data/lib/hecks/coder/coder.bluebook +385 -0
  173. data/lib/hecks/coder/coder.hecksagon +12 -0
  174. data/lib/hecks/command_names/check.rb +39 -0
  175. data/lib/hecks/command_names/extractor.rb +67 -0
  176. data/lib/hecks/command_names/index.rb +40 -0
  177. data/lib/hecks/command_names/resolution.rb +81 -0
  178. data/lib/hecks/command_names/scan.rb +54 -0
  179. data/lib/hecks/command_names/sources.rb +73 -0
  180. data/lib/hecks/command_names.rb +26 -0
  181. data/lib/hecks/composer/jobs.rb +1 -1
  182. data/lib/hecks/composer/toolbox.rb +8 -1
  183. data/lib/hecks/corpus/generated_key.rb +205 -0
  184. data/lib/hecks/corpus/listing.rb +34 -0
  185. data/lib/hecks/corpus/rust.rb +27 -11
  186. data/lib/hecks/corpus/sources.rb +2 -1
  187. data/lib/hecks/corpus.rb +37 -42
  188. data/lib/hecks/deprecation.rb +23 -0
  189. data/lib/hecks/doc/reference/readme.rb +1 -1
  190. data/lib/hecks/doc/reference/rendering.rb +2 -2
  191. data/lib/hecks/doc/reference.rb +1 -1
  192. data/lib/hecks/embryonaut_bluebook/manifest.rb +1 -1
  193. data/lib/hecks/fixer/fixer.bluebook +240 -0
  194. data/lib/hecks/fixer/fixer.hecksagon +17 -0
  195. data/lib/hecks/framework_bluebooks.rb +32 -7
  196. data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +1 -0
  197. data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +11 -12
  198. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +23 -5
  199. data/lib/hecks/fuzzing/isolated_boot.rb +1 -1
  200. data/lib/hecks/fuzzing/mutation/checks.rb +3 -3
  201. data/lib/hecks/grammar/translation.bluebook +1 -1
  202. data/lib/hecks/grammar/translation_rules.json +64 -0
  203. data/lib/hecks/hecks/adapter_words.json +7 -0
  204. data/lib/hecks/hecks/adapters/area_overlap.rb +156 -0
  205. data/lib/hecks/hecks/adapters/claude_agents.rb +8 -3
  206. data/lib/hecks/hecks/adapters/codebase/batch_runs.rb +60 -0
  207. data/lib/hecks/hecks/adapters/codebase/changed_specs.rb +52 -0
  208. data/lib/hecks/hecks/adapters/codebase/codemods.rb +3 -2
  209. data/lib/hecks/hecks/adapters/codebase/conformance.rb +14 -1
  210. data/lib/hecks/hecks/adapters/codebase/corpus_queries.rb +53 -0
  211. data/lib/hecks/hecks/adapters/codebase/generated_keys.rb +31 -0
  212. data/lib/hecks/hecks/adapters/codebase/impacted_specs.rb +110 -0
  213. data/lib/hecks/hecks/adapters/codebase/language.rb +2 -2
  214. data/lib/hecks/hecks/adapters/codebase/launcher_text.rb +39 -0
  215. data/lib/hecks/hecks/adapters/codebase/minitest_runs.rb +52 -0
  216. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +51 -8
  217. data/lib/hecks/hecks/adapters/codebase/run_options.rb +35 -0
  218. data/lib/hecks/hecks/adapters/codebase/scripting.rb +39 -0
  219. data/lib/hecks/hecks/adapters/codebase/search.rb +1 -1
  220. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +79 -51
  221. data/lib/hecks/hecks/adapters/codebase/spec_files/report.rb +71 -0
  222. data/lib/hecks/hecks/adapters/codebase/spec_files/shared_run.rb +73 -0
  223. data/lib/hecks/hecks/adapters/codebase/spec_files.rb +95 -0
  224. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +53 -4
  225. data/lib/hecks/hecks/adapters/codebase/test_scope.rb +105 -0
  226. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +48 -34
  227. data/lib/hecks/hecks/adapters/console_capture.rb +1 -1
  228. data/lib/hecks/hecks/adapters/cost_explorer.rb +9 -1
  229. data/lib/hecks/hecks/adapters/dispatching/brief_text.rb +51 -0
  230. data/lib/hecks/hecks/adapters/dispatching/launcher.rb +97 -0
  231. data/lib/hecks/hecks/adapters/dispatching/plan.rb +82 -0
  232. data/lib/hecks/hecks/adapters/dispatching/rows.rb +66 -0
  233. data/lib/hecks/hecks/adapters/dispatching/settings.rb +81 -0
  234. data/lib/hecks/hecks/adapters/dispatching/settler.rb +40 -0
  235. data/lib/hecks/hecks/adapters/dispatching.adapter +7 -0
  236. data/lib/hecks/hecks/adapters/dispatching.rb +93 -0
  237. data/lib/hecks/hecks/adapters/doctor_reading/report.rb +27 -0
  238. data/lib/hecks/hecks/adapters/doctor_reading.adapter +7 -0
  239. data/lib/hecks/hecks/adapters/doctor_reading.rb +161 -0
  240. data/lib/hecks/hecks/adapters/git_checkout.rb +1 -1
  241. data/lib/hecks/hecks/adapters/git_commit.adapter +7 -0
  242. data/lib/hecks/hecks/adapters/git_commit.rb +61 -0
  243. data/lib/hecks/hecks/adapters/git_landing/finisher.rb +82 -0
  244. data/lib/hecks/hecks/adapters/git_landing/foreign_hold.rb +111 -0
  245. data/lib/hecks/hecks/adapters/git_landing/line.rb +171 -0
  246. data/lib/hecks/hecks/adapters/git_landing/lineup.rb +98 -0
  247. data/lib/hecks/hecks/adapters/git_landing/merger.rb +1 -1
  248. data/lib/hecks/hecks/adapters/git_landing/numbering.rb +54 -0
  249. data/lib/hecks/hecks/adapters/git_landing/rivals.rb +59 -0
  250. data/lib/hecks/hecks/adapters/git_landing/ticket.rb +156 -0
  251. data/lib/hecks/hecks/adapters/git_landing/tidy.rb +147 -0
  252. data/lib/hecks/hecks/adapters/git_landing/train.rb +104 -0
  253. data/lib/hecks/hecks/adapters/git_landing/verdict.rb +64 -0
  254. data/lib/hecks/hecks/adapters/git_landing/waiting.rb +120 -0
  255. data/lib/hecks/hecks/adapters/git_landing.rb +106 -20
  256. data/lib/hecks/hecks/adapters/git_main_pull.rb +99 -0
  257. data/lib/hecks/hecks/adapters/git_rehearsal/bench.rb +82 -0
  258. data/lib/hecks/hecks/adapters/git_rehearsal/due.rb +84 -0
  259. data/lib/hecks/hecks/adapters/git_rehearsal/impacted/skips.rb +47 -0
  260. data/lib/hecks/hecks/adapters/git_rehearsal/impacted/spec_run.rb +75 -0
  261. data/lib/hecks/hecks/adapters/git_rehearsal/impacted.rb +181 -0
  262. data/lib/hecks/hecks/adapters/git_rehearsal/line.rb +76 -0
  263. data/lib/hecks/hecks/adapters/git_rehearsal/reading.rb +24 -0
  264. data/lib/hecks/hecks/adapters/git_rehearsal/record.rb +146 -0
  265. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/corpus.rb +25 -0
  266. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/needles.rb +61 -0
  267. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map.rb +105 -0
  268. data/lib/hecks/hecks/adapters/git_rehearsal/stages.rb +118 -0
  269. data/lib/hecks/hecks/adapters/git_rehearsal.adapter +7 -0
  270. data/lib/hecks/hecks/adapters/git_rehearsal.rb +141 -0
  271. data/lib/hecks/hecks/adapters/git_train/bench.rb +15 -15
  272. data/lib/hecks/hecks/adapters/git_train/branch_guard.rb +62 -0
  273. data/lib/hecks/hecks/adapters/git_train/carriage.rb +27 -28
  274. data/lib/hecks/hecks/adapters/git_train/launcher_shape.rb +75 -0
  275. data/lib/hecks/hecks/adapters/git_train/mint_step.rb +47 -0
  276. data/lib/hecks/hecks/adapters/git_train/settlement.rb +167 -0
  277. data/lib/hecks/hecks/adapters/git_train.rb +73 -15
  278. data/lib/hecks/hecks/adapters/git_worktree_add.adapter +7 -0
  279. data/lib/hecks/hecks/adapters/git_worktree_add.rb +68 -0
  280. data/lib/hecks/hecks/adapters/github_pull_requests.adapter +7 -0
  281. data/lib/hecks/hecks/adapters/github_pull_requests.rb +109 -0
  282. data/lib/hecks/hecks/adapters/host_http.rb +6 -6
  283. data/lib/hecks/hecks/adapters/in_process_boot.rb +10 -8
  284. data/lib/hecks/hecks/adapters/in_process_operations.rb +11 -17
  285. data/lib/hecks/hecks/adapters/in_process_undo.rb +17 -0
  286. data/lib/hecks/hecks/adapters/journal_store/changes.rb +13 -4
  287. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +28 -15
  288. data/lib/hecks/hecks/adapters/journal_store/examination.rb +17 -1
  289. data/lib/hecks/hecks/adapters/journal_store/held_domain/renaming.rb +45 -0
  290. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +31 -5
  291. data/lib/hecks/hecks/adapters/journal_store/held_mint.rb +128 -0
  292. data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +1 -1
  293. data/lib/hecks/hecks/adapters/journal_store/readings/boot_status.rb +58 -0
  294. data/lib/hecks/hecks/adapters/journal_store/readings/composition.rb +39 -0
  295. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/outcomes.rb +76 -0
  296. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/postgres_reader.rb +44 -0
  297. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/reader.rb +64 -0
  298. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/report.rb +102 -0
  299. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/sqlite_reader.rb +43 -0
  300. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/stores.rb +80 -0
  301. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/subscribers.rb +72 -0
  302. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/summary.rb +39 -0
  303. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace.rb +39 -0
  304. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/command_line.rb +57 -0
  305. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/edge_guards.rb +107 -0
  306. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/inspection.rb +94 -0
  307. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/plan.rb +66 -0
  308. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/report.rb +72 -0
  309. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/store.rb +34 -0
  310. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/watermark_guards.rb +86 -0
  311. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/world.rb +66 -0
  312. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan.rb +36 -0
  313. data/lib/hecks/hecks/adapters/journal_store/readings/projection_audit.rb +64 -0
  314. data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +3 -3
  315. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/database_reading.rb +113 -0
  316. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/read_only.rb +33 -0
  317. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status.rb +32 -0
  318. data/lib/hecks/hecks/adapters/journal_store/readings.rb +13 -1
  319. data/lib/hecks/hecks/adapters/journal_store/reconcile_report.rb +60 -0
  320. data/lib/hecks/hecks/adapters/journal_store/reconciliation.rb +121 -0
  321. data/lib/hecks/hecks/adapters/journal_store/translation_write/shape_edge.rb +59 -0
  322. data/lib/hecks/hecks/adapters/journal_store/translation_write.rb +123 -0
  323. data/lib/hecks/hecks/adapters/journal_store.rb +16 -0
  324. data/lib/hecks/hecks/adapters/landed_work.adapter +7 -0
  325. data/lib/hecks/hecks/adapters/landed_work.rb +52 -0
  326. data/lib/hecks/hecks/adapters/local_files.rb +6 -6
  327. data/lib/hecks/hecks/adapters/process_pool.rb +3 -2
  328. data/lib/hecks/hecks/adapters/push_size.rb +57 -0
  329. data/lib/hecks/hecks/adapters/qa_quiescing.adapter +7 -0
  330. data/lib/hecks/hecks/adapters/qa_quiescing.rb +57 -0
  331. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +30 -3
  332. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +63 -3
  333. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +29 -6
  334. data/lib/hecks/hecks/adapters/rehearsal/subject.rb +11 -5
  335. data/lib/hecks/hecks/adapters/rust_toolchain.rb +10 -1
  336. data/lib/hecks/hecks/adapters/rust_workspace.rb +1 -1
  337. data/lib/hecks/hecks/adapters/settings_reading/disposable_ledger.rb +32 -0
  338. data/lib/hecks/hecks/adapters/settings_reading/push_nudge.rb +26 -0
  339. data/lib/hecks/hecks/adapters/settings_reading/stores.rb +76 -0
  340. data/lib/hecks/hecks/adapters/settings_reading/test_scope.rb +28 -0
  341. data/lib/hecks/hecks/adapters/settings_reading.rb +28 -2
  342. data/lib/hecks/hecks/adapters/started_work.rb +42 -0
  343. data/lib/hecks/hecks/adapters/terminal.rb +12 -10
  344. data/lib/hecks/hecks/adapters/where_reading.adapter +7 -0
  345. data/lib/hecks/hecks/adapters/where_reading.rb +64 -0
  346. data/lib/hecks/hecks/adapters/work_areas.rb +57 -0
  347. data/lib/hecks/hecks/adapters/work_limits.rb +57 -0
  348. data/lib/hecks/hecks/build/build.bluebook +576 -0
  349. data/lib/hecks/hecks/check/check.bluebook +966 -0
  350. data/lib/hecks/hecks/codebase.behaviors +61 -5
  351. data/lib/hecks/hecks/composer.behaviors +1 -1
  352. data/lib/hecks/hecks/context_map.hecksagon +1 -1
  353. data/lib/hecks/hecks/custodian.behaviors +33 -7
  354. data/lib/hecks/hecks/delegate/delegate.bluebook +355 -0
  355. data/lib/hecks/hecks/deliver/deliver.bluebook +945 -0
  356. data/lib/hecks/hecks/deploy.behaviors +1 -1
  357. data/lib/hecks/hecks/evolve/evolve.bluebook +788 -0
  358. data/lib/hecks/hecks/find/find.bluebook +81 -0
  359. data/lib/hecks/hecks/hecks.behaviors +1 -1
  360. data/lib/hecks/hecks/hecks.bluebook +0 -133
  361. data/lib/hecks/hecks/hecks.contextmap +2 -0
  362. data/lib/hecks/hecks/hecks.hecksagon +185 -29
  363. data/lib/hecks/hecks/hecks.world +35 -9
  364. data/lib/hecks/hecks/implicit_moves.json +24 -0
  365. data/lib/hecks/hecks/migrate/migrate.bluebook +1066 -0
  366. data/lib/hecks/hecks/operate/operate.bluebook +695 -0
  367. data/lib/hecks/hecks/quiesce/quiesce.bluebook +117 -0
  368. data/lib/hecks/hecks/rehearse/rehearse.bluebook +133 -0
  369. data/lib/hecks/hecks/release/release.bluebook +916 -0
  370. data/lib/hecks/hecks/serve/serve.bluebook +134 -0
  371. data/lib/hecks/hecks/shapes.json +1 -15
  372. data/lib/hecks/hecks/site.behaviors +1 -1
  373. data/lib/hecks/hecks/start/start.bluebook +194 -0
  374. data/lib/hecks/hecks/test/test.bluebook +638 -0
  375. data/lib/hecks/hecks/tickets.world +14 -0
  376. data/lib/hecks/language/bluebook/aggregate.bluebook +22 -0
  377. data/lib/hecks/language/bluebook/bluebook.bluebook +34 -0
  378. data/lib/hecks/language/bluebook/command.bluebook +35 -0
  379. data/lib/hecks/language/bluebook/process_manager.bluebook +14 -1
  380. data/lib/hecks/language/bluebook/vocabulary.bluebook +174 -54
  381. data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -0
  382. data/lib/hecks/language/hecksagon/port_operation.bluebook +14 -0
  383. data/lib/hecks/language/kinds/run.kind +120 -0
  384. data/lib/hecks/language/oidc.json +10 -0
  385. data/lib/hecks/language/translation/translation_aggregate.bluebook +24 -0
  386. data/lib/hecks/module_folders.rb +31 -0
  387. data/lib/hecks/ports/key_vault.rb +1 -1
  388. data/lib/hecks/ports/persistence/append_only.rb +26 -8
  389. data/lib/hecks/ports/persistence/binding_policy.rb +3 -1
  390. data/lib/hecks/ports/persistence/codec_boundary.rb +1 -1
  391. data/lib/hecks/ports/persistence/mint_door.rb +74 -0
  392. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +6 -5
  393. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +5 -1
  394. data/lib/hecks/ports/persistence/plugins/era/era_status.rb +48 -0
  395. data/lib/hecks/ports/persistence/plugins/era/projected_bluebook.rb +127 -0
  396. data/lib/hecks/ports/persistence/plugins/era/translation/additive_shape.rb +107 -0
  397. data/lib/hecks/ports/persistence/plugins/era/translation/compose.rb +155 -0
  398. data/lib/hecks/ports/persistence/plugins/era/translation/compose_render.rb +79 -0
  399. data/lib/hecks/ports/persistence/plugins/era/translation/edge_files.rb +49 -0
  400. data/lib/hecks/ports/persistence/plugins/era/translation/edge_route.rb +61 -0
  401. data/lib/hecks/ports/persistence/plugins/era/translation/implicit_edge.rb +67 -0
  402. data/lib/hecks/ports/persistence/plugins/era/translation/reconcile.rb +130 -0
  403. data/lib/hecks/ports/persistence/plugins/era/translation/reconcile_files.rb +35 -0
  404. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +13 -5
  405. data/lib/hecks/ports/persistence/plugins/era/translation.rb +5 -0
  406. data/lib/hecks/ports/persistence/plugins/era.rb +1 -0
  407. data/lib/hecks/ports/persistence/repository_factory.rb +11 -3
  408. data/lib/hecks/ports/persistence/stored_name_guard.rb +36 -0
  409. data/lib/hecks/ports/persistence.rb +2 -0
  410. data/lib/hecks/projections/ci_pipeline/table/checks.rb +137 -0
  411. data/lib/hecks/projections/ci_pipeline/table/lookup.rb +59 -0
  412. data/lib/hecks/projections/ci_pipeline/table/refusals.rb +58 -0
  413. data/lib/hecks/projections/ci_pipeline/table/rows.rb +119 -0
  414. data/lib/hecks/projections/ci_pipeline/table/tree.rb +30 -0
  415. data/lib/hecks/projections/ci_pipeline/table/typing.rb +92 -0
  416. data/lib/hecks/projections/ci_pipeline/table.rb +112 -0
  417. data/lib/hecks/projections/ci_pipeline/workflows.rb +162 -0
  418. data/lib/hecks/projections/ci_pipeline/yaml_text.rb +104 -0
  419. data/lib/hecks/projections/deploy/box/hosting.rb +1 -1
  420. data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
  421. data/lib/hecks/projections/deploy/box/roll_scripts.rb +1 -1
  422. data/lib/hecks/projections/deploy/box.rb +1 -1
  423. data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +1 -1
  424. data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +3 -3
  425. data/lib/hecks/projections/undo.rb +46 -0
  426. data/lib/hecks/projections.rb +2 -0
  427. data/lib/hecks/projector/cli_projector/claims.rb +11 -0
  428. data/lib/hecks/projector/cli_projector/command_help.rb +6 -1
  429. data/lib/hecks/projector/cli_projector/command_specs.rb +11 -1
  430. data/lib/hecks/projector/cli_projector/completion.rb +87 -0
  431. data/lib/hecks/projector/cli_projector/everyday.rb +40 -0
  432. data/lib/hecks/projector/cli_projector/json_listing.rb +77 -0
  433. data/lib/hecks/projector/cli_projector/listing.rb +1 -1
  434. data/lib/hecks/projector/cli_projector/modules.rb +39 -0
  435. data/lib/hecks/projector/cli_projector/query_specs.rb +1 -0
  436. data/lib/hecks/projector/cli_projector/renames.rb +58 -0
  437. data/lib/hecks/projector/cli_projector/search.rb +74 -0
  438. data/lib/hecks/projector/cli_projector/usage.rb +23 -6
  439. data/lib/hecks/projector/cli_projector.rb +24 -1
  440. data/lib/hecks/quality_control/adapters/ci_head.adapter +8 -0
  441. data/lib/hecks/quality_control/adapters/image_roll.adapter +9 -0
  442. data/lib/hecks/quality_control/adapters/image_roll.rb +158 -0
  443. data/lib/hecks/quality_control/adapters/main_maintenance.adapter +8 -0
  444. data/lib/hecks/quality_control/adapters/main_maintenance.rb +275 -0
  445. data/lib/hecks/quality_control/adapters/pump_tools.adapter +7 -0
  446. data/lib/hecks/quality_control/adapters/pump_tools.rb +18 -0
  447. data/lib/hecks/quality_control/adapters/push_due_reader.adapter +8 -0
  448. data/lib/hecks/quality_control/adapters/push_due_reader.rb +99 -0
  449. data/lib/hecks/quality_control/adapters/qa_auto_mint.rb +183 -0
  450. data/lib/hecks/quality_control/adapters/qa_era_mint.rb +94 -0
  451. data/lib/hecks/quality_control/adapters/qa_quiesce_marker.rb +126 -0
  452. data/lib/hecks/quality_control/adapters/run_keys.rb +36 -0
  453. data/lib/hecks/quality_control/adapters/run_reader.adapter +7 -0
  454. data/lib/hecks/quality_control/adapters/run_reader.rb +188 -0
  455. data/lib/hecks/quality_control/cli/child.rb +1 -0
  456. data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +1 -1
  457. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +3 -3
  458. data/lib/hecks/quality_control/cli/qa_event_pump/attached.rb +67 -0
  459. data/lib/hecks/quality_control/cli/qa_event_pump/consumer.rb +103 -0
  460. data/lib/hecks/quality_control/cli/qa_event_pump/cursors.rb +60 -0
  461. data/lib/hecks/quality_control/cli/qa_event_pump/reactions.rb +46 -0
  462. data/lib/hecks/quality_control/cli/qa_event_pump/reader.rb +30 -0
  463. data/lib/hecks/quality_control/cli/qa_event_pump.rb +76 -0
  464. data/lib/hecks/quality_control/cli/qa_fix_main_bug/publishing.rb +79 -0
  465. data/lib/hecks/quality_control/cli/qa_fix_main_bug.rb +167 -0
  466. data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +1 -1
  467. data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +3 -3
  468. data/lib/hecks/quality_control/cli/qa_main_gate/gate_run.rb +52 -0
  469. data/lib/hecks/quality_control/cli/qa_main_gate/logging.rb +70 -0
  470. data/lib/hecks/quality_control/cli/qa_main_gate/shell.rb +47 -0
  471. data/lib/hecks/quality_control/cli/qa_main_gate/sweeping.rb +59 -0
  472. data/lib/hecks/quality_control/cli/qa_main_gate/worktree.rb +62 -0
  473. data/lib/hecks/quality_control/cli/qa_main_gate.rb +135 -0
  474. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +1 -1
  475. data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +2 -3
  476. data/lib/hecks/quality_control/cli/qa_push_nudge.rb +48 -0
  477. data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +1 -1
  478. data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +1 -1
  479. data/lib/hecks/quality_control/cli/qa_tick/event_pump_step.rb +34 -0
  480. data/lib/hecks/quality_control/cli/qa_tick/output.rb +16 -1
  481. data/lib/hecks/quality_control/cli/qa_tick/push_nudge_step.rb +28 -0
  482. data/lib/hecks/quality_control/cli/qa_tick/quiesce_guard.rb +51 -0
  483. data/lib/hecks/quality_control/cli/qa_tick.rb +36 -8
  484. data/lib/hecks/quality_control/quality_control.behaviors +65 -0
  485. data/lib/hecks/quality_control/quality_control.bluebook +1131 -11
  486. data/lib/hecks/quality_control/quality_control.hecksagon +11 -0
  487. data/lib/hecks/quality_control/quality_control.ports.hecksagon +138 -0
  488. data/lib/hecks/query_ir/touchpoints.rb +5 -7
  489. data/lib/hecks/refused.rb +21 -0
  490. data/lib/hecks/release/approval.rb +6 -3
  491. data/lib/hecks/release/conditions.rb +46 -0
  492. data/lib/hecks/release/runner/gem_publisher.rb +4 -4
  493. data/lib/hecks/release/version_commit.rb +48 -0
  494. data/lib/hecks/runtime/command_interpreter/hydration.rb +5 -4
  495. data/lib/hecks/runtime/command_interpreter/persisting.rb +11 -3
  496. data/lib/hecks/runtime/command_interpreter.rb +2 -2
  497. data/lib/hecks/runtime/command_rules/admissibility.rb +0 -2
  498. data/lib/hecks/runtime/command_rules/emission.rb +0 -1
  499. data/lib/hecks/runtime/dependency_planning/expression_reads.rb +0 -1
  500. data/lib/hecks/runtime/dispatcher/planning.rb +24 -0
  501. data/lib/hecks/runtime/dispatcher/routing.rb +6 -0
  502. data/lib/hecks/runtime/dispatcher/value_routing.rb +54 -0
  503. data/lib/hecks/runtime/dispatcher.rb +7 -1
  504. data/lib/hecks/runtime/dry_run_plan.rb +60 -0
  505. data/lib/hecks/runtime/entity_element/location.rb +0 -1
  506. data/lib/hecks/runtime/entity_element/mutations.rb +0 -1
  507. data/lib/hecks/runtime/entity_interpreter/locating.rb +5 -0
  508. data/lib/hecks/runtime/entity_interpreter.rb +0 -1
  509. data/lib/hecks/runtime/errors.rb +26 -0
  510. data/lib/hecks/runtime/instance.rb +0 -1
  511. data/lib/hecks/runtime/invocation_builder.rb +0 -1
  512. data/lib/hecks/runtime/outbox/consumer_runner.rb +9 -1
  513. data/lib/hecks/runtime/outbox/relay.rb +25 -4
  514. data/lib/hecks/runtime/outbox/runnable.rb +3 -1
  515. data/lib/hecks/runtime/outbox.rb +6 -2
  516. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +18 -2
  517. data/lib/hecks/runtime/policy_interpreter.rb +17 -9
  518. data/lib/hecks/runtime/port_operation_interpreter.rb +21 -7
  519. data/lib/hecks/runtime/query_interpreter/arguments.rb +6 -5
  520. data/lib/hecks/runtime/reaction_invocation.rb +0 -1
  521. data/lib/hecks/runtime/refusal_wording.rb +12 -1
  522. data/lib/hecks/runtime/registry/context_maps.rb +1 -5
  523. data/lib/hecks/runtime/registry/declarations.rb +34 -4
  524. data/lib/hecks/runtime/registry/hecksagon_rules.rb +15 -1
  525. data/lib/hecks/runtime/registry/runtime_state.rb +10 -0
  526. data/lib/hecks/runtime/registry/world_defaults.rb +24 -2
  527. data/lib/hecks/runtime/registry/world_names.rb +99 -0
  528. data/lib/hecks/runtime/registry.rb +33 -27
  529. data/lib/hecks/runtime/saga_interpreter/compensation.rb +10 -0
  530. data/lib/hecks/runtime/saga_interpreter/correlation.rb +29 -3
  531. data/lib/hecks/runtime/saga_interpreter/delivery.rb +0 -1
  532. data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +1 -1
  533. data/lib/hecks/runtime/saga_interpreter.rb +46 -2
  534. data/lib/hecks/runtime/value/coercion.rb +36 -8
  535. data/lib/hecks/rust_build/conformance.rb +16 -5
  536. data/lib/hecks/rust_build/parser.rb +25 -0
  537. data/lib/hecks/rust_build/project_rust/codegen_run.rb +45 -12
  538. data/lib/hecks/rust_build/project_rust/declared.rb +80 -0
  539. data/lib/hecks/rust_build/project_rust/features_header.rb +22 -0
  540. data/lib/hecks/rust_build/project_rust/manifest.rb +96 -0
  541. data/lib/hecks/rust_build/project_rust/meta.rb +36 -0
  542. data/lib/hecks/rust_build/project_rust.rb +28 -90
  543. data/lib/hecks/rust_build/write_if_changed.rb +19 -4
  544. data/lib/hecks/rust_build.rb +2 -1
  545. data/lib/hecks/rust_format.rb +32 -2
  546. data/lib/hecks/secrets.rb +111 -0
  547. data/lib/hecks/shape_ledger/edge_hygiene.rb +170 -0
  548. data/lib/hecks/shape_ledger/scope.rb +51 -0
  549. data/lib/hecks/shape_ledger/status.rb +89 -0
  550. data/lib/hecks/shape_ledger.rb +78 -33
  551. data/lib/hecks/site/bluebook/site.bluebook +1 -0
  552. data/lib/hecks/storehouse/audit.rb +34 -4
  553. data/lib/hecks/storehouse/callers.rb +8 -0
  554. data/lib/hecks/storehouse/dispatching.rb +14 -3
  555. data/lib/hecks/storehouse/identity.rb +41 -0
  556. data/lib/hecks/storehouse/querying.rb +7 -7
  557. data/lib/hecks/storehouse.rb +28 -10
  558. data/lib/hecks/tickets/bluebook/adapters/work_areas.adapter +7 -0
  559. data/lib/hecks/tickets/bluebook/adapters/work_limits.adapter +7 -0
  560. data/lib/hecks/tickets/bluebook/tickets.behaviors +70 -0
  561. data/lib/hecks/tickets/bluebook/tickets.bluebook +323 -28
  562. data/lib/hecks/tickets/bluebook/tickets.hecksagon +7 -0
  563. data/lib/hecks/tickets/bluebook/tickets.ports.hecksagon +17 -0
  564. data/lib/hecks/{cli → tools}/behaviors.rb +1 -1
  565. data/lib/hecks/{cli → tools}/canonicalise.rb +1 -1
  566. data/lib/hecks/{cli → tools}/check_engine_agreement.rb +1 -1
  567. data/lib/hecks/{cli → tools}/check_era.rb +6 -6
  568. data/lib/hecks/tools/ci_gates.rb +8 -2
  569. data/lib/hecks/tools/ci_workflows.rb +98 -0
  570. data/lib/hecks/{cli → tools}/console.rb +1 -1
  571. data/lib/hecks/{cli → tools}/deploy_template_diff.rb +1 -1
  572. data/lib/hecks/{cli → tools}/doc_coverage.rb +2 -2
  573. data/lib/hecks/{cli → tools}/document.rb +1 -1
  574. data/lib/hecks/{cli → tools}/domain_stub.rb +1 -1
  575. data/lib/hecks/{cli → tools}/domain_writer.rb +1 -1
  576. data/lib/hecks/tools/downstream_model_check.rb +122 -0
  577. data/lib/hecks/tools/evolve_run.rb +2 -2
  578. data/lib/hecks/{cli → tools}/expected_era.rb +1 -1
  579. data/lib/hecks/{cli → tools}/expression_projection.rb +1 -1
  580. data/lib/hecks/{cli → tools}/follow.rb +1 -1
  581. data/lib/hecks/tools/fuzz_sweep/options.rb +40 -5
  582. data/lib/hecks/tools/fuzz_sweep/pool.rb +12 -1
  583. data/lib/hecks/tools/fuzz_sweep/shards.rb +155 -0
  584. data/lib/hecks/tools/fuzz_sweep.rb +11 -5
  585. data/lib/hecks/tools/gate.rb +38 -29
  586. data/lib/hecks/tools/gate_memo/local_files.rb +33 -0
  587. data/lib/hecks/tools/gate_memo/rehearsal.rb +54 -0
  588. data/lib/hecks/tools/gate_memo/ruby_files.rb +152 -0
  589. data/lib/hecks/tools/gate_memo/session.rb +114 -0
  590. data/lib/hecks/tools/gate_memo/standalone.rb +67 -0
  591. data/lib/hecks/tools/gate_memo.rb +196 -0
  592. data/lib/hecks/tools/gate_report.rb +56 -0
  593. data/lib/hecks/{cli → tools}/history.rb +1 -1
  594. data/lib/hecks/{cli → tools}/interview_agent.rb +1 -1
  595. data/lib/hecks/{cli → tools}/interview_aggregate.rb +1 -1
  596. data/lib/hecks/{cli → tools}/interview_draft.rb +1 -1
  597. data/lib/hecks/{cli → tools}/interview_record.rb +1 -1
  598. data/lib/hecks/{cli → tools}/interview_run.rb +2 -2
  599. data/lib/hecks/{cli → tools}/interview_session/agent_state.rb +1 -1
  600. data/lib/hecks/{cli → tools}/interview_session/catalog.rb +1 -1
  601. data/lib/hecks/{cli → tools}/interview_session/manual_findings.rb +1 -1
  602. data/lib/hecks/{cli → tools}/interview_session/proposals.rb +1 -1
  603. data/lib/hecks/{cli → tools}/interview_session.rb +2 -2
  604. data/lib/hecks/{cli → tools}/interview_shape/lifecycle.rb +1 -1
  605. data/lib/hecks/{cli → tools}/interview_shape.rb +1 -1
  606. data/lib/hecks/{cli → tools}/ir.rb +1 -1
  607. data/lib/hecks/tools/lanes/files.rb +1 -1
  608. data/lib/hecks/tools/lanes/watch_workflow.rb +6 -8
  609. data/lib/hecks/tools/lanes/workflow.rb +1 -1
  610. data/lib/hecks/tools/lanes.rb +1 -1
  611. data/lib/hecks/{cli → tools}/mcp.rb +1 -1
  612. data/lib/hecks/{cli → tools}/model_check/examination.rb +1 -1
  613. data/lib/hecks/{cli → tools}/model_check/sources.rb +1 -1
  614. data/lib/hecks/{cli → tools}/model_check.rb +1 -1
  615. data/lib/hecks/tools/move_disables/reasons.rb +35 -0
  616. data/lib/hecks/tools/move_disables.rb +211 -0
  617. data/lib/hecks/tools/move_former_name.rb +105 -0
  618. data/lib/hecks/{cli → tools}/pattern_cases.rb +1 -1
  619. data/lib/hecks/{cli → tools}/persistence_notice.rb +1 -1
  620. data/lib/hecks/{cli → tools}/present.rb +1 -1
  621. data/lib/hecks/{cli → tools}/project_cli/launcher_source.rb +32 -22
  622. data/lib/hecks/{cli → tools}/project_cli/templates.rb +22 -15
  623. data/lib/hecks/{cli → tools}/project_cli.rb +11 -7
  624. data/lib/hecks/{cli → tools}/project_diagrams.rb +3 -3
  625. data/lib/hecks/{cli → tools}/project_glossary.rb +2 -2
  626. data/lib/hecks/{cli → tools}/reference.rb +2 -2
  627. data/lib/hecks/{cli → tools}/refresh_projections.rb +1 -1
  628. data/lib/hecks/{cli → tools}/refresh_rspec_runtime_baseline.rb +1 -1
  629. data/lib/hecks/tools/regeneration_run/pool.rb +148 -0
  630. data/lib/hecks/tools/regeneration_run/scratch.rb +76 -0
  631. data/lib/hecks/tools/regeneration_run.rb +125 -103
  632. data/lib/hecks/{cli → tools}/release.rb +1 -1
  633. data/lib/hecks/{cli → tools}/release_gem.rb +1 -1
  634. data/lib/hecks/{cli → tools}/rspec_io_parallel_files.rb +1 -1
  635. data/lib/hecks/{cli → tools}/rspec_shard_files.rb +1 -1
  636. data/lib/hecks/{cli → tools}/run.rb +9 -2
  637. data/lib/hecks/{cli → tools}/run_expectations.rb +1 -1
  638. data/lib/hecks/{cli → tools}/seed_semantics_corpus.rb +4 -4
  639. data/lib/hecks/{cli → tools}/serve_query_ir_mcp.rb +1 -1
  640. data/lib/hecks/{cli → tools}/shape.rb +3 -2
  641. data/lib/hecks/{cli → tools}/smoke_http/checks.rb +1 -1
  642. data/lib/hecks/{cli → tools}/smoke_http/settings.rb +1 -1
  643. data/lib/hecks/{cli → tools}/smoke_http/transport.rb +1 -1
  644. data/lib/hecks/{cli → tools}/smoke_http.rb +1 -1
  645. data/lib/hecks/{cli → tools}/smoke_test.rb +1 -1
  646. data/lib/hecks/{cli → tools}/spec_example.rb +1 -1
  647. data/lib/hecks/tools/stage_progress.rb +54 -0
  648. data/lib/hecks/{cli → tools}/statements.rb +1 -1
  649. data/lib/hecks/{cli → tools}/stores.rb +1 -1
  650. data/lib/hecks/{cli → tools}/stress_concurrency_specs/reporting.rb +1 -1
  651. data/lib/hecks/{cli → tools}/stress_concurrency_specs/usage.rb +4 -4
  652. data/lib/hecks/{cli → tools}/stress_concurrency_specs.rb +3 -3
  653. data/lib/hecks/tools/tenant_provisioning.rb +23 -0
  654. data/lib/hecks/tools/tools_doc.rb +10 -8
  655. data/lib/hecks/tools/translation_audit/edges.rb +21 -16
  656. data/lib/hecks/tools/translation_audit/verdicts.rb +1 -1
  657. data/lib/hecks/tools/translation_audit.rb +1 -1
  658. data/lib/hecks/tools/translation_scaffold.rb +1 -1
  659. data/lib/hecks/tools.rb +4 -1
  660. data/lib/hecks/version.rb +1 -1
  661. data/lib/hecks/vocabulary.rb +61 -31
  662. data/lib/hecks/workflow_pagination/judge.rb +48 -0
  663. data/lib/hecks/workflow_pagination/statement.rb +50 -0
  664. data/lib/hecks/workflow_pagination.rb +58 -0
  665. data/lib/hecks.rb +2 -0
  666. data/lib/rubocop/cop/hecks/bare_event_and_query_names.rb +58 -0
  667. data/lib/rubocop/cop/hecks/correlates_by_aggregate.rb +39 -0
  668. data/lib/rubocop/cop/hecks/creating_command_sets.rb +75 -0
  669. data/lib/rubocop/cop/hecks/invariant_expression_language.rb +47 -0
  670. data/lib/rubocop/cop/hecks/lifecycle_needs_attribute.rb +58 -0
  671. data/lib/rubocop/cop/hecks/no_id_string_attribute.rb +49 -0
  672. data/lib/rubocop/cop/hecks/one_terminal_mark_per_lifecycle.rb +47 -0
  673. data/lib/rubocop/cop/hecks/value_object_shorthand.rb +56 -0
  674. data/prebuilt/13c04bdc5970295b310f0a980d397ba722232c8da99cc1a0cdb383249921e871.marshal +0 -0
  675. data/prebuilt/e3857b77f47d9ecc1787b2e1f5136364f3cb3444ef4aea5479f3b98167affea2.marshal +0 -0
  676. data/qa/settings.yml +23 -0
  677. data/rust/.gitignore +0 -6
  678. data/rust/Cargo.toml +2 -1
  679. data/rust/build/Cargo.toml +1 -1
  680. data/rust/build/src/binding_pass.rs +57 -4
  681. data/rust/build/src/pipeline.rs +6 -4
  682. data/rust/build/src/resolve.rs +1 -0
  683. data/rust/codegen/Cargo.toml +1 -1
  684. data/rust/codegen/src/domain_generator.rs +3 -0
  685. data/rust/codegen/src/json_codec.rs +182 -23
  686. data/rust/codegen/src/one_of_references.rs +1 -0
  687. data/rust/codegen/src/queries.rs +20 -2
  688. data/rust/codegen/src/registry.rs +21 -5
  689. data/rust/expr/Cargo.toml +1 -1
  690. data/rust/host/Cargo.toml +1 -1
  691. data/rust/host/HECKS_RELEASE +1 -1
  692. data/rust/host/core/Cargo.toml +1 -1
  693. data/rust/host/src/bin/mint_harness.rs +1 -0
  694. data/rust/host/src/boot.rs +1 -0
  695. data/rust/host/src/store/mint.rs +40 -6
  696. data/rust/lsp/Cargo.toml +1 -1
  697. data/rust/parser/Cargo.toml +1 -1
  698. data/rust/parser/src/build/correlation_keys.rs +125 -0
  699. data/rust/parser/src/build/mod.rs +1 -0
  700. data/rust/parser/src/emit.rs +55 -3
  701. data/rust/parser/src/ir.rs +33 -1
  702. data/rust/parser/src/keywords.rs +289 -1
  703. data/rust/parser/src/main.rs +2 -0
  704. data/rust/parser/src/parse/aggregate.rs +10 -1
  705. data/rust/parser/src/parse/audience.rs +65 -0
  706. data/rust/parser/src/parse/command.rs +14 -0
  707. data/rust/parser/src/parse/declaration.rs +97 -0
  708. data/rust/parser/src/parse/domain_port.rs +6 -0
  709. data/rust/parser/src/parse/mod.rs +1 -0
  710. data/rust/parser/src/parse/process_manager.rs +17 -10
  711. data/rust/parser/src/parse/world.rs +12 -8
  712. data/rust/parser/src/render_ruby.rs +9 -0
  713. data/rust/parser/src/sentence/format.rs +3 -0
  714. data/rust/parser/src/sentence/process.rs +6 -2
  715. data/rust/src/exemplar/json.rs +17 -0
  716. data/rust/src/kernel/cli.rs +27 -3
  717. data/rust/src/kernel/dispatch.rs +4 -2
  718. data/rust/src/kernel/json.rs +62 -0
  719. data/rust/src/kernel/orchestrate.rs +28 -3
  720. data/rust/src/kernel/orchestrate_guard_tests.rs +12 -12
  721. data/rust/web/Cargo.toml +1 -1
  722. metadata +389 -96
  723. data/lib/hecks/cli/command_table.rb +0 -72
  724. data/lib/hecks/cli/launcher_words.rb +0 -168
  725. data/lib/hecks/cli.rb +0 -133
  726. data/lib/hecks/hecks/agents.bluebook +0 -246
  727. data/lib/hecks/hecks/codebase.bluebook +0 -3209
  728. data/lib/hecks/hecks/custodian.bluebook +0 -1300
  729. data/lib/hecks/hecks/ledger.bluebook +0 -190
  730. data/lib/hecks/hecks/rehearsal.bluebook +0 -437
  731. data/lib/hecks/hecks/tooling.bluebook +0 -1234
  732. data/lib/hecks/hecks/translations/2-148748.bluebook +0 -2
  733. data/lib/hecks/hecks/translations/2-15a2e4.bluebook +0 -2
  734. data/lib/hecks/hecks/translations/2-1b447c.bluebook +0 -5
  735. data/lib/hecks/hecks/translations/2-240474.bluebook +0 -2
  736. data/lib/hecks/hecks/translations/2-44446d.bluebook +0 -2
  737. data/lib/hecks/hecks/translations/2-46ca26.bluebook +0 -2
  738. data/lib/hecks/hecks/translations/2-473eab.bluebook +0 -2
  739. data/lib/hecks/hecks/translations/2-75cc28.bluebook +0 -2
  740. data/lib/hecks/hecks/translations/2-781c07.bluebook +0 -2
  741. data/lib/hecks/hecks/translations/2-84c18b.bluebook +0 -2
  742. data/lib/hecks/hecks/translations/2-aa5fff.bluebook +0 -2
  743. data/lib/hecks/hecks/translations/2-bfdb48.bluebook +0 -2
  744. data/lib/hecks/hecks/translations/2-cd96d8.bluebook +0 -10
  745. data/lib/hecks/hecks/translations/2-d43f71.bluebook +0 -2
  746. data/lib/hecks/hecks/translations/2-eea577.bluebook +0 -2
  747. data/lib/hecks/hecks/translations/2-f53248.bluebook +0 -2
  748. data/lib/hecks/hecks/translations/2-fbb677.bluebook +0 -2
  749. data/lib/hecks/hecks/translations/2-ffdf12.bluebook +0 -6
  750. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +0 -36
  751. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +0 -56
  752. data/prebuilt/31cf81e12f16236ad26249be590cfea3799c9db67432e6a4ef54b801c355b6ae.marshal +0 -0
  753. data/prebuilt/68ecb2bd3abb1a221007db4f2b0375834c13aaccac8f2b99778e8517f11aa113.marshal +0 -0
  754. data/prebuilt/verdicts-0328c2403383837d780ad5ed81d1da351c56436b894cf9015b5d56b8f1f1bf10.json +0 -1
@@ -5,6 +5,17 @@
5
5
  Hecks.hecksagon "QualityControl" do
6
6
  attaches "Governance"
7
7
  persisted_by "Memory"
8
+
9
+ # The fixer's steps, which the ledger records as the bug's state. Declarative: the Fixer domain
10
+ # emits them, and the Record policies above react.
11
+ subscribe "Fixer.AttemptClaimed"
12
+ subscribe "Fixer.AttemptInvestigated"
13
+ subscribe "Fixer.FixReady"
14
+ subscribe "Fixer.FixVerified"
15
+
16
+ # The coder's submitted branch, which starts the main maintenance run. Declarative: the Coder domain
17
+ # emits it, and the StartOnSubmission policy reacts.
18
+ subscribe "Coder.WorkSubmitted"
8
19
  end
9
20
 
10
21
  # The anti-corruption layer for Governance, which the bluebook's roles are checked against.
@@ -25,6 +25,28 @@ Hecks.hecksagon "QualityControl" do
25
25
  end
26
26
  end
27
27
 
28
+ # Bound by adapters/run_reader. It reads a CI run of main for its failing spec files, reports each
29
+ # to RedSpec, and answers the commit and whether the run settled.
30
+ QualityControl::MainRun.port "Reader" do
31
+ asks "Read", to: MainRun do
32
+ attribute :run, MainRunId
33
+ attribute :repo, HeadRepo
34
+ answers "MainRunRead"
35
+ refuses "MainRunReadRefused"
36
+ end
37
+ end
38
+
39
+ # Bound by adapters/push_due_reader. It asks the rehearsal port's `Due` whether a push of local main
40
+ # is due, applies the world's `push_nudge` thresholds, and answers the flags and numbers the
41
+ # bluebook's policies file the push-due Work row from.
42
+ QualityControl::PushNudge.port "PushDue" do
43
+ asks "Read", to: PushNudge do
44
+ attribute :nudge, NudgeKey
45
+ answers "PushDueRead"
46
+ refuses "PushDueReadRefused"
47
+ end
48
+ end
49
+
28
50
  # Queries answered from outside the domain. The bluebook declares each question and the value
29
51
  # object its answer takes and never says who answers it; each `answers_query` binds it to the
30
52
  # `*Tools` port's adapter, which runs the script's own command and answers what it printed.
@@ -37,6 +59,15 @@ Hecks.hecksagon "QualityControl" do
37
59
  answers_query "DiscoverExternalDomains"
38
60
  end
39
61
 
62
+ # Answers a requested pump run by running the `qa_event_pump` script, as the tick does.
63
+ QualityControl::EventPump.port "PumpTools" do
64
+ asks "Execute", to: EventPump do
65
+ attribute :run, PumpRun
66
+ answers "PumpAnswered"
67
+ refuses "PumpRefused"
68
+ end
69
+ end
70
+
40
71
  QualityControl::Sweep.port "SweepTools" do
41
72
  answers_query "Tick"
42
73
  answers_query "Run"
@@ -52,4 +83,111 @@ Hecks.hecksagon "QualityControl" do
52
83
  QualityControl::Clearance.port "ClearanceTools" do
53
84
  answers_query "CheckPullRequests"
54
85
  end
86
+
87
+ # Remote CI's verdict on one commit of a repository's main, answered by `adapters/ci_head`, which
88
+ # reads the
89
+ # runs GitHub reports for the commit. A run still going is a refusal: no verdict until every job
90
+ # settled.
91
+ QualityControl::Head.port "CiHead" do
92
+ asks "Check", to: Head do
93
+ attribute :branch, HeadBranch
94
+ attribute :repo, HeadRepo
95
+ answers "HeadChecked"
96
+ refuses "HeadRefused"
97
+ end
98
+ end
99
+
100
+ # Answered by `adapters/image_roll`: the classifier reads remote CI's green commit's change set,
101
+ # and the roll runs the console image's deploy; an infra roll also needs the quick gate on record
102
+ # green. A refusal ends the chain.
103
+ QualityControl::ImageRoll.port "ImageRoll" do
104
+ asks "Classify", to: ImageRoll do
105
+ attribute :branch, RollBranch
106
+ attribute :repo, RollRepo
107
+ answers "ImageClassified"
108
+ refuses "ClassifyRefused"
109
+ end
110
+
111
+ asks "Roll", to: ImageRoll do
112
+ attribute :app, AppName
113
+ answers "RollAnswered"
114
+ refuses "RollRefused"
115
+ end
116
+ end
117
+
118
+ # Answered by `adapters/main_maintenance`: the quick gate on main, the reconcile, and the push through the
119
+ # train. Each answers the event its policy waits for, or refuses with a named event and stops the run.
120
+ QualityControl::Maintenance.port "MainMaintenance" do
121
+ asks "Gate", to: Maintenance do
122
+ answers "GateVerdict"
123
+ refuses "GateRefused"
124
+ end
125
+
126
+ asks "Reconcile", to: Maintenance do
127
+ answers "ReconcileDone"
128
+ refuses "ReconcileRefused"
129
+ end
130
+
131
+ asks "Push", to: Maintenance do
132
+ answers "Pushed"
133
+ refuses "PushRefused"
134
+ end
135
+
136
+ # The mint answers `Minted`; a refusal (no would_mint, a stranded landing, the era check's refusal) is
137
+ # `MintRefused`. The landing answers `Landed`, and a landing that fails leaves the ledger ahead of main:
138
+ # that refusal is `MintStranded`, which stops every later mint until the owner resolves it.
139
+ # The mint's facts: the domain, the era and branch it lands, the rehearsal's verdict and the watermark it
140
+ # read, and whether the mint was confirmed. They are not attributes of Maintenance, so each is declared here.
141
+ # A mint with no `confirm` runs only when the auto-mint rule holds; a held mint is refused as
142
+ # "needs owner approval", and `AskOwnerApprovalOnHeldMint` asks for the approval.
143
+ asks "Mint", to: Maintenance do
144
+ attribute :domain, String
145
+ attribute :era, Integer
146
+ attribute :sha, MaintenanceSha
147
+ attribute :branch, String
148
+ attribute :watermark, Integer
149
+ attribute :rehearsal_verdict, MintVerdict
150
+ attribute :refusal_total, Integer, optional: true
151
+ attribute :ledger_dir, String, optional: true
152
+ attribute :confirm, Confirmation, optional: true
153
+ answers "Minted"
154
+ refuses "MintRefused"
155
+ end
156
+
157
+ # Answered by the mint entry point's approval step: a mint the auto-mint rule does not cover waits
158
+ # for the owner's confirm. The answer is `MintNeedsApproval`, and nothing follows it.
159
+ asks "Approval", to: Maintenance do
160
+ attribute :domain, String
161
+ attribute :era, Integer
162
+ attribute :reason, MintRefusal
163
+ answers "MintNeedsApproval"
164
+ refuses "MintApprovalRefused"
165
+ end
166
+
167
+ asks "Land", to: Maintenance do
168
+ attribute :era, MintedEra
169
+ attribute :sha, MaintenanceSha
170
+ attribute :branch, String
171
+ answers "Landed"
172
+ refuses "MintStranded"
173
+ end
174
+ end
175
+
176
+ # Answered by the `gh` adapter for the release PR: opening the PR for a version bump, and writing the
177
+ # release trailer on its merge once the owner has approved it. A refusal names the failure and stops the run.
178
+ QualityControl::ReleasePR.port "ReleaseGh" do
179
+ asks "OpenPullRequest", to: ReleasePR do
180
+ attribute :branch, ReleaseBranch
181
+ attribute :sha, MaintenanceSha
182
+ answers "ReleaseOpened"
183
+ refuses "ReleaseOpenRefused"
184
+ end
185
+
186
+ asks "WriteTrailer", to: ReleasePR do
187
+ attribute :approver, ReleaseApprover
188
+ attribute :trailer, ReleaseTrailer
189
+ answers "TrailerWritten"
190
+ refuses "TrailerRefused"
191
+ end
192
+ end
55
193
  end
@@ -33,7 +33,7 @@ module Hecks
33
33
  { touchpoint: "meta-domain grammar declares it", present: meta_declared(name).map(&:to_s).include?(field) },
34
34
  { touchpoint: "docs/resolution-rules/ names it", present: resolution_rule_mentions?(field) },
35
35
  { touchpoint: "Assembly::Contracts consumes it", present: contract_consumes?(name, field) },
36
- { touchpoint: "Reconstruction's hand-typed method reads it", present: reconstruction_reads?(name, field) },
36
+ { touchpoint: "Reconstruction's hand-typed method reads it", present: reconstruction_reads(name, field) },
37
37
  { touchpoint: "fuzzer FEATURE_COVERAGE/GUARANTEED_BY_CONSTRUCTION claims it", present: fuzzer_claims?(name, field) },
38
38
  { touchpoint: "Rust mirror (rust/parser/src/parse/*.rs) mentions it", present: rust_mentions?(field) }
39
39
  ]
@@ -52,13 +52,11 @@ module Hecks
52
52
  false
53
53
  end
54
54
 
55
- # nil, not false, for constructs without a hand-typed method: the touchpoint does not apply.
56
- def reconstruction_reads?(name, field)
55
+ # Whether the hand-typed Reconstruction method reads `field`. Answers nil, not false, for a
56
+ # construct without one: nil means "not applicable", false means "applicable, and it fails",
57
+ # and the touchpoint reports each differently. Named without `?` because it is not a predicate.
58
+ def reconstruction_reads(name, field)
57
59
  method_name = RECONSTRUCTION_METHODS[name]
58
- # rubocop:disable-next Style/ReturnNilInPredicateMethodDefinition -- nil vs
59
- # false is a deliberate distinction here: nil means "not applicable" (no
60
- # hand-typed method to check), false means "applicable, and it fails" —
61
- # see the spec's own "not-applicable (nil), not false" example.
62
60
  return nil unless method_name
63
61
 
64
62
  reconstruction_body(method_name).include?("#{field}:")
data/lib/hecks/refused.rb CHANGED
@@ -18,6 +18,9 @@ module Hecks
18
18
  # The last constant name of a class's path, such as `NotFound` of `Hecks::Runtime::NotFound`.
19
19
  LAST_NAME = /\w+\z/
20
20
 
21
+ # The boundary between a lower-case or digit letter and a capital, where a snake-case word starts.
22
+ CAMEL_BOUNDARY = /([a-z\d])([A-Z])/
23
+
21
24
  # @return [Symbol, nil] the attribute the refusal is about, when it is about one; the
22
25
  # first in sorted order when it names several
23
26
  attr_reader :attribute
@@ -75,6 +78,24 @@ module Hecks
75
78
  end
76
79
  end
77
80
 
81
+ # A stable identifier for the sort of no this is, for scripts and agents to branch on: the
82
+ # class's own name in snake case (`NotFound` is `not_found`). The names are the
83
+ # `DomainRefusal` vocabulary rows, so a new refusal gets its code by being declared there.
84
+ #
85
+ # @return [String] the snake-case name of the refusal's class
86
+ def code = snake_case(class_last_name)
87
+
88
+ # The last constant name of this refusal's class path, such as `NotFound`.
89
+ #
90
+ # @return [String] the class's own name without its namespace
91
+ def class_last_name = self.class.name[LAST_NAME]
92
+
93
+ # A CamelCase name in snake case, one word per capital.
94
+ #
95
+ # @param name [String] a constant's last name, such as `NotFound`
96
+ # @return [String] the name in snake case, such as `not_found`
97
+ def snake_case(name) = name.gsub(CAMEL_BOUNDARY, '\\1_\\2').downcase
98
+
78
99
  # @return [String, nil] a JSON Pointer to the offending value, such as `/balance/cents`
79
100
  def path = @path || (@attribute && "/#{@attribute}")
80
101
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "hecks/vocabulary"
4
+ require "hecks/release/version_commit"
4
5
 
5
6
  module Hecks
6
7
  module Release
@@ -57,12 +58,14 @@ module Hecks
57
58
 
58
59
  # Reads the decision's inputs from the environment `release.yml` gives it.
59
60
  #
60
- # @param env [#[]] `COMMIT_MESSAGE`, `TAG_EXISTS` (true/false), `APPROVED_BY`
61
+ # @param env [#[]] `COMMIT_MESSAGE`, or `COMMIT` (the first-parent commit that set the version,
62
+ # whose message is read as {VersionCommit} reads it), `TAG_EXISTS` (true/false), `APPROVED_BY`
61
63
  # @param out [#puts] where the words go
62
64
  # @return [Integer] the exit status: 0 to go ahead, 1 to refuse
63
65
  def check(env: ENV, out: $stdout)
64
- ok, words = verdict(message: env["COMMIT_MESSAGE"], tag_exists: env["TAG_EXISTS"] == "true",
65
- explicit: env["APPROVED_BY"])
66
+ ok, words = verdict(message: env["COMMIT_MESSAGE"] || VersionCommit.message(env["COMMIT"].to_s),
67
+ tag_exists: env["TAG_EXISTS"] == "true",
68
+ explicit: env["APPROVED_BY"])
66
69
  out.puts(ok ? "release approval: #{words}" : "::error::#{words}")
67
70
  ok ? 0 : 1
68
71
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Release
5
+ # The auto-approval conditions of a release PR, judged from facts a check has gathered.
6
+ #
7
+ # The names are the `ReleaseCondition` values the QualityControl bluebook declares. A release is
8
+ # approved only when every condition holds; otherwise the first failure in the order below is
9
+ # named, and that name is the refusal.
10
+ module Conditions
11
+ # The value an approval accepts.
12
+ MET = "met"
13
+
14
+ module_function
15
+
16
+ # @param version [String] the version the release bumps to
17
+ # @param stable_head [Boolean] whether the commit is on stable's head after promotion
18
+ # @param checks_green [Boolean] whether every required check passed on the commit
19
+ # @param changelog_dated [Boolean] whether the changelog has a dated `## [version]` heading
20
+ # @param versions [Hash{String => String}] each version file's version, keyed by its name
21
+ # @return [String] `met`, or the name of the first condition that failed
22
+ def judge(version:, stable_head:, checks_green:, changelog_dated:, versions:)
23
+ return "not_on_stable_head" unless stable_head
24
+ return "checks_not_green" unless checks_green
25
+ return "changelog_undated" unless changelog_dated
26
+ return "version_mismatch" unless versions_agree?(version, versions)
27
+
28
+ MET
29
+ end
30
+
31
+ # @param changelog [String] the text of the changelog
32
+ # @param version [String] the version the release bumps to
33
+ # @return [Boolean] whether a `## [version] - YYYY-MM-DD` heading stands in the changelog
34
+ def changelog_dated?(changelog, version)
35
+ changelog.match?(/^## \[#{Regexp.escape(version)}\] - \d{4}-\d{2}-\d{2}$/)
36
+ end
37
+
38
+ # @param version [String] the version the release bumps to
39
+ # @param versions [Hash{String => String}] each version file's version, keyed by its name
40
+ # @return [Boolean] whether every version file names the same version
41
+ def versions_agree?(version, versions)
42
+ versions.any? && versions.values.all?(version)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,13 +1,12 @@
1
1
  require_relative "commands"
2
2
  require_relative "clean_tree"
3
3
  require_relative "git"
4
- require_relative "../../cli/release_gem"
5
4
  require "hecks/hecks/adapters/codebase/gem_registry"
6
5
 
7
6
  module Hecks
8
7
  module Release
9
8
  class Runner
10
- # The gem step: hands the push to `Hecks::CLI::ReleaseGem`, which builds and pushes
9
+ # The gem step: hands the push to `Hecks::Tools::ReleaseGem`, which builds and pushes
11
10
  # it with the key 1Password holds; a dry run only builds it, then deletes it.
12
11
  class GemPublisher
13
12
  # @param root [String] the repository root
@@ -32,9 +31,10 @@ module Hecks
32
31
 
33
32
  CleanTree.new(git: Git.new(root: @root, commands: @commands)).check!
34
33
 
34
+ require_relative "../../tools/release_gem"
35
35
  @console.say("Publishing hecks #{version} to rubygems.org...")
36
- status = Hecks::CLI::ReleaseGem.call(root: @root, commands: @commands, out: @console.out,
37
- err: @console.err, version: version)
36
+ status = Hecks::Tools::ReleaseGem.call(root: @root, commands: @commands, out: @console.out,
37
+ err: @console.err, version: version)
38
38
  raise CommandFailed, "the gem push was refused" unless status.zero?
39
39
  end
40
40
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Hecks
6
+ module Release
7
+ # The message of the commit that set the version, as the owner's approval is read from it.
8
+ #
9
+ # A release branch merged with a merge commit leaves the version change on the merged side:
10
+ # the first-parent commit that touches `lib/hecks/version.rb` is then the merge, whose message
11
+ # the owner never wrote. For a merge, the message is that of the newest non-merge commit on
12
+ # the merged side that changed the `VERSION =` line, so a bump without the trailer still
13
+ # refuses, however the merge is worded.
14
+ module VersionCommit
15
+ # Raised when git cannot answer, so a release is never judged from a guess.
16
+ class GitFailed < StandardError; end
17
+
18
+ VERSION_LINE = "^ *VERSION = "
19
+ VERSION_FILE = "lib/hecks/version.rb"
20
+
21
+ module_function
22
+
23
+ # @param commit [String] the first-parent commit that touches the version file
24
+ # @param dir [String] the git work tree
25
+ # @return [String] the message of the commit that set the version
26
+ def message(commit, dir: Dir.pwd)
27
+ parents = git(dir, "rev-list", "--parents", "-n", "1", commit).split.drop(1)
28
+ side = parents.size > 1 ? side_message(dir, commit, parents) : ""
29
+ side.strip.empty? ? git(dir, "log", "-1", "--format=%B", commit) : side
30
+ end
31
+
32
+ # @return [String] the newest non-merge bump on the merged side, or "" when it has none
33
+ def side_message(dir, commit, parents)
34
+ git(dir, "log", "--no-merges", "-1", "--format=%B", "-G#{VERSION_LINE}", "#{parents.first}..#{commit}",
35
+ "--", VERSION_FILE)
36
+ end
37
+
38
+ # @return [String] what `git` prints in `dir`
39
+ # @raise [GitFailed] when git refuses
40
+ def git(dir, *args)
41
+ out, status = Open3.capture2e("git", "-C", dir, *args)
42
+ raise GitFailed, "git #{args.join(" ")} failed: #{out}" unless status.success?
43
+
44
+ out
45
+ end
46
+ end
47
+ end
48
+ end
@@ -111,10 +111,11 @@ module Hecks
111
111
  end
112
112
 
113
113
  def raise_record_missing(aggregate, id)
114
- raise(NotFound, RefusalWording.render_site("NotFound", "record_missing",
115
- aggregate: aggregate.hecks_name,
116
- identity: identity_reading(aggregate),
117
- offered: Rendering.describe(id)))
114
+ message = RefusalWording.render_site("NotFound", "record_missing",
115
+ aggregate: aggregate.hecks_name,
116
+ identity: identity_reading(aggregate),
117
+ offered: Rendering.describe(id))
118
+ raise(NotFound, RefusalWording.with_creator_hint(message, aggregate))
118
119
  end
119
120
 
120
121
  def raise_creating_no_identity(command, aggregate)
@@ -20,6 +20,7 @@ module Hecks
20
20
 
21
21
  if ctx.dry_run
22
22
  step(:save) { check_dry_run_creates_duplicate(ctx) }
23
+ DryRunPlan.write(ctx.aggregate, ctx.instance)
23
24
  else
24
25
  step(:save) { persist_and_check(ctx) }
25
26
  end
@@ -47,15 +48,22 @@ module Hecks
47
48
  # this interpreter reading the record first to check — a
48
49
  # `repository.find` before every atomic_put would be exactly the
49
50
  # read this strategy exists to skip.
50
- ctx.repository.atomic_put(ctx.instance, insert_only: ctx.command.creates?)
51
+ ctx.repository.atomic_put(ctx.instance, insert_only: ctx.command.creates?, mints_era: mints_era?(ctx))
51
52
  else
52
53
  # `expected_version:` is nil for a brand-new record or a
53
54
  # non-CAS repository, either of which falls through to a
54
- # plain, unconditional save inside `AppendOnly#save`.
55
- ctx.repository.save(ctx.instance, expected_version: ctx.instance_version)
55
+ # plain, unconditional save inside `AppendOnly#save`. `mints_era:`
56
+ # reaches the journal entry only when this command declares it.
57
+ ctx.repository.save(ctx.instance, expected_version: ctx.instance_version, mints_era: mints_era?(ctx))
56
58
  end
57
59
  end
58
60
 
61
+ # The one-write allowance this command's record holds through an unminted boot: the
62
+ # binding names it (`mints_era` in the world), or the command still says `mints_era true`.
63
+ def mints_era?(ctx)
64
+ ctx.command.mints_era? || ctx.repository.mints_era_declared?(ctx.aggregate_hecks_name, ctx.command_hecks_name)
65
+ end
66
+
59
67
  def raise_for_persistence_outcome!(ctx)
60
68
  case ctx.outcome_status
61
69
  when :conflicted
@@ -4,6 +4,7 @@ require_relative "command_interpreter/mutation_applier"
4
4
  require_relative "command_interpreter/enforcement"
5
5
  require_relative "command_interpreter/hydration"
6
6
  require_relative "command_interpreter/persisting"
7
+ require_relative "dry_run_plan"
7
8
  require_relative "command_interpreter/delegation"
8
9
  require_relative "../rendering"
9
10
  require_relative "errors"
@@ -68,7 +69,6 @@ module Hecks
68
69
  # @param dispatch_key [String, nil] a saga dispatch's identity; an applied one runs no step
69
70
  # @return [Array] the settled instance, events, plan, persistence outcome, and outbox rows
70
71
  # @raise [StandardError] a domain refusal, a StaleWrite once retries run out, or a WiringError
71
- # rubocop:disable-next Metrics/ParameterLists -- the public dispatch signature every entry point calls
72
72
  def call(domain, aggregate, command, invocation, correlation = nil, dry_run: false, dispatch_key: nil)
73
73
  args = invocation.to_args
74
74
  settings = { invocation:, route: invocation.target, correlation:, dry_run:, dispatch_key: }
@@ -181,7 +181,7 @@ module Hecks
181
181
  # `dry_run:` skips this too — nothing was committed, so `ctx.result`
182
182
  # stays nil.
183
183
  def step_emit(ctx)
184
- return if ctx.dry_run
184
+ return DryRunPlan.emits(ctx.command) if ctx.dry_run
185
185
 
186
186
  ctx.result = step(:emit) { emit_events(ctx) }
187
187
  end
@@ -29,7 +29,6 @@ module Hecks
29
29
  # @return [void]
30
30
  # @raise [Runtime::GivenNotMet] a declared `given` does not hold
31
31
  # @raise [Runtime::LifecycleRefused] `declaring`'s `from:` guard refuses the state
32
- # rubocop:disable-next Metrics/ParameterLists -- the dispatch context every interpreter passes by keyword
33
32
  def enforce_givens(subject, command, args, domain:, declaring: nil, parent: nil, correction: {})
34
33
  # A rule reads only within its own aggregate boundary (ADR 0025);
35
34
  # `dereference` below resolves fresh reference arguments only,
@@ -111,7 +110,6 @@ module Hecks
111
110
  # @param correction [Hash{Symbol => Object}] `corrects` event bindings, if any
112
111
  # @return [void]
113
112
  # @raise [Runtime::EnsuresNotMet] a declared `ensures` does not hold
114
- # rubocop:disable-next Metrics/ParameterLists -- the dispatch context every interpreter passes by keyword
115
113
  def enforce_ensures(subject, command, args, old:, domain:, parent: nil, correction: {})
116
114
  state = GuardState.new(subject)
117
115
  # Same aggregate-boundary rule as enforce_givens (ADR 0025) —
@@ -15,7 +15,6 @@ module Hecks
15
15
  # @param repository [Ports::Persistence::AppendOnly] asked to `record_event` if it can
16
16
  # @param correlation [Hash, nil] saga correlation, set before the event freezes
17
17
  # @return [Array<Runtime::Event>] the emitted events in `emits` order
18
- # rubocop:disable-next Metrics/ParameterLists -- the positional signature both interpreters call
19
18
  def emit(command, domain, aggregate, instance, args, repository, correlation = nil)
20
19
  stamp = { aggregate: "#{domain}::#{aggregate.hecks_name}", id: instance.id,
21
20
  payload: args, correlation: correlation }
@@ -13,7 +13,6 @@ module Hecks
13
13
  # raises before it is stored, so a failure is never cached. Written from dispatch
14
14
  # threads, so every access holds PATHS_LOCK; the cache is cleared when it reaches
15
15
  # PATHS_CACHE_LIMIT entries, so distinct texts cannot grow it without bound.
16
- # rubocop:disable-next Style/MutableConstant
17
16
  PATHS_CACHE = {}
18
17
  PATHS_LOCK = Mutex.new
19
18
  PATHS_CACHE_LIMIT = 4096
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Runtime
5
+ class Dispatcher
6
+ # What a command would write and announce, listed without writing or announcing it. Runs the
7
+ # in-memory pipeline `dry_run?` runs; the save and emit seams report to DryRunPlan.
8
+ module Planning
9
+ # Lists what a command would write and announce, without writing or announcing it.
10
+ #
11
+ # Runs the same in-memory pipeline as `dry_run?`, with the save and emit seams reporting
12
+ # instead of acting, so every command gets its plan from one place.
13
+ #
14
+ # @param verb [String] the fully qualified aggregate command verb
15
+ # @param args [Hash{Symbol => Object}] the facts as flat keywords
16
+ # @return [Array<String>] one `would write` or `would emit` line per effect, in order
17
+ # @raise [StandardError] any refusal the real dispatch would raise
18
+ def plan_flat(verb, **args)
19
+ DryRunPlan.collect { dry_run_call(flat_call(verb, args)) }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,7 @@ require_relative "../errors"
2
2
  require_relative "../refusal_wording"
3
3
  require_relative "../invocation"
4
4
  require_relative "../../naming"
5
+ require_relative "value_routing"
5
6
 
6
7
  module Hecks
7
8
  module Runtime
@@ -9,6 +10,8 @@ module Hecks
9
10
  # Finds what a verb names and runs it through the interpreter that owns it. Mixed into
10
11
  # {Dispatcher}, which holds the interpreters and the registry these read.
11
12
  module Routing
13
+ include ValueRouting
14
+
12
15
  # One dispatch request as the caller spelled it: the verb, its receiver and facts, and
13
16
  # the saga correlation to stamp on emitted events.
14
17
  Call = Struct.new(:verb, :to, :with, :saga_correlation, :dispatch_key, :flat, keyword_init: true)
@@ -57,6 +60,9 @@ module Hecks
57
60
 
58
61
  def route_aggregate(call, domain, aggregate, aggregate_name, command_name)
59
62
  command = command_of(aggregate, aggregate_name, command_name)
63
+ handler = value_handler(domain, aggregate, command, call)
64
+ return route_port(call, domain, aggregate, handler) if handler
65
+
60
66
  invocation = Invocation.from_call(call.verb, to: call.to, with: call.with, flat: call.flat) { command }
61
67
  @commands.call(domain, aggregate, command, invocation, call.saga_correlation, dispatch_key: call.dispatch_key)
62
68
  end
@@ -0,0 +1,54 @@
1
+ module Hecks
2
+ module Runtime
3
+ class Dispatcher
4
+ # Routes a command value to the port operation a hecksagon binds to it: the operations whose
5
+ # `handles` name this command and value (ADR 0163 step 52). Mixed into {Routing}.
6
+ module ValueRouting
7
+ private
8
+
9
+ # The port operation a command value is routed to, or nil when no hecksagon binds the
10
+ # command by value. A command that has bindings refuses a value none of them names.
11
+ def value_handler(domain, aggregate, command, call)
12
+ key = command_key(aggregate, command)
13
+ bindings = value_bindings(domain, key)
14
+ return nil if bindings.empty?
15
+
16
+ supplied = supplied_values(call)
17
+ found = bindings.find { |_, value| supplied.include?(value) }
18
+ return found.first if found
19
+
20
+ no_value_handler!(key, bindings, supplied)
21
+ end
22
+
23
+ def command_key(aggregate, command) = "#{aggregate.name}.#{Naming.snake(command.hecks_name)}!"
24
+
25
+ # Every port operation of the domain's aggregates that names the command, with its value.
26
+ def value_bindings(domain, key)
27
+ bluebook = @registry.bluebook(domain)
28
+ return [] unless bluebook
29
+
30
+ handling_operations(bluebook).flat_map { |operation| bindings_of(operation, key) }
31
+ end
32
+
33
+ def handling_operations(bluebook) = bluebook.aggregates.flat_map(&:ports).flat_map(&:operations)
34
+
35
+ def bindings_of(operation, key)
36
+ operation.handles.select { |held| held[:command] == key }.map { |held| [operation, held[:value]] }
37
+ end
38
+
39
+ # The string values the call supplies, one level down from a value object
40
+ # (`target: {value:}`).
41
+ def supplied_values(call)
42
+ facts = (call.with || {}).merge(call.flat || {})
43
+ facts.values.flat_map { |value| value.is_a?(Hash) ? value.values : [value] }.grep(String)
44
+ end
45
+
46
+ def no_value_handler!(key, bindings, supplied)
47
+ handled = bindings.map { |_, value| value }.join(", ")
48
+ raise(UnknownVerb, "#{key} has no handler for #{supplied.inspect}; " \
49
+ "its hecksagon handles #{handled.inspect}")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -16,6 +16,8 @@ require_relative "dispatcher/routing"
16
16
  require_relative "dispatcher/validating"
17
17
  require_relative "dispatcher/queries"
18
18
  require_relative "declarations"
19
+ require_relative "dry_run_plan"
20
+ require_relative "dispatcher/planning"
19
21
  require_relative "../naming"
20
22
 
21
23
  module Hecks
@@ -27,6 +29,7 @@ module Hecks
27
29
  include Validating
28
30
  include Queries
29
31
  include Declarations
32
+ include Planning
30
33
 
31
34
  MAX_REACTION_DEPTH = 5
32
35
 
@@ -67,6 +70,10 @@ module Hecks
67
70
  # @return [Array<Hash{Symbol => Object}>]
68
71
  def sagas = @registry.saga_log
69
72
 
73
+ # The interpreter that moves sagas through their stages, for `resume` and redelivery.
74
+ # @return [SagaInterpreter]
75
+ def saga_interpreter = @sagas
76
+
70
77
  # Exposes the raw inputs each saga dispatch bound its arguments from (Ruby-only).
71
78
  #
72
79
  # @return [Array<Hash{Symbol => Object}>]
@@ -147,7 +154,6 @@ module Hecks
147
154
  # @raise [Runtime::UnknownVerb] if the domain, aggregate, port or operation is undeclared
148
155
  # @raise [Runtime::TypeMismatch] if no receiving identity is found, or `to:`/`with:` is bad
149
156
  # @raise [Runtime::NotFound] if the receiving record does not exist
150
- # rubocop:disable-next Metrics/ParameterLists -- the public dispatcher's parts, one argument per verb segment
151
157
  def dispatch_port(domain, aggregate_name, port_name, operation_name, to: nil, with: nil, flat: {})
152
158
  verb = "#{domain}::#{aggregate_name}.#{port_name}.#{operation_name}"
153
159
  aggregate = resolve_aggregate(domain, aggregate_name, verb)