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
@@ -0,0 +1,49 @@
1
+ module Hecks
2
+ module Adapters
3
+ module Driving
4
+ module CliRunner
5
+ # The launcher's renamed table at run time: a line that spells a renamed command's old name
6
+ # is noted once on standard error, and its argument names translate before the command reads
7
+ # them. Extended into `CliRunner`.
8
+ module RenamedNames
9
+ # Notes a renamed spelling once, and returns the line's argv with its arguments translated.
10
+ #
11
+ # @param cli [Hash] the projection, holding `:names` with its `:renamed` table
12
+ # @param typed [String] the word typed, without its `!`
13
+ # @param name [String] the name the index resolved the word to
14
+ # @param argv [Array<String>] the line's words, the command name first
15
+ # @return [Array<String>] the words with renamed arguments translated
16
+ def renamed_line(cli, typed, name, argv)
17
+ table = cli.dig(:names, :renamed) || {}
18
+ note_renamed(cli, typed, name) if Array(table[:spellings]).include?(typed)
19
+ translate_arguments(table.dig(:arguments, typed), argv)
20
+ end
21
+
22
+ # Says once per process, on standard error, that a line used a renamed command's old name.
23
+ def note_renamed(cli, typed, name)
24
+ target = cli.dig(:names, :command, typed) || cli.dig(:names, :question, typed) || name
25
+ return unless VerbNames::NOTED.add?("spelling #{typed}")
26
+
27
+ warn "hecks: #{typed} is the former name of #{target}; use that spelling (this notice prints once)"
28
+ end
29
+
30
+ # Rewrites the argument names a renamed table translates (`old=value` to `new=value`); the
31
+ # name word and any other word pass through unchanged.
32
+ def translate_arguments(renames, argv)
33
+ return argv if renames.nil? || renames.empty?
34
+
35
+ [argv.first, *argv.drop(1).map { |word| translate_word(renames, word) }]
36
+ end
37
+
38
+ # One `old=value` word with its argument renamed when the table names it.
39
+ def translate_word(renames, word)
40
+ key, value = word.split("=", 2)
41
+ return word if value.nil? || !renames.key?(key)
42
+
43
+ "#{renames[key]}=#{value}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,9 +1,13 @@
1
+ require_relative "bang_rule"
2
+
1
3
  module Hecks
2
4
  module Adapters
3
5
  module Driving
4
6
  module CliRunner
5
7
  # Parses a command line against the projection. Extended into `CliRunner`.
6
8
  module Resolution
9
+ include BangRule
10
+
7
11
  # The words that ask for the usage.
8
12
  HELP_WORDS = ["--help", "-h", "help"].freeze
9
13
 
@@ -14,39 +18,58 @@ module Hecks
14
18
  # bluebook:, launcher:}` for a command to dispatch
15
19
  def resolve(runtime, argv, program)
16
20
  refused = Admission.refusal(runtime.registry, "Cli")
17
- return { answer: [refused, 1] } if refused
21
+ return { answer: [refused, ExitStatus::REFUSED] } if refused
18
22
 
19
23
  bluebook, argv, program = bluebook_for(runtime, argv, program)
20
24
  launcher = LauncherOptions.settings(runtime, bluebook.name)
21
25
  options = LauncherOptions.projection(launcher, program)
22
- cli = Projector.call(:cli, bluebook: bluebook, options: options.merge(audience(runtime, launcher)))
26
+ shown = options.merge(audience(runtime, launcher))
27
+ cli = Projector.call(:cli, bluebook: bluebook, options: shown)
23
28
  scope = { runtime: runtime, bluebook: bluebook, launcher: launcher, options: options,
24
- cli: cli, program: program }
25
- usage_answer(scope, argv.first) || command_plan(scope, argv)
29
+ shown: shown, cli: cli, program: program }
30
+ answer_for(scope, argv) || command_plan(scope, argv)
31
+ end
32
+
33
+ # The answer a line gets without naming a command, or nil when it names one.
34
+ def answer_for(scope, argv)
35
+ json_answer(scope, argv) || usage_answer(scope, argv.first) || module_answer(scope, argv.first) ||
36
+ search_answer(scope, argv) || completion_answer(scope, argv) || tour_answer(scope, argv) || resume(scope, argv)
26
37
  end
27
38
 
