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
@@ -4,11 +4,11 @@ require "json"
4
4
  require "time"
5
5
  require_relative "console_capture"
6
6
  require_relative "in_process_operations/tailing"
7
- require "hecks/cli/run"
8
- require "hecks/cli/model_check"
9
- require "hecks/cli/smoke_test"
10
- require "hecks/cli/behaviors"
11
- require "hecks/cli/refresh_projections"
7
+ require "hecks/tools/run"
8
+ require "hecks/tools/model_check"
9
+ require "hecks/tools/smoke_test"
10
+ require "hecks/tools/behaviors"
11
+ require "hecks/tools/refresh_projections"
12
12
 
13
13
  module Hecks
14
14
  module Adapters
@@ -16,7 +16,7 @@ module Hecks
16
16
  # the asks of `ModelCheckRun` and `Operation`, plus the `Follow` query.
17
17
  #
18
18
  # An ask is handed the whole record it was made on (its `held_state`), so each method reads the
19
- # record's fields, runs the existing `Hecks::CLI::*` entry point captured, and answers the text
19
+ # record's fields, runs the existing `Hecks::Tools::*` entry point captured, and answers the text
20
20
  # it printed. An answer records a success; a raise records a refusal, so a check that finds
21
21
  # something, or a run that fails, is refused with the report as its reason.
22
22
  module InProcessOperations
@@ -43,7 +43,7 @@ module Hecks
43
43
  argv = check_argv(held)
44
44
 
45
45
  text = ConsoleCapture.answer do
46
- CLI::ModelCheck.call(argv, program: "hecks model_check", root: checkout_root)
46
+ Tools::ModelCheck.call(argv, program: "hecks model_check", root: checkout_root)
47
47
  end
48
48
  { report: { value: text }, checked: { value: text.scan(REPORT_HEADER).size } }
49
49
  end
@@ -59,7 +59,7 @@ module Hecks
59
59
  script = plain(held[:script])
60
60
  argv += script ? [script] : [plain(held[:verb]), *words(held[:arguments])].compact
61
61
 
62
- output(ConsoleCapture.answer_apart { CLI::Run.call(argv, program: "hecks run") })
62
+ output(ConsoleCapture.answer_apart { Tools::Run.call(argv, program: "hecks run") })
63
63
  end
64
64
 
65
65
  # Forces every read-model projection the domain declares to catch up.
@@ -68,7 +68,7 @@ module Hecks
68
68
  # @return [Hash{Symbol => Hash}] `output:` how many projections were refreshed
69
69
  # @raise [Runtime::NotFound] if the domain cannot be found
70
70
  def refresh(**held)
71
- count = CLI::RefreshProjections.call(boot(held[:subject]))
71
+ count = Tools::RefreshProjections.call(boot(held[:subject]))
72
72
  output("refreshed #{count} projection(s)")
73
73
  end
74
74
 
@@ -105,7 +105,7 @@ module Hecks
105
105
  # @raise [ConsoleCapture::Failure] when any test failed, errored or did not parse
106
106
  def verify(**held)
107
107
  argv = [plain(held[:subject])].compact
108
- output(ConsoleCapture.answer { CLI::Behaviors.call(argv, program: "hecks run_behaviors") })
108
+ output(ConsoleCapture.answer { Tools::Behaviors.call(argv, program: "hecks run_behaviors") })
109
109
  end
110
110
 
111
111
  # Boots a wired domain and dispatches one synthesized call per command and report.
@@ -118,11 +118,9 @@ module Hecks
118
118
  domain = plain(held[:subject]) || (checkout_root ? nil : Folder.new.domain_root)
119
119
  argv = [domain].compact
120
120
 
121
- output(ConsoleCapture.answer { CLI::SmokeTest.call(argv, root: checkout_root || Dir.pwd) })
121
+ output(ConsoleCapture.answer { Tools::SmokeTest.call(argv, root: checkout_root || Dir.pwd) })
122
122
  end
123
123
 
124
- # rubocop:disable Metrics/ParameterLists -- the keywords are the `Follow` query's declared arguments
125
-
126
124
  # A domain's event log past a cursor, answered once: what the stream yielded before it
