hecks 2.8.0 → 3.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 (886) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +50 -7
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +32 -100
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
  25. data/lib/hecks/adapters/driven/postgres.rb +149 -136
  26. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  27. data/lib/hecks/adapters/driven/prism.rb +48 -38
  28. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  29. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  30. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  31. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  32. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  33. data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
  34. data/lib/hecks/adapters/driven.rb +5 -36
  35. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  36. data/lib/hecks/behaviors/dsl.rb +7 -25
  37. data/lib/hecks/behaviors/expectations.rb +32 -142
  38. data/lib/hecks/behaviors/ir.rb +7 -20
  39. data/lib/hecks/behaviors/rspec.rb +6 -17
  40. data/lib/hecks/behaviors/runner.rb +10 -34
  41. data/lib/hecks/behaviors.rb +4 -8
  42. data/lib/hecks/bench/cli.rb +62 -0
  43. data/lib/hecks/bench/environment.rb +71 -0
  44. data/lib/hecks/bench/postgres_probe.rb +30 -0
  45. data/lib/hecks/bench/report.rb +76 -0
  46. data/lib/hecks/bench/ruby_runner.rb +93 -0
  47. data/lib/hecks/bench/run.rb +55 -0
  48. data/lib/hecks/bench/rust_runner.rb +101 -0
  49. data/lib/hecks/bench/stats.rb +46 -0
  50. data/lib/hecks/bench/suite.rb +98 -0
  51. data/lib/hecks/bench/workload.rb +89 -0
  52. data/lib/hecks/bench.rb +17 -0
  53. data/lib/hecks/bluebook/aggregate.rb +9 -75
  54. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  55. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  56. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  57. data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
  58. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  59. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  60. data/lib/hecks/bluebook/assembly.rb +6 -45
  61. data/lib/hecks/bluebook/attribute.rb +12 -61
  62. data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
  63. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  64. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  65. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  66. data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
  67. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  68. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  69. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  70. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  71. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  73. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  74. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  75. data/lib/hecks/bluebook/capabilities.rb +17 -49
  76. data/lib/hecks/bluebook/chapter.rb +16 -50
  77. data/lib/hecks/bluebook/command.rb +23 -81
  78. data/lib/hecks/bluebook/domain_port.rb +49 -67
  79. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  80. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  81. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  82. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  83. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
  84. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
  85. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
  86. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  87. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  88. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
  89. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  90. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  91. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
  92. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  93. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  94. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  95. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  96. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  97. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  98. data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
  99. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  100. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  101. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  102. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  103. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  104. data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
  105. data/lib/hecks/bluebook/entity.rb +13 -71
  106. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  107. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  108. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  109. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  110. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  111. data/lib/hecks/bluebook/expression/resolver.rb +39 -661
  112. data/lib/hecks/bluebook/hexagon.rb +18 -33
  113. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  114. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  115. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  116. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  117. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  118. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  119. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
  120. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  121. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
  122. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  123. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
  124. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  125. data/lib/hecks/bluebook/meta_validator.rb +87 -352
  126. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  127. data/lib/hecks/bluebook/model_check.rb +122 -596
  128. data/lib/hecks/bluebook/pattern_subset.rb +49 -69
  129. data/lib/hecks/bluebook/process_manager.rb +13 -83
  130. data/lib/hecks/bluebook/project_loader.rb +3 -39
  131. data/lib/hecks/bluebook/project_register.rb +12 -60
  132. data/lib/hecks/bluebook/query.rb +27 -51
  133. data/lib/hecks/bluebook/read_model.rb +57 -81
  134. data/lib/hecks/bluebook/reference.rb +7 -41
  135. data/lib/hecks/bluebook/smoke_test.rb +9 -99
  136. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  137. data/lib/hecks/bluebook/translation.rb +26 -62
  138. data/lib/hecks/bluebook/value_object.rb +11 -36
  139. data/lib/hecks/bluebook.rb +5 -22
  140. data/lib/hecks/cache_dir.rb +4 -23
  141. data/lib/hecks/canonical_json.rb +30 -0
  142. data/lib/hecks/chapters.rb +102 -0
  143. data/lib/hecks/cli/behaviors.rb +61 -0
  144. data/lib/hecks/cli/canonicalise.rb +25 -0
  145. data/lib/hecks/cli/check_engine_agreement.rb +32 -0
  146. data/lib/hecks/cli/check_era.rb +88 -0
  147. data/lib/hecks/cli/console.rb +66 -0
  148. data/lib/hecks/cli/deploy_template_diff.rb +40 -0
  149. data/lib/hecks/cli/doc_coverage.rb +32 -0
  150. data/lib/hecks/cli/document.rb +5 -23
  151. data/lib/hecks/cli/expression_projection.rb +41 -0
  152. data/lib/hecks/cli/follow.rb +88 -0
  153. data/lib/hecks/cli/history.rb +44 -0
  154. data/lib/hecks/cli/ir.rb +4 -6
  155. data/lib/hecks/cli/mcp.rb +5 -6
  156. data/lib/hecks/cli/model_check.rb +24 -88
  157. data/lib/hecks/cli/pattern_cases.rb +47 -0
  158. data/lib/hecks/cli/present.rb +39 -0
  159. data/lib/hecks/cli/project_cli.rb +223 -64
  160. data/lib/hecks/cli/project_diagrams.rb +4 -10
  161. data/lib/hecks/cli/project_glossary.rb +44 -0
  162. data/lib/hecks/cli/reference.rb +46 -0
  163. data/lib/hecks/cli/refresh_projections.rb +44 -0
  164. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
  165. data/lib/hecks/cli/release.rb +70 -0
  166. data/lib/hecks/cli/release_gem.rb +59 -0
  167. data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
  168. data/lib/hecks/cli/rspec_shard_files.rb +66 -0
  169. data/lib/hecks/cli/run.rb +15 -61
  170. data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
  171. data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
  172. data/lib/hecks/cli/shape.rb +70 -0
  173. data/lib/hecks/cli/smoke_http.rb +230 -0
  174. data/lib/hecks/cli/smoke_test.rb +7 -19
  175. data/lib/hecks/cli/spec_example.rb +27 -0
  176. data/lib/hecks/cli/statements.rb +32 -0
  177. data/lib/hecks/cli/stores.rb +4 -6
  178. data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
  179. data/lib/hecks/cli.rb +216 -73
  180. data/lib/hecks/codemod.rb +324 -0
  181. data/lib/hecks/construct.rb +8 -34
  182. data/lib/hecks/corpus.rb +423 -0
  183. data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
  184. data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
  185. data/lib/hecks/deploy/oidc.json +82 -2
  186. data/lib/hecks/doc/reference.rb +351 -0
  187. data/lib/hecks/doors/cli_door.rb +196 -0
  188. data/lib/hecks/doors/cli_runner.rb +297 -0
  189. data/lib/hecks/{facade → doors}/command_request.rb +14 -34
  190. data/lib/hecks/doors/handle.rb +206 -0
  191. data/lib/hecks/doors/json_door.rb +132 -0
  192. data/lib/hecks/doors/launcher_options.rb +129 -0
  193. data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
  194. data/lib/hecks/doors/mcp_door_scope.rb +97 -0
  195. data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
  196. data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
  197. data/lib/hecks/doors/ruby_door.rb +77 -0
  198. data/lib/hecks/doors.rb +61 -0
  199. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  200. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  201. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  202. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  203. data/lib/hecks/embryonaut_bluebook.rb +5 -72
  204. data/lib/hecks/engine_agreement.rb +156 -0
  205. data/lib/hecks/facade.rb +23 -51
  206. data/lib/hecks/forms/app.rb +21 -76
  207. data/lib/hecks/forms/banking_presentation.rb +50 -0
  208. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  209. data/lib/hecks/forms/field_renderer.rb +17 -156
  210. data/lib/hecks/forms/field_shape.rb +31 -222
  211. data/lib/hecks/forms/html.rb +12 -47
  212. data/lib/hecks/forms/index_renderer.rb +1 -4
  213. data/lib/hecks/forms/page.rb +3 -9
  214. data/lib/hecks/forms/params.rb +14 -60
  215. data/lib/hecks/forms/port_argument.rb +2 -19
  216. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  217. data/lib/hecks/forms/record_renderer.rb +8 -75
  218. data/lib/hecks/forms/record_table.rb +7 -50
  219. data/lib/hecks/forms/reference_options.rb +3 -30
  220. data/lib/hecks/forms/value_object_shape.rb +8 -35
  221. data/lib/hecks/forms.rb +5 -33
  222. data/lib/hecks/fqn.rb +5 -12
  223. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  224. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  225. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  226. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  227. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  228. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  229. data/lib/hecks/framework.rb +11 -80
  230. data/lib/hecks/freezer.rb +5 -39
  231. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
  232. data/lib/hecks/fuzzing/combination_miner.rb +86 -0
  233. data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
  234. data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
  235. data/lib/hecks/fuzzing/differential.rb +156 -0
  236. data/lib/hecks/fuzzing/domain_generator.rb +615 -0
  237. data/lib/hecks/fuzzing/era_boundary.rb +71 -0
  238. data/lib/hecks/fuzzing/form_census.rb +136 -0
  239. data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
  240. data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
  241. data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
  242. data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
  243. data/lib/hecks/fuzzing/outside_world.rb +45 -0
  244. data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
  245. data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
  246. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
  247. data/lib/hecks/fuzzing/properties/guards.rb +190 -0
  248. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
  249. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
  250. data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
  251. data/lib/hecks/fuzzing/properties/querying.rb +175 -0
  252. data/lib/hecks/fuzzing/properties.rb +162 -0
  253. data/lib/hecks/fuzzing/qa_settings.rb +123 -0
  254. data/lib/hecks/fuzzing/replay.rb +505 -0
  255. data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
  256. data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
  257. data/lib/hecks/fuzzing/self_consistency.rb +339 -0
  258. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
  259. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
  260. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
  261. data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
  262. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
  263. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
  264. data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
  265. data/lib/hecks/fuzzing/shrinker.rb +166 -0
  266. data/lib/hecks/fuzzing/structural_skips.rb +33 -0
  267. data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
  268. data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
  269. data/lib/hecks/fuzzing/value_generator.rb +216 -0
  270. data/lib/hecks/fuzzing.rb +23 -0
  271. data/lib/hecks/grammar/evolve.rb +336 -0
  272. data/lib/hecks/grammar/expression.bluebook +15 -40
  273. data/lib/hecks/grammar/translation.bluebook +3 -6
  274. data/lib/hecks/grammar.rb +16 -41
  275. data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
  276. data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
  277. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
  278. data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
  279. data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
  280. data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
  281. data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
  282. data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
  283. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
  284. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
  285. data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
  286. data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
  287. data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
  288. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
  289. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
  290. data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
  291. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
  292. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
  293. data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
  294. data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
  295. data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
  296. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
  297. data/lib/hecks/hecks/adapters/git.adapter +7 -0
  298. data/lib/hecks/hecks/adapters/git.rb +102 -0
  299. data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
  300. data/lib/hecks/hecks/adapters/host_http.rb +65 -0
  301. data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
  302. data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
  303. data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
  304. data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
  305. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
  306. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
  307. data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
  308. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
  309. data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
  310. data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
  311. data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
  312. data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
  313. data/lib/hecks/hecks/adapters/local_files.rb +46 -0
  314. data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
  315. data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
  316. data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
  317. data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
  318. data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
  319. data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
  320. data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
  321. data/lib/hecks/hecks/adapters/shell.adapter +7 -0
  322. data/lib/hecks/hecks/adapters/shell.rb +49 -0
  323. data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
  324. data/lib/hecks/hecks/adapters/terminal.rb +74 -0
  325. data/lib/hecks/hecks/codebase.behaviors +172 -0
  326. data/lib/hecks/hecks/codebase.bluebook +2453 -0
  327. data/lib/hecks/hecks/context_map.hecksagon +13 -0
  328. data/lib/hecks/hecks/custodian.behaviors +179 -0
  329. data/lib/hecks/hecks/custodian.bluebook +1847 -0
  330. data/lib/hecks/hecks/deploy.behaviors +74 -0
  331. data/lib/hecks/hecks/deploy.world +12 -0
  332. data/lib/hecks/hecks/environments/memory.world +10 -0
  333. data/lib/hecks/hecks/governance.world +7 -0
  334. data/lib/hecks/hecks/hecks.behaviors +62 -0
  335. data/lib/hecks/hecks/hecks.bluebook +124 -0
  336. data/lib/hecks/hecks/hecks.hecksagon +390 -0
  337. data/lib/hecks/hecks/hecks.world +42 -0
  338. data/lib/hecks/ir.rb +14 -83
  339. data/lib/hecks/kernel_capabilities.rb +194 -0
  340. data/lib/hecks/language/adapter.bluebook +2 -7
  341. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  342. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  343. data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
  344. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  345. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  346. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  347. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  348. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  349. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  350. data/lib/hecks/language/bluebook/query.bluebook +19 -43
  351. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  352. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  353. data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
  354. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  355. data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
  356. data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
  357. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  358. data/lib/hecks/language/oidc.json +35 -0
  359. data/lib/hecks/language/port.bluebook +4 -17
  360. data/lib/hecks/language/translation/translation.bluebook +3 -9
  361. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  362. data/lib/hecks/language/world/wiring.bluebook +1 -3
  363. data/lib/hecks/language/world/world.bluebook +5 -7
  364. data/lib/hecks/literal.rb +8 -50
  365. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  366. data/lib/hecks/naming.rb +29 -137
  367. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
  368. data/lib/hecks/persistence_legacy_fixture.rb +113 -0
  369. data/lib/hecks/ports/access_control.rb +7 -23
  370. data/lib/hecks/ports/agent/answers.rb +5 -23
  371. data/lib/hecks/ports/agent.rb +47 -172
  372. data/lib/hecks/ports/authentication.rb +12 -39
  373. data/lib/hecks/ports/authorization.rb +16 -43
  374. data/lib/hecks/ports/clock.rb +5 -45
  375. data/lib/hecks/ports/extraction.rb +7 -12
  376. data/lib/hecks/ports/identity_assignment.rb +8 -29
  377. data/lib/hecks/ports/identity_generation.rb +6 -29
  378. data/lib/hecks/ports/identity_resolution.rb +2 -10
  379. data/lib/hecks/ports/key_vault.rb +9 -45
  380. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  381. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  382. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  383. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  384. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  385. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
  386. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  387. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
  388. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  389. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
  390. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  391. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  392. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  393. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  394. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  395. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  396. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  397. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  398. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
  399. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  400. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  401. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  402. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  403. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  404. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
  405. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  406. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
  407. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  408. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
  409. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  410. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  411. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  412. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  413. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  414. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
  415. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  416. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  417. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  418. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  419. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  420. data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
  421. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  422. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  423. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  424. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  425. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  426. data/lib/hecks/ports/persistence/state_codec.rb +47 -108
  427. data/lib/hecks/ports/persistence.rb +7 -14
  428. data/lib/hecks/ports/projection.rb +42 -84
  429. data/lib/hecks/ports/query/in_memory.rb +10 -58
  430. data/lib/hecks/ports/query/ordering.rb +11 -32
  431. data/lib/hecks/ports/query.rb +14 -37
  432. data/lib/hecks/ports.rb +2 -8
  433. data/lib/hecks/projection_files.rb +285 -0
  434. data/lib/hecks/projections/bootstrap_table.rb +12 -44
  435. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  436. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  437. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  438. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  439. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  440. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  441. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  442. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  443. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  444. data/lib/hecks/projections/deploy/fargate.rb +40 -207
  445. data/lib/hecks/projections/deploy/lambda.rb +191 -708
  446. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  447. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  448. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  449. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  450. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  451. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  452. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  453. data/lib/hecks/projections/deploy/preview/template.rb +3 -59
  454. data/lib/hecks/projections/deploy/preview.rb +2 -67
  455. data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
  456. data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
  457. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
  458. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  459. data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
  460. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  461. data/lib/hecks/projections/deploy/shared.rb +48 -147
  462. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  463. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  464. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  465. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  466. data/lib/hecks/projections/diagrams.rb +22 -584
  467. data/lib/hecks/projections/glossary/html.rb +14 -130
  468. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  469. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  470. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  471. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  472. data/lib/hecks/projections/glossary.rb +30 -222
  473. data/lib/hecks/projections/ir.rb +3 -10
  474. data/lib/hecks/projections/model/deviations.rb +16 -43
  475. data/lib/hecks/projections/model.rb +12 -51
  476. data/lib/hecks/projections/oidc.rb +12 -56
  477. data/lib/hecks/projections/parser_table.rb +13 -32
  478. data/lib/hecks/projections/reference.rb +4 -18
  479. data/lib/hecks/projections/rust_vocabulary.rb +13 -251
  480. data/lib/hecks/projections/shape.rb +3 -29
  481. data/lib/hecks/projections/statements.rb +7 -86
  482. data/lib/hecks/projections/vocabulary.rb +6 -22
  483. data/lib/hecks/projections.rb +2 -16
  484. data/lib/hecks/projector/cli_projector.rb +154 -400
  485. data/lib/hecks/projector/docs_projector.rb +10 -201
  486. data/lib/hecks/projector/exporter.rb +42 -134
  487. data/lib/hecks/projector/ir_projector.rb +2 -9
  488. data/lib/hecks/projector/narrate_projector.rb +15 -189
  489. data/lib/hecks/projector/target.rb +13 -76
  490. data/lib/hecks/projector.rb +30 -121
  491. data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
  492. data/lib/hecks/quality_control/adapters/agent.rb +58 -0
  493. data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
  494. data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
  495. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
  496. data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
  497. data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
  498. data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
  499. data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
  500. data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
  501. data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
  502. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
  503. data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
  504. data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
  505. data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
  506. data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
  507. data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
  508. data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
  509. data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
  510. data/lib/hecks/quality_control/cli/child.rb +45 -0
  511. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
  512. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
  513. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
  514. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
  515. data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
  516. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
  517. data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
  518. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
  519. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
  520. data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
  521. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
  522. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
  523. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
  524. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
  525. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
  526. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
  527. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
  528. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
  529. data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
  530. data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
  531. data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
  532. data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
  533. data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
  534. data/lib/hecks/query_ir.rb +346 -0
  535. data/lib/hecks/query_ir_mcp.rb +198 -0
  536. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  537. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  538. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  539. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  540. data/lib/hecks/query_specification/common/options.rb +2 -6
  541. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  542. data/lib/hecks/query_specification/field_path.rb +37 -77
  543. data/lib/hecks/query_specification/hop_path.rb +12 -76
  544. data/lib/hecks/release/gem_pin.rb +2 -26
  545. data/lib/hecks/release/runner/ci_publisher.rb +5 -8
  546. data/lib/hecks/release/runner/clean_tree.rb +42 -0
  547. data/lib/hecks/release/runner/commands.rb +2 -4
  548. data/lib/hecks/release/runner/console.rb +6 -0
  549. data/lib/hecks/release/runner/gem_publisher.rb +15 -9
  550. data/lib/hecks/release/runner/npm_publisher.rb +9 -53
  551. data/lib/hecks/release/runner/preflight.rb +29 -20
  552. data/lib/hecks/release/runner/published.rb +8 -26
  553. data/lib/hecks/release/runner/tagger.rb +31 -23
  554. data/lib/hecks/release/runner.rb +60 -38
  555. data/lib/hecks/rendering.rb +4 -26
  556. data/lib/hecks/router/namespace_installer.rb +15 -39
  557. data/lib/hecks/router.rb +4 -8
  558. data/lib/hecks/runtime/adapter_lookup.rb +124 -0
  559. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  560. data/lib/hecks/runtime/boot_gates.rb +3 -18
  561. data/lib/hecks/runtime/caller.rb +19 -59
  562. data/lib/hecks/runtime/capability_graph.rb +5 -21
  563. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  564. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
  565. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  566. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  567. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  568. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  569. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  570. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  571. data/lib/hecks/runtime/dependency_planning.rb +50 -104
  572. data/lib/hecks/runtime/dispatcher.rb +134 -243
  573. data/lib/hecks/runtime/entity_element.rb +40 -462
  574. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  575. data/lib/hecks/runtime/errors.rb +32 -115
  576. data/lib/hecks/runtime/event.rb +3 -25
  577. data/lib/hecks/runtime/identity.rb +18 -154
  578. data/lib/hecks/runtime/instance.rb +18 -150
  579. data/lib/hecks/runtime/interpreting.rb +14 -70
  580. data/lib/hecks/runtime/invocation.rb +28 -164
  581. data/lib/hecks/runtime/loader.rb +109 -194
  582. data/lib/hecks/runtime/outbox.rb +39 -262
  583. data/lib/hecks/runtime/policy_interpreter.rb +43 -202
  584. data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
  585. data/lib/hecks/runtime/query_interpreter.rb +122 -187
  586. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  587. data/lib/hecks/runtime/reaction_outcome.rb +89 -0
  588. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  589. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  590. data/lib/hecks/runtime/reference_hop.rb +8 -81
  591. data/lib/hecks/runtime/refusal_wording.rb +28 -87
  592. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  593. data/lib/hecks/runtime/registry/verification.rb +213 -227
  594. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  595. data/lib/hecks/runtime/registry.rb +156 -247
  596. data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
  597. data/lib/hecks/runtime/routing.rb +4 -15
  598. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  599. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  600. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  601. data/lib/hecks/runtime/tenant_check.rb +6 -68
  602. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  603. data/lib/hecks/runtime/value/admission.rb +16 -67
  604. data/lib/hecks/runtime/value/coercion.rb +162 -760
  605. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  606. data/lib/hecks/runtime/value/field_checks.rb +172 -0
  607. data/lib/hecks/runtime/value.rb +15 -84
  608. data/lib/hecks/runtime.rb +35 -69
  609. data/lib/hecks/rust_build/conformance.rb +158 -0
  610. data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
  611. data/lib/hecks/rust_build/coverage.rb +218 -0
  612. data/lib/hecks/rust_build/native_build.rb +124 -0
  613. data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
  614. data/lib/hecks/rust_build/project_rust.rb +332 -0
  615. data/lib/hecks/rust_build/wasm.rb +105 -0
  616. data/lib/hecks/rust_build/wasm_browser.rb +113 -0
  617. data/lib/hecks/rust_build.rb +144 -0
  618. data/lib/hecks/storehouse.rb +155 -582
  619. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
  620. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  621. data/lib/hecks/three_zero/forms.yml +127 -0
  622. data/lib/hecks/three_zero.rb +12 -0
  623. data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
  624. data/lib/hecks/tools/comment_style.rb +1070 -0
  625. data/lib/hecks/tools/corpus_report.rb +87 -0
  626. data/lib/hecks/tools/deploy_recipe.rb +255 -0
  627. data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
  628. data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
  629. data/lib/hecks/tools/era_projection_backfill.rb +94 -0
  630. data/lib/hecks/tools/era_reattest.rb +146 -0
  631. data/lib/hecks/tools/evolve_run.rb +189 -0
  632. data/lib/hecks/tools/fuzz_sweep.rb +373 -0
  633. data/lib/hecks/tools/heki_compaction.rb +100 -0
  634. data/lib/hecks/tools/hoist_local_givens.rb +246 -0
  635. data/lib/hecks/tools/journal_compaction.rb +89 -0
  636. data/lib/hecks/tools/oidc_manifests.rb +70 -0
  637. data/lib/hecks/tools/query_ir_run.rb +81 -0
  638. data/lib/hecks/tools/regeneration_run.rb +166 -0
  639. data/lib/hecks/tools/rust_comment_style.rb +642 -0
  640. data/lib/hecks/tools/sequence_script.rb +62 -0
  641. data/lib/hecks/tools/tail_merge.rb +117 -0
  642. data/lib/hecks/tools/tenant_provisioning.rb +142 -0
  643. data/lib/hecks/tools/translation_audit.rb +208 -0
  644. data/lib/hecks/tools/translation_scaffold.rb +131 -0
  645. data/lib/hecks/tools.rb +86 -0
  646. data/lib/hecks/vendoring/git_environment.rb +2 -8
  647. data/lib/hecks/vendoring/git_source.rb +4 -10
  648. data/lib/hecks/vendoring.rb +7 -46
  649. data/lib/hecks/version.rb +3 -14
  650. data/lib/hecks.rb +52 -90
  651. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  652. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  653. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  654. data/qa/settings.yml +66 -0
  655. data/rust/.cargo/config.toml +6 -0
  656. data/rust/.gitignore +2 -0
  657. data/rust/Cargo.lock +54 -0
  658. data/rust/Cargo.toml +61 -0
  659. data/rust/build/.cargo/config.toml +3 -0
  660. data/rust/build/.gitignore +1 -0
  661. data/rust/build/Cargo.lock +7 -0
  662. data/rust/build/Cargo.toml +19 -0
  663. data/rust/build/src/build_artifact.rs +47 -0
  664. data/rust/build/src/cargo_sync.rs +248 -0
  665. data/rust/build/src/json.rs +421 -0
  666. data/rust/build/src/lineage_pass.rs +285 -0
  667. data/rust/build/src/main.rs +51 -0
  668. data/rust/build/src/optional_pass.rs +150 -0
  669. data/rust/build/src/pipeline.rs +264 -0
  670. data/rust/build/src/reserved_names.rs +76 -0
  671. data/rust/build/src/resolve.rs +124 -0
  672. data/rust/build/src/root.rs +25 -0
  673. data/rust/build/src/sidecars.rs +73 -0
  674. data/rust/build/src/subprocess.rs +51 -0
  675. data/rust/build/src/tmp.rs +31 -0
  676. data/rust/codegen/.cargo/config.toml +3 -0
  677. data/rust/codegen/.gitignore +1 -0
  678. data/rust/codegen/Cargo.lock +7 -0
  679. data/rust/codegen/Cargo.toml +20 -0
  680. data/rust/codegen/src/attr.rs +32 -0
  681. data/rust/codegen/src/bridging.rs +481 -0
  682. data/rust/codegen/src/commands.rs +1226 -0
  683. data/rust/codegen/src/constraints.rs +109 -0
  684. data/rust/codegen/src/dependency_planning.rs +209 -0
  685. data/rust/codegen/src/domain_generator.rs +1288 -0
  686. data/rust/codegen/src/exemplar.rs +230 -0
  687. data/rust/codegen/src/expr_emitter.rs +87 -0
  688. data/rust/codegen/src/fielded.rs +192 -0
  689. data/rust/codegen/src/hecks_naming.rs +33 -0
  690. data/rust/codegen/src/json.rs +335 -0
  691. data/rust/codegen/src/json_codec.rs +697 -0
  692. data/rust/codegen/src/literal.rs +207 -0
  693. data/rust/codegen/src/main.rs +290 -0
  694. data/rust/codegen/src/manifest.rs +227 -0
  695. data/rust/codegen/src/mutations.rs +784 -0
  696. data/rust/codegen/src/naming.rs +286 -0
  697. data/rust/codegen/src/ports.rs +208 -0
  698. data/rust/codegen/src/prelude.rs +116 -0
  699. data/rust/codegen/src/queries.rs +786 -0
  700. data/rust/codegen/src/reactions.rs +532 -0
  701. data/rust/codegen/src/read_models.rs +697 -0
  702. data/rust/codegen/src/reference_specs.rs +40 -0
  703. data/rust/codegen/src/registry.rs +966 -0
  704. data/rust/codegen/src/reserved_names.rs +76 -0
  705. data/rust/codegen/src/shared.rs +93 -0
  706. data/rust/codegen/src/skip_reason.rs +25 -0
  707. data/rust/codegen/src/types.rs +362 -0
  708. data/rust/host/.cargo/config.toml +3 -0
  709. data/rust/host/.gitignore +1 -0
  710. data/rust/host/Cargo.lock +4297 -0
  711. data/rust/host/Cargo.toml +61 -0
  712. data/rust/host/HECKS_RELEASE +1 -0
  713. data/rust/host/rds-ca-bundle.pem +2736 -0
  714. data/rust/host/src/api.rs +1596 -0
  715. data/rust/host/src/approval.rs +652 -0
  716. data/rust/host/src/auth.rs +1287 -0
  717. data/rust/host/src/bin/expr_harness.rs +46 -0
  718. data/rust/host/src/bin/lineage_harness.rs +119 -0
  719. data/rust/host/src/bin/mint_harness.rs +135 -0
  720. data/rust/host/src/checkout.rs +265 -0
  721. data/rust/host/src/dispatch.rs +1443 -0
  722. data/rust/host/src/expr_json.rs +1117 -0
  723. data/rust/host/src/field_hints.rs +52 -0
  724. data/rust/host/src/ir.rs +733 -0
  725. data/rust/host/src/journal.rs +874 -0
  726. data/rust/host/src/lambda_client.rs +378 -0
  727. data/rust/host/src/log.rs +147 -0
  728. data/rust/host/src/main.rs +474 -0
  729. data/rust/host/src/mint.rs +1865 -0
  730. data/rust/host/src/payments/keystore.rs +330 -0
  731. data/rust/host/src/payments/tests.rs +1400 -0
  732. data/rust/host/src/payments.rs +767 -0
  733. data/rust/host/src/presentation.rs +698 -0
  734. data/rust/host/src/presentation_write.rs +1431 -0
  735. data/rust/host/src/query_step.rs +149 -0
  736. data/rust/host/src/rate_limit.rs +904 -0
  737. data/rust/host/src/reference_transform.rs +241 -0
  738. data/rust/host/src/reference_validate.rs +338 -0
  739. data/rust/host/src/resend.rs +296 -0
  740. data/rust/host/src/secrets.rs +106 -0
  741. data/rust/host/src/server.rs +663 -0
  742. data/rust/host/src/storage_shape.rs +175 -0
  743. data/rust/host/src/test_pg.rs +40 -0
  744. data/rust/host/src/ui_schema.rs +1351 -0
  745. data/rust/host/src/wasm_runner.rs +191 -0
  746. data/rust/host/src/web/newsletter/cooldown.rs +126 -0
  747. data/rust/host/src/web/newsletter/tests.rs +104 -0
  748. data/rust/host/src/web/newsletter.rs +310 -0
  749. data/rust/host/src/web/newsletter_send.rs +357 -0
  750. data/rust/host/src/web/registrations.rs +1505 -0
  751. data/rust/host/src/web.rs +2937 -0
  752. data/rust/lsp/.gitignore +1 -0
  753. data/rust/lsp/Cargo.lock +7 -0
  754. data/rust/lsp/Cargo.toml +16 -0
  755. data/rust/lsp/README.md +133 -0
  756. data/rust/lsp/src/diagnostics.rs +165 -0
  757. data/rust/lsp/src/json.rs +385 -0
  758. data/rust/lsp/src/main.rs +399 -0
  759. data/rust/lsp/src/outline.rs +177 -0
  760. data/rust/lsp/src/rpc.rs +67 -0
  761. data/rust/parser/.cargo/config.toml +5 -0
  762. data/rust/parser/.gitignore +1 -0
  763. data/rust/parser/Cargo.lock +7 -0
  764. data/rust/parser/Cargo.toml +21 -0
  765. data/rust/parser/src/build/closed_sets.rs +27 -0
  766. data/rust/parser/src/build/identity.rs +276 -0
  767. data/rust/parser/src/build/mod.rs +12 -0
  768. data/rust/parser/src/build/naming.rs +141 -0
  769. data/rust/parser/src/build/pattern_subset.rs +161 -0
  770. data/rust/parser/src/build/query_derive.rs +72 -0
  771. data/rust/parser/src/build/query_inference.rs +269 -0
  772. data/rust/parser/src/build/query_options.rs +100 -0
  773. data/rust/parser/src/build/read_model.rs +94 -0
  774. data/rust/parser/src/build/references.rs +32 -0
  775. data/rust/parser/src/canonical.rs +114 -0
  776. data/rust/parser/src/diag.rs +55 -0
  777. data/rust/parser/src/emit.rs +953 -0
  778. data/rust/parser/src/expr/ast_json.rs +147 -0
  779. data/rust/parser/src/expr/evaluator.rs +81 -0
  780. data/rust/parser/src/expr/mod.rs +84 -0
  781. data/rust/parser/src/expr/resolver.rs +497 -0
  782. data/rust/parser/src/ir.rs +387 -0
  783. data/rust/parser/src/keywords.rs +585 -0
  784. data/rust/parser/src/lex.rs +662 -0
  785. data/rust/parser/src/main.rs +252 -0
  786. data/rust/parser/src/parse/aggregate.rs +612 -0
  787. data/rust/parser/src/parse/chapter.rs +517 -0
  788. data/rust/parser/src/parse/command.rs +637 -0
  789. data/rust/parser/src/parse/domain_port.rs +127 -0
  790. data/rust/parser/src/parse/entity.rs +527 -0
  791. data/rust/parser/src/parse/file.rs +67 -0
  792. data/rust/parser/src/parse/hecksagon.rs +231 -0
  793. data/rust/parser/src/parse/lifecycle.rs +162 -0
  794. data/rust/parser/src/parse/mod.rs +1262 -0
  795. data/rust/parser/src/parse/policy.rs +87 -0
  796. data/rust/parser/src/parse/process_manager.rs +305 -0
  797. data/rust/parser/src/parse/query.rs +100 -0
  798. data/rust/parser/src/parse/read_model.rs +214 -0
  799. data/rust/parser/src/parse/value_object.rs +250 -0
  800. data/rust/parser/src/ruby_value.rs +422 -0
  801. data/rust/project/bridging.rb +257 -0
  802. data/rust/project/commands.rb +877 -0
  803. data/rust/project/constraints.rb +86 -0
  804. data/rust/project/dependency_planning.rb +178 -0
  805. data/rust/project/domain_generator.rb +980 -0
  806. data/rust/project/exemplar.rb +148 -0
  807. data/rust/project/expr_emitter.rb +72 -0
  808. data/rust/project/fielded.rb +141 -0
  809. data/rust/project/json_codec.rb +641 -0
  810. data/rust/project/mutations.rb +721 -0
  811. data/rust/project/naming.rb +205 -0
  812. data/rust/project/ports.rb +65 -0
  813. data/rust/project/queries.rb +493 -0
  814. data/rust/project/reactions.rb +317 -0
  815. data/rust/project/read_models.rb +690 -0
  816. data/rust/project/reference_specs.rb +27 -0
  817. data/rust/project/registry.rb +396 -0
  818. data/rust/project/skip_reason.rb +29 -0
  819. data/rust/project/types.rb +225 -0
  820. data/rust/project/write_if_changed.rb +83 -0
  821. data/rust/project.rb +30 -0
  822. data/rust/project_rust_pipeline.rb +383 -0
  823. data/rust/src/exemplar/commands.rs +279 -0
  824. data/rust/src/exemplar/constraints.rs +18 -0
  825. data/rust/src/exemplar/fielded.rs +280 -0
  826. data/rust/src/exemplar/json.rs +277 -0
  827. data/rust/src/exemplar/mod.rs +17 -0
  828. data/rust/src/exemplar/mutations.rs +80 -0
  829. data/rust/src/exemplar/queries.rs +33 -0
  830. data/rust/src/exemplar/reactions.rs +88 -0
  831. data/rust/src/exemplar/read_models.rs +48 -0
  832. data/rust/src/exemplar/registry.rs +166 -0
  833. data/rust/src/exemplar/types.rs +44 -0
  834. data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
  835. data/rust/src/kernel/attribute_shapes/list.rs +18 -0
  836. data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
  837. data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
  838. data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
  839. data/rust/src/kernel/cli.rs +585 -0
  840. data/rust/src/kernel/dispatch.rs +1090 -0
  841. data/rust/src/kernel/expr.rs +458 -0
  842. data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
  843. data/rust/src/kernel/expression_operators/comparison.rs +48 -0
  844. data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
  845. data/rust/src/kernel/expression_operators/logical.rs +13 -0
  846. data/rust/src/kernel/expression_operators/membership.rs +18 -0
  847. data/rust/src/kernel/expression_operators/mod.rs +68 -0
  848. data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
  849. data/rust/src/kernel/expression_operators/positional.rs +126 -0
  850. data/rust/src/kernel/expression_operators/presence.rs +101 -0
  851. data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
  852. data/rust/src/kernel/expression_operators/sized.rs +35 -0
  853. data/rust/src/kernel/expression_operators/text.rs +79 -0
  854. data/rust/src/kernel/expression_operators/to_string.rs +18 -0
  855. data/rust/src/kernel/json.rs +779 -0
  856. data/rust/src/kernel/mod.rs +133 -0
  857. data/rust/src/kernel/named_query.rs +219 -0
  858. data/rust/src/kernel/orchestrate.rs +1810 -0
  859. data/rust/src/kernel/pattern.rs +307 -0
  860. data/rust/src/kernel/query_comparators.rs +206 -0
  861. data/rust/src/kernel/query_ordering.rs +103 -0
  862. data/rust/src/kernel/read_model.rs +914 -0
  863. data/rust/src/kernel/reference_lookup.rs +149 -0
  864. data/rust/src/kernel/repository.rs +468 -0
  865. data/rust/src/kernel/routing.rs +612 -0
  866. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
  867. data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
  868. data/rust/src/kernel/vocab/field_hint.rs +70 -0
  869. data/rust/src/kernel/vocab/mod.rs +20 -0
  870. data/rust/src/kernel/vocab/query_comparator.rs +65 -0
  871. data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
  872. data/rust/src/lib.rs +8 -0
  873. data/rust/src/main.rs +16 -0
  874. data/rust/web/.gitignore +1 -0
  875. data/rust/web/Cargo.lock +119 -0
  876. data/rust/web/Cargo.toml +18 -0
  877. data/rust/web/src/lib.rs +8 -0
  878. metadata +478 -12
  879. data/lib/hecks/facade/cli_door.rb +0 -178
  880. data/lib/hecks/facade/cli_runner.rb +0 -271
  881. data/lib/hecks/facade/handle.rb +0 -293
  882. data/lib/hecks/facade/json_door.rb +0 -247
  883. data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
  884. data/lib/hecks/facade/surface/chapter.rb +0 -116
  885. data/lib/hecks/facade/surface.rb +0 -61
  886. data/lib/hecks/mcp_door_scope.rb +0 -176
