hecks 6.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (754) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +19 -12
  3. data/lib/hecks/adapters/driven/claude_code.rb +2 -2
  4. data/lib/hecks/adapters/driven/folder.rb +10 -1
  5. data/lib/hecks/adapters/driven/folder_overlay.rb +15 -0
  6. data/lib/hecks/adapters/driven/heki.rb +1 -1
  7. data/lib/hecks/adapters/driven/in_process_key_vault.rb +1 -1
  8. data/lib/hecks/adapters/driven/memory/outbox_rows.rb +2 -2
  9. data/lib/hecks/adapters/driven/postgres/name_guard.rb +25 -0
  10. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -3
  11. data/lib/hecks/adapters/driven/postgres/repository.rb +1 -1
  12. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +1 -1
  13. data/lib/hecks/adapters/driven/postgres.rb +3 -0
  14. data/lib/hecks/adapters/driven/postgres_era/boot.rb +28 -16
  15. data/lib/hecks/adapters/driven/postgres_era/class_methods.rb +27 -7
  16. data/lib/hecks/adapters/driven/postgres_era/dialect.rb +10 -5
  17. data/lib/hecks/adapters/driven/postgres_era/field_cache_provisioner.rb +39 -0
  18. data/lib/hecks/adapters/driven/postgres_era/journal.rb +52 -13
  19. data/lib/hecks/adapters/driven/postgres_era/lineage/chain_sql.rb +29 -49
  20. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_sql.rb +73 -0
  21. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.json +10 -0
  22. data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.rb +65 -0
  23. data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename.rb +77 -25
  24. data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename_state.rb +108 -0
  25. data/lib/hecks/adapters/driven/postgres_era/lineage/era_integrity.rb +11 -6
  26. data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +63 -5
  27. data/lib/hecks/adapters/driven/postgres_era/lineage/layered_sql.rb +64 -0
  28. data/lib/hecks/adapters/driven/postgres_era/lineage/ledger_reset.rb +150 -0
  29. data/lib/hecks/adapters/driven/postgres_era/lineage/mint_provisioning.rb +85 -0
  30. data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +11 -7
  31. data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +11 -5
  32. data/lib/hecks/adapters/driven/postgres_era/lineage/split_sql.rb +76 -0
  33. data/lib/hecks/adapters/driven/postgres_era/lineage/sql_templates.rb +9 -0
  34. data/lib/hecks/adapters/driven/postgres_era/lineage.rb +10 -2
  35. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/context.rb +23 -3
  36. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +3 -1
  37. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/disposable_ledger.rb +119 -0
  38. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolution.rb +219 -0
  39. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +68 -71
  40. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/held_era.rb +68 -0
  41. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/ledger_change.rb +63 -0
  42. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
  43. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_decision.rb +163 -0
  44. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_request.rb +24 -0
  45. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +59 -21
  46. data/lib/hecks/adapters/driven/postgres_era/lineage_manager/refusals.rb +24 -11
  47. data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +40 -6
  48. data/lib/hecks/adapters/driven/postgres_era/shared_tables.rb +32 -0
  49. data/lib/hecks/adapters/driven/postgres_era.adapter +12 -0
  50. data/lib/hecks/adapters/driven/postgres_era.rb +25 -10
  51. data/lib/hecks/adapters/driven/prism.rb +0 -1
  52. data/lib/hecks/adapters/driven/sql_query_builder.rb +1 -0
  53. data/lib/hecks/adapters/driven/sqlite/dispatch_claims.rb +1 -1
  54. data/lib/hecks/adapters/driven/sqlite/name_guard.rb +25 -0
  55. data/lib/hecks/adapters/driven/sqlite/outbox.rb +2 -2
  56. data/lib/hecks/adapters/driven/sqlite/repository.rb +1 -1
  57. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +20 -0
  58. data/lib/hecks/adapters/driven/sqlite.rb +9 -1
  59. data/lib/hecks/adapters/driven/tenant_provisioner.rb +1 -1
  60. data/lib/hecks/adapters/driven/worktree_overlay.rb +117 -0
  61. data/lib/hecks/adapters/driving/cli/shorthand.rb +5 -1
  62. data/lib/hecks/adapters/driving/cli.rb +1 -1
  63. data/lib/hecks/adapters/driving/cli_runner/answers.rb +77 -22
  64. data/lib/hecks/adapters/driving/cli_runner/bang_rule.rb +35 -0
  65. data/lib/hecks/adapters/driving/cli_runner/completion_words.rb +36 -0
  66. data/lib/hecks/adapters/driving/cli_runner/json_words.rb +55 -0
  67. data/lib/hecks/adapters/driving/cli_runner/name_index.rb +63 -0
  68. data/lib/hecks/adapters/driving/cli_runner/read_context.rb +32 -0
  69. data/lib/hecks/adapters/driving/cli_runner/renamed_names.rb +49 -0
  70. data/lib/hecks/adapters/driving/cli_runner/resolution.rb +43 -17
  71. data/lib/hecks/adapters/driving/cli_runner/resume_words.rb +63 -0
  72. data/lib/hecks/adapters/driving/cli_runner/run_reference.rb +66 -0
  73. data/lib/hecks/adapters/driving/cli_runner/run_replay.rb +118 -0
  74. data/lib/hecks/adapters/driving/cli_runner/search_words.rb +35 -0
  75. data/lib/hecks/adapters/driving/cli_runner/settling.rb +6 -5
  76. data/lib/hecks/adapters/driving/cli_runner/streaming.rb +11 -10
  77. data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +1 -1
  78. data/lib/hecks/adapters/driving/cli_runner/tour_words.rb +77 -0
  79. data/lib/hecks/adapters/driving/cli_runner/verb_names.rb +36 -4
  80. data/lib/hecks/adapters/driving/cli_runner/verbosity.rb +75 -0
  81. data/lib/hecks/adapters/driving/cli_runner.rb +106 -7
  82. data/lib/hecks/adapters/driving/context_line.rb +85 -0
  83. data/lib/hecks/adapters/driving/exit_status.rb +31 -0
  84. data/lib/hecks/adapters/driving/launcher_options.rb +7 -5
  85. data/lib/hecks/adapters/driving/mcp/progress_sink.rb +45 -0
  86. data/lib/hecks/adapters/driving/mcp/tool_calls.rb +7 -5
  87. data/lib/hecks/adapters/driving/mcp.rb +25 -5
  88. data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +40 -7
  89. data/lib/hecks/adapters/driving/mcp_scope.rb +8 -7
  90. data/lib/hecks/adapters/driving/ruby/aggregate_module/hooks.rb +154 -0
  91. data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +64 -93
  92. data/lib/hecks/adapters/driving/usage_log.rb +146 -0
  93. data/lib/hecks/adapters/driving/write_guard.rb +55 -0
  94. data/lib/hecks/adapters/driving.rb +0 -1
  95. data/lib/hecks/behaviors/dsl.rb +5 -1
  96. data/lib/hecks/behaviors/expectations/boot.rb +0 -1
  97. data/lib/hecks/bluebook/acknowledgements.rb +1 -1
  98. data/lib/hecks/bluebook/aggregate.rb +21 -18
  99. data/lib/hecks/bluebook/assembly/contracts/sagas.rb +2 -0
  100. data/lib/hecks/bluebook/assembly/contracts/structure.rb +18 -13
  101. data/lib/hecks/bluebook/behaviour/aggregate.rb +27 -3
  102. data/lib/hecks/bluebook/command.rb +16 -5
  103. data/lib/hecks/bluebook/declaration.rb +32 -4
  104. data/lib/hecks/bluebook/domain_port.rb +7 -3
  105. data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +0 -2
  106. data/lib/hecks/bluebook/dsl/aggregate_builder/renaming.rb +25 -0
  107. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +3 -0
  108. data/lib/hecks/bluebook/dsl/attribute_collector.rb +0 -1
  109. data/lib/hecks/bluebook/dsl/audience_word.rb +40 -0
  110. data/lib/hecks/bluebook/dsl/bluebook_builder/metadata.rb +56 -0
  111. data/lib/hecks/bluebook/dsl/bluebook_builder/modules.rb +80 -0
  112. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +51 -0
  113. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +1 -0
  114. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +17 -34
  115. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +8 -0
  116. data/lib/hecks/bluebook/dsl/command_builder.rb +13 -3
  117. data/lib/hecks/bluebook/dsl/entity_builder.rb +0 -2
  118. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +6 -4
  119. data/lib/hecks/bluebook/dsl/kinds.rb +53 -0
  120. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +9 -2
  121. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +25 -15
  122. data/lib/hecks/bluebook/dsl/translation_builder.rb +16 -1
  123. data/lib/hecks/bluebook/dsl/word_gate.rb +1 -1
  124. data/lib/hecks/bluebook/dsl.rb +1 -0
  125. data/lib/hecks/bluebook/meta_validator/judge/identity.rb +9 -4
  126. data/lib/hecks/bluebook/meta_validator/plan/category.rb +10 -2
  127. data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +9 -0
  128. data/lib/hecks/bluebook/meta_validator/plan.rb +2 -1
  129. data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +3 -1
  130. data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +7 -0
  131. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +7 -2
  132. data/lib/hecks/bluebook/meta_validator/shapes.rb +3 -0
  133. data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +1 -1
  134. data/lib/hecks/bluebook/model_check/aggregate_checks.rb +27 -0
  135. data/lib/hecks/bluebook/model_check/ask_checks.rb +25 -0
  136. data/lib/hecks/bluebook/model_check/reaction_chains.rb +114 -0
  137. data/lib/hecks/bluebook/model_check/reaction_cycles.rb +53 -0
  138. data/lib/hecks/bluebook/model_check/reaction_depth_checks.rb +58 -0
  139. data/lib/hecks/bluebook/model_check/reaction_walk.rb +62 -0
  140. data/lib/hecks/bluebook/model_check.rb +5 -27
  141. data/lib/hecks/bluebook/process_manager.rb +20 -3
  142. data/lib/hecks/bluebook/translation.rb +5 -3
  143. data/lib/hecks/bluebook/translation_plan.rb +9 -2
  144. data/lib/hecks/ci_pipeline/adapters/ci_cache.adapter +7 -0
  145. data/lib/hecks/ci_pipeline/adapters/ci_cache.rb +39 -0
  146. data/lib/hecks/ci_pipeline/adapters/ci_runner.adapter +7 -0
  147. data/lib/hecks/ci_pipeline/adapters/ci_runner.rb +55 -0
  148. data/lib/hecks/ci_pipeline/ci_pipeline.behaviors +322 -0
  149. data/lib/hecks/ci_pipeline/ci_pipeline.bluebook +938 -0
  150. data/lib/hecks/ci_pipeline/ci_pipeline.hecksagon +12 -0
  151. data/lib/hecks/ci_pipeline/ci_pipeline.ports.hecksagon +16 -0
  152. data/lib/hecks/ci_speed/adapters/ci_reader.adapter +7 -0
  153. data/lib/hecks/ci_speed/adapters/ci_reader.rb +141 -0
  154. data/lib/hecks/ci_speed/adapters/local_runner/answer.rb +41 -0
  155. data/lib/hecks/ci_speed/adapters/local_runner/catalog.rb +89 -0
  156. data/lib/hecks/ci_speed/adapters/local_runner/checkouts.rb +89 -0
  157. data/lib/hecks/ci_speed/adapters/local_runner/launcher.rb +69 -0
  158. data/lib/hecks/ci_speed/adapters/local_runner/load_average.rb +38 -0
  159. data/lib/hecks/ci_speed/adapters/local_runner/refs.rb +39 -0
  160. data/lib/hecks/ci_speed/adapters/local_runner/refused.rb +11 -0
  161. data/lib/hecks/ci_speed/adapters/local_runner/verdict.rb +71 -0
  162. data/lib/hecks/ci_speed/adapters/local_runner.adapter +7 -0
  163. data/lib/hecks/ci_speed/adapters/local_runner.rb +168 -0
  164. data/lib/hecks/ci_speed/adapters/replayed_runner.rb +39 -0
  165. data/lib/hecks/ci_speed/ci_speed.behaviors +341 -0
  166. data/lib/hecks/ci_speed/ci_speed.bluebook +1073 -0
  167. data/lib/hecks/ci_speed/ci_speed.hecksagon +11 -0
  168. data/lib/hecks/ci_speed/ci_speed.ports.hecksagon +21 -0
  169. data/lib/hecks/ci_workflows/ci_workflows.behaviors +13 -0
  170. data/lib/hecks/ci_workflows/ci_workflows.bluebook +173 -0
  171. data/lib/hecks/ci_workflows/ci_workflows.hecksagon +15 -0
  172. data/lib/hecks/coder/coder.bluebook +385 -0
  173. data/lib/hecks/coder/coder.hecksagon +12 -0
  174. data/lib/hecks/command_names/check.rb +39 -0
  175. data/lib/hecks/command_names/extractor.rb +67 -0
  176. data/lib/hecks/command_names/index.rb +40 -0
  177. data/lib/hecks/command_names/resolution.rb +81 -0
  178. data/lib/hecks/command_names/scan.rb +54 -0
  179. data/lib/hecks/command_names/sources.rb +73 -0
  180. data/lib/hecks/command_names.rb +26 -0
  181. data/lib/hecks/composer/jobs.rb +1 -1
  182. data/lib/hecks/composer/toolbox.rb +8 -1
  183. data/lib/hecks/corpus/generated_key.rb +205 -0
  184. data/lib/hecks/corpus/listing.rb +34 -0
  185. data/lib/hecks/corpus/rust.rb +27 -11
  186. data/lib/hecks/corpus/sources.rb +2 -1
  187. data/lib/hecks/corpus.rb +37 -42
  188. data/lib/hecks/deprecation.rb +23 -0
  189. data/lib/hecks/doc/reference/readme.rb +1 -1
  190. data/lib/hecks/doc/reference/rendering.rb +2 -2
  191. data/lib/hecks/doc/reference.rb +1 -1
  192. data/lib/hecks/embryonaut_bluebook/manifest.rb +1 -1
  193. data/lib/hecks/fixer/fixer.bluebook +240 -0
  194. data/lib/hecks/fixer/fixer.hecksagon +17 -0
  195. data/lib/hecks/framework_bluebooks.rb +32 -7
  196. data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +1 -0
  197. data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +11 -12
  198. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +23 -5
  199. data/lib/hecks/fuzzing/isolated_boot.rb +1 -1
  200. data/lib/hecks/fuzzing/mutation/checks.rb +3 -3
  201. data/lib/hecks/grammar/translation.bluebook +1 -1
  202. data/lib/hecks/grammar/translation_rules.json +64 -0
  203. data/lib/hecks/hecks/adapter_words.json +7 -0
  204. data/lib/hecks/hecks/adapters/area_overlap.rb +156 -0
  205. data/lib/hecks/hecks/adapters/claude_agents.rb +8 -3
  206. data/lib/hecks/hecks/adapters/codebase/batch_runs.rb +60 -0
  207. data/lib/hecks/hecks/adapters/codebase/changed_specs.rb +52 -0
  208. data/lib/hecks/hecks/adapters/codebase/codemods.rb +3 -2
  209. data/lib/hecks/hecks/adapters/codebase/conformance.rb +14 -1
  210. data/lib/hecks/hecks/adapters/codebase/corpus_queries.rb +53 -0
  211. data/lib/hecks/hecks/adapters/codebase/generated_keys.rb +31 -0
  212. data/lib/hecks/hecks/adapters/codebase/impacted_specs.rb +110 -0
  213. data/lib/hecks/hecks/adapters/codebase/language.rb +2 -2
  214. data/lib/hecks/hecks/adapters/codebase/launcher_text.rb +39 -0
  215. data/lib/hecks/hecks/adapters/codebase/minitest_runs.rb +52 -0
  216. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +51 -8
  217. data/lib/hecks/hecks/adapters/codebase/run_options.rb +35 -0
  218. data/lib/hecks/hecks/adapters/codebase/scripting.rb +39 -0
  219. data/lib/hecks/hecks/adapters/codebase/search.rb +1 -1
  220. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +79 -51
  221. data/lib/hecks/hecks/adapters/codebase/spec_files/report.rb +71 -0
  222. data/lib/hecks/hecks/adapters/codebase/spec_files/shared_run.rb +73 -0
  223. data/lib/hecks/hecks/adapters/codebase/spec_files.rb +95 -0
  224. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +53 -4
  225. data/lib/hecks/hecks/adapters/codebase/test_scope.rb +105 -0
  226. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +48 -34
  227. data/lib/hecks/hecks/adapters/console_capture.rb +1 -1
  228. data/lib/hecks/hecks/adapters/cost_explorer.rb +9 -1
  229. data/lib/hecks/hecks/adapters/dispatching/brief_text.rb +51 -0
  230. data/lib/hecks/hecks/adapters/dispatching/launcher.rb +97 -0
  231. data/lib/hecks/hecks/adapters/dispatching/plan.rb +82 -0
  232. data/lib/hecks/hecks/adapters/dispatching/rows.rb +66 -0
  233. data/lib/hecks/hecks/adapters/dispatching/settings.rb +81 -0
  234. data/lib/hecks/hecks/adapters/dispatching/settler.rb +40 -0
  235. data/lib/hecks/hecks/adapters/dispatching.adapter +7 -0
  236. data/lib/hecks/hecks/adapters/dispatching.rb +93 -0
  237. data/lib/hecks/hecks/adapters/doctor_reading/report.rb +27 -0
  238. data/lib/hecks/hecks/adapters/doctor_reading.adapter +7 -0
  239. data/lib/hecks/hecks/adapters/doctor_reading.rb +161 -0
  240. data/lib/hecks/hecks/adapters/git_checkout.rb +1 -1
  241. data/lib/hecks/hecks/adapters/git_commit.adapter +7 -0
  242. data/lib/hecks/hecks/adapters/git_commit.rb +61 -0
  243. data/lib/hecks/hecks/adapters/git_landing/finisher.rb +82 -0
  244. data/lib/hecks/hecks/adapters/git_landing/foreign_hold.rb +111 -0
  245. data/lib/hecks/hecks/adapters/git_landing/line.rb +171 -0
  246. data/lib/hecks/hecks/adapters/git_landing/lineup.rb +98 -0
  247. data/lib/hecks/hecks/adapters/git_landing/merger.rb +1 -1
  248. data/lib/hecks/hecks/adapters/git_landing/numbering.rb +54 -0
  249. data/lib/hecks/hecks/adapters/git_landing/rivals.rb +59 -0
  250. data/lib/hecks/hecks/adapters/git_landing/ticket.rb +156 -0
  251. data/lib/hecks/hecks/adapters/git_landing/tidy.rb +147 -0
  252. data/lib/hecks/hecks/adapters/git_landing/train.rb +104 -0
  253. data/lib/hecks/hecks/adapters/git_landing/verdict.rb +64 -0
  254. data/lib/hecks/hecks/adapters/git_landing/waiting.rb +120 -0
  255. data/lib/hecks/hecks/adapters/git_landing.rb +106 -20
  256. data/lib/hecks/hecks/adapters/git_main_pull.rb +99 -0
  257. data/lib/hecks/hecks/adapters/git_rehearsal/bench.rb +82 -0
  258. data/lib/hecks/hecks/adapters/git_rehearsal/due.rb +84 -0
  259. data/lib/hecks/hecks/adapters/git_rehearsal/impacted/skips.rb +47 -0
  260. data/lib/hecks/hecks/adapters/git_rehearsal/impacted/spec_run.rb +75 -0
  261. data/lib/hecks/hecks/adapters/git_rehearsal/impacted.rb +181 -0
  262. data/lib/hecks/hecks/adapters/git_rehearsal/line.rb +76 -0
  263. data/lib/hecks/hecks/adapters/git_rehearsal/reading.rb +24 -0
  264. data/lib/hecks/hecks/adapters/git_rehearsal/record.rb +146 -0
  265. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/corpus.rb +25 -0
  266. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/needles.rb +61 -0
  267. data/lib/hecks/hecks/adapters/git_rehearsal/spec_map.rb +105 -0
  268. data/lib/hecks/hecks/adapters/git_rehearsal/stages.rb +118 -0
  269. data/lib/hecks/hecks/adapters/git_rehearsal.adapter +7 -0
  270. data/lib/hecks/hecks/adapters/git_rehearsal.rb +141 -0
  271. data/lib/hecks/hecks/adapters/git_train/bench.rb +15 -15
  272. data/lib/hecks/hecks/adapters/git_train/branch_guard.rb +62 -0
  273. data/lib/hecks/hecks/adapters/git_train/carriage.rb +27 -28
  274. data/lib/hecks/hecks/adapters/git_train/launcher_shape.rb +75 -0
  275. data/lib/hecks/hecks/adapters/git_train/mint_step.rb +47 -0
  276. data/lib/hecks/hecks/adapters/git_train/settlement.rb +167 -0
  277. data/lib/hecks/hecks/adapters/git_train.rb +73 -15
  278. data/lib/hecks/hecks/adapters/git_worktree_add.adapter +7 -0
  279. data/lib/hecks/hecks/adapters/git_worktree_add.rb +68 -0
  280. data/lib/hecks/hecks/adapters/github_pull_requests.adapter +7 -0
  281. data/lib/hecks/hecks/adapters/github_pull_requests.rb +109 -0
  282. data/lib/hecks/hecks/adapters/host_http.rb +6 -6
  283. data/lib/hecks/hecks/adapters/in_process_boot.rb +10 -8
  284. data/lib/hecks/hecks/adapters/in_process_operations.rb +11 -17
  285. data/lib/hecks/hecks/adapters/in_process_undo.rb +17 -0
  286. data/lib/hecks/hecks/adapters/journal_store/changes.rb +13 -4
  287. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +28 -15
  288. data/lib/hecks/hecks/adapters/journal_store/examination.rb +17 -1
  289. data/lib/hecks/hecks/adapters/journal_store/held_domain/renaming.rb +45 -0
  290. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +31 -5
  291. data/lib/hecks/hecks/adapters/journal_store/held_mint.rb +128 -0
  292. data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +1 -1
  293. data/lib/hecks/hecks/adapters/journal_store/readings/boot_status.rb +58 -0
  294. data/lib/hecks/hecks/adapters/journal_store/readings/composition.rb +39 -0
  295. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/outcomes.rb +76 -0
  296. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/postgres_reader.rb +44 -0
  297. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/reader.rb +64 -0
  298. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/report.rb +102 -0
  299. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/sqlite_reader.rb +43 -0
  300. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/stores.rb +80 -0
  301. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/subscribers.rb +72 -0
  302. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/summary.rb +39 -0
  303. data/lib/hecks/hecks/adapters/journal_store/readings/event_trace.rb +39 -0
  304. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/command_line.rb +57 -0
  305. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/edge_guards.rb +107 -0
  306. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/inspection.rb +94 -0
  307. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/plan.rb +66 -0
  308. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/report.rb +72 -0
  309. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/store.rb +34 -0
  310. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/watermark_guards.rb +86 -0
  311. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/world.rb +66 -0
  312. data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan.rb +36 -0
  313. data/lib/hecks/hecks/adapters/journal_store/readings/projection_audit.rb +64 -0
  314. data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +3 -3
  315. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/database_reading.rb +113 -0
  316. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/read_only.rb +33 -0
  317. data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status.rb +32 -0
  318. data/lib/hecks/hecks/adapters/journal_store/readings.rb +13 -1
  319. data/lib/hecks/hecks/adapters/journal_store/reconcile_report.rb +60 -0
  320. data/lib/hecks/hecks/adapters/journal_store/reconciliation.rb +121 -0
  321. data/lib/hecks/hecks/adapters/journal_store/translation_write/shape_edge.rb +59 -0
  322. data/lib/hecks/hecks/adapters/journal_store/translation_write.rb +123 -0
  323. data/lib/hecks/hecks/adapters/journal_store.rb +16 -0
  324. data/lib/hecks/hecks/adapters/landed_work.adapter +7 -0
  325. data/lib/hecks/hecks/adapters/landed_work.rb +52 -0
  326. data/lib/hecks/hecks/adapters/local_files.rb +6 -6
  327. data/lib/hecks/hecks/adapters/process_pool.rb +3 -2
  328. data/lib/hecks/hecks/adapters/push_size.rb +57 -0
  329. data/lib/hecks/hecks/adapters/qa_quiescing.adapter +7 -0
  330. data/lib/hecks/hecks/adapters/qa_quiescing.rb +57 -0
  331. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +30 -3
  332. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +63 -3
  333. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +29 -6
  334. data/lib/hecks/hecks/adapters/rehearsal/subject.rb +11 -5
  335. data/lib/hecks/hecks/adapters/rust_toolchain.rb +10 -1
  336. data/lib/hecks/hecks/adapters/rust_workspace.rb +1 -1
  337. data/lib/hecks/hecks/adapters/settings_reading/disposable_ledger.rb +32 -0
  338. data/lib/hecks/hecks/adapters/settings_reading/push_nudge.rb +26 -0
  339. data/lib/hecks/hecks/adapters/settings_reading/stores.rb +76 -0
  340. data/lib/hecks/hecks/adapters/settings_reading/test_scope.rb +28 -0
  341. data/lib/hecks/hecks/adapters/settings_reading.rb +28 -2
  342. data/lib/hecks/hecks/adapters/started_work.rb +42 -0
  343. data/lib/hecks/hecks/adapters/terminal.rb +12 -10
  344. data/lib/hecks/hecks/adapters/where_reading.adapter +7 -0
  345. data/lib/hecks/hecks/adapters/where_reading.rb +64 -0
  346. data/lib/hecks/hecks/adapters/work_areas.rb +57 -0
  347. data/lib/hecks/hecks/adapters/work_limits.rb +57 -0
  348. data/lib/hecks/hecks/build/build.bluebook +576 -0
  349. data/lib/hecks/hecks/check/check.bluebook +966 -0
  350. data/lib/hecks/hecks/codebase.behaviors +61 -5
  351. data/lib/hecks/hecks/composer.behaviors +1 -1
  352. data/lib/hecks/hecks/context_map.hecksagon +1 -1
  353. data/lib/hecks/hecks/custodian.behaviors +33 -7
  354. data/lib/hecks/hecks/delegate/delegate.bluebook +355 -0
  355. data/lib/hecks/hecks/deliver/deliver.bluebook +945 -0
  356. data/lib/hecks/hecks/deploy.behaviors +1 -1
  357. data/lib/hecks/hecks/evolve/evolve.bluebook +788 -0
  358. data/lib/hecks/hecks/find/find.bluebook +81 -0
  359. data/lib/hecks/hecks/hecks.behaviors +1 -1
  360. data/lib/hecks/hecks/hecks.bluebook +0 -133
  361. data/lib/hecks/hecks/hecks.contextmap +2 -0
  362. data/lib/hecks/hecks/hecks.hecksagon +185 -29
  363. data/lib/hecks/hecks/hecks.world +35 -9
  364. data/lib/hecks/hecks/implicit_moves.json +24 -0
  365. data/lib/hecks/hecks/migrate/migrate.bluebook +1066 -0
  366. data/lib/hecks/hecks/operate/operate.bluebook +695 -0
  367. data/lib/hecks/hecks/quiesce/quiesce.bluebook +117 -0
  368. data/lib/hecks/hecks/rehearse/rehearse.bluebook +133 -0
  369. data/lib/hecks/hecks/release/release.bluebook +916 -0
  370. data/lib/hecks/hecks/serve/serve.bluebook +134 -0
  371. data/lib/hecks/hecks/shapes.json +1 -15
  372. data/lib/hecks/hecks/site.behaviors +1 -1
  373. data/lib/hecks/hecks/start/start.bluebook +194 -0
  374. data/lib/hecks/hecks/test/test.bluebook +638 -0
  375. data/lib/hecks/hecks/tickets.world +14 -0
  376. data/lib/hecks/language/bluebook/aggregate.bluebook +22 -0
  377. data/lib/hecks/language/bluebook/bluebook.bluebook +34 -0
  378. data/lib/hecks/language/bluebook/command.bluebook +35 -0
  379. data/lib/hecks/language/bluebook/process_manager.bluebook +14 -1
  380. data/lib/hecks/language/bluebook/vocabulary.bluebook +174 -54
  381. data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -0
  382. data/lib/hecks/language/hecksagon/port_operation.bluebook +14 -0
  383. data/lib/hecks/language/kinds/run.kind +120 -0
  384. data/lib/hecks/language/oidc.json +10 -0
  385. data/lib/hecks/language/translation/translation_aggregate.bluebook +24 -0
  386. data/lib/hecks/module_folders.rb +31 -0
  387. data/lib/hecks/ports/key_vault.rb +1 -1
  388. data/lib/hecks/ports/persistence/append_only.rb +26 -8
  389. data/lib/hecks/ports/persistence/binding_policy.rb +3 -1
  390. data/lib/hecks/ports/persistence/codec_boundary.rb +1 -1
  391. data/lib/hecks/ports/persistence/mint_door.rb +74 -0
  392. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +6 -5
  393. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +5 -1
  394. data/lib/hecks/ports/persistence/plugins/era/era_status.rb +48 -0
  395. data/lib/hecks/ports/persistence/plugins/era/projected_bluebook.rb +127 -0
  396. data/lib/hecks/ports/persistence/plugins/era/translation/additive_shape.rb +107 -0
  397. data/lib/hecks/ports/persistence/plugins/era/translation/compose.rb +155 -0
  398. data/lib/hecks/ports/persistence/plugins/era/translation/compose_render.rb +79 -0
  399. data/lib/hecks/ports/persistence/plugins/era/translation/edge_files.rb +49 -0
  400. data/lib/hecks/ports/persistence/plugins/era/translation/edge_route.rb +61 -0
  401. data/lib/hecks/ports/persistence/plugins/era/translation/implicit_edge.rb +67 -0
  402. data/lib/hecks/ports/persistence/plugins/era/translation/reconcile.rb +130 -0
  403. data/lib/hecks/ports/persistence/plugins/era/translation/reconcile_files.rb +35 -0
  404. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +13 -5
  405. data/lib/hecks/ports/persistence/plugins/era/translation.rb +5 -0
  406. data/lib/hecks/ports/persistence/plugins/era.rb +1 -0
  407. data/lib/hecks/ports/persistence/repository_factory.rb +11 -3
  408. data/lib/hecks/ports/persistence/stored_name_guard.rb +36 -0
  409. data/lib/hecks/ports/persistence.rb +2 -0
  410. data/lib/hecks/projections/ci_pipeline/table/checks.rb +137 -0
  411. data/lib/hecks/projections/ci_pipeline/table/lookup.rb +59 -0
  412. data/lib/hecks/projections/ci_pipeline/table/refusals.rb +58 -0
  413. data/lib/hecks/projections/ci_pipeline/table/rows.rb +119 -0
  414. data/lib/hecks/projections/ci_pipeline/table/tree.rb +30 -0
  415. data/lib/hecks/projections/ci_pipeline/table/typing.rb +92 -0
  416. data/lib/hecks/projections/ci_pipeline/table.rb +112 -0
  417. data/lib/hecks/projections/ci_pipeline/workflows.rb +162 -0
  418. data/lib/hecks/projections/ci_pipeline/yaml_text.rb +104 -0
  419. data/lib/hecks/projections/deploy/box/hosting.rb +1 -1
  420. data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
  421. data/lib/hecks/projections/deploy/box/roll_scripts.rb +1 -1
  422. data/lib/hecks/projections/deploy/box.rb +1 -1
  423. data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +1 -1
  424. data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +3 -3
  425. data/lib/hecks/projections/undo.rb +46 -0
  426. data/lib/hecks/projections.rb +2 -0
  427. data/lib/hecks/projector/cli_projector/claims.rb +11 -0
  428. data/lib/hecks/projector/cli_projector/command_help.rb +6 -1
  429. data/lib/hecks/projector/cli_projector/command_specs.rb +11 -1
  430. data/lib/hecks/projector/cli_projector/completion.rb +87 -0
  431. data/lib/hecks/projector/cli_projector/everyday.rb +40 -0
  432. data/lib/hecks/projector/cli_projector/json_listing.rb +77 -0
  433. data/lib/hecks/projector/cli_projector/listing.rb +1 -1
  434. data/lib/hecks/projector/cli_projector/modules.rb +39 -0
  435. data/lib/hecks/projector/cli_projector/query_specs.rb +1 -0
  436. data/lib/hecks/projector/cli_projector/renames.rb +58 -0
  437. data/lib/hecks/projector/cli_projector/search.rb +74 -0
  438. data/lib/hecks/projector/cli_projector/usage.rb +23 -6
  439. data/lib/hecks/projector/cli_projector.rb +24 -1
  440. data/lib/hecks/quality_control/adapters/ci_head.adapter +8 -0
  441. data/lib/hecks/quality_control/adapters/image_roll.adapter +9 -0
  442. data/lib/hecks/quality_control/adapters/image_roll.rb +158 -0
  443. data/lib/hecks/quality_control/adapters/main_maintenance.adapter +8 -0
  444. data/lib/hecks/quality_control/adapters/main_maintenance.rb +275 -0
  445. data/lib/hecks/quality_control/adapters/pump_tools.adapter +7 -0
  446. data/lib/hecks/quality_control/adapters/pump_tools.rb +18 -0
  447. data/lib/hecks/quality_control/adapters/push_due_reader.adapter +8 -0
  448. data/lib/hecks/quality_control/adapters/push_due_reader.rb +99 -0
  449. data/lib/hecks/quality_control/adapters/qa_auto_mint.rb +183 -0
  450. data/lib/hecks/quality_control/adapters/qa_era_mint.rb +94 -0
  451. data/lib/hecks/quality_control/adapters/qa_quiesce_marker.rb +126 -0
  452. data/lib/hecks/quality_control/adapters/run_keys.rb +36 -0
  453. data/lib/hecks/quality_control/adapters/run_reader.adapter +7 -0
  454. data/lib/hecks/quality_control/adapters/run_reader.rb +188 -0
  455. data/lib/hecks/quality_control/cli/child.rb +1 -0
  456. data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +1 -1
  457. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +3 -3
  458. data/lib/hecks/quality_control/cli/qa_event_pump/attached.rb +67 -0
  459. data/lib/hecks/quality_control/cli/qa_event_pump/consumer.rb +103 -0
  460. data/lib/hecks/quality_control/cli/qa_event_pump/cursors.rb +60 -0
  461. data/lib/hecks/quality_control/cli/qa_event_pump/reactions.rb +46 -0
  462. data/lib/hecks/quality_control/cli/qa_event_pump/reader.rb +30 -0
  463. data/lib/hecks/quality_control/cli/qa_event_pump.rb +76 -0
  464. data/lib/hecks/quality_control/cli/qa_fix_main_bug/publishing.rb +79 -0
  465. data/lib/hecks/quality_control/cli/qa_fix_main_bug.rb +167 -0
  466. data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +1 -1
  467. data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +3 -3
  468. data/lib/hecks/quality_control/cli/qa_main_gate/gate_run.rb +52 -0
  469. data/lib/hecks/quality_control/cli/qa_main_gate/logging.rb +70 -0
  470. data/lib/hecks/quality_control/cli/qa_main_gate/shell.rb +47 -0
  471. data/lib/hecks/quality_control/cli/qa_main_gate/sweeping.rb +59 -0
  472. data/lib/hecks/quality_control/cli/qa_main_gate/worktree.rb +62 -0
  473. data/lib/hecks/quality_control/cli/qa_main_gate.rb +135 -0
  474. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +1 -1
  475. data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +2 -3
  476. data/lib/hecks/quality_control/cli/qa_push_nudge.rb +48 -0
  477. data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +1 -1
  478. data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +1 -1
  479. data/lib/hecks/quality_control/cli/qa_tick/event_pump_step.rb +34 -0
  480. data/lib/hecks/quality_control/cli/qa_tick/output.rb +16 -1
  481. data/lib/hecks/quality_control/cli/qa_tick/push_nudge_step.rb +28 -0
  482. data/lib/hecks/quality_control/cli/qa_tick/quiesce_guard.rb +51 -0
  483. data/lib/hecks/quality_control/cli/qa_tick.rb +36 -8
  484. data/lib/hecks/quality_control/quality_control.behaviors +65 -0
  485. data/lib/hecks/quality_control/quality_control.bluebook +1131 -11
  486. data/lib/hecks/quality_control/quality_control.hecksagon +11 -0
  487. data/lib/hecks/quality_control/quality_control.ports.hecksagon +138 -0
  488. data/lib/hecks/query_ir/touchpoints.rb +5 -7
  489. data/lib/hecks/refused.rb +21 -0
  490. data/lib/hecks/release/approval.rb +6 -3
  491. data/lib/hecks/release/conditions.rb +46 -0
  492. data/lib/hecks/release/runner/gem_publisher.rb +4 -4
  493. data/lib/hecks/release/version_commit.rb +48 -0
  494. data/lib/hecks/runtime/command_interpreter/hydration.rb +5 -4
  495. data/lib/hecks/runtime/command_interpreter/persisting.rb +11 -3
  496. data/lib/hecks/runtime/command_interpreter.rb +2 -2
  497. data/lib/hecks/runtime/command_rules/admissibility.rb +0 -2
  498. data/lib/hecks/runtime/command_rules/emission.rb +0 -1
  499. data/lib/hecks/runtime/dependency_planning/expression_reads.rb +0 -1
  500. data/lib/hecks/runtime/dispatcher/planning.rb +24 -0
  501. data/lib/hecks/runtime/dispatcher/routing.rb +6 -0
  502. data/lib/hecks/runtime/dispatcher/value_routing.rb +54 -0
  503. data/lib/hecks/runtime/dispatcher.rb +7 -1
  504. data/lib/hecks/runtime/dry_run_plan.rb +60 -0
  505. data/lib/hecks/runtime/entity_element/location.rb +0 -1
  506. data/lib/hecks/runtime/entity_element/mutations.rb +0 -1
  507. data/lib/hecks/runtime/entity_interpreter/locating.rb +5 -0
  508. data/lib/hecks/runtime/entity_interpreter.rb +0 -1
  509. data/lib/hecks/runtime/errors.rb +26 -0
  510. data/lib/hecks/runtime/instance.rb +0 -1
  511. data/lib/hecks/runtime/invocation_builder.rb +0 -1
  512. data/lib/hecks/runtime/outbox/consumer_runner.rb +9 -1
  513. data/lib/hecks/runtime/outbox/relay.rb +25 -4
  514. data/lib/hecks/runtime/outbox/runnable.rb +3 -1
  515. data/lib/hecks/runtime/outbox.rb +6 -2
  516. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +18 -2
  517. data/lib/hecks/runtime/policy_interpreter.rb +17 -9
  518. data/lib/hecks/runtime/port_operation_interpreter.rb +21 -7
  519. data/lib/hecks/runtime/query_interpreter/arguments.rb +6 -5
  520. data/lib/hecks/runtime/reaction_invocation.rb +0 -1
  521. data/lib/hecks/runtime/refusal_wording.rb +12 -1
  522. data/lib/hecks/runtime/registry/context_maps.rb +1 -5
  523. data/lib/hecks/runtime/registry/declarations.rb +34 -4
  524. data/lib/hecks/runtime/registry/hecksagon_rules.rb +15 -1
  525. data/lib/hecks/runtime/registry/runtime_state.rb +10 -0
  526. data/lib/hecks/runtime/registry/world_defaults.rb +24 -2
  527. data/lib/hecks/runtime/registry/world_names.rb +99 -0
  528. data/lib/hecks/runtime/registry.rb +33 -27
  529. data/lib/hecks/runtime/saga_interpreter/compensation.rb +10 -0
  530. data/lib/hecks/runtime/saga_interpreter/correlation.rb +29 -3
  531. data/lib/hecks/runtime/saga_interpreter/delivery.rb +0 -1
  532. data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +1 -1
  533. data/lib/hecks/runtime/saga_interpreter.rb +46 -2
  534. data/lib/hecks/runtime/value/coercion.rb +36 -8
  535. data/lib/hecks/rust_build/conformance.rb +16 -5
  536. data/lib/hecks/rust_build/parser.rb +25 -0
  537. data/lib/hecks/rust_build/project_rust/codegen_run.rb +45 -12
  538. data/lib/hecks/rust_build/project_rust/declared.rb +80 -0
  539. data/lib/hecks/rust_build/project_rust/features_header.rb +22 -0
  540. data/lib/hecks/rust_build/project_rust/manifest.rb +96 -0
  541. data/lib/hecks/rust_build/project_rust/meta.rb +36 -0
  542. data/lib/hecks/rust_build/project_rust.rb +28 -90
  543. data/lib/hecks/rust_build/write_if_changed.rb +19 -4
  544. data/lib/hecks/rust_build.rb +2 -1
  545. data/lib/hecks/rust_format.rb +32 -2
  546. data/lib/hecks/secrets.rb +111 -0
  547. data/lib/hecks/shape_ledger/edge_hygiene.rb +170 -0
  548. data/lib/hecks/shape_ledger/scope.rb +51 -0
  549. data/lib/hecks/shape_ledger/status.rb +89 -0
  550. data/lib/hecks/shape_ledger.rb +78 -33
  551. data/lib/hecks/site/bluebook/site.bluebook +1 -0
  552. data/lib/hecks/storehouse/audit.rb +34 -4
  553. data/lib/hecks/storehouse/callers.rb +8 -0
  554. data/lib/hecks/storehouse/dispatching.rb +14 -3
  555. data/lib/hecks/storehouse/identity.rb +41 -0
  556. data/lib/hecks/storehouse/querying.rb +7 -7
  557. data/lib/hecks/storehouse.rb +28 -10
  558. data/lib/hecks/tickets/bluebook/adapters/work_areas.adapter +7 -0
  559. data/lib/hecks/tickets/bluebook/adapters/work_limits.adapter +7 -0
  560. data/lib/hecks/tickets/bluebook/tickets.behaviors +70 -0
  561. data/lib/hecks/tickets/bluebook/tickets.bluebook +323 -28
  562. data/lib/hecks/tickets/bluebook/tickets.hecksagon +7 -0
  563. data/lib/hecks/tickets/bluebook/tickets.ports.hecksagon +17 -0
  564. data/lib/hecks/{cli → tools}/behaviors.rb +1 -1
  565. data/lib/hecks/{cli → tools}/canonicalise.rb +1 -1
  566. data/lib/hecks/{cli → tools}/check_engine_agreement.rb +1 -1
  567. data/lib/hecks/{cli → tools}/check_era.rb +6 -6
  568. data/lib/hecks/tools/ci_gates.rb +8 -2
  569. data/lib/hecks/tools/ci_workflows.rb +98 -0
  570. data/lib/hecks/{cli → tools}/console.rb +1 -1
  571. data/lib/hecks/{cli → tools}/deploy_template_diff.rb +1 -1
  572. data/lib/hecks/{cli → tools}/doc_coverage.rb +2 -2
  573. data/lib/hecks/{cli → tools}/document.rb +1 -1
  574. data/lib/hecks/{cli → tools}/domain_stub.rb +1 -1
  575. data/lib/hecks/{cli → tools}/domain_writer.rb +1 -1
  576. data/lib/hecks/tools/downstream_model_check.rb +122 -0
  577. data/lib/hecks/tools/evolve_run.rb +2 -2
  578. data/lib/hecks/{cli → tools}/expected_era.rb +1 -1
  579. data/lib/hecks/{cli → tools}/expression_projection.rb +1 -1
  580. data/lib/hecks/{cli → tools}/follow.rb +1 -1
  581. data/lib/hecks/tools/fuzz_sweep/options.rb +40 -5
  582. data/lib/hecks/tools/fuzz_sweep/pool.rb +12 -1
  583. data/lib/hecks/tools/fuzz_sweep/shards.rb +155 -0
  584. data/lib/hecks/tools/fuzz_sweep.rb +11 -5
  585. data/lib/hecks/tools/gate.rb +38 -29
  586. data/lib/hecks/tools/gate_memo/local_files.rb +33 -0
  587. data/lib/hecks/tools/gate_memo/rehearsal.rb +54 -0
  588. data/lib/hecks/tools/gate_memo/ruby_files.rb +152 -0
  589. data/lib/hecks/tools/gate_memo/session.rb +114 -0
  590. data/lib/hecks/tools/gate_memo/standalone.rb +67 -0
  591. data/lib/hecks/tools/gate_memo.rb +196 -0
  592. data/lib/hecks/tools/gate_report.rb +56 -0
  593. data/lib/hecks/{cli → tools}/history.rb +1 -1
  594. data/lib/hecks/{cli → tools}/interview_agent.rb +1 -1
  595. data/lib/hecks/{cli → tools}/interview_aggregate.rb +1 -1
  596. data/lib/hecks/{cli → tools}/interview_draft.rb +1 -1
  597. data/lib/hecks/{cli → tools}/interview_record.rb +1 -1
  598. data/lib/hecks/{cli → tools}/interview_run.rb +2 -2
  599. data/lib/hecks/{cli → tools}/interview_session/agent_state.rb +1 -1
  600. data/lib/hecks/{cli → tools}/interview_session/catalog.rb +1 -1
  601. data/lib/hecks/{cli → tools}/interview_session/manual_findings.rb +1 -1
  602. data/lib/hecks/{cli → tools}/interview_session/proposals.rb +1 -1
  603. data/lib/hecks/{cli → tools}/interview_session.rb +2 -2
  604. data/lib/hecks/{cli → tools}/interview_shape/lifecycle.rb +1 -1
  605. data/lib/hecks/{cli → tools}/interview_shape.rb +1 -1
  606. data/lib/hecks/{cli → tools}/ir.rb +1 -1
  607. data/lib/hecks/tools/lanes/files.rb +1 -1
  608. data/lib/hecks/tools/lanes/watch_workflow.rb +6 -8
  609. data/lib/hecks/tools/lanes/workflow.rb +1 -1
  610. data/lib/hecks/tools/lanes.rb +1 -1
  611. data/lib/hecks/{cli → tools}/mcp.rb +1 -1
  612. data/lib/hecks/{cli → tools}/model_check/examination.rb +1 -1
  613. data/lib/hecks/{cli → tools}/model_check/sources.rb +1 -1
  614. data/lib/hecks/{cli → tools}/model_check.rb +1 -1
  615. data/lib/hecks/tools/move_disables/reasons.rb +35 -0
  616. data/lib/hecks/tools/move_disables.rb +211 -0
  617. data/lib/hecks/tools/move_former_name.rb +105 -0
  618. data/lib/hecks/{cli → tools}/pattern_cases.rb +1 -1
  619. data/lib/hecks/{cli → tools}/persistence_notice.rb +1 -1
  620. data/lib/hecks/{cli → tools}/present.rb +1 -1
  621. data/lib/hecks/{cli → tools}/project_cli/launcher_source.rb +32 -22
  622. data/lib/hecks/{cli → tools}/project_cli/templates.rb +22 -15
  623. data/lib/hecks/{cli → tools}/project_cli.rb +11 -7
  624. data/lib/hecks/{cli → tools}/project_diagrams.rb +3 -3
  625. data/lib/hecks/{cli → tools}/project_glossary.rb +2 -2
  626. data/lib/hecks/{cli → tools}/reference.rb +2 -2
  627. data/lib/hecks/{cli → tools}/refresh_projections.rb +1 -1
  628. data/lib/hecks/{cli → tools}/refresh_rspec_runtime_baseline.rb +1 -1
  629. data/lib/hecks/tools/regeneration_run/pool.rb +148 -0
  630. data/lib/hecks/tools/regeneration_run/scratch.rb +76 -0
  631. data/lib/hecks/tools/regeneration_run.rb +125 -103
  632. data/lib/hecks/{cli → tools}/release.rb +1 -1
  633. data/lib/hecks/{cli → tools}/release_gem.rb +1 -1
  634. data/lib/hecks/{cli → tools}/rspec_io_parallel_files.rb +1 -1
  635. data/lib/hecks/{cli → tools}/rspec_shard_files.rb +1 -1
  636. data/lib/hecks/{cli → tools}/run.rb +9 -2
  637. data/lib/hecks/{cli → tools}/run_expectations.rb +1 -1
  638. data/lib/hecks/{cli → tools}/seed_semantics_corpus.rb +4 -4
  639. data/lib/hecks/{cli → tools}/serve_query_ir_mcp.rb +1 -1
  640. data/lib/hecks/{cli → tools}/shape.rb +3 -2
  641. data/lib/hecks/{cli → tools}/smoke_http/checks.rb +1 -1
  642. data/lib/hecks/{cli → tools}/smoke_http/settings.rb +1 -1
  643. data/lib/hecks/{cli → tools}/smoke_http/transport.rb +1 -1
  644. data/lib/hecks/{cli → tools}/smoke_http.rb +1 -1
  645. data/lib/hecks/{cli → tools}/smoke_test.rb +1 -1
  646. data/lib/hecks/{cli → tools}/spec_example.rb +1 -1
  647. data/lib/hecks/tools/stage_progress.rb +54 -0
  648. data/lib/hecks/{cli → tools}/statements.rb +1 -1
  649. data/lib/hecks/{cli → tools}/stores.rb +1 -1
  650. data/lib/hecks/{cli → tools}/stress_concurrency_specs/reporting.rb +1 -1
  651. data/lib/hecks/{cli → tools}/stress_concurrency_specs/usage.rb +4 -4
  652. data/lib/hecks/{cli → tools}/stress_concurrency_specs.rb +3 -3
  653. data/lib/hecks/tools/tenant_provisioning.rb +23 -0
  654. data/lib/hecks/tools/tools_doc.rb +10 -8
  655. data/lib/hecks/tools/translation_audit/edges.rb +21 -16
  656. data/lib/hecks/tools/translation_audit/verdicts.rb +1 -1
  657. data/lib/hecks/tools/translation_audit.rb +1 -1
  658. data/lib/hecks/tools/translation_scaffold.rb +1 -1
  659. data/lib/hecks/tools.rb +4 -1
  660. data/lib/hecks/version.rb +1 -1
  661. data/lib/hecks/vocabulary.rb +61 -31
  662. data/lib/hecks/workflow_pagination/judge.rb +48 -0
  663. data/lib/hecks/workflow_pagination/statement.rb +50 -0
  664. data/lib/hecks/workflow_pagination.rb +58 -0
  665. data/lib/hecks.rb +2 -0
  666. data/lib/rubocop/cop/hecks/bare_event_and_query_names.rb +58 -0
  667. data/lib/rubocop/cop/hecks/correlates_by_aggregate.rb +39 -0
  668. data/lib/rubocop/cop/hecks/creating_command_sets.rb +75 -0
  669. data/lib/rubocop/cop/hecks/invariant_expression_language.rb +47 -0
  670. data/lib/rubocop/cop/hecks/lifecycle_needs_attribute.rb +58 -0
  671. data/lib/rubocop/cop/hecks/no_id_string_attribute.rb +49 -0
  672. data/lib/rubocop/cop/hecks/one_terminal_mark_per_lifecycle.rb +47 -0
  673. data/lib/rubocop/cop/hecks/value_object_shorthand.rb +56 -0
  674. data/prebuilt/13c04bdc5970295b310f0a980d397ba722232c8da99cc1a0cdb383249921e871.marshal +0 -0
  675. data/prebuilt/e3857b77f47d9ecc1787b2e1f5136364f3cb3444ef4aea5479f3b98167affea2.marshal +0 -0
  676. data/qa/settings.yml +23 -0
  677. data/rust/.gitignore +0 -6
  678. data/rust/Cargo.toml +2 -1
  679. data/rust/build/Cargo.toml +1 -1
  680. data/rust/build/src/binding_pass.rs +57 -4
  681. data/rust/build/src/pipeline.rs +6 -4
  682. data/rust/build/src/resolve.rs +1 -0
  683. data/rust/codegen/Cargo.toml +1 -1
  684. data/rust/codegen/src/domain_generator.rs +3 -0
  685. data/rust/codegen/src/json_codec.rs +182 -23
  686. data/rust/codegen/src/one_of_references.rs +1 -0
  687. data/rust/codegen/src/queries.rs +20 -2
  688. data/rust/codegen/src/registry.rs +21 -5
  689. data/rust/expr/Cargo.toml +1 -1
  690. data/rust/host/Cargo.toml +1 -1
  691. data/rust/host/HECKS_RELEASE +1 -1
  692. data/rust/host/core/Cargo.toml +1 -1
  693. data/rust/host/src/bin/mint_harness.rs +1 -0
  694. data/rust/host/src/boot.rs +1 -0
  695. data/rust/host/src/store/mint.rs +40 -6
  696. data/rust/lsp/Cargo.toml +1 -1
  697. data/rust/parser/Cargo.toml +1 -1
  698. data/rust/parser/src/build/correlation_keys.rs +125 -0
  699. data/rust/parser/src/build/mod.rs +1 -0
  700. data/rust/parser/src/emit.rs +55 -3
  701. data/rust/parser/src/ir.rs +33 -1
  702. data/rust/parser/src/keywords.rs +289 -1
  703. data/rust/parser/src/main.rs +2 -0
  704. data/rust/parser/src/parse/aggregate.rs +10 -1
  705. data/rust/parser/src/parse/audience.rs +65 -0
  706. data/rust/parser/src/parse/command.rs +14 -0
  707. data/rust/parser/src/parse/declaration.rs +97 -0
  708. data/rust/parser/src/parse/domain_port.rs +6 -0
  709. data/rust/parser/src/parse/mod.rs +1 -0
  710. data/rust/parser/src/parse/process_manager.rs +17 -10
  711. data/rust/parser/src/parse/world.rs +12 -8
  712. data/rust/parser/src/render_ruby.rs +9 -0
  713. data/rust/parser/src/sentence/format.rs +3 -0
  714. data/rust/parser/src/sentence/process.rs +6 -2
  715. data/rust/src/exemplar/json.rs +17 -0
  716. data/rust/src/kernel/cli.rs +27 -3
  717. data/rust/src/kernel/dispatch.rs +4 -2
  718. data/rust/src/kernel/json.rs +62 -0
  719. data/rust/src/kernel/orchestrate.rs +28 -3
  720. data/rust/src/kernel/orchestrate_guard_tests.rs +12 -12
  721. data/rust/web/Cargo.toml +1 -1
  722. metadata +389 -96
  723. data/lib/hecks/cli/command_table.rb +0 -72
  724. data/lib/hecks/cli/launcher_words.rb +0 -168
  725. data/lib/hecks/cli.rb +0 -133
  726. data/lib/hecks/hecks/agents.bluebook +0 -246
  727. data/lib/hecks/hecks/codebase.bluebook +0 -3209
  728. data/lib/hecks/hecks/custodian.bluebook +0 -1300
  729. data/lib/hecks/hecks/ledger.bluebook +0 -190
  730. data/lib/hecks/hecks/rehearsal.bluebook +0 -437
  731. data/lib/hecks/hecks/tooling.bluebook +0 -1234
  732. data/lib/hecks/hecks/translations/2-148748.bluebook +0 -2
  733. data/lib/hecks/hecks/translations/2-15a2e4.bluebook +0 -2
  734. data/lib/hecks/hecks/translations/2-1b447c.bluebook +0 -5
  735. data/lib/hecks/hecks/translations/2-240474.bluebook +0 -2
  736. data/lib/hecks/hecks/translations/2-44446d.bluebook +0 -2
  737. data/lib/hecks/hecks/translations/2-46ca26.bluebook +0 -2
  738. data/lib/hecks/hecks/translations/2-473eab.bluebook +0 -2
  739. data/lib/hecks/hecks/translations/2-75cc28.bluebook +0 -2
  740. data/lib/hecks/hecks/translations/2-781c07.bluebook +0 -2
  741. data/lib/hecks/hecks/translations/2-84c18b.bluebook +0 -2
  742. data/lib/hecks/hecks/translations/2-aa5fff.bluebook +0 -2
  743. data/lib/hecks/hecks/translations/2-bfdb48.bluebook +0 -2
  744. data/lib/hecks/hecks/translations/2-cd96d8.bluebook +0 -10
  745. data/lib/hecks/hecks/translations/2-d43f71.bluebook +0 -2
  746. data/lib/hecks/hecks/translations/2-eea577.bluebook +0 -2
  747. data/lib/hecks/hecks/translations/2-f53248.bluebook +0 -2
  748. data/lib/hecks/hecks/translations/2-fbb677.bluebook +0 -2
  749. data/lib/hecks/hecks/translations/2-ffdf12.bluebook +0 -6
  750. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +0 -36
  751. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +0 -56
  752. data/prebuilt/31cf81e12f16236ad26249be590cfea3799c9db67432e6a4ef54b801c355b6ae.marshal +0 -0
  753. data/prebuilt/68ecb2bd3abb1a221007db4f2b0375834c13aaccac8f2b99778e8517f11aa113.marshal +0 -0
  754. data/prebuilt/verdicts-0328c2403383837d780ad5ed81d1da351c56436b894cf9015b5d56b8f1f1bf10.json +0 -1