127
125
  # ended. Pass the answered `cursor` back as `since` to keep tailing. `wait` bounds the stream
128
126
  # and it ends at the first entries, so a call returns as soon as there is something to say.
@@ -136,7 +134,6 @@ module Hecks
136
134
  # @return [Hash] the `Tail` row: `cursor:`, `events:` (payloads as JSON text) and `taken_at:`
137
135
  # @raise [Runtime::NotFound] if the domain cannot be found or keeps no event log
138
136
  def follow(domain:, aggregate: nil, since: nil, from_now: nil, wait: nil, interval: nil)
139
- # rubocop:enable Metrics/ParameterLists
140
137
  registry = boot(domain).registry
141
138
  entries = []
142
139
  cursor = stream(domain: domain, aggregate: aggregate, since: since, from_now: from_now,
@@ -148,8 +145,6 @@ module Hecks
148
145
  { cursor: cursor, events: entries, taken_at: Time.at(Ports::Clock.now(registry)).utc.iso8601 }
149
146
  end
150
147
 
151
- # rubocop:disable Metrics/ParameterLists -- the keywords are the caller-facing shape of a tail
152
-
153
148
  # Tails a domain's event log, handing each entry to the block as the log shows it, until
154
149
  # the block returns `:stop` (or `:batch`: after this check's entries), `limit` entries were
155
150
  # handed over, `timeout` seconds pass, or the reader goes away; unbounded, until interrupted.
@@ -164,7 +159,6 @@ module Hecks
164
159
  # @raise [Runtime::NotFound] if the domain cannot be found or keeps no event log
165
160
  def stream(domain:, aggregate: nil, since: nil, from_now: nil, limit: nil, timeout: nil, interval: nil,
166
161
  registry: nil, &)
167
- # rubocop:enable Metrics/ParameterLists
168
162
  repository = event_repository(domain, registry)
169
163
  tail = Tail.new(plain(since)&.to_i || (plain(from_now) ? repository.events.size : 0), 0, false)
170
164
  bounds = Bounds.new(plain(aggregate), plain(limit)&.to_i, deadline_for(timeout), plain(interval))
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ # The answer to `Introspection.Undo`, mixed into the in-process boot adapter: the command
6
+ # that undoes a declared command, from the bluebook's compensations (`Projections::Undo`).
7
+ module InProcessUndo
8
+ # @param domain [Hash, String] a domain directory
9
+ # @param bluebook [Hash, String] the bluebook's name
10
+ # @param command [Hash, String] the command's verb form, e.g. "Account.Debit"
11
+ # @return [Hash] `text:` the command that undoes it, or that none is declared
12
+ def undo(domain:, bluebook:, command:)
13
+ report(Projector.call(:undo, bluebook: bluebook_of(domain, bluebook), options: { command: plain(command) }).join("\n"))
14
+ end
15
+ end
16
+ end
17
+ end
@@ -42,13 +42,22 @@ module Hecks
42
42
  def apply_hold_first(held)
43
43
  domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
44
44
  domain.writing do |lineage|
45
- raise Runtime::WiringError, "#{domain.domain_name} already holds an era" unless lineage.eras.empty?
46
-
47
- lineage.hold_first!(domain.source_text, projection: domain.shape)
45
+ lineage.hold_first_era!(domain.source_text, projection: domain.shape, aggregates: domain.aggregates,
46
+ role: domain.app_role)
48
47
  end
49
48
  "#{domain.domain_name} holds era 1 now."
50
49
  end
51
50
 
51
+ # Moves the history held under the former name to the current one, in one transaction. A
52
+ # failure rolls it back whole, so the old name still holds everything.
53
+ def apply_rename_domain(held)
54
+ domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
55
+ moved = domain.renaming do |lineage|
56
+ lineage.rename_domain!(storage_names: domain.aggregates.map(&:storage_name), cache_fields: domain.cache_fields)
57
+ end
58
+ "#{domain.domain_name} holds the #{moved} era#{"s" unless moved == 1} of #{domain.former_name} now."
59
+ end
60
+
52
61
  def apply_merge_tail(held)
53
62
  domain = HeldDomain.open(plain(held[:domain]))
54
63
  named = winners(held)
@@ -100,7 +109,7 @@ module Hecks
100
109
  rescue Runtime::WiringError => e
101
110
  raise Runtime::WiringError, "#{domain.domain_name}: stopped at a row that isn't merely legacy — " \
102
111
  "it fails its own integrity check: #{e.message} — resolve that first " \
103
- "(`hecks reattest`), then run this again for the remaining rows."
112
+ "(`hecks era.reattest!`), then run this again for the remaining rows."
104
113
  end
105
114
 
106
115
  def missing_projections(lineage)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "json"
4
4
  require_relative "held_domain"
5
+ require_relative "../../../adapters/driven/postgres_era/lineage_manager/mint_decision"
5
6
 
6
7
  module Hecks
7
8
  module Adapters
@@ -22,29 +23,33 @@ module Hecks
22
23
  # @param held [HeldDomain] the loaded domain, translation edges included
23
24
  # @param lineage [Lineage] the domain's lineage
24
25
  # @param eras [Array<Hash>] the eras the lineage holds, at least one
26
+ # @param edge [Object, nil] the edge the shared decision named for the pending shape, when
27
+ # the caller decided it already; nil makes the audit decide it
25
28
  # @return [Finding, nil] the finding; nil when the domain stands at era 1, with no edge
26
- # @raise [Runtime::NotFound] if no edge leads the latest era to the current shape, or a
29
+ # @raise [Runtime::NotFound] if the shared decision names no edge to the current shape, or a
27
30
  # preview query is refused by Postgres
28
- def self.call(held, lineage, eras)
29
- new(held, lineage, eras).call
31
+ def self.call(held, lineage, eras, edge: nil)
32
+ new(held, lineage, eras, edge: edge).call
30
33
  end
31
34
 
32
35
  # @param held [HeldDomain] the loaded domain
33
36
  # @param lineage [Lineage] the domain's lineage
34
37
  # @param eras [Array<Hash>] the held eras
35
- def initialize(held, lineage, eras)
38
+ # @param edge [Object, nil] see `EdgeAudit.call`
39
+ def initialize(held, lineage, eras, edge: nil)
36
40
  @held = held
37
41
  @bluebook = held.bluebook
38
42
  @registry = held.registry
39
43
  @lineage = lineage
40
44
  @eras = eras
45
+ @edge = edge
41
46
  @manager = PostgresEra::LineageManager
42
47
  end
43
48
 
44
49
  # @return [Finding, nil] see `EdgeAudit.call`
45
50
  def call
46
51
  latest = @held.named(@eras.last)
47
- if @held.shape == Runtime::StorageShape.project(@manager.shadow(latest[:held_text]))
52
+ if @held.shape == @manager.held_shape(latest)
48
53
  return nil if latest[:ordinal] == 1
49
54
 
50
55
  settled(latest)
@@ -57,7 +62,7 @@ module Hecks
57
62
 
58
63
  # The shape already minted: the edge that arrives at the latest era.
59
64
  def settled(latest)
60
- chain = @manager.edge_chain(@registry, @bluebook, @eras[0..-2], latest[:label])
65
+ chain = @manager.edge_chain(@registry, @bluebook, @eras[0..-2], latest[:label], target: latest)
61
66
  finding(chain, latest[:ordinal], 1)
62
67
  end
63
68
 
@@ -65,16 +70,23 @@ module Hecks
65
70
  def pending(latest)
66
71
  label = Runtime::StorageShape.mint_hash(@bluebook)[0, Runtime::StorageShape::LABEL_LENGTH]
67
72
  leaving = leaving_edges(latest)
68
- edge = edge_to(leaving, latest, label)
69
- chain = @manager.edge_chain(@registry, @bluebook, @eras[0..-2] + [latest], label)
73
+ edge = @edge || decided_edge(latest, label)
74
+ chain = @manager.edge_chain(@registry, @bluebook, @eras[0..-2] + [latest], label,
75
+ target: edge.is_a?(Translation::ImplicitEdge) ? edge.record : nil)
70
76
  finding(chain, latest[:ordinal] + 1, leaving.size, edge)
71
77
  end
72
78
 
73
- # The leaving edge that arrives at the current shape.
74
- def edge_to(leaving, latest, label)
75
- leaving.find { |t| t.to == label } or
76
- raise Runtime::NotFound, "no translation edge leads #{latest[:label]} to #{label} — " \
77
- "run `hecks scaffold_translation` first"
79
+ # The edge the shared decision leads the latest era by. A decision that does not mint names
80
+ # the refusal, so the audit raises rather than audit an edge a mint would not take.
81
+ def decided_edge(latest, label)
82
+ verdict = PostgresEra::LineageManager::MintDecision.decide_latest(
83
+ latest, bluebook: @bluebook, translations: @registry.translations, directory: @held.directory,
84
+ watermark: @lineage.last_ordinal
85
+ )
86
+ return verdict.edge if verdict.verdict == "would_mint"
87
+
88
+ raise Runtime::NotFound, "no translation edge leads #{latest[:label]} to #{label} " \
89
+ "(the decision is #{verdict.verdict}) — run `hecks query era.scaffold_translation` first"
78
90
  end
79
91
 
80
92
  # The registered translations that leave the latest era.
@@ -93,8 +105,9 @@ module Hecks
93
105
 
94
106
  def verdict_for(aggregate, edge, era, chain)
95
107
  after = translated(aggregate, era, chain)
96
- before = if chain.size > 1
97
- translated(aggregate, era, chain[0..-2])
108
+ before = @lineage.split_latest(aggregate, chain) ||
109
+ if chain.size > 1
110
+ @lineage.received_latest(aggregate, era, chain)
98
111
  else
99
112
  @lineage.ancestor_latest(aggregate, era, chain)
100
113
  end
@@ -41,6 +41,21 @@ module Hecks
41
41
  { capable: true, held: domain.reading { |lineage| domain.held_eras(lineage).size } }
42
42
  end
43
43
 
44
+ # The facts of a rename: `held` is the eras under the former name that would move, and 0
45
+ # unless the domain declares a former name, the current name holds none, and the former
46
+ # name holds some.
47
+ def examine_rename_domain(held)
48
+ domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
49
+ return {} unless domain.capable?
50
+
51
+ { capable: true, held: domain.renaming { |lineage| lineage.rename_pending? ? former_eras(lineage) : 0 } }
52
+ end
53
+
54
+ def former_eras(lineage)
55
+ lineage.db.exec_params("SELECT count(*)::int AS n FROM hecks_eras WHERE domain = $1",
56
+ [lineage.formerly_known_as])[0]["n"].to_i
57
+ end
58
+
44
59
  def examine_merge_tail(held)
45
60
  domain = HeldDomain.open(plain(held[:domain]))
46
61
  return {} unless domain.capable?
@@ -102,7 +117,8 @@ module Hecks
102
117
  # Records both worlds wrote since the cut that no winner was named for.
103
118
  def unresolved_conflicts(domain, lineage, eras, named)
104
119
  latest = eras.last
105
- chain = PostgresEra::LineageManager.edge_chain(domain.registry, domain.bluebook, eras[0..-2], latest[:label])
120
+ chain = PostgresEra::LineageManager.edge_chain(domain.registry, domain.bluebook, eras[0..-2],
121
+ latest[:label], target: latest)
106
122
  conflicts = domain.aggregates.flat_map do |aggregate|
107
123
  lineage.conflict_ids(aggregate, chain, latest[:ordinal], latest[:watermark].to_i)
108
124
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ class JournalStore
6
+ class HeldDomain
7
+ # How a held domain reaches the journal store to rename it: with its former name known,
8
+ # and nothing provisioned.
9
+ module Renaming
10
+ # Connects to the journal store and yields a lineage that knows the domain's former name,
11
+ # with nothing provisioned: the rename moves what is there and builds nothing, and a
12
+ # database that holds no eras is left as it is. A role that bypasses the write fence is
13
+ # refused unless the world allows it.
14
+ #
15
+ # @yield [Lineage] the domain's lineage, with `formerly_known_as` set
16
+ # @return [Object] the block's value
17
+ # @raise [Runtime::WiringError] on a superuser connection the world has not allowed
18
+ def renaming
19
+ db = PostgresEra.connect_for(bluebook.name, settings, provision: false)
20
+ lineage = PostgresEra::Lineage.new(db, bluebook.name, formerly_known_as: bluebook.formerly_known_as)
21
+ lineage.check_fence_applies!(allow_superuser: PostgresEra.setting(settings, :allow_superuser, default: false))
22
+ yield lineage
23
+ ensure
24
+ db&.close
25
+ end
26
+
27
+ # The where-fields each aggregate's queries narrow by, whose cache tables hash the
28
+ # domain's name and so are renamed with it. A superset of the fields actually cached:
29
+ # a table that does not exist is skipped.
30
+ #
31
+ # @return [Hash{String => Array<String>}] storage name to field names
32
+ def cache_fields
33
+ aggregates.to_h do |aggregate|
34
+ queries = aggregate.queries + aggregate.entities.flat_map(&:queries)
35
+ [aggregate.storage_name, queries.flat_map { |query| query.wheres.map { |clause| clause.field.to_s } }.uniq]
36
+ end
37
+ end
38
+
39
+ # @return [String, nil] the name the domain was known by before its rename
40
+ def former_name = bluebook.formerly_known_as
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "hecks"
4
4
  require "hecks/ports/persistence/plugins/era"
5
+ require "hecks/indifferent_key"
6
+ require_relative "held_domain/renaming"
5
7
 
6
8
  module Hecks
7
9
  module Adapters
@@ -14,6 +16,8 @@ module Hecks
14
16
  # text from being attested; `scaffold` loads everything but the edges, since an unresolved
15
17
  # edge file refuses to load and writing it is the point.
16
18
  class HeldDomain
19
+ include Renaming
20
+
17
21
  MODES = %i[translated bare scaffold].freeze
18
22
 
19
23
  attr_reader :registry, :bluebook, :directory, :adapter_name
@@ -21,6 +25,9 @@ module Hecks
21
25
  # @return [String] the held domain's name
22
26
  def domain_name = bluebook.name
23
27
 
28
+ # @return [Array<String>] the names of every bluebook the registry loaded
29
+ def bluebook_names = registry.bluebooks.keys
30
+
24
31
  # @return [Array<Bluebook::Aggregate>] the held domain's aggregates
25
32
  def aggregates = bluebook.aggregates
26
33
 
@@ -79,11 +86,15 @@ module Hecks
79
86
 
80
87
  # @param registry [Runtime::Registry] the loaded registry
81
88
  # @param directory [String] the domain's bluebook directory
89
+ # @param name [String, nil] the bluebook to hold, by name; the registry's first when absent
82
90
  # @raise [Runtime::NotFound] if the registry holds no bluebook, or a bluebook no aggregate
83
- def initialize(registry, directory)
91
+ def initialize(registry, directory, name = nil)
84
92
  @registry = registry
85
93
  @directory = directory
86
- @bluebook = registry.first_bluebook or raise Runtime::NotFound, "no bluebook in #{directory}"
94
+ @bluebook = name ? registry.bluebooks[name] : registry.first_bluebook
95
+
96
+ raise Runtime::NotFound, "no bluebook in #{directory}" unless @bluebook
97
+
87
98
  first = @bluebook.aggregates.first or raise Runtime::NotFound, "#{@bluebook.name} declares no aggregates"
88
99
  @adapter_name = Ports::Persistence::BindingPolicy.resolve(registry, @bluebook.name, first).adapter
89
100
  end
@@ -109,6 +120,11 @@ module Hecks
109
120
  @database ? declared.merge(database: @database) : declared
110
121
  end
111
122
 
123
+ # The app role the world names, which provisioning grants what the app needs to write.
124
+ #
125
+ # @return [String, nil] the role, or nil when the world names none
126
+ def app_role = IndifferentKey.read(settings, :role)
127
+
112
128
  # Names the schema its journal store is read in, over the world's and `HECKS_SCHEMA`, so a
113
129
  # rehearsal reads the schema it reports.
114
130
  #
@@ -146,7 +162,7 @@ module Hecks
146
162
  def named(era)
147
163
  return era if era[:hash]
148
164
 
149
- hash = Runtime::StorageShape.mint_hash(PostgresEra::LineageManager.shadow(era[:held_text]))
165
+ hash = PostgresEra::LineageManager.held_hash(era)
150
166
  era.merge(hash: hash, label: hash[0, Runtime::StorageShape::LABEL_LENGTH])
151
167
  end
152
168
 
@@ -161,8 +177,8 @@ module Hecks
161
177
  # @yield [Lineage] the domain's lineage
162
178
  # @return [Object] the block's value
163
179
  def reading
164
- db = PostgresEra.connect_for(bluebook.name, settings)
165
- yield PostgresEra::Lineage.new(db, bluebook.name)
180
+ db = PostgresEra.connect_for(bluebook.name, settings, provision: false)
181
+ yield PostgresEra::Lineage.new(db, bluebook.name, reading: true)
166
182
  ensure
167
183
  db&.close
168
184
  end
@@ -183,6 +199,16 @@ module Hecks
183
199
  db&.close
184
200
  end
185
201
 
202
+ # What a boot of the held bluebook would resolve, read from its database over a connection
203
+ # that only reads: the resolution the boot records (`LineageManager::EraResolution`).
204
+ #
205
+ # @return [PostgresEra::LineageManager::EraResolution::Answer]
206
+ # @raise [Runtime::WiringError] if the connection is refused or a held text was altered
207
+ def resolution
208
+ PostgresEra::LineageManager::EraResolution.read(bluebook: bluebook, settings: settings,
209
+ translations: translations, directory: directory)
210
+ end
211
+
186
212
  # The eras a lineage holds, without provisioning anything: none when the lineage tables do
187
213
  # not exist yet.
188
214
  #
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "held_domain"
4
+ require_relative "../../../quality_control/adapters/qa_era_mint"
5
+ require_relative "../../../quality_control/adapters/qa_auto_mint"
6
+ require_relative "../../../adapters/driven/postgres_era"
7
+
8
+ module Hecks
9
+ module Adapters
10
+ class JournalStore
11
+ # The Hecks domain's held mint, answered on the `JournalStore` port's `Mint`.
12
+ #
13
+ # It reads the domain's facts through the shared mint decision (`QaAutoMint.facts`, which
14
+ # runs `MintDecision.decide_latest`), refuses by name whatever the decision does not allow,
15
+ # and mints through `QaEraMint`, the mint transaction the QualityControl ledger uses. The
16
+ # reader and the minter are injected so a spec runs with no database.
17
+ class HeldMint
18
+ # The Hecks domain's bluebook directory, the one a checkout boots.
19
+ DOMAIN = File.expand_path("../..", __dir__)
20
+
21
+ # The domain name the mint is recorded under.
22
+ NAME = "Hecks"
23
+
24
+ # Reads the facts a mint decides on from a bluebook directory.
25
+ #
26
+ # @param directory [String] the domain's bluebook directory
27
+ # @return [Hash] `eraless:` alone, the adapter's name, for a domain bound to a store that
28
+ # holds no eras (Memory, the default); `disposable: true` alone for a world that
29
+ # declares `disposable_ledger true`; else `held` (the count of held eras), and when any
30
+ # are held, `next_era`, `status` (the boot's resolution,
31
+ # `LineageManager::EraResolution`), `watermark`, `from`, `to` and `verdict` (see
32
+ # `QaAutoMint.facts`)
33
+ def self.read(directory)
34
+ domain = HeldDomain.open(directory, mode: :translated)
35
+ return { eraless: domain.adapter_name } unless domain.capable?
36
+ return { disposable: true } if PostgresEra::LineageManager::DisposableLedger.declared?(domain.settings)
37
+
38
+ resolution = domain.resolution
39
+ return { held: 0 } if resolution.status == "unheld"
40
+
41
+ QaAutoMint.facts(directory).merge(held: resolution.held_count, next_era: resolution.latest[:ordinal] + 1,
42
+ status: resolution.status)
43
+ end
44
+
45
+ # Mints the era through the QualityControl mint transaction, against the Hecks domain.
46
+ #
47
+ # @return [Array(String, Boolean)] the minted label or the refusal, and whether it minted
48
+ def self.mint(era, request)
49
+ QaEraMint.call(DOMAIN, domain: NAME, era: era, request: request, ledger: DOMAIN)
50
+ end
51
+
52
+ # @param directory [String] the bluebook directory a mint is for
53
+ # @param reader [#call] reads the facts of a directory; `HeldMint.read` when not given
54
+ # @param minter [#call] mints (era, request); `HeldMint.mint` when not given
55
+ def initialize(directory: DOMAIN, reader: nil, minter: nil)
56
+ @directory = directory
57
+ @reader = reader || ->(dir) { HeldMint.read(dir) }
58
+ @minter = minter || ->(era, request) { HeldMint.mint(era, request) }
59
+ end
60
+
61
+ # Answers a `MintHeld` request: a minted era, a shape that did not move, a store that holds
62
+ # no eras or a disposable ledger (neither needs a mint), or a named refusal.
63
+ #
64
+ # @param run [String] the run the mint belongs to
65
+ # @param confirm [Boolean, nil] whether the mint was confirmed
66
+ # @param rehearsal_verdict [String, nil] the verdict the caller read, when it read one
67
+ # @param watermark [Integer, nil] the watermark the caller read, when it read one
68
+ # @return [Hash{Symbol => Hash}] `run`, `outcome` (`minted`, `no_change` or `disposable`)
69
+ # (also `eraless`) and `label` (the adapter's name for `eraless`, empty for `disposable`)
70
+ # @raise [Runtime::WiringError] naming why the mint was refused
71
+ def answer(run:, confirm: nil, rehearsal_verdict: nil, watermark: nil)
72
+ refuse!("the mint needs --confirm") unless confirm == true
73
+ facts = @reader.call(@directory)
74
+ passed = no_mint_needed(run, facts)
75
+ return passed if passed
76
+
77
+ refuse!("the Hecks domain holds no era; hold its first era before a mint") if facts[:held].zero?
78
+ return unchanged(run, facts) if facts[:status] == "current"
79
+
80
+ refuse!("the current shape is held by an era a later one superseded; nothing to mint") if facts[:status] == "superseded"
81
+ decide!(facts, rehearsal_verdict, watermark)
82
+ minted(run, facts)
83
+ end
84
+
85
+ private
86
+
87
+ # Refuses a mint whose decision is not `would_mint`, a rehearsal that disagrees with the
88
+ # decision, or a watermark that moved since the rehearsal.
89
+ def decide!(facts, rehearsal_verdict, watermark)
90
+ verdict = facts[:verdict]
91
+ refuse!("the decision is #{verdict.verdict}, not would_mint: #{verdict.reason}") unless verdict.verdict == "would_mint"
92
+ refuse_rehearsal!(rehearsal_verdict)
93
+ stale = watermark && QaAutoMint.stale_watermark(watermark, facts[:watermark])
94
+ refuse!(stale) if stale
95
+ end
96
+
97
+ # Refuses a rehearsal that said anything but would_mint; a caller that read none passes nil.
98
+ def refuse_rehearsal!(rehearsal_verdict)
99
+ return if rehearsal_verdict.nil? || rehearsal_verdict == "would_mint"
100
+
101
+ refuse!("the rehearsal said #{rehearsal_verdict}, not would_mint")
102
+ end
103
+
104
+ # A store that holds no eras (Memory) has no shape to move, and a disposable ledger's boot
105
+ # brings its own; neither needs a mint.
106
+ def no_mint_needed(run, facts)
107
+ outcome = { eraless: "eraless", disposable: "disposable" }.find { |fact, _| facts[fact] }&.last
108
+ return unless outcome
109
+
110
+ { run: { value: run }, outcome: { value: outcome }, label: { value: facts[:eraless] || "" } }
111
+ end
112
+
113
+ def unchanged(run, facts)
114
+ { run: { value: run }, outcome: { value: "no_change" }, label: { value: facts[:to] } }
115
+ end
116
+
117
+ def minted(run, facts)
118
+ request = { confirm: true, verdict: "would_mint", watermark: facts[:watermark] }
119
+ label, ran = @minter.call(facts[:next_era], request)
120
+ refuse!(label) unless ran
121
+ { run: { value: run }, outcome: { value: "minted" }, label: { value: label } }
122
+ end
123
+
124
+ def refuse!(reason) = raise(Runtime::WiringError, reason)
125
+ end
126
+ end
127
+ end
128
+ end
@@ -30,7 +30,7 @@ module Hecks
30
30
  shape_line(held, era, ordinal),
31
31
  "The held text AS IT NOW STANDS — the original is gone; this is what you would be attesting to:",
32
32
  "─" * 72, era[:held_text], "─" * 72,
33
- "Read it, then `hecks reattest #{held.domain_name} era=#{ordinal} --confirm` accepts it."
33
+ "Read it, then `hecks era.reattest! #{held.domain_name} era=#{ordinal} --confirm` accepts it."
34
34
  ].join("\n")
