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,80 @@
1
+ module Hecks
2
+ module Bluebook
3
+ module DSL
4
+ class BluebookBuilder
5
+ # Groups a bluebook's aggregates in the modules it declares (ADR 0163). `domain_module
6
+ # "Deliver" do … end` opens a block whose `aggregate` words are recorded under the module;
7
+ # the module changes no aggregate, it names the task each one belongs to. Policies, read
8
+ # models and process managers inside the block are the bluebook's own, as they are outside it.
9
+ module Modules
10
+ # Opens the module `name` and evaluates its body; a module of that name that an earlier
11
+ # file opened gains the aggregates this body declares.
12
+ #
13
+ # @param name [String] the module's own name, such as `"Deliver"`
14
+ # @yield the module body: its vision, aggregates, policies, read models and process managers
15
+ # @return [Array<Bluebook::Declaration::ModuleRow>] every membership declared so far
16
+ # @raise [Bluebook::DSL::Malformed] if a module opens inside another, or holds no aggregate
17
+ def domain_module(name, &)
18
+ refuse_nested_module!(name)
19
+ @open_module = name.to_s
20
+ instance_eval(&) if block_given?
21
+ refuse_empty_module!(@open_module)
22
+ module_rows
23
+ ensure
24
+ @open_module = nil
25
+ end
26
+
27
+ private
28
+
29
+ # One row per aggregate a module groups, in declaration order, each carrying its module's
30
+ # vision (empty when the module names none).
31
+ def module_rows
32
+ module_members.map do |name, aggregate|
33
+ Declaration::ModuleRow.new(name: name, vision: module_visions[name].to_s, aggregate: aggregate)
34
+ end
35
+ end
36
+
37
+ # Each `[module, aggregate]` pair declared so far, in declaration order.
38
+ def module_members = @module_members ||= []
39
+
40
+ # Each module's vision by its name, for the modules that declared one.
41
+ def module_visions = @module_visions ||= {}
42
+
43
+ # Records an aggregate under the open module, if one is open.
44
+ def note_in_open_module(name)
45
+ module_members << [@open_module, name.to_s] if @open_module
46
+ end
47
+
48
+ # Records the open module's vision.
49
+ def module_vision(value)
50
+ held = module_visions[@open_module]
51
+ raise Malformed, "domain_module #{@open_module.inspect} declares two visions" if held && held != value
52
+
53
+ module_visions[@open_module] = value
54
+ end
55
+
56
+ # Refuses a bluebook-wide word written inside a module block.
57
+ def bluebook_wide!(word)
58
+ return unless @open_module
59
+
60
+ raise Malformed, "#{word} describes the whole bluebook, so it cannot sit inside " \
61
+ "domain_module #{@open_module.inspect}"
62
+ end
63
+
64
+ def refuse_nested_module!(name)
65
+ return unless @open_module
66
+
67
+ raise Malformed, "domain_module #{name.inspect} sits inside domain_module " \
68
+ "#{@open_module.inspect}; modules do not nest"
69
+ end
70
+
71
+ def refuse_empty_module!(name)
72
+ return if module_members.any? { |held, _| held == name }
73
+
74
+ raise Malformed, "domain_module #{name.inspect} holds no aggregate"
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -8,6 +8,57 @@ module Hecks
8
8
  module CorrelationKeys
9
9
  private
10
10
 