@@ -4,11 +4,15 @@ module Hecks
4
4
  module CliRunner
5
5
  # Reads the spellings a line may give a command or query. The launcher indexes them by the
6
6
  # snake-case `aggregate.verb` the projection prints; the bluebook's own verb form, such as
7
- # `Hecks::PushTrain.Board`, reaches the same one. Extended into `CliRunner`.
7
+ # `Hecks::SendTrain.Board`, reaches the same one. Extended into `CliRunner`.
8
8
  module VerbNames
9
9
  # A realm written before the aggregate: `Hecks::`.
10
10
  REALM = /\A(?:[A-Z]\w*::)+/
11
11
 
12
+ # The spelling notices this process has already printed, keyed by the spelling typed, so each
13
+ # prints once.
14
+ NOTED = Set.new
15
+
12
16
  # The name the projection indexes a typed name under: the name itself when it is one,
13
17
  # else its verb form read into snake case, else the name as typed, for the refusal to
14
18
  # name.
@@ -20,8 +24,36 @@ module Hecks
20
24
  [typed, *verb_form_names(typed)].find { |name| indexed?(cli, name) } || typed
21
25
  end
22
26
 
27
+ # Says once, on standard error, that a line used an aggregate's former name and names the
28
+ # spelling to use. Short-name aliases stay silent.
29
+ #
30
+ # @param cli [Hash] the projection
31
+ # @param typed [String] the word typed, without its `!`
32
+ # @param name [String] the name the index resolved the word to
33
+ # @return [void]
34
+ def note_former_name(cli, typed, name)
35
+ spec = indexed_spec(cli, name)
36
+ return unless former_spelling?(spec, typed)
37
+ return unless NOTED.add?("spelling #{typed}")
38
+
39
+ warn "hecks: #{typed} is the former name of #{spec[:command]}; use that spelling (this notice prints once)"
40
+ end
41
+
42
+ # The command or query a name in the index resolves to, or nil.
43
+ def indexed_spec(cli, name)
44
+ target = cli[:names][:command][name] || cli[:names][:question][name]
45
+ cli[:commands][target] || cli[:questions][target]
46
+ end
47
+
48
+ # Whether the word typed begins with the former name of the aggregate its spec belongs to.
49
+ def former_spelling?(spec, typed)
50
+ return false unless spec && spec[:formerly]
51
+
52
+ snake_form(typed).start_with?("#{Naming.snake(spec[:formerly])}.")
53
+ end
54
+
23
55
  # A typed name as the projection spells it, to match what was typed against the names it