28
39
  # The answer to a line that is only a request for usage, or nil.
29
40
  def usage_answer(scope, name)
30
- return { answer: [scope[:cli][:usage], 0] } if name.nil? || HELP_WORDS.include?(name)
31
- return { answer: [all_usage(*scope.values_at(:runtime, :bluebook, :launcher, :options)), 0] } if name == "--all"
32
- return unless name == "--maintainer"
41
+ return { answer: [scope[:cli][:usage], ExitStatus::ANSWERED] } if name.nil? || HELP_WORDS.include?(name)
42
+ return unless %w[--all --maintainer].include?(name)
43
+
44
+ shown = scope.values_at(:runtime, :bluebook, :launcher, :options)
45
+ { answer: [name == "--all" ? all_usage(*shown) : maintainer_usage(*shown), ExitStatus::ANSWERED] }
46
+ end
47
+
48
+ # The help of the module a line is only the word of, or nil. A module groups aggregates of
49
+ # one bluebook (ADR 0163), so `hecks deliver` lists what `deliver` holds.
50
+ def module_answer(scope, word)
51
+ name = Projector::CliProjector.module_named(scope[:bluebook], word)
52
+ return unless name
33
53
 
34
- { answer: [maintainer_usage(*scope.values_at(:runtime, :bluebook, :launcher, :options)), 0] }
54
+ shown = scope[:shown].merge(module: name, program: scope[:program])
55
+ { answer: [Projector.call(:cli, bluebook: scope[:bluebook], options: shown)[:usage], ExitStatus::ANSWERED] }
35
56
  end
36
57
 
37
- # The command a line names, or the answer when it names none or asks for its help.
58
+ # The command a line names, or the answer when it names none or asks for its help. A
59
+ # line that names nothing, or something the bluebook does not declare, could not be read.
38
60
  def command_plan(scope, argv)
39
61
  cli = scope[:cli]
62
+ word = typed_word(argv)
40
63
  asking, name, argv = entry_word(cli, argv)
41
- return { answer: [cli[:usage], 1] } if name.nil?
64
+ return { answer: [cli[:usage], ExitStatus::USAGE] } if name.nil?
42
65
 
43
66
  spec = find_spec(cli, asking, name)
44
- return { answer: [unknown(cli, name, asking, scope[:program]), 1] } unless spec
67
+ return { answer: [unknown(cli, name, asking, scope[:program]), ExitStatus::USAGE] } unless spec
45
68
 
46
- rest = argv[1..]
47
- return { answer: [command_help(scope, name, asking), 0] } if rest.include?("--help")
69
+ answer = early_answer(scope, cli, { asking: asking, word: word, name: name, argv: argv })
70
+ return { answer: answer } if answer
48
71
 