11
+ # A bare name (`correlates_by Message`) naming an aggregate of this bluebook means
12
+ # that aggregate's identity, `"Message.id"`. Any other bare name is refused here,
13
+ # with the message the builder used to give. Runs before the other correlation
14
+ # checks, so they only ever see the dotted form.
15
+ def resolve_bare_correlation_keys!(bluebook)
16
+ bluebook.process_managers.each do |process_manager|
17
+ key = process_manager.correlates_by.to_s
18
+ next if bare_correlation_key?(key)
19
+
20
+ resolve_bare_correlation_key!(bluebook, process_manager, key)
21
+ end
22
+ end
23
+
24
+ def bare_correlation_key?(key)
25
+ key.empty? || key.include?(".")
26
+ end
27
+
28
+ def resolve_bare_correlation_key!(bluebook, process_manager, key)
29
+ aggregate = find_correlated_aggregate(bluebook, key)
30
+ unless aggregate
31
+ raise ProcessManagerBuilder::InvalidProcessManager,
32
+ bare_correlation_message(process_manager.name, key)
33
+ end
34
+
35
+ path = identity_path(process_manager, aggregate)
36
+ process_manager.correlate_by!("#{aggregate.name}.#{path}")
37
+ end
38
+
39
+ # The refusal for a bare name that does not name an aggregate of the bluebook.
40
+ def bare_correlation_message(name, key)
41
+ "#{name} correlates_by #{key}, which names a whole field rather than one of its scalars " \
42
+ "— say which one, e.g. #{key}.value (or name an aggregate of this bluebook, " \
43
+ "which correlates by its identity)"
44
+ end
45
+
46
+ def find_correlated_aggregate(bluebook, key)
47
+ bluebook.aggregates.find { |candidate| candidate.name.to_s == Naming.demodulise(key) }
48
+ end
49
+
50
+ # The one field an aggregate is correlated by: its identity, or `id` when it declares none.
51
+ # A value-object identity drops its trailing `.value`, so `Thing` reads as `Thing.id`.
52
+ def identity_path(process_manager, aggregate)
53
+ paths = aggregate.identity_paths.map(&:to_s)
54
+ return "id" if paths.empty?
55
+ return paths.first.delete_suffix(".value") if paths.one?
56
+
57
+ raise ProcessManagerBuilder::InvalidProcessManager,
58
+ "#{process_manager.name} correlates_by #{aggregate.name}, but #{aggregate.name} has a " \
59
+ "composite identity — name the one field, e.g. #{aggregate.name}.#{paths.first}"
60
+ end
61
+
11
62
  # `correlates_by` must land on a scalar: the dotted path is walked against each
12
63
  # command that emits an event the process manager reacts to. A command lacking the
13
64
  # first segment is skipped, since correlation has fallback tiers
@@ -35,6 +35,7 @@ module Hecks
35
35
  # @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a
36
36
  # `correlates_by` resolves to something other than a scalar field
37
37
  def validate_assembled!(bluebook)
38
+ resolve_bare_correlation_keys!(bluebook)
38
39
  validate_not_the_gem_module!(bluebook)
39
40
  validate_declarations!(bluebook)
40
41
  validate_owner_stamped!(bluebook)
@@ -1,6 +1,8 @@
1
1
  require_relative "word_gate"
2
2
  require_relative "bluebook_builder/validation"
3
3
  require_relative "bluebook_builder/pending_givens"
4
+ require_relative "bluebook_builder/modules"
5
+ require_relative "bluebook_builder/metadata"
4
6
  module Hecks
5
7
  module Bluebook
6
8
  module DSL
@@ -10,6 +12,8 @@ module Hecks
10
12
  GRAMMAR_CONTEXT = "Bluebook".freeze
11
13
 
12
14
  include WordGate
15
+ include Modules
16
+ include Metadata
13
17
  extend Validation
14
18
 
15
19
  attr_reader :classification
@@ -56,23 +60,11 @@ module Hecks
56
60
  # @param value [String] the vision text, as given to `vision "..."`
57
61
  # @return [void]
58
62
  def vision(value)
63
+ return module_vision(value) if @open_module
64
+
59
65
  @vision = value
60
66
  end
61
67
 
62
- # Records the bluebook's earlier name, so the storage layer recognizes its history
63
- # under it instead of minting a new lineage — a bluebook's identity can change.
64
- #
65
- # @param value [String, Symbol] the bluebook's earlier name
66
- # @return [String] `value`, stringified, as stored
67
- def formerly_known_as(value) = @formerly_known_as = value.to_s
68
-
69
- # Names the Ruby module the bluebook's constants install under instead of its own name,
70
- # such as `namespace "Hecks::Domain"` for a bluebook that would otherwise collide.
71
- #
72
- # @param value [String] a constant path, such as `"Hecks::Domain"`
73
- # @return [String] `value`, stringified, as stored
74
- def namespace(value) = @namespace = value.to_s
75
-
76
68
  # Names a core grammar context this bluebook's sub-language extends (ADR 0026).
