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
@@ -3,8 +3,8 @@
3
3
  require "fileutils"
4
4
  require_relative "console_capture"
5
5
  require_relative "rails_app_files"
6
- require "hecks/cli/project_cli"
7
- require "hecks/cli/domain_stub"
6
+ require "hecks/tools/project_cli"
7
+ require "hecks/tools/domain_stub"
8
8
 
9
9
  module Hecks
10
10
  module Adapters
@@ -21,7 +21,7 @@ module Hecks
21
21
  def initialize(aggregate: nil, settings: {}, root: nil); end
22
22
 
23
23
  # Writes a command-line launcher beside each domain of the current directory, or beside the
24
- # named ones, through `Hecks::CLI::ProjectCli`. A launcher is a generated file that only
24
+ # named ones, through `Hecks::Tools::ProjectCli`. A launcher is a generated file that only
25
25
  # points at its domain, so an existing one is replaced and nothing else is touched.
26
26
  #
27
27
  # @param held [Hash] the `Launch` record: `domains` (comma separated paths under the current
@@ -31,7 +31,7 @@ module Hecks
31
31
  def write(**held)
32
32
  domains = Text.comma_list(plain(held[:domains]))
33
33
  text = ConsoleCapture.answer do
34
- CLI::ProjectCli.call(domains, program: "hecks project_cli", root: Dir.pwd, remove_stale_bin: false)
34
+ Tools::ProjectCli.call(domains, program: "hecks project_cli", root: Dir.pwd, remove_stale_bin: false)
35
35
  end
36
36
  unless text.include?("->")
37
37
  reason = text.strip.empty? ? "no domain found" : text.strip
@@ -79,7 +79,7 @@ module Hecks
79
79
  # The directory the stub is written into: the named one, or the snake-cased name under the
80
80
  # current directory.
81
81
  def stub_target(held)
82
- File.expand_path(plain(held[:dir]) || CLI::DomainStub.directory(plain(held[:name])), Dir.pwd)
82
+ File.expand_path(plain(held[:dir]) || Tools::DomainStub.directory(plain(held[:name])), Dir.pwd)
83
83
  end
84
84
 
85
85
  # Warns that a service written inside the hecks clone is not one to deploy from there.
@@ -101,7 +101,7 @@ module Hecks
101
101
  def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
102
102
 
103
103
  def stub_files(name, adapter)
104
- CLI::DomainStub.files(name: name, adapter: adapter)
104
+ Tools::DomainStub.files(name: name, adapter: adapter)
105
105
  rescue ArgumentError => e
106
106
  raise ConsoleCapture::Failure, e.message
107
107
  end
@@ -43,7 +43,7 @@ module Hecks
43
43
 
44
44
  # The flags of a sweep, and the fields of the record that fill them.
45
45
  SWEEP_FLAGS = { "--seeds" => :seeds, "--steps" => :steps, "--workers" => :workers,
46
- "--adapter" => :adapter }.freeze
46
+ "--adapter" => :adapter, "--shard" => :shard, "--list-shards" => :list_shards }.freeze
47
47
 
48
48
  class << self
49
49
  # @return [#call, nil] runs a child given `(command, env, chdir)` and answers a `Finished`;
@@ -60,7 +60,8 @@ module Hecks
60
60
 
61
61
  # Runs a fuzz sweep over one domain, or over every domain of the checkout when none is named.
62
62
  #
63
- # @param held [Hash] the `Fuzzing` record: `domain`, `seeds`, `steps`, `workers`, `adapter`
63
+ # @param held [Hash] the `Fuzzing` record: `domain`, `seeds`, `steps`, `workers`, `adapter`,
64
+ # `shard` and `list_shards`
64
65
  # @return [Hash{Symbol => Hash}] `report:` what the sweep printed
65
66
  # @raise [ConsoleCapture::Failure] when the sweep found something, or could not run