49
- { spec: spec, name: name, rest: rest, asking: asking, program: scope[:program],
72
+ { spec: spec, name: name, rest: argv[1..], asking: asking, program: scope[:program],
50
73
  bluebook: scope[:bluebook], launcher: scope[:launcher] }
51
74
  end
52
75
 
@@ -116,7 +139,7 @@ module Hecks
116
139
  # declare a command and a query of one name. A trailing `!` says the word is a command and
117
140
  # is not part of the name. A query answers to its bare name too; `query` is needed only
118
141
  # when a command shares it. The name may be written in the bluebook's verb form
119
- # (`Hecks::PushTrain.board!`), which reaches the same command (see `VerbNames`).
142
+ # (`Hecks::SendTrain.board!`), which reaches the same command (see `VerbNames`).
120
143
  #
121
144
  # @return [Array(Boolean, String, Array<String>)] `asking`, `name` (nil when absent),
122
145
  # `argv`
@@ -126,8 +149,11 @@ module Hecks
126
149
  name = argv.first
127
150
  return [asking, nil, argv] if name.nil?
128
151
 
129
- bang = name.end_with?("!")
130
- name = canonical_name(cli, name.chomp("!"))
152
+ bang = name.end_with?("!")
153
+ typed = name.chomp("!")
154
+ name = canonical_name(cli, typed)
155
+ note_former_name(cli, typed, name)
156
+ argv = renamed_line(cli, typed, name, argv)
131
157
  [asking || (!bang && query_only?(cli, name)), name, argv]
132
158
  end
133
159
 
@@ -0,0 +1,63 @@
1
+ module Hecks
2
+ module Adapters
3
+ module Driving
4
+ module CliRunner
5
+ # The launcher word `resume <run>` (ADR 0163, plan step 31): continues a saga that faulted
6
+ # from the stage it faulted in. The saga saved its arguments and the stage; the process
7
+ # manager's `resumes` list names the command that re-runs that stage, and that command is
8
+ # dispatched with the saved arguments through the ordinary line path.
9
+ module ResumeWords
10
+ SAGA = "GateAndBoard".freeze
11
+
12
+ # The answer to `resume <run>`, or nil when the line is not a resume.
13
+ def resume(scope, argv)
14
+ return unless argv.first == "resume"
15
+ return { answer: [resume_usage, ExitStatus::USAGE] } unless argv[1] && booted?(scope)
16
+
17
+ outcome = scope[:runtime].saga_interpreter.resume(scope[:bluebook].name, SAGA, argv[1])
18
+ return { answer: [resume_refusal(outcome), ExitStatus::REFUSED] } unless outcome[:resumed]
19
+
20
+ resume_stage(scope, outcome)
21
+ end
22
+
23
+ # Whether the line runs against a booted domain: a describe-only runtime (the usage path)
24
+ # has no saga interpreter, so a resume there answers its usage rather than failing.
25
+ def booted?(scope)
26
+ scope[:runtime].respond_to?(:saga_interpreter)
27
+ end
28
+
29
+ # Dispatches the stage's resume command with the saved arguments, or refuses when the
30
+ # stage declares none.
31
+ def resume_stage(scope, outcome)
32
+ command = resume_command(scope[:bluebook], outcome[:stage])
33
+ unless command
34
+ return { answer: ["resume refused: stage #{outcome[:stage]} declares no resume command",
35
+ ExitStatus::REFUSED] }
36
+ end
37
+
38
+ line = [command, *outcome[:arguments].map { |key, value| "#{key}=#{value}" }]
39
+ text, status = CliRunner.call(runtime: scope[:runtime], argv: line, program: scope[:program])
40
+ { answer: [text, status] }
41
+ end
42
+
43
+ # The command the process manager's `resumes` list names for a stage, as a bang line.
44
+ def resume_command(bluebook, stage)
45
+ process_manager = bluebook.process_managers.find { |pm| pm.name == SAGA }
46
+ entry = process_manager&.resumes&.find { |line| line.start_with?("#{stage}=") }
47
+ entry && "#{entry.split("=", 2).last}!"
48
+ end
49
+
50
+ # The reason a resume refuses: the saga is missing, or it is not waiting for a person.
51
+ def resume_refusal(outcome)
52
+ "resume refused: #{outcome[:reason]}"
53
+ end
54
+
55
+ # The usage line of `resume`.
56
+ def resume_usage
57
+ "usage: resume <run> (continues a GateAndBoard saga that faulted, from the stage it faulted in)"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,66 @@
1
+ require_relative "../../../storehouse"
2
+
3
+ module Hecks
4
+ module Adapters
5
+ module Driving
6
+ module CliRunner
7
+ # Lets a landing name the linked worktree it lands by its run id, rather than repeating its
8
+ # checkout and branch. An explicit checkout or branch always wins over the one the worktree holds.
9
+ module RunReference
10
+ # The aggregate whose record a landing's `from` names.
11
+ SOURCE = "LinkedTree".freeze
12
+
13
+ # The arguments a result names as the ids a command used.
14
+ IDENTITY = %i[run from checkout branch].freeze
15
+
16
+ # The command that lands a branch: `Hecks::Landing.Land`, and its qualified forms.
17
+ LANDING = /Landing\.Land\z/
18
+
19
+ module_function
20
+
21
+ # Mints the run key a creating command is owed, then fills the arguments a `from` names.
22
+ #
23
+ # @return [Array(Hash, String, nil)] the arguments and the minted key, if one was minted
24
+ def prepare(runtime, spec, args, settings)
25
+ args, minted = LauncherOptions.run_key(runtime, spec, args, settings)
26
+ [fill(runtime, spec, args), minted]
27
+ end
28
+
29
+ # @param runtime [Runtime::Registry] the booted domain the command runs against
30
+ # @param spec [Hash] the resolved command
31
+ # @param args [Hash] the parsed arguments, keyed by name
32
+ # @return [Hash] the arguments, with checkout and branch filled from the named worktree when the
33
+ # caller gave a `from` and left them out
34
+ def fill(runtime, spec, args)
35
+ from = args[:from]&.fetch(:value, nil)
36
+ return args unless from && spec[:command].to_s.match?(LANDING)
37
+
38
+ tree = Storehouse.state(runtime: runtime, aggregate: SOURCE, id: from,
39
+ summary: "landing reads the worktree it names")
40
+ return args unless tree[:ok]
41
+
42
+ record = tree[:record]
43
+ args.merge(checkout: args[:checkout] || { value: value_of(record[:path]) },
44
+ branch: args[:branch] || { value: value_of(record[:branch]) })
45
+ end
46
+
47
+ # The ids a result names: the run key, the record written, and the references the command used,
48
+ # with the checkout and branch it resolved. Absent ones are left out.
49
+ #
50
+ # @param args [Hash] the arguments the command ran with, after any reference was filled
51
+ # @param record_id [String, nil] the id of the record the command wrote
52
+ # @return [Hash] the ids the command used
53
+ def ids(args, record_id)
54
+ named = IDENTITY.to_h { |key| [key, value_of(args[key])] }
55
+ named.merge(id: record_id).compact
56
+ end
57
+
58
+ # A stored field is its value, or the `{value:}` wrapper a word carries.
59
+ def value_of(field)
60
+ field.is_a?(Hash) ? field[:value] : field
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,118 @@
1
+ module Hecks
2
+ module Adapters
3
+ module Driving
4
+ module CliRunner
5
+ # Answers a creating command that names a run key the store already holds.
6
+ #
7
+ # Where the aggregate persists (SQLite, Postgres), a repeat with the same key and the same
8
+ # arguments answers the record written first, and a repeat with other arguments is refused:
9
+ # the key names a different run. Memory holds nothing across processes, so it cannot
10
+ # answer a repeat; it refuses the key and says which store would answer it.
11
+ module RunReplay
12
+ MEMORY = "Memory".freeze
13
+
14
+ module_function
15
+
16
+ # @param runtime [Runtime::Dispatcher] the booted domain
17
+ # @param spec [Hash] the command's projected spec
18
+ # @param args [Hash] the parsed arguments, including `run` when one was given
19
+ # @return [Array(String, Integer), nil] the answer and its status, or nil when the
20
+ # key is not recorded and the command should run
21
+ def answer(runtime, spec, args)
22
+ return unless replayable?(runtime, spec, args)
23
+
24
+ target = target(runtime, spec)
25
+ record = target && recorded(target, run_key(args))
26
+ return unless record
27
+
28
+ return memory_refusal(args) if memory?(target)
29
+
30
+ same?(record, args) ? [recorded_text(record, args), ExitStatus::ANSWERED] : [different_text(args), ExitStatus::REFUSED]
31
+ end
32
+
33
+ # Whether the command creates a record under a run key the caller gave.
34
+ def replayable?(runtime, spec, args)
35
+ spec[:creates] && args.key?(:run) && runtime.respond_to?(:registry)
36
+ end
37
+
38
+ # The registry, domain and aggregate the command writes to, or nil when it has none.
39
+ def target(runtime, spec)
40
+ registry = runtime.registry
41
+ domain = registry.first_domain_name
42
+ aggregate = registry.bluebook(domain)&.aggregate(spec[:group].to_s)
43
+ aggregate && { registry: registry, domain: domain, aggregate: aggregate }
44
+ end
45
+
46
+ # Whether the aggregate's authoritative store is Memory.
47
+ def memory?(target)
48
+ bind = Ports::Persistence::BindingPolicy.resolve(target[:registry], target[:domain], target[:aggregate])
49
+ bind.adapter.to_s == MEMORY
50
+ end
51
+
52
+ # The run key's value, whether given bare or as `{ value: }`.
53
+ def run_key(args)
54
+ value = args[:run]
55
+ value.is_a?(Hash) ? value[:value] : value
56
+ end
57
+
58
+ # The stored record of the key, or nil when none is held.
59
+ def recorded(target, key)
60
+ registry, domain = target.values_at(:registry, :domain)
61
+ registry.repository(domain, target[:aggregate]).find(key.to_s)
62
+ end
63
+
64
+ # Whether the stored record holds every argument the repeat gave.
65
+ def same?(record, args)
66
+ given(args).all? { |name, value| stored(record, name) == value.to_s }
67
+ end
68
+
69
+ # A stored field as its text: a value object answers its `value` field.
70
+ def stored(record, name)
71
+ held = record.state[name.to_sym]
72
+ (held.is_a?(Hecks::Runtime::Value) ? held[:value] : held).to_s
73
+ end
74
+
75
+ # The arguments that describe the record, without the run key.
76
+ def given(args)
77
+ args.except(:run).transform_values { |value| plain(value) }
78
+ end
79
+
80
+ # A value as its text: `{ value: x }` and `{ cents: x }` both answer `x`.
81
+ def plain(value)
82
+ return value unless value.is_a?(Hash)
83
+
84
+ value.values.first
85
+ end
86
+
87
+ # The first answer's text: the run key, the record it already holds and the ids it named.
88
+ def recorded_text(record, args)
89
+ JSON.pretty_generate("id" => run_key(args).to_s, "state" => recorded_state(record), "events" => [],
90
+ "ids" => { "run" => run_key(args).to_s, "id" => record.id.to_s })
91
+ end
92
+
93
+ # The stored fields as text, keyed by name, then the record's id, as the first answer
94
+ # printed them.
95
+ def recorded_state(record)
96
+ fields = record.state.keys.to_h { |name| [name.to_s, stored(record, name)] }
97
+ fields.merge("id" => record.id.to_s)
98
+ end
99
+
100
+ # The refusal for a key held with other arguments.
101
+ def different_text(args)
102
+ "[already_recorded] refused: run #{run_key(args)} is already recorded with other arguments: nothing written"
103
+ end
104
+
105
+ # The refusal for a key held in Memory, which does not remember runs across processes.
106
+ def memory_refusal(args) = [refusal_text(args), ExitStatus::REFUSED]
107
+
108
+ # The text naming Memory and the persisting stores that would answer the repeat.
109
+ def refusal_text(args)
110
+ "[memory_store] refused: run #{run_key(args)} is held in Memory, which does not remember runs across " \
111
+ "processes: nothing written. A persisting store (SQLite or Postgres) answers a repeat " \
112
+ "with the first outcome."
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,35 @@
1
+ module Hecks
2
+ module Adapters
3
+ module Driving
4
+ module CliRunner
5
+ # The launcher word `search`: the commands and queries a word appears in, read from the same
6
+ # projection the help prints (ADR 0163, step 20). Extended into `CliRunner`.
7
+ module SearchWords
8
+ # The answer to `search <word> [--all]`: the commands and queries a word appears in, or
9
+ # the line saying none does.
10
+ def search_answer(scope, argv)
11
+ return unless argv.first == "search"
12
+
13
+ word = argv.drop(1).find { |arg| !arg.start_with?("--") }
14
+ return { answer: ["usage: #{scope[:program]} search <word> [--all]", ExitStatus::USAGE] } unless word
15
+
16
+ options = search_options(scope, argv.include?("--all"))
17
+ lines = Projector::CliProjector.search_lines(scope[:bluebook], scope[:cli][:commands],
18
+ scope[:cli][:questions], options, word)
19
+ return { answer: ["no command or query matches #{word}", ExitStatus::REFUSED] } unless lines
20
+
21
+ { answer: [lines.join("\n"), ExitStatus::ANSWERED] }
22
+ end
23
+
24
+ # The listing's options for a search: the audience the help shows, or with `--all` the
25
+ # maintainer's audience and the internal commands too.
26
+ def search_options(scope, all)
27
+ return scope[:shown] unless all
28
+
29
+ scope[:options].merge(audience(scope[:runtime], scope[:launcher], maintainer: true)).merge(all: true)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -21,7 +21,7 @@ module Hecks
21
21
  #
22
22
  # @return [Array(String, Integer)] the JSON and the status, plus (Array(String, Integer,
23
23
  # String)) why the run failed when it did
24
- def settled(runtime, spec, handle, bluebook, launcher, extra, text: false) # rubocop:disable Metrics/ParameterLists -- pinned by the callers and specs
24
+ def settled(runtime, spec, handle, bluebook, launcher, extra, text: false)
25
25
  why = reactions_failed(handle)
26
26
  return finish(stateless_json(handle, extra), why) if handle.state.nil?
27
27
 
@@ -62,12 +62,12 @@ module Hecks
62
62
  end
63
63
 
64
64
  # The answer of a command the launcher prints as its report: the text it recorded, with
65
- # the status 1 when the run failed, and nothing else.
65
+ # the status `REFUSED` when the run failed, and nothing else.
66
66
  def report_of(state, why)
67
67
  text = state[why.empty? ? :output : :refusal]
68
68
  text = text[:value] if text.is_a?(Hash)
69
69
  text = why.join("\n") if text.to_s.strip.empty?
70
- [text.to_s, why.empty? ? 0 : 1]
70
+ [text.to_s, why.empty? ? ExitStatus::ANSWERED : ExitStatus::REFUSED]
71
71
  end
72
72
 
73
73
  # The sentence for a record that ended in a failure state: the state, then the record's
@@ -83,9 +83,10 @@ module Hecks
83
83
  "#{sentence}: #{refusal.to_s.strip.sub(QUALIFIED_CLASS_PREFIX, "")}"
84
84
  end
85
85
 
86
- # The answer and its status: 0 when nothing failed, else 1 with the reasons joined.
86
+ # The answer and its status: `ANSWERED` when nothing failed, else `REFUSED` with the
87
+ # reasons joined.
87
88
  def finish(text, reasons)
88
- reasons.empty? ? [text, 0] : [text, 1, reasons.join("\n")]
89
+ reasons.empty? ? [text, ExitStatus::ANSWERED] : [text, ExitStatus::REFUSED, reasons.join("\n")]
89
90
  end
90
91
 
91
92
  # What the reactions of the run the handle reports did wrong: each refusal that blocks it
@@ -18,31 +18,32 @@ module Hecks
18
18
  # @param out [IO] where each entry's line goes
19
19
  # @param err [IO] where a refusal goes
20
20
  # @param max_polls [Integer, nil] stop after this many asks; unbounded when nil
21
- # @return [Integer, nil] 0 or 1 for a stream, nil when `call` should run the line
22
- def stream(runtime:, argv:, program: "hecks run", out: $stdout, err: $stderr, max_polls: nil) # rubocop:disable Metrics/ParameterLists -- the keyword API is what callers pass
23
- plan = resolve(runtime, argv, program)
21
+ # @return [Integer, nil] the stream's `ExitStatus`, nil when `call` should run the line
22
+ def stream(runtime:, argv:, program: "hecks run", out: $stdout, err: $stderr, max_polls: nil)
23
+ plan = resolve(runtime, split_verbosity(argv).last, program)
24
24
  words = stream_words(plan)
25
25
  return unless words
26
26
 
27
27
  run_stream(runtime, plan[:spec], words, out, max_polls)
28
28
  rescue Interrupt, Errno::EPIPE
29
- 0
29
+ ExitStatus::ANSWERED
30
30
  rescue Runtime::NotFound, Runtime::TypeMismatch => e
31
- refuse(err, "#{e.message}\n\n #{program} #{plan[:name]} --help")
31
+ refuse(err, "#{e.message}\n\n #{program} #{plan[:name]} --help", ExitStatus::USAGE)
32
32
  rescue *Runtime::DOMAIN_REFUSALS => e
33
33
  refuse(err, e.message)
34
34
  end
35
35
 
36
- # Tails the question the line names and answers 0, the status of a stream that ended.
36
+ # Tails the question the line names and answers `ANSWERED`, the status of a stream that
37
+ # ended.
37
38
  def run_stream(runtime, spec, words, out, max_polls)
38
39
  tail(runtime, spec, Cli.arguments(spec, words), out, max_polls)
39
- 0
40
+ ExitStatus::ANSWERED
40
41
  end
41
42
 
42
- # Prints a refusal and answers status 1.
43
- def refuse(err, text)
43
+ # Prints a refusal and answers its status, `REFUSED` unless told otherwise.
44
+ def refuse(err, text, status = ExitStatus::REFUSED)
44
45
  err.puts(text)
45
- 1
46
+ status
46
47
  end
47
48
 
48
49
  # One ask after another, each from the cursor the last gave.
@@ -9,7 +9,7 @@ module Hecks
9
9
  # Ranked by shared prefix, which survives a dropped letter where a substring would not.
10
10
  def unknown(cli, name, asking, program)
11
11
  near = near_names(cli, snake_form(name), asking)
12
- lines = ["no such #{asking ? "query" : "command"}: #{name}"]
12
+ lines = ["[unknown_#{asking ? "query" : "command"}] no such #{asking ? "query" : "command"}: #{name}"]
13
13
  shown = near.first(5).map { |candidate| " #{shown_name(cli, candidate, asking)}" }
14
14
  lines += ["", "did you mean:", *shown] unless near.empty?
15
15
  lines += ["", " #{program}#{" query" if asking} for the full list"]
@@ -0,0 +1,77 @@
1
+ require "fileutils"
2
+ require "stringio"
3
+
4
+ module Hecks
5
+ module Adapters
6
+ module Driving
7
+ module CliRunner
8
+ # The launcher word `tour [dir]` (ADR 0163, plan step 40): writes a sample domain into a new
9
+ # directory, runs one command against it in memory, and says what to type next. It writes
10
+ # only into a directory that does not exist yet.
11
+ module TourWords
12
+ TOUR_NAME = "Tour".freeze
13
+ TOUR_COMMAND = %w[Example.create! name=hello].freeze
14
+ TOUR_DIRECTORY = "hecks-tour".freeze
15
+
16
+ # The answer to `tour [dir]`, or nil when the line is not a tour.
17
+ def tour_answer(scope, argv)
18
+ return unless argv.first == "tour"
19
+
20
+ target = File.expand_path(argv[1] || TOUR_DIRECTORY, Dir.pwd)
21
+ return { answer: [tour_refusal(target), ExitStatus::REFUSED] } if File.exist?(target)
22
+
23
+ write_tour(target)
24
+ { answer: [tour_report(scope, target), ExitStatus::ANSWERED] }
25
+ end
26
+
27
+ # The reason a tour refuses a directory that already exists.
28
+ def tour_refusal(target)
29
+ "tour refused: #{shown_tour(target)} already exists; name a new directory: hecks tour <dir>"
30
+ end
31
+
32
+ # Writes each stub file of the sample domain under `target`.
33
+ def write_tour(target)
34
+ require_relative "../../../tools/domain_stub"
35
+ Tools::DomainStub.files(name: TOUR_NAME).each do |path, text|
36
+ full = File.join(target, path)
37
+ FileUtils.mkdir_p(File.dirname(full))
38
+ File.write(full, text)
39
+ end
40
+ end
41
+
42
+ # The report of a tour: what was written, the command's result, and the next command.
43
+ def tour_report(scope, target)
44
+ shown = shown_tour(target)
45
+ result = capture_run(target)
46
+ ran = "ran: #{tour_line(scope, shown, TOUR_COMMAND)}"
47
+ lines = ["wrote a sample domain in #{shown}/", "", ran, result]
48
+ lines + ["", "next: #{tour_line(scope, shown, %w[Example.create! name=yourname])}"]
49
+ end
50
+
51
+ # The launcher line that runs `command` (a verb and its arguments) against the domain in
52
+ # `shown`: `run` is a verb of Operation, not a launcher word.
53
+ def tour_line(scope, shown, command)
54
+ verb, *arguments = command
55
+ given = arguments.map { |argument| "arguments.value=#{argument}" }
56
+ [scope[:program], "Operation.run!", "subject.value=#{shown}", "verb.value=#{verb}",
57
+ *given].join(" ")
58
+ end
59
+
60
+ # The command's own answer, from a booted copy of the sample domain. The runner answers
61
+ # without exiting, unlike the launcher's `run`, so the report can carry the text.
62
+ def capture_run(target)
63
+ runtime = Hecks.boot(target, install_driving: false)
64
+ Assembly.bind_ported_runtime(runtime)
65
+ text, _status = CliRunner.call(runtime: runtime, argv: TOUR_COMMAND, program: "hecks run #{target}")
66
+ text.to_s.strip
67
+ end
68
+
69
+ # The directory as the user typed it, relative to where they are, when it is inside.
70
+ def shown_tour(target)
71
+ target.delete_prefix("#{Dir.pwd}/")
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end