@@ -1,15 +1,5 @@
1
- # ITS OWN BOUNDED CONTEXT, booted centrally like `Deploy` — never
2
- # attached via `uses_framework` (a framework member's aggregate folds
3
- # into the ATTACHING domain's own per-boot registry, framework.rb:43-66
4
- # — since hecks gives each tenant its own separate `Runtime.boot`, a
5
- # framework-attached Tenant would exist as a single-row copy inside
6
- # EVERY tenant's own boot, never as one cross-tenant list, defeating
7
- # this domain's whole point). `Deploy::Tenant` (deploy.bluebook) stays
8
- # a SEPARATE, validation-only aggregate — a shape check before
9
- # provisioning; this is the durable, reactable runtime fact that
10
- # aggregate's own comment named and deliberately deferred. Two
11
- # different meanings of "Tenant," on purpose, translated at the one
12
- # explicit seam `tenancy.hecksagon`'s own `translates` line names.
1
+ # Its own bounded context, booted centrally like `Deploy` and never attached via `uses_framework`:
2
+ # an attached Tenant would be a single-row copy in every tenant's boot, not one cross-tenant list.
13
3
  Hecks.bluebook "Tenancy" do
14
4
  vision "Which tenants exist, which realm and storage each one owns, and whether each is currently allowed to run, is one queryable, historical fact — not scattered across a world-file overlay and a validation-only command."