66
67
  def sweep(**held)
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ # How big a push is, against the QualityControl world's `push_nudge` setting: `commits:` and
6
+ # `hours:` for when a push is due, and `urgent_commits:` for when it is urgent. It only says so
7
+ # in a line; a push of any size is never refused.
8
+ module PushSize
9
+ # The world verb that carries the thresholds.
10
+ VERB = "push_nudge"
11
+
12
+ # The thresholds when the world declares none.
13
+ DEFAULTS = { commits: 15, hours: 6, urgent_commits: 40 }.freeze
14
+
15
+ # The word a Work row's title opens with when the push is past `urgent_commits`.
16
+ URGENT = "URGENT"
17
+
18
+ module_function
19
+
20
+ # @param registry [Runtime::Registry, nil]
21
+ # @return [Hash{Symbol => Integer, Float}] `commits:`, `hours:` and `urgent_commits:`
22
+ def thresholds(registry)
23
+ declared = registry&.world("QualityControl")&.for_verb(VERB) || {}
24
+ merged = DEFAULTS.merge(declared.slice(*DEFAULTS.keys))
25
+ { commits: Integer(merged[:commits]), hours: Float(merged[:hours]),
26
+ urgent_commits: Integer(merged[:urgent_commits]) }
27
+ end
28
+
29
+ # @param ahead [Integer] the unpushed commits
30
+ # @param limits [Hash] see {thresholds}
31
+ # @return [Symbol] `:urgent`, `:over` or `:within`
32
+ def size_class(ahead, limits)
33
+ return :urgent if ahead > limits[:urgent_commits]
34
+
35
+ ahead > limits[:commits] ? :over : :within
36
+ end
37
+
38
+ # @return [String] the sentence past the threshold, "" within it
39
+ def sentence(ahead, limits)
40
+ kind = size_class(ahead, limits)
41
+ return "" if kind == :within
42
+
43
+ "#{"#{URGENT} " if kind == :urgent}PUSH NOW: #{ahead} commits is over the #{limits[:commits]} you set " \
44
+ "(urgent at #{limits[:urgent_commits]})"
45
+ end
46
+
47
+ # @return [String] the `push-due` Work row's title, naming the size class past the threshold
48
+ def title(base, ahead, limits)
49
+ case size_class(ahead, limits)
50
+ when :urgent then "#{URGENT}: #{base}, #{ahead} commits"
51
+ when :over then "#{base}, #{ahead} commits"
52
+ else base
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,7 @@
1
+ # Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
2
+ # and the implementation must load once, from `lib/`, not from the copy.
3
+ require "hecks/hecks/adapters/qa_quiescing"
4
+
5
+ Hecks.adapter "QaQuiescing" do
6
+ port "Quiescing"
7
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "console_capture"
4
+ require "hecks/quality_control/adapters/qa_quiesce_marker"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ # The `Quiescing` port's adapter: writes, removes and reads the QA quiet marker
9
+ # (`QaQuiesceMarker`). It touches no ledger and no git state.
10
+ class QaQuiescing
11
+ # @param aggregate [Object, nil] unused
12
+ # @param settings [Hash] `marker:` a `QaQuiesceMarker`, for a spec
13
+ # @param root [String, nil] unused
14
+ def initialize(aggregate: nil, settings: {}, root: nil)
15
+ @marker = settings[:marker] || QaQuiesceMarker.new
16
+ end
17
+
18
+ # Writes the marker.
19
+ #
20
+ # @param held [Hash] the `QaQuiesce` record: `reason`, optional `owner` and `force`
21
+ # @return [Hash{Symbol => Hash}] `output:` what was held
22
+ # @raise [ConsoleCapture::Failure] when another owner holds a fresh marker
23
+ def mark(**held)
24
+ hold = @marker.hold!(owner: owner(held), reason: plain(held[:reason]), force: plain(held[:force]) == true)
25
+ { output: { value: "quiesced: #{@marker.describe(hold)}" } }
26
+ rescue QaQuiesceMarker::Refused => e
27
+ raise ConsoleCapture::Failure, e.message
28
+ end
29
+
30
+ # Removes the marker.
31
+ #
32
+ # @param held [Hash] the `QaQuiesce` record: optional `owner` and `force`
33
+ # @return [Hash{Symbol => Hash}] `output:` what was released
34
+ # @raise [ConsoleCapture::Failure] when another owner holds a fresh marker
35
+ def clear(**held)
36
+ removed = @marker.release!(owner: owner(held), force: plain(held[:force]) == true)
37
+ { output: { value: removed ? "released: #{@marker.describe(removed)}" : "released: no marker was held" } }
38
+ rescue QaQuiesceMarker::Refused => e
39
+ raise ConsoleCapture::Failure, e.message
40
+ end
41
+
42
+ # @return [Hash{Symbol => String}] `text:` owner, reason and age of the marker
43
+ def status(**)
44
+ { text: @marker.status }
45
+ end
46
+
47
+ private
48
+
49
+ # The caller's name for the hold: the argument, else `HECKS_QUIESCE_OWNER`, else "unnamed".
50
+ def owner(held)
51
+ plain(held[:owner]) || ENV["HECKS_QUIESCE_OWNER"] || "unnamed"
52
+ end
53
+
54
+ def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
55
+ end
56
+ end
57
+ end
@@ -20,7 +20,6 @@ module Hecks
20
20
  ALWAYS = [
21
21
  { what: "the mint itself",
22
22
  why: "no era was written: the edge, its approval and the audit were evaluated, nothing minted" },
23
- { what: "an edge's coverage of every change in the shape", why: "the mint checks it; the rehearsal does not yet" },
24
23
  { what: "commands, policies and requests", why: "no traffic was run: only the stored data and the shape were read" },
25
24
  { what: "data written after the copy was made", why: "a copy is a moment; the mint sees the data of its own" }
26
25
  ].freeze