24
- # indexes: `Hecks::PushTrain.bord` as `push_train.bord`.
56
+ # indexes: `Hecks::SendTrain.bord` as `send_train.bord`.
25
57
  #
26
58
  # @param typed [String] the word typed, without its `!`
27
59
  # @return [String] the realm dropped and each dotted segment in snake case
@@ -29,8 +61,8 @@ module Hecks
29
61
 
30
62
  private
31
63
 
32
- # `Hecks::PushTrain.board` as `push_train.board`; a verb that names an entity's command,
33
- # `PushTrain.Launcher.Refresh`, also as `push_train.refresh`, the way the projection
64
+ # `Hecks::SendTrain.board` as `send_train.board`; a verb that names an entity's command,
65
+ # `SendTrain.Launcher.Refresh`, also as `send_train.refresh`, the way the projection
34
66
  # exposes it.
35
67
  def verb_form_names(typed)
36
68
  segments = snake_segments(typed)
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ module Driving
6
+ module CliRunner
7
+ # The launcher's output levels. `-q` prints only the result and any refusal, so the progress
8
+ # and the context line are left out. `-v` adds, on standard error, the command that ran, its
9
+ # checkout and stores, and how long it took. The default prints what the launcher always
10
+ # printed. The flags are taken from anywhere in the line, and cannot be given together.
11
+ module Verbosity
12
+ QUIET_FLAG = "-q"
13
+ VERBOSE_FLAG = "-v"
14
+ FLAGS = { QUIET_FLAG => :quiet, VERBOSE_FLAG => :verbose }.freeze
15
+ CONFLICT = "hecks: -q and -v cannot be given together; give one of them, or neither"
16
+
17
+ # Takes the level flags out of a line.
18
+ #
19
+ # @param argv [Array<String>] the words the launcher was given
20
+ # @return [Array(Symbol, Array<String>)] the level (`:quiet`, `:verbose`, `:default`, or
21
+ # `:conflict` when both flags came) and the words without the flags
22
+ def split_verbosity(argv)
23
+ levels = argv.filter_map { |word| FLAGS[word] }.uniq
24
+ return [:conflict, argv] if levels.length > 1
25
+
26
+ [levels.first || :default, argv.reject { |word| FLAGS.key?(word) }]
27
+ end
28
+
29
+ # Runs a block at one level, and resets the level and the stage progress afterwards.
30
+ #
31
+ # @param level [Symbol] `:quiet`, `:verbose` or `:default`
32
+ # @yield the answer the line gets at that level
33
+ # @return [Object] the block's value
34
+ def with_verbosity(level)
35
+ require_relative "../../../tools/stage_progress"
36
+ previous = Thread.current[:hecks_verbosity]
37
+ Thread.current[:hecks_verbosity] = level
38
+ Tools::StageProgress.quiet = level == :quiet
39
+ yield
40
+ ensure
41
+ Thread.current[:hecks_verbosity] = previous
42
+ Tools::StageProgress.quiet = previous == :quiet
43
+ end
44
+
45
+ # @return [Symbol] the level the line runs at
46
+ def verbosity = Thread.current[:hecks_verbosity] || :default
47
+
48
+ # @return [Boolean] whether only the result and any refusal are printed
49
+ def quiet? = verbosity == :quiet
50
+
51
+ # @return [Boolean] whether each step's details are printed on standard error
52
+ def verbose? = verbosity == :verbose
53
+
54
+ # The details `-v` adds after a command ran: the command, how long it took, and the
55
+ # checkout and stores the line ran in.
56
+ #
57
+ # @param err [#puts] where the details go
58
+ # @param name [String] the command or query that ran
59
+ # @param started [Float] the monotonic clock reading when the line began
60
+ # @return [void]
61
+ def verbose_details(err, name, started)
62
+ elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
63
+ err.puts("command #{name}", format("took %.2fs", elapsed), checkout_line)
64
+ end
65
+
66
+ # @return [String] the context line, as `-v` prints it
67
+ def checkout_line
68
+ ContextLine.line(directory: Dir.pwd, stores: SettingsReading.new.stores(Dir.pwd),
69
+ audience: ContextLine.audience(Dir.pwd))
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,6 +1,9 @@
1
1
  require "json"