15
5
 
@@ -27,7 +17,7 @@ Hecks.bluebook "Tenancy" do
27
17
  attribute :status, Status, default: { value: "Active" }
28
18
 
29
19
  value_object "Slug" do
30
- attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
20
+ attribute :value, String, pattern: '\A[a-z][a-z0-9_]*\z'
31
21
  invariant("a tenant slug is named") { !value.to_s.empty? }
32
22
  end
33
23
 
@@ -42,7 +32,7 @@ Hecks.bluebook "Tenancy" do
42
32
  end
43
33
 
44
34
  value_object "Schema" do
45
- attribute :value, String, pattern: '^[a-z][a-z0-9_]*$'
35
+ attribute :value, String, pattern: '\A[a-z][a-z0-9_]*\z'
46
36
  invariant("a schema is named") { !value.to_s.empty? }
47
37
  end
48
38
 
@@ -50,14 +40,8 @@ Hecks.bluebook "Tenancy" do
50
40
  attribute :value, String, one_of: ["Active", "Suspended", "Retired"]
51
41
  end
52
42
 
53
- # FIRES AFTER PROVISIONING, NEVER BEFORE — a pure record with no
54
- # side effects, dispatched by `tenancy.hecksagon`'s own `translates`
55
- # reaction once `Deploy::Tenant.Provision`'s adapter has already
56
- # written the world overlay and proven the domain boots. Driving
57
- # provisioning FROM this command's own emission would need a
58
- # process manager reacting to it — the exact durable-saga cost
59
- # `deploy.bluebook`'s own `Tenant` aggregate comment already argued
60
- # three local, idempotent, single-process steps don't need.
43
+ # Fires after provisioning, never before: driving provisioning from this command's emission
44
+ # would need a process manager, the durable-saga cost `deploy.bluebook` argues against.
61
45
  command "Register" do