@@ -41,8 +40,9 @@ module Hecks
41
40
  # @return [Hash] the edge facts, every refused row and its total, what was read, the parity
42
41
  # of the two engines, and what was not checked
43
42
  def examine
44
- edge = minting == "next" ? @subject.edge_from(before) : nil
43
+ edge = decided_edge
45
44
  refusals, after = edge ? @store.audit(@subject, edge) : [[], {}]
45
+ refusals = coverage_refusals(edge) + refusals
46
46
  rust = RustAudit.call(@subject, after)
47
47
  report = AuditReport.new(minting: minting, edge: edge, states: after, ruby: refusals, rust: rust)
48
48
  answer(edge, report, (refusals + rust.violations).uniq, limits(rust, report))
@@ -52,6 +52,27 @@ module Hecks
52
52
 
53
53
  def plain(value) = { value: value }
54
54
 
55
+ # The edge a mint would use, as the shared decision names it; nil unless it would mint.
56
+ def decided_edge
57
+ return unless minting == "next" && latest[:held_text]
58
+
59
+ verdict = resolution.verdict
60
+ verdict&.verdict == "would_mint" ? verdict.edge : nil
61
+ end
62
+
63
+ # What the mint's coverage check would refuse of the decided edge, in the same words: a
64
+ # change in the shape that no rule of the edge explains. The mint raises it before it
65
+ # writes an era.
66
+ def coverage_refusals(edge)
67
+ return [] unless edge
68
+
69
+ held = PostgresEra::LineageManager.held_bluebook(latest)
70
+ PostgresEra::LineageManager.check_coverage!(@subject.registry, @subject.bluebook, held, edge)
71
+ []
72
+ rescue Runtime::WiringError => e
73
+ [e.message]
74
+ end
75
+
55
76
  def shape