77
69
  # Variadic and accumulates across calls, like `identified_by`/`group_by`.
78
70
  #
@@ -82,7 +74,10 @@ module Hecks
82
74
  # @param contexts [Array<String>] one or more core grammar context names, such as
83
75
  # `"Query"`/`"ReadModel"`
84
76
  # @return [Array<String>] every context named so far, this call's included
85
- def attaches_to_impl(*contexts) = (@attaches_to ||= []).concat(contexts.map(&:to_s))
77
+ def attaches_to_impl(*contexts)
78
+ bluebook_wide!(:attaches_to)
79
+ (@attaches_to ||= []).concat(contexts.map(&:to_s))
80
+ end
86
81
 
87
82
  # Records a capability this bluebook answers for other domains, one row per key —
88
83
  # checked once the bluebook is whole, since verbs may be declared later in the file.
@@ -94,6 +89,7 @@ module Hecks
94
89
  # this capability's included
95
90
  # @raise [Bluebook::DSL::Malformed] if `verbs` is empty
96
91
  def provides_impl(capability, **verbs)
92
+ bluebook_wide!(:provides)
97
93
  if verbs.empty?
98
94
  raise Malformed, "#{@name}'s provides #{capability.inspect} names no verb — say which of this " \
99
95
  "bluebook's commands and queries answer it"
@@ -103,22 +99,6 @@ module Hecks
103
99
  (@provides ||= []).concat(rows)
104
100
  end
105
101
 
106
- # Classifies this bluebook as core to the framework, rather than a domain built on it.
107
- #
108
- # @return [Symbol] `:core`
109
- def core = @classification = :core
110
-
111
- # Classifies this bluebook as a supporting piece of the framework, rather than a domain
112
- # built on it.
113
- #
114
- # @return [Symbol] `:supporting`
115
- def supporting = @classification = :supporting
116
-
117
- # Classifies this bluebook as generic infrastructure, rather than a domain built on it.
118
- #
119
- # @return [Symbol] `:generic`
120
- def generic = @classification = :generic
121
-
122
102
  # Declares an aggregate belonging to this bluebook. `@bluebook_named_givens` is
123
103
  # threaded into it — see `AggregateBuilder#given` for the sharing this enables.
124
104
  #
@@ -126,15 +106,18 @@ module Hecks
126
106
  # named in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
127
107
  #
128
108
  # @param name [String] the aggregate's own name
109
+ # @param kind [String, nil] the kind whose text the aggregate's body is evaluated within
129
110
  # @yield the aggregate body, evaluated against a new `AggregateBuilder`; may be omitted
130
111
  # @return [Array<Bluebook::Aggregate>] every aggregate declared so far, this one last
131
112
  # @raise [Bluebook::DSL::Malformed] if the aggregate's own body fails any check
132
113
  # `AggregateBuilder#build` raises
133
- def aggregate_impl(name, &)
114
+ def aggregate_impl(name, kind: nil, &body)
115
+ note_in_open_module(name)
134
116
  @aggregates << AggregateBuilder.build(name, bluebook_named_givens: @bluebook_named_givens,
135
117
  bluebook_pending_givens: @bluebook_pending_givens,
136
118
  bluebook_entity_named_givens: @bluebook_entity_named_givens,
137
- bluebook_entity_pending_givens: @bluebook_entity_pending_givens, &)
119
+ bluebook_entity_pending_givens: @bluebook_entity_pending_givens,
120
+ &Kinds.wrap(name, kind, &body))
138
121
  end
139
122
 
140
123
  # Declares a read model belonging to this bluebook.