35
35
  end
36
36
 
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "hecks/ports/persistence/plugins/era"
5
+ require_relative "../../../../shape_ledger"
6
+
7
+ module Hecks
8
+ module Adapters
9
+ class JournalStore
10
+ module Readings
11
+ # What a boot of each bluebook under a domain directory would resolve, answered by
12
+ # `Runtime::EraStatus`, the resolution the boot itself records, against the database each
13
+ # bluebook's own world declares. Both queries only read: the connection refuses writes.
14
+ module BootStatus
15
+ # Each bluebook's boot status: from its own database when it declares one, else from the
16
+ # committed ledger and its edges (`source` says which).
17
+ #
18
+ # @param domain [Hash, String] the domain directory
19
+ # @return [Hash] `text:` the status as JSON, one row per bluebook
20
+ # @raise [Runtime::NotFound] if the directory cannot be loaded or a database refuses
21
+ def boot_status(domain:)
22
+ answering do
23
+ directory = plain(domain)
24
+ registry = Hecks.describe(directory).registry
25
+ JSON.pretty_generate(with_ledger(directory, registry, Runtime::EraStatus.rows(registry, directory)))
26
+ end
27
+ end
28
+
29
+ # What a boot would resolve for each bluebook, from its own database only: status, held
30
+ # and current labels, the ordinal it reads, and the reason. A bluebook bound to a store
31
+ # that holds no eras answers `no_eras`.
32
+ #
33
+ # @param domain [Hash, String] the domain directory
34
+ # @return [Hash] `text:` the resolution as JSON, one row per bluebook
35
+ # @raise [Runtime::NotFound] if the directory cannot be loaded or a database refuses
36
+ def boot_resolution(domain:)
37
+ answering do
38
+ directory = plain(domain)
39
+ rows = Runtime::EraStatus.rows(Hecks.describe(directory).registry, directory)
40
+ JSON.pretty_generate({ "domain" => directory, "bluebooks" => rows })
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ # The rows, with each `no_eras` row answered by the ledger instead.
47
+ def with_ledger(directory, registry, rows)
48
+ ledger = ShapeLedger::Status.of(directory, registry: registry)["bluebooks"] if no_database?(rows)
49
+ bluebooks = rows.to_h { |name, row| [name, row["source"] == "none" ? ledger.fetch(name, row) : row] }
50
+ { "domain" => directory, "bluebooks" => bluebooks }
51
+ end
52
+
53
+ def no_database?(rows) = rows.each_value.any? { |row| row["source"] == "none" }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ class JournalStore
6
+ module Readings
7
+ # The dry run of `write_translation`: the edge that would be written, and the files it would
8
+ # delete, answered as text and written nowhere.
9
+ module Composition
10
+ # The composed edge `write_translation` would write, under comments that say which files
11
+ # it would remove.
12
+ #
13
+ # @param domain [Hash, String] the domain directory
14
+ # @return [Hash] `text:` the edge file's text, or the sentence that says nothing is to be written
15
+ # @raise [Runtime::NotFound] if the domain holds no eras, cannot be loaded, or its chain
16
+ # cannot be composed
17
+ def compose_translation(domain:)
18
+ answering do
19
+ held = HeldDomain.open(plain(domain))
20
+ refuse_incapable!(held)
21
+ held.reading { |lineage| composition_text(held, lineage) }
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def composition_text(held, lineage)
28
+ plan = translation_plan(held, lineage)
29
+ return plan.message if plan.message
30
+
31
+ notes = ["# Would write #{plan.path}."]
32
+ notes += plan.removals.map { |path| "# Would delete #{path}." }
33
+ [*notes, plan.text.chomp].join("\n")
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end