2
2
  require_relative "cli"
3
3
  require_relative "command_request"
4
+ require_relative "context_line"
5
+ require_relative "exit_status"
6
+ require_relative "write_guard"
4
7
  require_relative "json"
5
8
  require_relative "launcher_options"
6
9
  require_relative "newcomer"
@@ -8,25 +11,45 @@ require_relative "../../projector"
8
11
  require_relative "../../ports/clock"
9
12
  require_relative "cli_runner/answers"
10
13
  require_relative "cli_runner/resolution"
14
+ require_relative "cli_runner/run_replay"
15
+ require_relative "cli_runner/search_words"
16
+ require_relative "cli_runner/completion_words"
17
+ require_relative "cli_runner/tour_words"
18
+ require_relative "cli_runner/resume_words"
19
+ require_relative "cli_runner/json_words"
11
20
  require_relative "cli_runner/settling"
12
21
  require_relative "cli_runner/streaming"
13
22
  require_relative "cli_runner/suggestions"
14
23
  require_relative "cli_runner/verb_names"
24
+ require_relative "cli_runner/renamed_names"
25
+ require_relative "cli_runner/verbosity"
26
+ require_relative "cli_runner/name_index"
15
27
 
16
28
  module Hecks
17
29
  module Adapters
18
30
  module Driving