@@ -257,7 +240,7 @@ module Hecks
257
240
  { aggregates: @aggregates, read_models: @read_models,
258
241
  policies: @aggregates.flat_map(&:policies) + @policies,
259
242
  process_managers: @process_managers,
260
- attaches_to: @attaches_to || [], provides: @provides || [] }
243
+ attaches_to: @attaches_to || [], provides: @provides || [], modules: module_rows }
261
244
  end
262
245
  end
263
246
  end
@@ -15,6 +15,8 @@ module Hecks
15
15
  # [context, word] => the method a word's whole call forwards to.
16
16
  CALLS = {
17
17
  ["Aggregate", "provenance"] => :provenance_impl,
18
+ ["Aggregate", "formerly_known_as"] => :formerly_known_as_impl,
19
+ ["Aggregate", "created_by"] => :created_by_impl,
18
20
  ["Aggregate", "identified_by"] => :identified_by_impl,
19
21
  ["Aggregate", "reference_to"] => :reference_to_impl,
20
22
  ["Aggregate", "has_many"] => :has_many_impl,
@@ -36,8 +38,10 @@ module Hecks
36
38
  ["Bluebook", "provides"] => :provides_impl,
37
39
  ["Bluebook", "aggregate"] => :aggregate_impl,
38
40
  ["Command", "role"] => :role_impl,
41
+ ["Command", "audience"] => :audience_impl,
39
42
  ["Command", "provenance"] => :provenance_impl,
40
43
  ["Command", "idempotent"] => :idempotent_impl,
44
+ ["Command", "mints_era"] => :mints_era_impl,
41
45
  ["Command", "reference_to"] => :reference_to_impl,
42
46
  ["Command", "given"] => :given_impl,
43
47
  ["Command", "sets"] => :sets_impl,
@@ -62,8 +66,10 @@ module Hecks
62
66
  ["Policy", "trigger"] => :trigger_impl,
63
67
  ["Policy", "ask"] => :ask_impl,
64
68
  ["Policy", "across"] => :across_impl,
69
+ ["ProcessManager", "correlates_by"] => :correlates_by_impl,
65
70
  ["ProcessManager", "starts_on"] => :starts_on_impl,
66
71
  ["ProcessManager", "ends_on"] => :ends_on_impl,
72
+ ["ProcessManager", "resumes"] => :resumes_impl,
67
73
  ["ProcessManager", "transition"] => :transition_impl,
68
74
  ["Handler", "dispatch"] => :dispatch_impl,
69
75
  ["Dispatch", "compensates"] => :compensates_impl,
@@ -98,8 +104,10 @@ module Hecks
98
104
  ["Hecksagon", "port"] => :port_impl,
99
105
  ["PortOperation", "reference_to"] => :reference_to_impl,
100
106
  ["PortOperation", "attribute"] => :attribute_impl,
107
+ ["PortOperation", "handles"] => :handles_impl,
101
108
  ["Translation", "aggregate"] => :aggregate_impl,
102
109
  ["TranslationAggregate", "rename"] => :rename_impl,
110
+ ["TranslationAggregate", "split"] => :split_impl,
103
111
  ["TranslationAggregate", "move"] => :move_impl,
104
112
  ["TranslationAggregate", "convert"] => :convert_impl,
105
113
  ["TranslationAggregate", "retype"] => :retype_impl,
@@ -1,5 +1,6 @@
1
1
  require_relative "word_gate"
2
2
  require_relative "need_word"
3
+ require_relative "audience_word"
3
4
  require_relative "command_builder/owner"
4
5
  require_relative "command_builder/rules"
5
6
  require_relative "command_builder/mutations"
@@ -22,6 +23,7 @@ module Hecks
22
23
  include RuleReference
23
24
  include WordGate
24
25
  include NeedWord
26
+ include AudienceWord
25
27
  include ImplicitAttributes
26
28
  include Operands
27
29
  include FoldedSets
@@ -82,6 +84,14 @@ module Hecks
82
84
  # @return [true]
83
85
  def idempotent_impl = @idempotent = true
84
86
 
87
+ # Declares that this command's own record may be written through a boot whose shape no era
88
+ # holds yet, so the command that mints the held era can persist its request. Every other
89
+ # write from such a boot stays refused.
90
+ #
91
+ # @param value [Boolean] `true` to allow the write; any other value declares nothing
92
+ # @return [Boolean] the flag as stored
93
+ def mints_era_impl(value) = @mints_era = value == true
94
+
85
95
  # Declares the aggregate this command acts on (with no `as:`), or a cross-reference to
86
96
  # another aggregate (with `as:`).
87
97
  #
@@ -203,13 +213,13 @@ module Hecks
203
213
  end
204
214
 
205
215
  def declared_rules
206
- { name: @name, role: @role, roles: @roles || [], goal: @goal, attributes: attributes, givens: @givens,
207
- ensures: @ensures, needs: @needs }
216
+ { name: @name, role: @role, roles: @roles || [], audience: @audience || [], goal: @goal,
217
+ attributes: attributes, givens: @givens, ensures: @ensures, needs: @needs }
208
218
  end
209
219
 
210
220
  def declared_effects
211
221
  { mutations: @mutations, emits: @emits, references: @references, from: @from,
212
- provenance: @provenance, idempotent: @idempotent || false }
222
+ provenance: @provenance, idempotent: @idempotent || false, mints_era: @mints_era || false }
213
223
  end