62
46
  goal "Record that a tenant now exists, after its shape has been validated and its schema provisioned"
63
47
 
@@ -74,13 +58,8 @@ Hecks.bluebook "Tenancy" do
74
58
  emits "TenantRegistered"
75
59
  end
76
60
 
77
- # RECORD-ONLY — nothing today reads `status` before dispatch or
78
- # boot, so suspending a tenant here does not yet stop anything from
79
- # running. Spelled out in this command's own `goal`, not just a
80
- # comment, so it survives into generated docs/corpus rather than
81
- # quietly reading as enforced when it isn't — the exact "a dial
82
- # says a check runs when nothing runs it" defect class this
83
- # project has already been burned by once.
61
+ # Record-only: nothing reads `status` before dispatch or boot yet. Stated in the `goal` too,
62
+ # so generated docs do not read it as enforced.
84
63
  command "Suspend" do
85
64
  goal "Record that a tenant should no longer be treated as active — nothing yet enforces this at dispatch or boot time"
86
65
 
@@ -101,11 +80,8 @@ Hecks.bluebook "Tenancy" do
101
80
  emits "TenantReactivated"
102
81
  end
103
82
 
104
- # RECORD-ONLY, DELIBERATELY — dropping a live Postgres schema as an
105
- # automatic side effect of a command handler would break the pure,
106
- # no-adapter-calls-from-a-handler shape every other command in this
107
- # corpus holds to. Real teardown, if ever built, is its own
108
- # separate, deliberately reviewed tool — never implicit here.
83
+ # Record-only: dropping a live schema from a command handler would break the pure, no-adapter
84
+ # handler shape. Teardown, if built, is a separate reviewed tool.
109
85
  command "Retire" do