19
31
  # Parses and dispatches a command line against a `Projector::CliProjector` projection.
20
- # Does no IO: it answers `[text, status]` and leaves printing and exiting to its callers.
32
+ # Does no IO: it answers `[text, status]` (an `ExitStatus`) and leaves printing and exiting
33
+ # to its callers.
21
34
  module CliRunner
35
+ include ExitStatus
36
+ extend Verbosity
37
+
22
38
  # The class an adapter raises when the tool it wraps refuses.
23
39
  TOOL_REFUSAL = "Hecks::Adapters::ConsoleCapture::Failure".freeze
24
40
  # The words that open the query namespace; `ask` is the older spelling.
25
41
  QUERY_WORDS = %w[query ask].freeze
26
42
 
27
43
  extend Resolution
44
+ extend SearchWords
45
+ extend CompletionWords
46
+ extend TourWords
47
+ extend ResumeWords
48
+ extend JsonWords
28
49
  extend Suggestions
50
+ extend NameIndex
29
51
  extend VerbNames
52
+ extend RenamedNames
30
53
  extend Answers
31
54
  extend Settling
32
55
  extend Streaming
@@ -38,18 +61,91 @@ module Hecks
38
61
  #
39
62
  # @param runtime [Runtime::Dispatcher, Adapters::Lambda::RemoteDispatcher] the booted domain