214
224
  end
215
225
  end
@@ -51,7 +51,6 @@ module Hecks
51
51
 
52
52
  # `has_many_impl`/`has_one_impl` are DSL keywords (`has_many`/`has_one` in a bluebook),
53
53
  # not real predicates, so Naming/PredicatePrefix does not apply here.
54
- # rubocop:disable Naming/PredicatePrefix
55
54
  # Declares a list-typed relationship to another entity, referenced by its plural name.
56
55
  def has_many_impl(type, as: nil, **options)
57
56
  unless options.empty?
@@ -69,7 +68,6 @@ module Hecks
69
68
  target = Naming.demodulise(type)
70
69
  relationship_attribute(target, :has_one, as || Naming.snake(target).to_sym, optional: optional)
71
70
  end
72
- # rubocop:enable Naming/PredicatePrefix
73
71
 
74
72
  # Declares a single-valued relationship to the entity that owns this one.
75
73
  def belongs_to_impl(type, as: nil, optional: false)
@@ -10,6 +10,9 @@ module Hecks
10
10
 
11
11
  COERCE_BY_KIND = { "text" => :to_s, "symbol" => :to_sym }.freeze
12
12
 
13
+ # The arguments of one word call: its positional arguments, its keyword arguments, and its block.
14
+ Invocation = Struct.new(:args, :kwargs, :block)
15
+
13
16
  # Not derivable from `fills:` (these rows all carry `fills: ""`) — the append target
14
17
  # for each opens-block word must be named here explicitly.