110
86
  goal "Record that a tenant is permanently done — real schema teardown is a deliberately separate, manually-run tool, never automatic here"
111
87
 
@@ -1,30 +1,13 @@
1
1
  Hecks.hecksagon "Tenancy" do
2
2
  Tenancy::Tenant.persisted_by("LocalStorage")
3
3
 
4
- # THE TRANSLATION SEAM — the one explicit place Deploy's "Tenant"
5
- # (a validated request) becomes Tenancy's "Tenant" (a durable fact).
6
- # `on` deliberately omits the "Deploy::" prefix: PolicyInterpreter
7
- # matches by event name plus the emitting aggregate's own demodulised
8
- # name only, never the domain (confirmed live — a domain-qualified
9
- # `on` silently never matches).
4
+ # The one seam where Deploy's "Tenant" (a validated request) becomes Tenancy's "Tenant" (a fact).
5
+ # `on` omits the "Deploy::" prefix: PolicyInterpreter matches event and aggregate name only.
6
+ # `with:` is required: the event payload also carries the port's dispatch-time args, which
7
+ # `Register` does not declare and would refuse.
10
8
  #
11
- # `with:` IS REQUIRED, confirmed live — `TenantProvisioned`'s own
12
- # payload is the ANSWER (slug/domain/realm/schema) merged with the
13
- # port operation's OWN dispatch-time args (database/adapter,
14
- # PortOperationInterpreter#ask's `ctx.args.merge(spread(answer))`),
15
- # so the whole payload forwarded verbatim carries two fields
16
- # `Register` never declares and gets refused outright.
17
- # CHECKED TOGETHER, NOT IN ISOLATION — `bin/model_check`'s own
18
- # `deaf_policy` check only sees ONE domain's own emitted events by
19
- # default, which would flag this reaction as deaf (it reacts to a
20
- # FOREIGN event, not one Tenancy itself emits). Fixed by
21
- # `global_emitted_events:`, a cross-domain set `bin/model_check`
22
- # builds across every target it boots in one run — run `bin/model_check
23
- # lib/hecks/deploy lib/hecks/tenancy` (both targets, one invocation),
24
- # not each directory separately, or this reads as a false positive
25
- # again. Neither `deploy` nor `tenancy` is in
26
- # `Hecks::Corpus::MODEL_CHECK_KINDS`, so the automatic sweep never
27
- # reaches this at all, checked or not.
9
+ # Check with `hecks model_check lib/hecks/deploy lib/hecks/tenancy` in one run; alone, the
10
+ # reaction to a foreign event reads as a deaf policy.
28
11
  translates "RegisterProvisionedTenant" do