40
63
  # @param argv [Array<String>] an optional `query` (or `ask`), the command or query name,
41
- # then
42
- # `path=value` pairs; `--help`, `-h`, `help` or nothing answers usage
64
+ # then `path=value` pairs; `--help`, `-h`, `help` or nothing answers usage
43
65
  # @param program [String] how the caller was invoked, echoed in usage and hints
44
- # @return [Array(String, Integer)] the text and the status: 0 answered, 1 refused or misused
66
+ # @return [Array(String, Integer)] the text and the `ExitStatus`: `ANSWERED`, `REFUSED`
67
+ # when the domain said no or the run failed, `USAGE` when the line could not be read
45
68
  # @raise [Runtime::WiringError] if a repository or the clock adapter cannot be resolved
46
69
  # @raise [Runtime::StaleWrite] if concurrent writers beat the command through every retry
47
- def call(runtime:, argv:, program: "hecks run")
70
+ def call(runtime:, argv:, program: "hecks run", usage_log: false, err: $stderr)
71
+ level, argv = split_verbosity(argv)
72
+ return [Verbosity::CONFLICT, USAGE] if level == :conflict
73
+ return if argv.first == "resume" && argv[1] # a resume that names a run runs a saga: it needs a booted domain
74
+
75
+ with_verbosity(level) { answer_line(runtime, argv, program, usage_log, err) }
76
+ rescue Interrupt
77
+ [interrupted(argv), ExitStatus::REFUSED]
78
+ end
79
+
80
+ # Answers one line: resolves it, guards a write, dispatches it and records its usage.
81
+ #
82
+ # @api private
83
+ # @return [Array(String, Integer)] the text and the `ExitStatus`
84
+ def answer_line(runtime, argv, program, usage_log, err)
85
+ started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
48
86
  plan = resolve(runtime, argv, program)