15
18
  SAFE_OPENS_BLOCK = {
@@ -31,13 +34,12 @@ module Hecks
31
34
 
32
35
  # Executes a table-admitted word via the shape `shape_for` found for it, or returns
33
36
  # NOT_HANDLED so the caller can fall back to its own "not yet implemented" refusal.
34
- # The seven-argument form is the entry point `WordGate` and the dispatch specs call.
35
- # rubocop:disable-next Metrics/ParameterLists
36
- def try(builder, context, word, args, kwargs, block, rows)
37
+ # The call's arguments travel together as an `Invocation`, which keeps the signature short.
38
+ def try(builder, context, word, invocation, rows)
37
39
  shape = shape_for(context, word, rows)
38
40
  return NOT_HANDLED unless shape
39
41
 
40
- run_shape(shape, builder, args, kwargs, block)
42
+ run_shape(shape, builder, invocation.args, invocation.kwargs, invocation.block)
41
43
  end
42
44
 
43
45
  # Runs the dispatcher the shape's kind names.
@@ -0,0 +1,53 @@
1
+ module Hecks
2
+ module Bluebook
3
+ module DSL
4
+ # The aggregate kinds: `aggregate "GateRun", kind: "Run"` evaluates the kind's own text,
5
+ # written in the bluebook's words, around the aggregate's body. A kind is data, the file
6
+ # `lib/hecks/language/kinds/<kind>.kind`, not code: `{Name}` in it stands for the aggregate's
7
+ # name and `{Stem}` for that name without the kind, and a `# body` line marks where the
8
+ # aggregate's own body is evaluated.
9
+ module Kinds
10
+ DIRECTORY = File.expand_path("../../language/kinds", __dir__).freeze
11
+ BODY_MARK = /^# body\n/
12
+
13
+ module_function
14
+
15
+ # The block an aggregate is built from: its own body, or, for a kind, that body inside the
16
+ # kind's text.
17
+ #
18
+ # @param name [String] the aggregate's name
19
+ # @param kind [String, nil] the kind written after `kind:`, if any
20
+ # @yield the aggregate's own body; may be omitted
21
+ # @return [Proc, nil] the block to evaluate on the aggregate's builder
22
+ # @raise [Malformed] if the kind has no file
23
+ def wrap(name, kind, &body)
24
+ return body unless kind
25
+
26
+ before, after = halves(kind, name)
27
+ file = path(kind)
28
+ proc do
29
+ instance_eval(before, file, 1)
30
+ instance_eval(&body) if body
31
+ instance_eval(after, file, before.lines.size + 2)
32
+ end
33
+ end
34
+
35
+ # @return [Array(String, String)] the kind's text, names filled in, split at the body
36
+ def halves(kind, name)
37
+ before, after = File.read(path(kind)).split(BODY_MARK, 2)
38
+ [before, after].map { |text| fill(text, name, kind) }
39
+ rescue Errno::ENOENT
40
+ raise Malformed, "#{name} declares kind #{kind.inspect}, which has no file at #{path(kind)}"
41
+ end
42
+
43
+ # @return [String] the kind's text with `{Name}` and `{Stem}` replaced
44
+ def fill(text, name, kind)
45
+ text.gsub("{Name}", name.to_s).gsub("{Stem}", name.to_s.delete_suffix(kind.to_s))
46
+ end
47
+
48
+ # @return [String] the file that holds a kind
49
+ def path(kind) = File.join(DIRECTORY, "#{kind.to_s.downcase}.kind")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -25,6 +25,7 @@ module Hecks
25
25
  @owner = owner
26
26
  @direction = direction
27
27
  @emits = []
28
+ @handles = []
28
29
  end
29
30
 
30
31
  # Refuses `reference_to` inside an operation body; a port operation has no self-reference
@@ -47,6 +48,12 @@ module Hecks
47
48
  # Names one event an inbound operation records once the external fact has arrived.
48
49
  def emits(event_name) = @emits << event_name.to_s
49
50
 
51
+ # Names one value of a command this operation handles, e.g. `handles "Build.build!",
52
+ # value: "wasm"`. Recorded in the IR only; nothing routes on it yet.
53
+ def handles_impl(command, value:)
54
+ @handles << { command: command.to_s, value: value.to_s }
55
+ end
56
+
50
57
  # `answers`/`refuses`, the two halves of an `asks` — separate words rather than two
51
58
  # `emits` so a reader can tell what came back from what the outside refused, without
52
59
  # reading the adapter.
@@ -64,7 +71,8 @@ module Hecks
64
71
 
65
72
  PortOperation.new(
66
73
  name: @name, attributes: attributes, emits: @emits,
67
- direction: @direction, answers: @answers, refuses: @refuses, to: @to
74
+ direction: @direction, answers: @answers, refuses: @refuses, to: @to,
75
+ handles: @handles
68
76
  )
69
77
  end
70
78
 
@@ -116,7 +124,6 @@ module Hecks
116
124
 
117
125
  # Evaluates one operation block against a fresh builder and returns what it built;
118
126
  # `private` above doesn't reach this singleton method, since `.build` is the real entry.
119
- # rubocop:disable-next Lint/IneffectiveAccessModifier
120
127
  def self.build(name, to: nil, owner: nil, direction: :inbound, &block)
121
128
  builder = new(name, to: to, owner: owner, direction: direction)
122
129
  builder.instance_eval(&block) if block
@@ -17,6 +17,15 @@ module Hecks
17
17
  @handlers = []
18
18
  end
19
19
 
20
+ # Records the key that ties one instance's events together. A dotted path or symbol is
21
+ # kept as written; a bare aggregate name (`correlates_by Message`) is kept as its bare
22
+ # name, which `BluebookBuilder` resolves to `"Message.<identity>"` once every aggregate
23
+ # is known.
24
+ #
25
+ # @param key [Symbol, String, Module] the dotted path, or a bare aggregate name
26
+ # @return [void]
27
+ def correlates_by_impl(key) = @correlates_by = key
28
+
20
29
  # Records the event that begins a fresh instance of this process manager.
21
30
  #
22
31
  # `starts_on Transfer::TransferRequested`: a bare constant, stored as the bare event
@@ -35,9 +44,14 @@ module Hecks
35
44
  # @param event_ref [Symbol, String, Module] the event, as a bare constant (a
36
45
  # `ScopedConstant` module `ConstShim` resolves) or quoted text
37
46
  # @return [void]
38
- def ends_on_impl(event_ref)
39
- @ends_on = Naming.event_name_ref(event_ref)
40
- end
47
+ def ends_on_impl(event_ref) = (@endings ||= []) << Naming.event_name_ref(event_ref)
48
+
49
+ # Records the command that resumes one stage, written `stage=command`, as the stage
50
+ # map a resume reads. The runtime does not read it yet.
51
+ #
52
+ # @param entry [String] one `stage=command` pair, for example `"gated=GateRun.Gate"`
53
+ # @return [void]
54
+ def resumes_impl(entry) = (@resumes ||= []) << entry.to_s
41
55
 
42
56
  # Records one leg of the state machine: the event that takes it, the state(s) it
43
57
  # applies from, and the dispatches (with optional compensations) it fires.
@@ -81,7 +95,8 @@ module Hecks
81
95
  name: @name,
82
96
  correlates_by: @correlates_by,
83
97
  starts_on: @starts_on,
84
- ends_on: @ends_on,
98
+ ends_on: @endings&.first,
99
+ endings: @endings || [], resumes: @resumes || [],
85
100
  states: derived_states,
86
101
  handlers: @handlers
87
102
  )