29
12
  on Tenant::TenantProvisioned
30
13
  trigger Tenant::Register, with: { slug: :slug, domain: :domain, realm: :realm, schema: :schema }
@@ -0,0 +1,127 @@
1
+ # Each bin/ script and exe/hecks route, and the hecks 3.0 form that replaces it: the verb spelling the
2
+ # 3.0 launcher answers to (ADR 0080, section 7), with QualityControl verbs after `hecks quality_control`.
3
+ ---
4
+ argument_gate_matrix: hecks argument_gate_matrix [--confirm] (writes only with --confirm)
5
+ backfill_era_projections: hecks backfill_projections <domain>
6
+ behaviors: hecks run_behaviors subject=<path>
7
+ bench: hecks bench [domains=pizzas,banking] [targets=] [iterations=1000] [warmup=200]
8
+ [runs=3] [rust_binary=] [format=markdown] [output=]
9
+ canonicalise: hecks canonicalise <file.json>
10
+ check_engine_agreement: hecks check_engine_agreement
11
+ check_era: hecks check_era <url> expected=era-file [timeout=10]
12
+ codemod_hoist_local_givens: hecks hoist_local_givens --confirm
13
+ codemod_implicit_append_fields: hecks drop_implicit_append_fields --confirm
14
+ compact: hecks compact <domain> [aggregates=A,B] --confirm
15
+ console: hecks console [subject=<domain>]
16
+ corpus: hecks rust_domains; hecks regen_order; hecks corpus_rust_coverage
17
+ deploy_template_diff: hecks deploy diff before=a.yaml after=b.yaml [--json] [--strict]
18
+ doc_coverage: hecks measure_doc_coverage
19
+ docs: hecks docs [domain-path] [aggregate]
20
+ evolve: hecks word_status; hecks propose <word> context=X [body=none] [inner=] [opens=]
21
+ [fills=]; hecks admit|deprecate|retire <word> context=X; hecks rename <word> context=X
22
+ new_name=Y; hecks propose_argument <word> context=X kind=K [required=false] [at=N]
23
+ [named=] [fills=] [pairs_shape=]; hecks admit_argument|deprecate_argument|retire_argument
24
+ <word> context=X [at=N] [named=]
25
+ expression_projection: hecks project_expression_tables [--stdout]
26
+ follow: hecks follow <domain> [aggregate=Name] [since=N] [interval=0.5] [wait=N] [--from-now]
27
+ fuzz: hecks fuzz [domain] [seeds=20] [steps=30] [workers=] [adapter=memory]
28
+ generate: hecks generate_sequence <domain> [seed=1] [steps=30] [adversarial=0.0]
29
+ hecks_mcp_door: hecks mcp [--stdio]
30
+ hecks_query_ir_mcp: hecks serve_query_ir_mcp
31
+ heki_compact: hecks compact_heki <domain> [aggregates=A,B] --confirm
32
+ history: hecks history <domain>
33
+ ir: hecks ir <domain> [--translations] | hecks ir --meta
34
+ lint_deploy_recipes: hecks deploy lint [makefiles=a,b]
35
+ merge_tail: hecks merge_tail <domain> winners=id:old,id:new --confirm
36
+ model_check: hecks model_check [--strict] [--profile client] [<domain> …]
37
+ narrate: hecks narrate [domain-path] [aggregate]
38
+ pattern-cases: hecks record_pattern_cases
39
+ present: hecks present [port=4567]
40
+ project: hecks refresh_projections subject=<domain>
41
+ project_bootstrap_table: hecks project_bootstrap_table
42
+ project_cli: hecks project_cli [domain-path …]
43
+ project_deploy: hecks deploy project <domain> [tenant=] [schema=] [out=] [environment=]
44
+ project_diagrams: hecks project_diagrams <domain-path> <ChapterName>
45
+ project_field_hints: hecks project_field_hints
46
+ project_glossary: hecks glossary <domain> chapter=Name
47
+ project_kernel_capabilities: hecks project_kernel_capabilities
48
+ project_model: hecks project_model
49
+ project_oidc: hecks deploy project_oidc [domains=a,b]
50
+ project_parser_table: hecks project_parser_table
51
+ project_refusal_wording: hecks project_refusal_wording
52
+ project_reserved_names: hecks project_reserved_names
53
+ project_rust: hecks project_rust <domain>
54
+ project_rust_vocabulary: hecks project_rust_vocabulary
55
+ project_tenant: hecks deploy provision <domain_dir> slug=s domain= realm= schema=
56
+ database= [adapter=PostgresEra]; hecks deploy reprovision <tenant> directory= database=
57
+ [adapter=PostgresEra]
58
+ project_vocabulary: hecks project_vocabulary
59
+ project_wasm: hecks build_wasm <domain>
60
+ project_wasm_browser: hecks build_browser_wasm <domain>
61
+ qa_concurrency_racer: not user-facing; ProcessPool starts it as hecks quality_control
62
+ race domain= database= schema= verb= step_arguments=
63
+ qa_discover_external_domains: hecks quality_control discover_external_domains [arguments="--projects-dir
64
+ ~/Projects --max-depth 3 --known-path PATH …"]
65
+ qa_domain_novelty: hecks quality_control judge_novelty <domain> [arguments="--against
66
+ PATH …"]
67
+ qa_generated_domains: hecks quality_control check_generated_domains [arguments="--domains
68
+ 3 --start N --forms a,b --seeds 5 --steps 25 --adversarial 0.3 --rust --shrink-budget
69
+ 200 --domain-shrink-budget 40 --promote dir --name N --from-dials --blueprint F
70
+ --source F"]
71
+ qa_log_bug: hecks quality_control log sweep=<sweep id> reference= sequence=N title=
72
+ demonstration= symptom= expectation= submitter= [tags=a,b] [name=] [reproduced=yes|no]
73
+ qa_mine_combinations: hecks quality_control mine_combinations [arguments="--candidates
74
+ 3 --rust --seeds 5 --steps 25 --adversarial 0.3 --repair-rounds 1 --agent CMD --from
75
+ DIR --against PATH --brief"]
76
+ qa_open_pr: hecks quality_control patch.open bug=BUG#n number=N url=… branch=… commit=SHA
77
+ title=… [now=]; hecks quality_control improvement.open [angle=ANGLE-n] number=N
78
+ url=… branch=… title=… [now=]
79
+ qa_postgres_migrate: hecks quality_control migrate_ledger_from_heki domain=<domain_dir>
80
+ data=<heki_dir> [arguments="[aggregate …] --force"] (a dry run without --force)
81
+ qa_postgres_role: hecks quality_control create_ledger_role <database> [role=hecks_qa]
82
+ qa_pr_check: hecks quality_control check_pull_requests
83
+ qa_seed_angles: hecks quality_control angle.seed
84
+ qa_seed_targets: hecks quality_control target.seed
85
+ qa_sweep: hecks quality_control ask run [target=] [arguments="--all --seeds N --steps
86
+ N --adversarial F --role-draw F --dry-run F --self-consistency BOOL --modes a,b
87
+ --persistence-parity --no-parity"]; hecks quality_control release <target> [now=]
88
+ [next_streak=] [capabilities=] [yield_score=]
89
+ qa_tick: hecks quality_control tick
90
+ query_ir: hecks ir_constructs [names=a,b]; hecks ir_duplicates [domains=a,b] [--meta];
91
+ hecks ir_impact name=N field=F
92
+ reattest_era: hecks reattest <domain> era=N --confirm
93
+ reference: hecks project_reference
94
+ refresh_rspec_runtime_baseline: hecks refresh_runtime_baseline [workers=6] [from_run=ID]
95
+ regen_codegen_domains: hecks regenerate_corpus [--check]
96
+ regenerate_persistence_legacy_fixtures: hecks regenerate_legacy_fixtures --confirm
97
+ release: hecks publish [--gem-only] [--npm-only] [--npm-local] [--no-wait] --confirm
98
+ (without --confirm, the old --dry-run)
99
+ release_gem: hecks publish_gem --confirm
100
+ rspec_io_parallel_files: hecks list_io_parallel_specs exclude=REGEX [tags=] [check=file];
101
+ hecks write_io_parallel_spec_list exclude=REGEX [tags=] write=file --confirm
102
+ rspec_shard_files: hecks shard_specs group=1 groups=N [runtime_log=]
103
+ run: hecks run [domain] <verb [name=value …] | script.json | - | '{"steps":[…]}'>
104
+ rust_conformance: hecks check_conformance <domain> script=steps.json [artifact=native]
105
+ rust_conformance_fuzz: hecks fuzz_conformance <domain> artifact=native [seeds=10]
106
+ [steps=25]
107
+ rust_coverage: hecks rust_coverage <module> [codegen=ruby]; hecks check_coverage_allowlist
108
+ rust_kernel_coverage: hecks measure_kernel_coverage
109
+ scaffold_translation: hecks scaffold_translation <domain>
110
+ seed_semantics_corpus: hecks seed_semantics_corpus [fixture=name]
111
+ shape: hecks shape <domain>
112
+ smoke_http: hecks smoke_http path=/p [url=] [header=] [scheme=timestamped]
113
+ [payload=] [payload_file=] [health_path=] [state_path=]
114
+ smoke_test: hecks smoke_test [domain]
115
+ spec_example: hecks run_spec_example file=path example=text
116
+ standardize_comments: hecks report_comments paths=a,b [only=] [--json] [top=20]; hecks
117
+ check_comments paths=…; hecks fix_comments paths=… --confirm; hecks write_comment_baseline
118
+ --confirm; hecks check_comments_unchanged ref=REF
119
+ standardize_comments_rust: hecks report_rust_comments paths=a,b [only=] [--json] [top=N];
120
+ hecks check_rust_comments paths=… [only=]; hecks fix_rust_comments paths=… [only=]
121
+ --confirm
122
+ statements: hecks statements <domain> chapter=Name
123
+ stores: hecks stores <domain>
124
+ stress_concurrency_specs: hecks stress_concurrency [runs=30] [parallel=] [seed_start=1]
125
+ translation_audit: hecks audit_translation <domain>; hecks approve_translation <domain>
126
+ [snapshot=] [host_version=] [rehearsal=pass|fail] [rehearsed_at=] --confirm
127
+ vendor_bluebook: hecks vendor <package[@version]> [from=path] [root=path]
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Hecks
6
+ # The table of what each retired `bin/` script became in hecks 3.0.0 (ADR 0080): a command on
7
+ # the Hecks domain, run through `exe/hecks`. `docs/tools.md` is pinned to it.
8
+ module ThreeZero
9
+ # Each retired script's name mapped to the 3.0 form that replaced it.
10
+ FORMS = YAML.safe_load_file(File.join(__dir__, "three_zero/forms.yml")).freeze
11
+ end
12
+ end
@@ -0,0 +1,316 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hecks"
4
+ require "hecks/fuzzing"
5
+ require "json"
6
+ require "fileutils"
7
+ require_relative "../tools"
8
+
9
+ module Hecks
10
+ module Tools
11
+ # Generates the argument-gate ordering matrix: for each adjacent pair of gates a command
12
+ # can violate, one input violating both, with Ruby's refusal recorded as the expected answer.
13
+ # A row is kept only when Ruby's dispatch trace shows the earlier gate refused (ADR 0010).
14
+ #
15
+ # hecks argument_gate_matrix # report only
16
+ # hecks argument_gate_matrix --write # rewrite the matrix + fixtures
17
+ module ArgumentGateMatrix
18
+ # Domains chosen for the argument shapes they carry: value objects, references, roles,
19
+ # entity commands, closed sets, and an identity key colliding with an argument.
20
+ DOMAINS = %w[
21
+ examples/banking
22
+ examples/pizzas
23
+ examples/roster
24
+ examples/chess
25
+ qa/stress_domains/nested_pieces
26
+ qa/stress_domains/ledger_ordering
27
+ ].freeze
28
+
29
+ MATRIX_FILE = "spec/corpus/argument_gate_order/matrix.json"
30
+
31
+ FIXTURE_NOTE = "GENERATED by hecks argument_gate_matrix (roadmap D2) — one step per adjacent pair of " \
32
+ "argument-gate steps this domain's own commands can violate, each input violating BOTH, so " \
33
+ "the refusal that wins is the EARLIER declared step's. Ruby's own answers are pinned in " \
34
+ "spec/corpus/argument_gate_order/matrix.json; this file holds the Rust port to the same rows " \
35
+ "through the ordinary conformance harness. Do not hand-edit — re-run " \
36
+ "hecks argument_gate_matrix --confirm."
37
+
38
+ # Gate order comes from the vocabulary table, so reordering it reorders the pairs.
39
+ AGGREGATE_ORDER = Hecks::Vocabulary.symbols("AggregateDispatchOrder").map(&:to_s)
40
+ ENTITY_ORDER = Hecks::Vocabulary.symbols("EntityDispatchOrder").map(&:to_s)
41
+ # `decode_arguments` is a no-op in Ruby, so no input can violate it.
42
+ GATES = %w[refuse_unknown_arguments refuse_absent_arguments normalize_args refuse_role_mismatch resolve_references].freeze
43
+ # The identity-resolution step that follows the gates in both orders.
44
+ SETTLES = { "aggregate" => "hydrate", "entity" => "hydrate_parent" }.freeze
45
+
46
+ # A `Random` whose no-argument `rand` is a constant above every "generate something invalid"
47
+ # probability in `ValueGenerator`, so generated payloads are always valid.
48
+ class SteadyRandom
49
+ def initialize(seed) = @random = Random.new(seed)
50
+
51
+ def rand(limit = nil) = limit.nil? ? 0.99 : @random.rand(limit)
52
+
53
+ def bytes(count) = @random.bytes(count)
54
+ end
55
+
56
+ module_function
57
+
58
+ def order_for(kind) = kind == "entity" ? ENTITY_ORDER : AGGREGATE_ORDER
59
+
60
+ def base_args(command, aggregate, random)
61
+ command.attributes.to_h do |attribute|
62
+ [attribute.name.to_s, Hecks::Fuzzing::ValueGenerator.value_for(attribute, aggregate, random: random, known_ids: {})]
63
+ end
64
+ rescue ArgumentError
65
+ nil
66
+ end
67
+
68
+ def identity_args(construct, aggregate, random)
69
+ Array(construct.identified_by).to_h do |path|
70
+ head = path.to_s.split(".").first
71
+ attribute = construct.attributes.find { |a| a.name.to_s == head }
72
+ value = attribute && Hecks::Fuzzing::ValueGenerator.value_for(attribute, aggregate, random: random, known_ids: {})
73
+ [head, value || "no-such-#{head}"]
74
+ end
75
+ rescue ArgumentError
76
+ {}
77
+ end
78
+
79
+ # `to:`/`with:` are dispatch envelope keywords, so an attribute with either name is read as
80
+ # a route; corrupting it would exercise envelope parsing, not an argument gate.
81
+ ENVELOPE_KEYS = %w[to with].freeze
82
+
83
+ def corruptible(command)
84
+ command.attributes.reject { |a| a.list? || a.reference? || ENVELOPE_KEYS.include?(a.name.to_s) }
85
+ end
86
+
87
+ def droppable(command)
88
+ command.attributes.reject { |a| a.optional? || a.list? || ENVELOPE_KEYS.include?(a.name.to_s) }
89
+ end
90
+
91
+ def live_gates(command, kind)
92
+ gates = ["refuse_unknown_arguments"]
93
+ gates << "refuse_absent_arguments" if droppable(command).any?
94
+ gates << "normalize_args" if corruptible(command).any?
95
+ gates << "refuse_role_mismatch" unless command.role.to_s.empty?
96
+ gates << "resolve_references" if command.attributes.any?(&:reference?)
97
+ gates << SETTLES.fetch(kind) unless kind == "aggregate" && command.creates?
98
+ gates
99
+ end
100
+
101
+ MISMATCHED_ROLE = "a role this caller does not hold"
102
+
103
+ # Mutates `args` to violate `step`; returns a description of the violation, or nil if the
104
+ # command cannot violate it.
105
+ def violate!(step, args, command, aggregate, random)
106
+ case step
107
+ when "refuse_unknown_arguments" then violate_unknown!(args, random)
108
+ when "refuse_absent_arguments" then violate_absent!(args, command)
109
+ when "normalize_args" then violate_normalize!(args, command, aggregate, random)
110
+ when "refuse_role_mismatch" then MISMATCHED_ROLE
111
+ when "resolve_references" then violate_reference!(args, command)
112
+ # The world is empty, so every acting command addresses a missing record.
113
+ when "hydrate", "hydrate_parent" then "no record exists"
114
+ end
115
+ end
116
+
117
+ def violate_unknown!(args, random)
118
+ name, value = Hecks::Fuzzing::InvalidValueGenerator.undeclared_argument(random: random)
119
+ args[name.to_s] = value
120
+ name.to_s
121
+ end
122
+
123
+ def violate_absent!(args, command)
124
+ dropped = droppable(command).first or return nil
125
+
126
+ args.delete(dropped.name.to_s)
127
+ dropped.name.to_s
128
+ end
129
+
130
+ # Corrupts one attribute with a wrong value both engines word identically. It avoids
131
+ # `InvalidValueGenerator.corrupt`, whose composite-value-object and Array shapes render
132
+ # differently in Ruby and Rust, and corrupts a declared value-object field instead.
133
+ def violate_normalize!(args, command, aggregate, _random)
134
+ attribute = corruptible(command).find { |a| args.key?(a.name.to_s) } || corruptible(command).first
135
+ return nil unless attribute
136
+
137
+ value_object = Hecks::Runtime::Value.value_object_for(aggregate, attribute.type.to_s)
138
+ current = args[attribute.name.to_s]
139
+ wrong =
140
+ if value_object.nil?
141
+ mistyped_scalar(attribute.type)
142
+ elsif current.is_a?(Hash)
143
+ field = value_object.attributes.find { |f| current.key?(f.name.to_s) } or return nil
144
+
145
+ current.merge(field.name.to_s => value_object.closed_set? ? NON_MEMBER : mistyped_scalar(field.type))
146
+ end
147
+ return nil if wrong.nil?
148
+
149
+ args[attribute.name.to_s] = wrong
150
+ attribute.name.to_s
151
+ end
152
+
153
+ # A well-typed string no `one_of` admits, so a closed set refuses on membership.
154
+ NON_MEMBER = "not a declared member"
155
+
156
+ # For a String field a plain scalar is worded differently by Ruby and Rust, so an empty
157
+ # Hash (the branch they share) stands in as the wrong value.
158
+ def mistyped_scalar(type_name)
159
+ type_name.to_s == "String" ? {} : "not a #{type_name.to_s.downcase}"
160
+ end
161
+
162
+ def violate_reference!(args, command)
163
+ reference = command.attributes.find(&:reference?) or return nil
164
+
165
+ args[reference.name.to_s] = "no-such-#{reference.type.target_name.to_s.downcase}"
166
+ reference.name.to_s
167
+ end
168
+
169
+ # The first declared step missing from the dispatch trace is the one that refused.
170
+ def refused_step(kind)
171
+ interpreter = kind == "entity" ? Hecks::Runtime::EntityInterpreter : Hecks::Runtime::CommandInterpreter
172
+ ran = interpreter.trace || []
173
+ # `decode_arguments` never traces, so it must not be read as the refusing step.
174
+ order_for(kind).reject { |step| step == "decode_arguments" }.find { |step| !ran.include?(step.to_sym) }
175
+ end
176
+
177
+ # Dispatches one row; returns [refusal class, message, refused step], or nils if it succeeded.
178
+ def run_row(runtime, row, kind)
179
+ Hecks::Runtime::CommandInterpreter.trace = []
180
+ Hecks::Runtime::EntityInterpreter.trace = []
181
+ args = JSON.parse(JSON.generate(row[:args])).transform_keys(&:to_sym)
182
+ begin
183
+ if row[:role]
184
+ Hecks.as_caller(role: row[:role]) { runtime.dispatch_flat(row[:verb], args) }
185
+ else
186
+ runtime.dispatch_flat(row[:verb], args)
187
+ end
188
+ [nil, nil, nil]
189
+ rescue *Hecks::Runtime::DOMAIN_REFUSALS => e
190
+ [e.class.name.split("::").last, e.message, refused_step(kind)]
191
+ end
192
+ ensure
193
+ Hecks::Runtime::CommandInterpreter.trace = nil
194
+ Hecks::Runtime::EntityInterpreter.trace = nil
195
+ end
196
+
197
+ # One row per adjacent live-gate pair the command can violate on both steps. Commands with an
198
+ # envelope-keyword attribute never reach an argument gate, so they yield none.
199
+ def rows_for(command, aggregate, verb, kind, random)
200
+ return [] if command.attributes.any? { |a| ENVELOPE_KEYS.include?(a.name.to_s) }
201
+
202
+ base = base_args(command, aggregate, random)
203
+ return [] if base.nil?
204
+
205
+ gates = live_gates(command, kind)
206
+ gates.each_cons(2).filter_map do |earlier, later|
207
+ args = JSON.parse(JSON.generate(base))
208
+ args.merge!(identity_args(aggregate, aggregate, random)) unless kind == "aggregate" && command.creates?
209
+ role = nil
210
+ earlier_detail = violate!(earlier, args, command, aggregate, random)
211
+ later_detail = violate!(later, args, command, aggregate, random)
212
+ next if earlier_detail.nil? || later_detail.nil?
213
+
214
+ role = MISMATCHED_ROLE if [earlier, later].include?("refuse_role_mismatch")
215
+
216
+ { verb: verb, kind: kind, role: role, pair: [earlier, later],
217
+ violates: { earlier => earlier_detail, later => later_detail }, args: args }
218
+ end
219
+ end
220
+
221
+ def candidates(runtime, chapter)
222
+ bluebook = runtime.registry.bluebook(chapter)
223
+ random = SteadyRandom.new(20_260_918)
224
+ bluebook.aggregates.flat_map do |aggregate|
225
+ aggregate_rows = aggregate.commands.flat_map do |command|
226
+ rows_for(command, aggregate, "#{chapter}::#{aggregate.hecks_name}.#{command.hecks_name}", "aggregate", random)
227
+ end
228
+ entity_rows = aggregate.entities.flat_map do |entity|
229
+ entity.commands.flat_map do |command|
230
+ verb = "#{chapter}::#{aggregate.hecks_name}.#{entity.hecks_name}.#{command.hecks_name}"
231
+ rows = rows_for(command, aggregate, verb, "entity", random)
232
+ rows.each { |row| row[:args] = identity_args(entity, aggregate, random).merge(row[:args]) }
233
+ end
234
+ end
235
+ aggregate_rows + entity_rows
236
+ end
237
+ end
238
+
239
+ # Dispatches every candidate row of each domain, keeps the ones Ruby's dispatch trace
240
+ # confirms, and prints how many; with `--write` it rewrites the matrix and the Rust
241
+ # conformance fixtures.
242
+ def main(argv, root: Tools::ROOT)
243
+ kept, dropped = sweep(root)
244
+ report(kept, dropped)
245
+ write(root, kept) if argv.include?("--write")
246
+ 0
247
+ end
248
+
249
+ def sweep(root)
250
+ kept = []
251
+ dropped = []
252
+ DOMAINS.each do |domain|
253
+ Hecks::Fuzzing::IsolatedBoot.call(File.join(root, domain)) do |copy|
254
+ runtime = Hecks.boot(copy, environment: nil)
255
+ chapters = runtime.registry.bluebooks.keys
256
+ chapter = chapters.find { |name| candidates(runtime, name).any? } || chapters.first
257
+ candidates(runtime, chapter).each do |row|
258
+ kind, error, refused = run_row(runtime, row, row[:kind])
259
+ if kind.nil?
260
+ dropped << row.merge(reason: "Ruby accepted it — neither gate refused")
261
+ elsif refused.to_s != row[:pair].first
262
+ dropped << row.merge(reason: "Ruby refused at #{refused.inspect} (#{kind}), not the earlier declared step")
263
+ else
264
+ kept << row.merge(domain: domain, expected: { "kind" => kind, "error" => error, "refused_at" => refused.to_s })
265
+ end
266
+ end
267
+ end
268
+ end
269
+ [kept, dropped]
270
+ end
271
+
272
+ def report(kept, dropped)
273
+ pairs = kept.group_by { |row| row[:pair].join(" before ") }.transform_values(&:size)
274
+ puts "kept #{kept.size} rows over #{DOMAINS.size} domains; dropped #{dropped.size}"
275
+ pairs.sort.each { |pair, count| puts " #{pair}: #{count}" }
276
+ dropped.group_by { |row| row[:reason] }.sort_by { |_, rows| -rows.size }.each do |reason, rows|
277
+ puts " dropped #{rows.size}: #{reason}"
278
+ end
279
+ end
280
+
281
+ def write(root, kept)
282
+ path = File.join(root, MATRIX_FILE)
283
+ FileUtils.mkdir_p(File.dirname(path))
284
+ matrix = {
285
+ "generated_by" => "hecks argument_gate_matrix",
286
+ "aggregate_order" => AGGREGATE_ORDER,
287
+ "entity_order" => ENTITY_ORDER,
288
+ "rows" => kept.map do |row|
289
+ { "domain" => row[:domain], "verb" => row[:verb], "kind" => row[:kind], "pair" => row[:pair],
290
+ "violates" => row[:violates], "role" => row[:role], "args" => row[:args], "expected" => row[:expected] }
291
+ end
292
+ }
293
+ File.write(path, "#{JSON.pretty_generate(matrix)}\n")
294
+ puts "wrote #{path}"
295
+
296
+ kept.group_by { |row| row[:domain] }.each { |domain, rows| write_fixture(root, domain, rows) }
297
+ end
298
+
299
+ def write_fixture(root, domain, rows)
300
+ path = File.join(root, "spec/corpus/rust_conformance/argument_gate_order_#{File.basename(domain)}.json")
301
+ fixture = {
302
+ "domain" => domain,
303
+ "note" => FIXTURE_NOTE,
304
+ "steps" => rows.map do |row|
305
+ step = { "verb" => row[:verb] }
306
+ step["role"] = row[:role] if row[:role]
307
+ step["args"] = row[:args]
308
+ step
309
+ end
310
+ }
311
+ File.write(path, "#{JSON.pretty_generate(fixture)}\n")
312
+ puts "wrote #{path}"
313
+ end
314
+ end
315
+ end
316
+ end