49
87
  return plan[:answer] if plan[:answer]
50
88
 
51
- dispatch(runtime, plan[:spec], plan[:name], plan[:rest], plan[:program], plan[:asking],
52
- bluebook: plan[:bluebook], launcher: plan[:launcher])
89
+ refused = guard_command(plan, err)
90
+ return [refused, ExitStatus::REFUSED] if refused
91
+
92
+ answer = dispatch(runtime, plan[:spec], plan[:name], plan[:rest], plan[:program], plan[:asking],
93
+ bluebook: plan[:bluebook], launcher: plan[:launcher])
94
+ finish_line(answer, plan, started, { argv: argv, usage_log: usage_log, err: err })
95
+ end
96
+
97
+ # Records a line that ran and prints its details when `-v` asked for them.
98
+ #
99
+ # @api private
100
+ # @return [Array(String, Integer)] the answer, unchanged
101
+ def finish_line(answer, plan, started, details)
102
+ UsageLog.record(argv: details[:argv], resolved: plan[:name], status: answer[1], started: started) if details[:usage_log]
103
+ verbose_details(details[:err], plan[:name], started) if verbose?
104
+ answer
105
+ end
106
+
107
+ # The line an interrupted command ends with: what it was and that it was not finished,
108
+ # so the caller sees a refusal rather than a bare stop.
109
+ #
110
+ # @api private
111
+ # @return [String] the text the caller prints on standard error
112
+ def interrupted(argv)
113
+ name = argv.first || "the command"
114
+ "interrupted during #{name}: the run was stopped before it finished"
115
+ end
116
+
117
+ # Before a command (not a query) runs: refuses a write that would land in Memory from a
118
+ # worktree whose main checkout stores it elsewhere, else prints the context line.
119
+ #
120
+ # @api private
121
+ # @return [String, nil] the refusal, or nil when the command may run
122
+ def guard_command(plan, err)
123
+ return if plan[:asking]
124
+
125
+ refusal = WriteGuard.refusal(Dir.pwd, plan[:bluebook]&.name)
126
+ return refusal if refusal
127
+
128
+ ContextLine.announce(err) unless quiet?
129
+ nil
130
+ end
131
+
132
+ # The names a person can type at the launcher, as the projection names them: commands and
133
+ # queries, leaving out the internal steps a run records about itself.
134
+ #
135
+ # @param runtime [#registry] a booted domain, or what `Hecks.describe` answers
136
+ # @param program [String] how the caller was invoked
137
+ # @return [Array<String>] the sorted names
138
+ def known_names(runtime:, program: "hecks run")
139
+ bluebook, = bluebook_for(runtime, [], program)
140
+ launcher = LauncherOptions.settings(runtime, bluebook.name)
141
+ options = LauncherOptions.projection(launcher, program)
142
+ cli = Projector.call(:cli, bluebook: bluebook, options: options.merge(audience(runtime, launcher)))
143
+ public_names(cli[:names][:command], cli[:commands]) + public_names(cli[:names][:question], cli[:questions])
144
+ end
145
+
146
+ # @return [Array<String>] the names whose spec is not internal
147
+ def public_names(names, specs)
148
+ names.reject { |_, id| specs.dig(id, :internal) }.keys.sort
53
149
  end
54
150
 
55
151
  # Answers a command line that asks only for usage, from the projection alone.
@@ -64,6 +160,9 @@ module Hecks
64
160
  # @return [Array(String, Integer), nil] the text and status, or nil when the line would
65
161
  # run a command or question and so needs a booted domain
66
162
  def usage(runtime:, argv:, program: "hecks run")
163
+ level, argv = split_verbosity(argv)
164
+ return [Verbosity::CONFLICT, USAGE] if level == :conflict
165
+
67
166
  UsageCache.fetch(runtime, argv, program, audience: audience_key) { resolve(runtime, argv, program)[:answer] }
68
167
  end
69
168
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require_relative "launcher_options"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ module Driving
9
+ # The one line a command prints before it writes: which checkout it runs in, the store each
10
+ # bluebook uses, and the audience the launcher lists for. It reads only, through the store
11
+ # resolution `hecks config` uses, so the line cannot disagree with a boot.
12
+ module ContextLine
13
+ MEMORY = "Memory"
14
+
15
+ # The store of a bluebook, as a label with no aggregate in it.
16
+ BLUEBOOK_STORE = /\Astore [^:]+\z/
17
+
18
+ # The storage kinds a store description starts with.
19
+ SQLITE_STORE = /\ASqlite/i
20
+ POSTGRES_STORE = /\APostgres/
21
+
22
+ module_function
23
+
24
+ # Prints the line on a terminal; a pipe or a file gets nothing, so stdout stays clean.
25
+ #
26
+ # @param err [#tty?, #puts] where the line goes
27
+ # @param directory [String] the checkout a command runs in
28
+ # @return [String, nil] the line printed, or nil when nothing was printed
29
+ def announce(err, directory: Dir.pwd)
30
+ return unless err.respond_to?(:tty?) && err.tty?
31
+
32
+ require_relative "../../hecks/adapters/settings_reading"
33
+
34
+ text = line(directory: directory, stores: SettingsReading.new.stores(directory),
35
+ audience: audience(directory))
36
+ err.puts(text)
37
+ text
38
+ end
39
+
40
+ # @param directory [String] the checkout a command runs in
41
+ # @param stores [Array<Array(String, String, String)>] store rows, as `stores` answers them
42
+ # @param audience [String] the audience the launcher lists for
43
+ # @return [String] the line
44
+ def line(directory:, stores:, audience:)
45
+ ["checkout #{File.basename(directory)} (#{branch(directory)})", stored(stores),
46
+ "audience #{audience}"].join(" · ")
47
+ end
48
+
49
+ # @param stores [Array<Array(String, String, String)>] store rows
50
+ # @return [String] "Tickets in SQLite" for each bluebook off Memory, else Memory
51
+ def stored(stores)
52
+ found = stores.filter_map do |label, value, _source|
53
+ next unless label.match?(BLUEBOOK_STORE) && kind(value) != MEMORY
54
+
55
+ "#{label.delete_prefix("store ")} in #{kind(value)}"
56
+ end
57
+ found.empty? ? MEMORY : found.join(", ")
58
+ end
59
+
60
+ # @param value [String] a store's description, as the rows give it
61
+ # @return [String] the store's kind
62
+ def kind(value)
63
+ case value.to_s
64
+ when SQLITE_STORE then "SQLite"
65
+ when POSTGRES_STORE then "Postgres"
66
+ else value.to_s.split.first || MEMORY
67
+ end
68
+ end
69
+
70
+ # @param directory [String]
71
+ # @return [String] the checked-out branch, or "detached" when there is none
72
+ def branch(directory)
73
+ out, status = Open3.capture2e("git", "-C", directory, "symbolic-ref", "--short", "HEAD")
74
+ status.success? ? out.strip : "detached"
75
+ end
76
+
77
+ # @param directory [String]
78
+ # @return [String] "maintainer" inside a hecks checkout, else "person"
79
+ def audience(directory)
80
+ LauncherOptions.maintainer?(directory) ? "maintainer" : "person"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,31 @@
1
+ module Hecks
2
+ module Adapters
3
+ module Driving
4
+ # The statuses a launcher exits with, which a script branches on: `CliRunner` answers them
5
+ # beside its text, the runner returns them, and every generated launcher passes them to
6
+ # `exit`. Three suffice: the line was answered, the domain said no, or the line could not
7
+ # be read. A crash and a domain that cannot be opened both end as `REFUSED`, because the
8
+ # launcher distinguishes neither from a refusal.
9
+ module ExitStatus
10
+ # The line ran and was answered: a usage, a command's outcome, a query's rows, a stream
11
+ # that ended, and a port operation's refusal event, which is an answer.
12
+ ANSWERED = 0
13
+
14
+ # The domain said no, or the run failed: a refusal, a record that is not there, a
15
+ # `--wait` run that ended in a failure state or whose reaction was refused or crashed, a
16
+ # question that reports a gap under `--wait`, the door refusing the caller, or a domain
17
+ # that cannot be opened.
18
+ REFUSED = 1
19
+
20
+ # The line could not be read: no command named, a command or query the bluebook does not
21
+ # declare, a word the command does not take, a value its type cannot hold, or a flag the
22
+ # command lacks.
23
+ USAGE = 2
24
+
25
+ # One line a launcher's help prints, naming the three statuses.
26
+ HELP_LINE = "exit status: #{ANSWERED} answered, #{REFUSED} refused or failed, " \
27
+ "#{USAGE} a line it could not read".freeze
28
+ end
29
+ end
30
+ end
31
+ end
@@ -59,7 +59,7 @@ module Hecks
59
59
  # @param program [String] how the caller was invoked