@@ -148,19 +163,14 @@ module Hecks
148
163
  refuse_ambiguous_legs!
149
164
  end
150
165
 
166
+ # A bare name is not checked here: it may name an aggregate, which only the bluebook
167
+ # can see. `BluebookBuilder` resolves it to `"<Aggregate>.<identity>"`, or refuses it
168
+ # with `bare_correlation_message`. A dotted path is a scalar by its spelling.
151
169
  def refuse_bad_correlation!
152
- unless @correlates_by
153
- raise InvalidProcessManager, "#{@name} declares no correlates_by — " \
154
- "nothing would tie its events to one instance"
155
- end
156
-
157
- # Names a scalar (`:"end_to_end.value"`), never a whole field or value object.
158
- # A syntactic check: the dotted spelling leaves no question about the key's type.
159
- return if @correlates_by.to_s.include?(".")
170
+ return if @correlates_by
160
171
 
161
- raise InvalidProcessManager, "#{@name} correlates_by #{@correlates_by.inspect}, which names a whole " \
162
- "field rather than one of its scalars — say which one, e.g. " \
163
- "#{@correlates_by}.value"
172
+ raise InvalidProcessManager, "#{@name} declares no correlates_by — " \
173
+ "nothing would tie its events to one instance"
164
174
  end
165
175
 
166
176
  # A leg is selected by (event, current state), so two legs on the same pair would
@@ -121,6 +121,20 @@ module Hecks
121
121
  # `method_missing`/`respond_to_missing?` (via the included `WordGate`) give a
122
122
  # table-driven refusal naming the legal words, rather than a hand-typed list.