56
77
  { booted: flag(true), host_version: plain(Rehearsal.host_version), store: plain(@subject.store_kind),
57
78
  mode: plain(@subject.copy_mode), before: plain(before), after: plain(@subject.label),
@@ -91,10 +112,16 @@ module Hecks
91
112
 
92
113
  def before = latest ? latest[:label] : "none"
93
114
 
115
+ # Which held era the shape resolves to, by the resolution a boot records; the latest era is
116
+ # named as it would be minted.
117
+ def resolution
118
+ @resolution ||= @subject.resolve([*eras[0...-1], latest]) { @store.watermark(@subject) }
119
+ end
120
+
94
121
  def minting
95
122
  return "first" unless latest
96
123
 
97
- before == @subject.label ? "none" : "next"
124
+ resolution.status == "current" ? "none" : "next"
98
125
  end
99
126
 
100
127
  def limits(rust, report)
@@ -26,12 +26,29 @@ module Hecks
26
26
  # @return [void] there is nothing to drop
27
27
  def drop! = nil
28
28
 
29
+ # The document's eras as a lineage stores them, each with the storage shape a mint records:
30
+ # the document's own `projection` when it gives one, else the shape of its `held_text`,
31
+ # which a document holds whole, since it is written as the domain's source.
32
+ #
29
33
  # @param _subject [Subject] unused: the document holds its own eras
30
- # @return [Array<Hash>] the eras, `ordinal` and `held_text`
34
+ # @return [Array<Hash>] the eras, `ordinal`, `held_text` and `projection`
31
35
  def eras(_subject)
32
- Array(@document["eras"]).map { |era| { ordinal: era["ordinal"], held_text: era["held_text"] } }
36
+ Array(@document["eras"]).map do |era|
37
+ { ordinal: era["ordinal"], held_text: era["held_text"], projection: era["projection"] || shape_of(era["held_text"]) }
38
+ end
33
39
  end
34
40
 
41
+ # @return [Hash, nil] the storage shape a held text declares; nil for no text
42
+ def shape_of(text)
43
+ text && Runtime::StorageShape.project(PostgresEra::LineageManager.shadow(text))
44
+ end
45
+
46
+ # A document holds no ledger, so its watermark is zero and never moves.
47
+ #
48
+ # @param _subject [Subject] unused
49
+ # @return [Integer] the ledger watermark
50
+ def watermark(_subject) = 0
51
+
35
52
  # What the document holds: it keeps the latest state of each record only, so the head and
36
53
  # the journal counts are the same number.
37
54
  #
@@ -56,7 +73,7 @@ module Hecks
56
73
  refusals = []
57
74
  after = subject.aggregates.to_h do |aggregate|
58
75
  declared = edge.for_aggregate(aggregate.name)
59
- before = records(declared&.was || aggregate.name)
76
+ before = split_before(edge, aggregate) || records(declared&.was || aggregate.name)
60
77
  translated = translate(aggregate, declared, before)
61
78
  refusals.concat(Translation::Audit.check(aggregate: aggregate, declared: declared, before: before,
62
79
  after: translated).violations)
@@ -67,6 +84,49 @@ module Hecks
67
84
 
68
85
  private
69
86
 
87
+ # A split target's "before": its source's held records, fanned out one per key the split names,
88
+ # carrying the split's fields (ADR 0166). Nil when the aggregate is not a split target.
89
+ def split_before(edge, aggregate)
90
+ source, split = split_source_for(edge, aggregate)
91
+ source && fan_out(records(source.was || source.name), split)
92
+ end
93
+
94
+ # The source aggregate and the split that feeds `aggregate`, or nil.
95
+ def split_source_for(edge, aggregate)
96
+ edge.aggregates.each do |source|
97
+ split = source.splits.find { |candidate| candidate.into == aggregate.name }
98
+ return [source, split] if split
99
+ end
100
+ []
101
+ end
102
+
103
+ # One target record per source record that carries the split's key, holding the split's fields.
104
+ def fanned_out(held, split)
105
+ fields = split.fields.map(&:to_s)
106
+ held.filter_map do |_id, state|
107
+ key = split_key(state, split)
108
+ [key.to_s, state.slice(*fields)] if key
109
+ end.to_h
110
+ end
111
+
112
+ # A value object key is identified by its `value` member.
113
+ def split_key(state, split)
114
+ key = state[split.keyed_by.to_s]
115
+ key.is_a?(Hash) ? key["value"] : key
116
+ end
117
+
118
+ def fan_out(held, split)
119
+ fields = split.fields.map(&:to_s)
120
+ held.filter_map { |_id, state| fanned_row(state, split.keyed_by.to_s, fields) }.to_h
121
+ end
122
+
123
+ # One target row keyed by the held record's key, a value object's `value` member when it has one.
124
+ def fanned_row(state, key, fields)
125
+ value = state[key]
126
+ value = value["value"] if value.is_a?(Hash)
127
+ [value.to_s, state.slice(*fields)] if value
128
+ end
129
+
70
130
  def records(name) = @document.dig("records", name.to_s) || {}
71
131
 
72
132
  def translate(aggregate, declared, before)
@@ -30,14 +30,23 @@ module Hecks
30
30
  end
31
31
 
32
32
  # @param subject [Subject] the loaded domain
33
- # @param _edge [Bluebook::Translation] the edge leading to the shape
33
+ # @return [Integer] the ledger watermark the copy holds: zero when it holds no lineage
34
+ def watermark(subject)
35
+ return 0 unless census(subject).present
36
+
37
+ reading(subject, &:last_ordinal)
38
+ end
39
+
40
+ # @param subject [Subject] the loaded domain
41
+ # @param subject [Subject] the loaded domain
42
+ # @param edge [Object] the edge `Subject#decide` named for the shape, the one the mint takes
34
43
  # @return [Array(Array<String>, Hash)] what the audit's layers refuse over the stored
35
44
  # records, and the records as translated, by aggregate name and id
36
- def audit(subject, _edge)
45
+ def audit(subject, edge)
37
46
  return [[], {}] unless census(subject).present
38
47
 
39
48
  reading(subject) do |lineage|
40
- finding = JournalStore::EdgeAudit.call(subject.held, lineage, subject.held.held_eras(lineage))
49
+ finding = JournalStore::EdgeAudit.call(subject.held, lineage, subject.held.held_eras(lineage), edge: edge)
41
50
  finding ? [finding.refusals, finding.after] : [[], {}]
42
51
  end
43
52
  end
@@ -53,12 +62,26 @@ module Hecks
53
62
 
54
63
  def reading(subject)
55
64
  subject.held.read_from(url)
56
- db = PostgresEra.connect_for(subject.bluebook_name, subject.settings)
57
- db.exec("SET default_transaction_read_only = on") if @declaration.mode == "readonly_copy"
58
- yield PostgresEra::Lineage.new(db, subject.bluebook_name)
65
+ db = connect(subject)
66
+ yield PostgresEra::Lineage.new(db, subject.bluebook_name, reading: reads_only?)
59
67
  ensure
60
68
  db&.close
61
69
  end
70
+
71
+ # A copy somebody else made is opened read-only before any statement runs: the schema is
72
+ # selected, never created, and a digest the copy lacks is left unwritten. A database the run
73
+ # made is its own to touch, so it is opened as a PostgresEra boot opens it.
74
+ def connect(subject)
75
+ return PostgresEra.connect_for(subject.bluebook_name, subject.settings) unless reads_only?
76
+
77
+ require "pg"
78
+ PG.connect(url).tap do |db|
79
+ db.exec("SET default_transaction_read_only = on")
80
+ db.exec("SET search_path TO #{db.quote_ident(subject.settings[:schema])}") if subject.settings[:schema]
81
+ end
82
+ end
83
+
84
+ def reads_only? = @declaration.mode == "readonly_copy"
62
85
  end
63
86
  end
64
87
  end
@@ -4,6 +4,7 @@ require_relative "declaration"
4
4
  require_relative "environment"
5
5
  require_relative "../journal_store/edge_audit"
6
6
  require_relative "../journal_store/held_domain"
7
+ require_relative "../../../adapters/driven/postgres_era/lineage_manager/era_resolution"
7
8
 
8
9
  module Hecks
9
10
  module Adapters
@@ -113,12 +114,17 @@ module Hecks
113
114
  # @return [String] the domain's bluebook directory
114
115
  def directory = held.directory
115
116
 
116
- # The edge that leads one era's label to the shape's label.
117
+ # Which held era the subject's shape resolves to, and the verdict a mint from the latest one
118
+ # would reach, by the resolution a boot records (`LineageManager::EraResolution`). It reads
119
+ # only the eras it is handed.
117
120
  #
118
- # @param from [String] the held era's label
119
- # @return [Bluebook::Translation, nil] the edge; nil when none is declared
120
- def edge_from(from)
121
- registry.translations.find { |t| t.domain == bluebook.name && t.from == from && t.to == label }
121
+ # @param eras [Array<Hash>] the copy's held eras, oldest first: `label`, `held_text`
122
+ # @yieldreturn [Integer] the copy's ledger watermark, read only when no held era matches
123
+ # @return [PostgresEra::LineageManager::EraResolution::Answer]
124
+ def resolve(eras, &)
125
+ PostgresEra::LineageManager::EraResolution.resolve(
126
+ eras: eras, bluebook: bluebook, translations: registry.translations, directory: directory, &
127
+ )
122
128
  end
123
129
 
124
130
  # @return [Array<String>] the persisted databases the domain's own world names, which a
@@ -21,7 +21,7 @@ module Hecks
21
21
  # The `Hecks::RustBuild` tool each ask runs.
22
22
  TOOLS = { generate: "project_rust", wasm: "project_wasm", host: "project_host",
23
23
  browser_wasm: "project_wasm_browser", conform: "rust_conformance",
24
- replay: "rust_conformance_fuzz", coverage: "rust_coverage" }.freeze
24
+ replay: "rust_conformance_fuzz", coverage: "rust_coverage", parser: "build_parser" }.freeze
25
25
 