60
60
  # @return [Hash{Symbol => Object}] the options `Projector::CliProjector` reads
61
61
  def projection(settings, program)
62
- { program: program, names: settings && settings[:names], mint_run_keys: settings && settings[:run_keys] }
62
+ { program:, opted: !settings.nil?, **settings.to_h.slice(:names, :renamed), mint_run_keys: settings&.dig(:run_keys) }
63
63
  end
64
64
 
65
65
  # Whether the person is working on a hecks checkout: `dir` or a directory above it holds
@@ -79,17 +79,19 @@ module Hecks
79
79
 
80
80
  # The help options one audience gets: the aggregates left out of the lists (`maintainer`,
81
81
  # shown only in a hecks checkout or to `--maintainer`) and the bluebooks pointed at
82
- # (`bluebooks`, plus `maintainer_bluebooks` in a checkout). A bluebook that did not opt in
83
- # gets neither.
82
+ # (`bluebooks`, plus `maintainer_bluebooks` in a checkout), and the commands listed first
83
+ # (`everyday`). A bluebook that did not opt in gets none of them.
84
84
  #
85
85
  # @param settings [Hash, nil] the bluebook's `launcher` setting
86
86
  # @param maintainer [Boolean] whether the help is for someone working on a hecks checkout
87
- # @return [Hash{Symbol => Object}] `:hide` and `:bluebooks`, to merge into the projection
87
+ # @return [Hash{Symbol => Object}] `:hide`, `:bluebooks` and `:everyday` (empty when the
88
+ # setting names none), to merge into the projection
88
89
  def audience(settings, maintainer)
89
90
  return {} unless settings
90
91
 
91
92
  named = Array(settings[:bluebooks]) + (maintainer ? Array(settings[:maintainer_bluebooks]) : [])
92
- { hide: maintainer ? [] : Array(settings[:maintainer]).map(&:to_s), declarations: named.map(&:to_s) }
93
+ { hide: maintainer ? [] : Array(settings[:maintainer]).map(&:to_s), declarations: named.map(&:to_s),
94
+ everyday: Array(settings[:everyday]).map(&:to_s) }
93
95
  end
94
96
 
95
97
  # Runs the block with standard error held back, so the wiring notes hecks prints about its
@@ -0,0 +1,45 @@
1
+ require "json"
2
+ require_relative "../../../tools/stage_progress"
3
+
4
+ module Hecks
5
+ module Adapters
6
+ module Driving
7
+ module Mcp
8
+ # Where a stage's progress lines go when the client asked for them with a progress token: each
9
+ # line becomes one `notifications/progress` message on the server's output, ahead of the
10
+ # response to the call. Stands in for the standard error that `Tools::StageProgress` writes to.
11
+ class ProgressSink
12
+ # @param token [Object] the client's `progressToken`, echoed back on every notification
13
+ # @param out [#puts] the server's output, where each notification is written
14
+ def initialize(token, out:)
15
+ @token = token
16
+ @out = out
17
+ @count = 0
18
+ end
19
+
20
+ # Sends one line as a progress notification. The count rises by one per line, so a client
21
+ # can order them.
22
+ # @param text [String] the line
23
+ # @return [void]
24
+ def puts(text)
25
+ @count += 1
26
+ @out.puts(JSON.generate(notification(text)))
27
+ end
28
+
29
+ # Nothing is buffered, so there is nothing to flush.
30
+ # @return [nil]
31
+ def flush = nil
32
+
33
+ private
34
+
35
+ # @param text [String] the line
36
+ # @return [Hash] the JSON-RPC notification carrying it
37
+ def notification(text)
38
+ { jsonrpc: "2.0", method: "notifications/progress",
39
+ params: { progressToken: @token, progress: @count, message: text } }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -48,10 +48,10 @@ module Hecks
48
48
 
49
49
  # A question, once the scope has admitted its arguments.
50
50
  def query_tool(args)
51
- Mcp.scope.admit_arguments!(args["args"])
51
+ Mcp.scope.admit_arguments!(args["args"], args["question"])
52
52
  Storehouse.query(runtime: Mcp.boot(args["domain"]), question: args["question"],
53
53
  summary: args["summary"], args: args["args"] || {}, source: args["source"],
54
- role: args["role"], actor_id: args["actor_id"])
54
+ role: args["role"], actor_id: args["actor_id"], surface: "mcp")
55
55
  end
56
56
 
57
57
  # A single command or a batch, once the scope has admitted every command in it.
@@ -62,14 +62,16 @@ module Hecks
62
62
  Mcp.scope.admit_command!(runtime, args["command"], args["args"])
63
63
  Storehouse.dispatch(runtime: runtime, command: args["command"], summary: args["summary"],
64
64
  args: args["args"] || {}, source: args["source"],
65
- dry_run: args["dry_run"] == true, role: args["role"], actor_id: args["actor_id"])
65
+ dry_run: args["dry_run"] == true, role: args["role"], actor_id: args["actor_id"],
66
+ surface: "mcp")
66
67
  end
67
68
 
68
69
  # Several commands in one call.
69
70
  def dispatch_steps(runtime, args)
70
71
  Mcp.scope.admit_steps!(runtime, args["steps"])
71
72
  Storehouse.dispatch_batch(runtime: runtime, steps: args["steps"], summary: args["summary"],
72
- source: args["source"], role: args["role"], actor_id: args["actor_id"])
73
+ source: args["source"], role: args["role"], actor_id: args["actor_id"],
74
+ surface: "mcp")
73
75
  end
74
76
 
75
77
  def events_tool(args)
@@ -79,7 +81,7 @@ module Hecks
79
81
 
80
82
  def state_tool(args)
81
83
  Storehouse.state(runtime: Mcp.boot(args["domain"]), aggregate: args["aggregate"],
82
- summary: args["summary"], id: args["id"])
84
+ summary: args["summary"], id: args["id"], surface: "mcp")
83
85
  end
84
86
 
85
87
  def catalog_tool(args)
@@ -1,8 +1,9 @@
1
1
  require "json"
2
2
  require_relative "../.."
3
- require_relative "../../cli/mcp"
3
+ require_relative "../../tools/mcp"
4
4
  require_relative "mcp/tool_definitions"
5
5
  require_relative "mcp/tool_calls"
6
+ require_relative "mcp/progress_sink"
6
7
 
7
8
  module Hecks
8
9
  module Adapters
@@ -42,7 +43,7 @@ module Hecks
42
43
  # Read once, so a bad setting refuses to start the server before anything is
43
44
  # written to stdout.
44
45
  def scope
45
- @scope ||= McpScope.start!(server: CLI::Mcp::SERVER)
46
+ @scope ||= McpScope.start!(server: Tools::Mcp::SERVER)
46
47
  end
47
48
 
48
49
  # The standing notes, then what this server's scope says about `domain:`.
@@ -51,7 +52,7 @@ module Hecks
51
52
  end
52
53
 
53
54
  def serve
54
- McpStdioGuard.warn!(server: CLI::Mcp::SERVER, notes: warning_notes)
55
+ McpStdioGuard.warn!(server: Tools::Mcp::SERVER, notes: warning_notes)
55
56
  $stdout.sync = true
56
57
 
57
58
  $stdin.each_line { |line| answer_line(line.strip) }
@@ -138,7 +139,7 @@ module Hecks
138
139
 
139
140
  def initialize_result(_params)
140
141
  { protocolVersion: PROTOCOL_VERSION, capabilities: { tools: {} },
141
- serverInfo: { name: CLI::Mcp::SERVER, version: "1.1.0" } }
142
+ serverInfo: { name: Tools::Mcp::SERVER, version: "1.1.0" } }
142
143
  end
143
144
 
144
145
  # The tools this server's scope permits, each presented with the command guide.
@@ -149,9 +150,28 @@ module Hecks
149
150
  end
150
151
 
151
152
  def tools_call(params)
152
- tool_result(answer_tool(params["name"], params["arguments"] || {}))
153
+ token = params.dig("_meta", "progressToken")
154
+ return tool_result(answer_tool(params["name"], params["arguments"] || {})) if token.nil?
155
+
156
+ with_progress(token) { tool_result(answer_tool(params["name"], params["arguments"] || {})) }
157
+ end
158
+
159
+ # Runs the block with a progress seam for this call's stages, so their lines reach the client as
160
+ # notifications. The seam is per thread and removed when the call ends.
161
+ # @param token [Object] the client's progress token
162
+ # @return [Object] the block's value
163
+ def with_progress(token)
164
+ previous = Thread.current[:mcp_progress]
165
+ Thread.current[:mcp_progress] = Tools::StageProgress.new(ProgressSink.new(token, out: $stdout))
166
+ yield
167
+ ensure
168
+ Thread.current[:mcp_progress] = previous
153
169
  end
154
170
 
171
+ # The progress seam of the call on this thread: nil when the client sent no progress token.
172
+ # @return [Tools::StageProgress, nil]
173
+ def progress = Thread.current[:mcp_progress]
174
+
155
175
  def ping_result(_params) = {}
156
176
  end
157
177
  end