123
123
 
124
+ # ADR 0166: writes rows into `into` from this aggregate's rows, keyed by `keyed_by`.
125
+ #
126
+ # @param into [String, Symbol] the aggregate that receives the rows
127
+ # @param keyed_by [Symbol] the field both aggregates carry, which the target identifies by
128
+ # @param fields [Array<Symbol>] the fields copied into the target
129
+ # @raise [Bluebook::DSL::Malformed] if any of the three is missing or empty
130
+ def split_impl(into: nil, keyed_by: nil, fields: nil)
131
+ raise Malformed, "a split needs a target aggregate (into:)" if into.to_s.empty?
132
+ raise Malformed, "a split needs a key field (keyed_by:)" if keyed_by.to_s.empty?
133
+ raise Malformed, "a split needs at least one field (fields:)" if Array(fields).empty?
134
+
135
+ @splits << TranslationSplit.new(into.to_s, keyed_by.to_sym, Array(fields).map(&:to_sym))
136
+ end
137
+
124
138
  # Assembles the declared rules into a `TranslationAggregate`.
125
139
  #
126
140
  # @return [Bluebook::TranslationAggregate] the built per-aggregate translation
@@ -128,7 +142,7 @@ module Hecks
128
142
  TranslationAggregate.new(
129
143
  name: @name, was: @was, renames: @renames, moves: @moves, converts: @converts,
130
144
  drops: @drops, retypes: @retypes, derives: @derives, rekeys: @rekeys,
131
- backfills: @backfills
145
+ backfills: @backfills, splits: @splits
132
146
  )
133
147
  end
134
148
 
@@ -142,6 +156,7 @@ module Hecks
142
156
  @retypes = []
143
157
  @derives = []
144
158
  @rekeys = []
159
+ @splits = []
145
160
  @backfills = []
146
161
  end
147
162
 
@@ -72,7 +72,7 @@ module Hecks
72
72
 
73
73
  refuse_unadmitted_word!(keywords, context, word) if admitted.empty?
74
74
 
75
- dispatched = GenericDispatch.try(self, context, word.to_s, args, kwargs, block, rows)
75
+ dispatched = GenericDispatch.try(self, context, word.to_s, GenericDispatch::Invocation.new(args, kwargs, block), rows)
76
76
  return dispatched unless dispatched.equal?(GenericDispatch::NOT_HANDLED)
77
77
 
78
78
  raise Malformed,
@@ -25,6 +25,7 @@ require_relative "dsl/attribute_collector"
25
25
  require_relative "dsl/identity_declaration"
26
26
  require_relative "dsl/rule_reference"
27
27
  require_relative "dsl/word_gate"
28
+ require_relative "dsl/kinds"
28
29
  require_relative "dsl/value_object_builder"
29
30
  require_relative "dsl/command_builder"
30
31
  require_relative "dsl/lifecycle_builder"
@@ -17,14 +17,19 @@ module Hecks
17
17
  { value: text.to_s }
18
18
  end
19
19
 
20
- # A reference argument is passed as the bare id it names; every
21
- # other field is wrapped as a one-field value object instead.
20
+ # A reference argument is passed as the bare id it names; a list argument is passed
21
+ # as one value per item; every other field is wrapped as a one-field value object.
22
22
  def carried(plan, verb, argument, value)
23
- return v(value) unless plan && verb && plan.references?(verb, argument)
23
+ return value if reference?(plan, verb, argument)
24
+ return value.map { |item| v(item) } if list?(plan, verb, argument, value)
24
25
 
25
- value
26
+ v(value)
26
27
  end
27
28
 
29
+ def reference?(plan, verb, argument) = !!(plan && verb && plan.references?(verb, argument))
30
+
31
+ def list?(plan, verb, argument, value) = value.is_a?(Array) && !!(plan && verb && plan.list?(verb, argument))
32
+
28
33
  # A record's id is its declared identity, joined the same way the
29
34
  # runtime joins it, so there is exactly one way to name a thing.
30
35
  # Each part comes from the parent link, the walk index