26
26
  # The load path the benchmark child runs with: this checkout's or gem's `lib/`.
27
27
  LIB = File.expand_path("../../..", __dir__)
@@ -133,6 +133,15 @@ module Hecks
133
133
  child(:coverage, ["--check-allowlist"])
134
134
  end
135
135
 
136
+ # Builds the `hecks-parse` binary the parser specs run, in `rust/parser`.
137
+ #
138
+ # @param _held [Hash] the `Build` record, which holds nothing this needs
139
+ # @return [Hash{Symbol => Hash}] `output:` what cargo reported
140
+ # @raise [ConsoleCapture::Failure] when cargo cannot build the crate
141
+ def parser(**_held)
142
+ child(:parser, [])
143
+ end
144
+
136
145
  # Measures command throughput and latency for each target, building the Rust binary in the
137
146
  # workspace when it is a target and none was named. The benchmark can run for minutes, so it
138
147
  # starts through `ProcessPool`, which passes an interrupt on to it.
@@ -22,7 +22,7 @@ module Hecks
22
22
  CHECKOUT_MARKER = "hecks.gemspec"
23
23
 
24
24
  # What a copy holds: the workspace manifest, the kernel and every crate a domain build uses.
25
- PACKAGED = %w[Cargo.toml Cargo.lock src codegen parser
25
+ PACKAGED = %w[Cargo.toml Cargo.lock src codegen parser expr
26
26
  host build web lsp].freeze
27
27
 
28
28
  # Left out of a copy: build output anywhere, the corpus tests, and the corpus domains.
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ class SettingsReading
6
+ # The `disposable ledger` row of `hecks config`: whether the copy's world declares its
7
+ # PostgresEra store a disposable tooling ledger, which needs no era for a shape change, and
8
+ # whether the world or the default says so.
9
+ module DisposableLedger
10
+ # @param directory [String] the domain directory
11
+ # @return [Array(String, String, String)] the row's name, value and source
12
+ def disposable_ledger(directory)
13
+ registry = Hecks.describe(directory).registry
14
+ declared = registry.binding_settings(registry.first_domain_name, Ports::Persistence::VERB, "PostgresEra")
15
+ ["disposable ledger", disposable_wording(declared), declared.key?(:disposable_ledger) ? "world" : "default"]
16
+ rescue StandardError => e
17
+ ["disposable ledger", "could not be read", first_line(e.message)]
18
+ end
19
+
20
+ private
21
+
22
+ def disposable_wording(declared)
23
+ if [true, "true"].include?(declared[:disposable_ledger])
24
+ "yes: a shape change needs no era, and a breaking one archives its rows"
25
+ else
26
+ "no: a shape change needs an era"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../quality_control/adapters/push_due_reader"
4
+
5
+ module Hecks
6
+ module Adapters
7
+ class SettingsReading
8
+ # The `push nudge` row of `hecks config`: how many commits or hours local main may drift ahead
9
+ # of origin/main before QA files the `push-due` Work row, how many commits make it urgent, and
10
+ # whether the QualityControl world or the default says so.
11
+ module PushNudge
12
+ # @param directory [String] the domain directory
13
+ # @return [Array(String, String, String)] the row's name, value and source
14
+ def push_nudge(directory)
15
+ registry = Hecks.describe(directory).registry
16
+ declared = registry.world("QualityControl")&.for_verb(PushDueReader::VERB)
17
+ limits = PushDueReader.thresholds(registry)
18
+ value = "#{limits[:commits]} commits or #{limits[:hours]} hours, urgent at #{limits[:urgent_commits]} commits"
19
+ ["push nudge", value, declared ? "world" : "default"]
20
+ rescue StandardError => e
21
+ ["push nudge", "could not be read", first_line(e.message)]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ class SettingsReading
6
+ # The store rows of `hecks config`: each loaded bluebook's store, and the aggregates whose own
7
+ # bind overrides it. Resolved through the runtime's binding policy, so these rows cannot
8
+ # disagree with a boot.
9
+ module Stores
10
+ # The adapter names the store rows recognise by their storage.
11
+ SQLITE = /Sqlite/
12
+ POSTGRES = /Postgres/
13
+
14
+ # cannot disagree with a boot.
15
+ def stores(directory)
16
+ registry = Hecks.describe(directory).registry
17
+ registry.bluebooks.each_value.flat_map { |declaration| store_rows(registry, declaration) }
18
+ rescue StandardError => e
19
+ [["store", "could not be read", first_line(e.message)]]
20
+ end
21
+
22
+ def store_rows(registry, declaration)
23
+ name = declaration.name
24
+ adapter = registry.default_adapter_for(name) || Ports::Persistence::BindingPolicy.inherited_adapter(registry,
25
+ name) || DEFAULT
26
+ [["store #{name}", store_of(registry, name, adapter), default_store_source(registry, name)],
27
+ *aggregate_store_rows(registry, declaration)]
28
+ end
29
+
30
+ def aggregate_store_rows(registry, declaration)
31
+ declaration.aggregates.filter_map do |aggregate|
32
+ next unless bound_here?(registry, declaration.name, aggregate)
33
+
34
+ bind = Ports::Persistence::BindingPolicy.resolve(registry, declaration.name, aggregate)
35
+ ["store #{declaration.name}::#{aggregate.name}", store_of(registry, declaration.name, bind.adapter),
36
+ "aggregate bind in the hecksagon"]
37
+ end
38
+ end
39
+
40
+ def bound_here?(registry, domain, aggregate)
41
+ registry.hecksagon(domain)&.binds&.any? { |bind| named?(bind, aggregate) && bind.verb == VERB } || false
42
+ end
43
+
44
+ # A bind names its aggregate bare or qualified by its bluebook (`Tickets::Work`), as the
45
+ # hecksagon wrote it.
46
+ def named?(bind, aggregate)
47
+ bind.aggregate.to_s.split("::").last == aggregate.hecks_name
48
+ end
49
+
50
+ def default_store_source(registry, name)
51
+ return "hecksagon" if registry.hecksagon(name)&.default_binds(VERB)&.any?
52
+ return "world default_adapter" if registry.default_adapter_for(name)
53
+ return "attaching domain's root default" if Ports::Persistence::BindingPolicy.inherited_adapter(registry, name)
54
+
55
+ "default"
56
+ end
57
+
58
+ def store_of(registry, domain, adapter)
59
+ settings = registry.binding_settings(domain, VERB, adapter)
60
+ case adapter
61
+ when DEFAULT then DEFAULT
62
+ when SQLITE then "SqliteAt #{settings[:database]}"
63
+ when POSTGRES then "Postgres #{database_name(settings[:database])}"
64
+ else adapter
65
+ end
66
+ end
67
+
68
+ # The database's name from a URL, with the password hidden and the query string left out.
69
+ def database_name(url)
70
+ without_query = hide_password(url).split("?").first.to_s
71
+ without_query.split("/").last.to_s
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../codebase/test_scope"
4
+
5
+ module Hecks
6
+ module Adapters
7
+ class SettingsReading
8
+ # The `test scope` row of `hecks config`: where the full spec suite runs and how many spec
9
+ # files one local call may run, and whether the Hecks world or the default says so.
10
+ module TestScope
11
+ # @param directory [String] the domain directory
12
+ # @return [Array(String, String, String)] the row's name, value and source
13
+ def test_scope(directory)
14
+ declared = Codebase::TestScope.setting(Hecks.describe(directory).registry)
15
+ return ["test scope", "no limit", "default"] if declared.empty?
16
+
17
+ ["test scope", wording(declared), "world"]
18
+ rescue StandardError => e
19
+ ["test scope", "could not be read", first_line(e.message)]
20
+ end
21
+
22
+ def wording(declared)
23
+ "full suite in #{declared[:suite_runs_in]}; at most #{declared[:spec_files_limit]} spec files per call locally"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end