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
@@ -0,0 +1,336 @@
1
+ module Hecks
2
+ module Grammar
3
+ # File surgery under `hecks word_status` and its siblings: reads and rewrites the
4
+ # aggregate-local KeywordSeed/ArgumentSeed rows as text, preserving the table's own formatting.
5
+ module Evolve
6
+ class Refusal < StandardError; end
7
+
8
+ module_function
9
+
10
+ # Only consumes the next argv element as the value when it isn't itself
11
+ # a flag, so `--foo --bar` doesn't swallow `--bar` as `--foo`'s value.
12
+ def option(argv, name, default = nil)
13
+ index = argv.index("--#{name}")
14
+ return default unless index
15
+
16
+ value = argv[index + 1]
17
+ value.nil? || value.start_with?("-") ? default : value
18
+ end
19
+
20
+ # Runs the block against an in-memory copy of the tables: every edit it makes is held, none
21
+ # is written, and later reads see the earlier edits.
22
+ #
23
+ # @yield the edits to rehearse
24
+ # @return [Hash{String => String}] each file the edits changed, with the text it would hold
25
+ def rehearse
26
+ @overlay = {}
27
+ yield
28
+ @overlay.dup
29
+ ensure
30
+ @overlay = nil
31
+ end
32
+
33
+ # @param path [String] a table file
34
+ # @return [String] its text: a rehearsed edit if one was made, else what the file holds
35
+ def read_source(path)
36
+ @overlay&.key?(path) ? @overlay[path] : File.read(path)
37
+ end
38
+
39
+ # @param path [String] a table file
40
+ # @param text [String] what it holds afterwards; held, not written, while rehearsing
41
+ # @return [Object] the text
42
+ def write_source(path, text)
43
+ @overlay ? (@overlay[path] = text) : File.write(path, text)
44
+ end
45
+
46
+ # Snapshots `paths` before running the block and restores every file
47
+ # if it raises, even partway through a multi-file write.
48
+ def restore_on_raise(paths)
49
+ snapshots = paths.to_h { |path| [path, File.read(path)] }
50
+ yield
51
+ rescue StandardError
52
+ snapshots.each { |path, content| File.write(path, content) }
53
+ raise
54
+ end
55
+
56
+ # Every syntax-table file declaring a KeywordSeed or ArgumentSeed value object.
57
+ def syntax_paths
58
+ Dir.glob(File.expand_path("../language/**/*.bluebook", __dir__)).select do |path|
59
+ source = read_source(path)
60
+ source.include?('value_object "KeywordSeed"') || source.include?('value_object "ArgumentSeed"')
61
+ end
62
+ end
63
+
64
+ # Narrow compatibility door for single-file callers; syntax_paths is normal.
65
+ def syntax_path = syntax_paths.first
66
+
67
+ # Resolves the file(s) a call should search or write.
68
+ def paths_for(path) = path ? Array(path) : syntax_paths
69
+
70
+ # Parses the Keyword one_of's member rows leniently off the text.
71
+ def keyword_rows(path = nil)
72
+ paths_for(path).flat_map do |candidate|
73
+ blocks = seed_blocks(read_source(candidate), "KeywordSeed")
74
+ raise Refusal, "source declares no KeywordSeed value object" if path && blocks.empty?
75
+
76
+ blocks.flat_map do |block|
77
+ block.scan(/^\s*member (.+)$/).map do |(cells)|
78
+ row = cells.scan(/(\w+): "((?:[^"\\]|\\.)*)"/).to_h
79
+ { word: row["word"], context: row["context"],
80
+ status: row.fetch("status", "admitted"), was: row["was"] }
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ # Declares a new, proposed keyword row in the syntax table that owns
87
+ # `context` (or the aggregate `opens` names, for a File-context word).
88
+ def propose(word:, context:, body: "none", inner: "", opens: "", fills: "", path: nil)
89
+ if keyword_rows(path).any? do |row|
90
+ row[:word] == word && row[:context] == context
91
+ end
92
+ raise Refusal,
93
+ "#{context}.#{word} is already declared — one row per (word, context, form)"
94
+ end
95
+
96
+ path = owner_path(context: context, word: word, opens: opens, paths: paths_for(path))
97
+ source = read_source(path)
98
+ block = keyword_blocks(source).find { |candidate| candidate.include?(%(context: "#{context}")) } || keyword_block(source)
99
+ indent = block[/^(\s*)member /, 1] || " "
100
+ row = %(#{indent}member word: "#{word}", context: "#{context}", body: "#{body}", ) +
101
+ %(inner: "#{inner}", opens: "#{opens}", fills: "#{fills}", status: "proposed"\n)
102
+
103
+ # Appended at the end; whoever admits it may move it to its group.
104
+ closing = block.rindex(/^\s*end\s*$/)
105
+ updated = block[0...closing] + row + block[closing..]
106
+ write_source(path, source.sub(block, updated))
107
+ end
108
+
109
+ # Rewrites a declared keyword row's status: cell in place.
110
+ def set_status(word:, context:, to:, path: nil)
111
+ raise Refusal, "#{to.inspect} is not a station a word's life admits" unless %w[proposed admitted deprecated
112
+ retired].include?(to)
113
+
114
+ path = path_holding_keyword(word, context, paths_for(path))
115
+ source = read_source(path)
116
+ block = keyword_blocks(source).find { |candidate| candidate.lines.any? { |line| member_row?(line, word, context) } }
117
+ rows = block.lines.select { |line| member_row?(line, word, context) }
118
+ raise Refusal, "#{context}.#{word} is not declared" if rows.empty?
119
+
120
+ updated = block.lines.map do |line|
121
+ next line unless member_row?(line, word, context)
122
+
123
+ stripped = line.sub(/,\s*status: "[^"]*"/, "")
124
+ # Admitted is the default and stays unspelled in the row.
125
+ to == "admitted" ? stripped : stripped.sub(/\n\z/, %(, status: "#{to}"\n))
126
+ end.join
127
+
128
+ write_source(path, source.sub(block, updated))
129
+ end
130
+
131
+ # Respells a keyword row (was: holds the old spelling) — one hop only;
132
+ # its Argument rows follow, row-aware (see cascade_argument_rename).
133
+ def rename(word:, context:, to:, path: nil)
134
+ row = keyword_rows(path).find { |r| r[:word] == word && r[:context] == context }
135
+ raise Refusal, "#{context}.#{word} is not declared" unless row
136
+ raise Refusal, "#{context}.#{word} was already #{row[:was]} — one rename hop, then eras" if row[:was]
137
+ if keyword_rows(path).any? do |r|
138
+ r[:word] == to && r[:context] == context
139
+ end
140
+ raise Refusal,
141
+ "#{context}.#{to} is already declared — a rename cannot land on a living word"
142
+ end
143
+
144
+ paths = paths_for(path)
145
+ path = path_holding_keyword(word, context, paths)
146
+ source = read_source(path)
147
+ block = keyword_blocks(source).find { |candidate| candidate.lines.any? { |line| member_row?(line, word, context) } }
148
+ updated = block.lines.map do |line|
149
+ next line unless member_row?(line, word, context)
150
+
151
+ line.sub(%(word: "#{word}"), %(word: "#{to}"))
152
+ .sub(/\n\z/, %(, was: "#{word}"\n))
153
+ end.join
154
+ source = source.sub(block, updated)
155
+ write_source(path, source)
156
+
157
+ cascade_argument_rename(keyword: word, context: context, to: to, path: paths)
158
+ end
159
+
160
+ # Tells whether `line` is a KeywordSeed member row for (word, context).
161
+ def member_row?(line, word, context)
162
+ line =~ /^\s*member / && line.include?(%(word: "#{word}")) && line.include?(%(context: "#{context}"))
163
+ end
164
+
165
+ # Finds which syntax-table path declares a keyword row.
166
+ def path_holding_keyword(word, context, paths = syntax_paths)
167
+ paths.find do |candidate|
168
+ keyword_blocks(read_source(candidate)).any? { |block| block.lines.any? { |line| member_row?(line, word, context) } }
169
+ end || raise(Refusal, "#{context}.#{word} is not declared")
170
+ end
171
+
172
+ # Finds which syntax-table path declares an argument row.
173
+ def path_holding_argument(keyword, context, at, named, paths = syntax_paths)
174
+ paths.find do |candidate|
175
+ argument_blocks(read_source(candidate)).any? do |block|
176
+ block.lines.any? do |line|
177
+ argument_row?(line, keyword, context, at, named)
178
+ end
179
+ end
180
+ end || raise(Refusal, "#{context}.#{keyword}'s argument at #{at.inspect}/named #{named.inspect} is not declared")
181
+ end
182
+
183
+ # Picks the owning file for a new row; opens names the aggregate for a File-context word.
184
+ def owner_path(context:, word:, opens: "", paths: syntax_paths)
185
+ if context == "File" && !opens.to_s.empty?
186
+ aggregate_path = paths.find { |candidate| read_source(candidate).match?(/^\s*aggregate "#{Regexp.escape(opens)}" do$/) }
187
+ return aggregate_path if aggregate_path
188
+ end
189
+
190
+ paths.find do |candidate|
191
+ source = read_source(candidate)
192
+ %w[KeywordSeed ArgumentSeed].any? do |seed|
193
+ seed_blocks(source, seed).any? { |block| block.include?(%(context: "#{context}")) }
194
+ end
195
+ end || raise(Refusal, "no aggregate-local syntax table owns context #{context.inspect} for #{word}")
196
+ end
197
+
198
+ # Every value_object "<name>" block's full source text, opener to closing end.
199
+ def seed_blocks(source, name)
200
+ opener = /^([ \t]*)value_object "#{Regexp.escape(name)}" do$/
201
+ source.to_enum(:scan, opener).map do
202
+ match = Regexp.last_match
203
+ start = match.begin(0)
204
+ indent = match[1]
205
+ closing = source.index(/^#{Regexp.escape(indent)}end\s*$/, match.end(0))
206
+ closing = source.index(/\n/, closing) + 1
207
+ source[start...closing]
208
+ end
209
+ end
210
+
211
+ # The first value_object "<name>" block's source text.
212
+ def seed_block(source, name, required: false)
213
+ block = seed_blocks(source, name).first
214
+ unless block
215
+ raise Refusal, "source declares no #{name} value object" if required
216
+
217
+ return
218
+ end
219
+ block
220
+ end
221
+
222
+ # First `end` after the opener is the block's own — member rows sit bare (ADR 0025).
223
+ def keyword_blocks(source) = seed_blocks(source, "KeywordSeed")
224
+
225
+ # The first KeywordSeed block's source text.
226
+ def keyword_block(source) = seed_block(source, "KeywordSeed", required: true)
227
+
228
+ # Parses the ArgumentSeed's member rows leniently off the text.
229
+ def argument_rows(path = nil)
230
+ paths_for(path).flat_map do |candidate|
231
+ blocks = seed_blocks(read_source(candidate), "ArgumentSeed")
232
+ raise Refusal, "source declares no ArgumentSeed value object" if path && blocks.empty?
233
+
234
+ blocks.flat_map do |block|
235
+ block.scan(/^\s*member (.+)$/).map do |(cells)|
236
+ row = cells.scan(/(\w+): "((?:[^"\\]|\\.)*)"/).to_h
237
+ { keyword: row["keyword"], context: row["context"], at: row["at"].to_s,
238
+ named: row["named"].to_s, kind: row["kind"], required: row["required"],
239
+ fills: row["fills"].to_s, status: row.fetch("status", "admitted") }
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ # Declares a new, proposed argument row; pairs_shape marks a `pairs`
246
+ # argument that fills a whole key/value list, not a single field.
247
+ def propose_argument(keyword:, context:, kind:, required: "false", at: "", named: "", fills: "",
248
+ pairs_shape: nil, path: nil)
249
+ if argument_rows(path).any? { |r| argument_identity(r) == [keyword, context, at, named] }
250
+ raise Refusal, "#{context}.#{keyword}'s argument at #{at.inspect}/named #{named.inspect} is " \
251
+ "already declared — one row per (keyword, context, at, named)"
252
+ end
253
+
254
+ path = owner_path(context: context, word: keyword, paths: paths_for(path))
255
+ source = read_source(path)
256
+ block = argument_blocks(source).find do |candidate|
257
+ candidate.include?(%(context: "#{context}"))
258
+ end || argument_block(source)
259
+ indent = block[/^(\s*)member /, 1] || " "
260
+ shape = pairs_shape.to_s.empty? ? "" : %(pairs_shape: "#{pairs_shape}", )
261
+ row = %(#{indent}member keyword: "#{keyword}", context: "#{context}", at: "#{at}", ) +
262
+ %(named: "#{named}", kind: "#{kind}", required: "#{required}", fills: "#{fills}", ) +
263
+ shape + %(status: "proposed"\n)
264
+
265
+ closing = block.rindex(/^\s*end\s*$/)
266
+ updated = block[0...closing] + row + block[closing..]
267
+ write_source(path, source.sub(block, updated))
268
+ end
269
+
270
+ # Rewrites a declared argument row's status: cell in place.
271
+ def set_argument_status(keyword:, context:, to:, at: "", named: "", path: nil)
272
+ raise Refusal, "#{to.inspect} is not a station an argument's life admits" unless %w[proposed admitted deprecated
273
+ retired].include?(to)
274
+
275
+ path = path_holding_argument(keyword, context, at, named, paths_for(path))
276
+ source = read_source(path)
277
+ block = argument_blocks(source).find do |candidate|
278
+ candidate.lines.any? do |line|
279
+ argument_row?(line, keyword, context, at, named)
280
+ end
281
+ end
282
+ rows = block.lines.select { |line| argument_row?(line, keyword, context, at, named) }
283
+ if rows.empty?
284
+ raise Refusal, "#{context}.#{keyword}'s argument at #{at.inspect}/named #{named.inspect} is not " \
285
+ "declared"
286
+ end
287
+
288
+ updated = block.lines.map do |line|
289
+ next line unless argument_row?(line, keyword, context, at, named)
290
+
291
+ stripped = line.sub(/,\s*status: "[^"]*"/, "")
292
+ to == "admitted" ? stripped : stripped.sub(/\n\z/, %(, status: "#{to}"\n))
293
+ end.join
294
+
295
+ write_source(path, source.sub(block, updated))
296
+ end
297
+
298
+ # Tells whether `line` is an ArgumentSeed row for this (keyword, context, at, named) tuple.
299
+ def argument_row?(line, keyword, context, at, named)
300
+ line =~ /^\s*member / &&
301
+ line.include?(%(keyword: "#{keyword}")) && line.include?(%(context: "#{context}")) &&
302
+ line.include?(%(at: "#{at}")) && line.include?(%(named: "#{named}"))
303
+ end
304
+
305
+ # The (keyword, context, at, named) identity tuple an argument row is keyed
306
+ # by — wider than a Keyword row's two-field key.
307
+ def argument_identity(row) = [row[:keyword], row[:context], row[:at], row[:named]]
308
+
309
+ # Row-aware rename cascade — updates only the argument rows that belong
310
+ # to the renamed keyword, not a blind gsub across the file.
311
+ def cascade_argument_rename(keyword:, context:, to:, path: nil)
312
+ paths_for(path).each do |candidate|
313
+ source = read_source(candidate)
314
+ original = source
315
+ argument_blocks(source).each do |block|
316
+ updated = block.lines.map do |line|
317
+ next line unless line =~ /^\s*member / &&
318
+ line.include?(%(keyword: "#{keyword}")) && line.include?(%(context: "#{context}"))
319
+
320
+ line.sub(%(keyword: "#{keyword}"), %(keyword: "#{to}"))
321
+ end.join
322
+ source = source.sub(block, updated) if updated != block
323
+ end
324
+ write_source(candidate, source) if source != original
325
+ end
326
+ end
327
+
328
+ # ArgumentSeed blocks; see keyword_blocks for why the first bare end
329
+ # after the opener is already the block's own.
330
+ def argument_blocks(source) = seed_blocks(source, "ArgumentSeed")
331
+
332
+ # The first ArgumentSeed block's source text.
333
+ def argument_block(source) = seed_block(source, "ArgumentSeed", required: true)
334
+ end
335
+ end
336
+ end
@@ -6,21 +6,9 @@ Hecks.bluebook "Expression" do
6
6
  aggregate "Operator" do
7
7
  description "One admitted operation — its symbol, its precedence, and how it reads in every target that must evaluate it."
8
8
 
9
- # WHAT IS NOT HERE, on purpose. The outer grammar
10
- # has two rules that are not operators: parenthesization (a structural
11
- # strip-and-recurse, no symbol of its own) and the bare-leaf fallback
12
- # (whatever matches nothing else falls through to the inner grammar).
13
- # Its inner grammar has three more: integer/float/string/bool/nil/
14
- # array literals and the dotted-lookup fallback are TERMINAL
15
- # productions — they recognize text, they do not combine operands,
16
- # and they have nothing meaningful to render per target (a literal's
17
- # spelling does not differ between targets the way an operation's
18
- # might — `rust/src/kernel/expr.rs`'s own `Expr::Array` is a LEAF
19
- # there too, for the identical reason, not routed through
20
- # `OperatorCategory`).
21
- # Forcing them into this shape would stretch `renderings` and the
22
- # Arity invariant past what they mean. They stay declared only in
23
- # prose — named here rather than silently left out.
9
+ # Not operators, so not declared here: parenthesization, the bare-leaf fallback,
10
+ # and the terminal literals and dotted lookup. They recognize text rather than
11
+ # combine operands, and a literal reads the same in every target.
24
12
  identified_by :symbol
25
13
 
26
14
  attribute :symbol, OperatorSymbol
@@ -54,47 +42,34 @@ Hecks.bluebook "Expression" do
54
42
 
55
43
  value_object "Arity" do
56
44
  attribute :value, Integer
57
- # WRITTEN ACROSS LINES ON PURPOSE, and this is the only predicate in the
58
- # corpus that is. A CONTINUATION line is where extraction used to break:
59
- # a naive line join reads `value > 0 && && value <= 3` — a different
60
- # canonical form for the same source, waiting for the first multi-line
61
- # rule anyone wrote. Every predicate here was kept on one line to dodge
62
- # that. The join is continuation-aware now, so this case holds the fix:
63
- # if it regresses, the canonical text of THIS invariant changes and the
64
- # golden IR goes red.
45
+ # Written across lines on purpose: it pins continuation-aware line joining in
46
+ # extraction. If that regresses, this invariant's canonical text changes and
47
+ # the golden IR goes red.
65
48
  invariant("an operator takes one, two or three operands") do
66
49
  value > 0 &&
67
50
  value <= 3
68
51
  end
69
52
  end
70
53
 
71
- # OUTER checks a leaf against `.include?`/comparators/`!` before falling
72
- # through to INNER's arithmetic/dotted-lookup grammar — two stacked
73
- # grammars. Which one an operator belongs
74
- # to is not derivable from its symbol alone (`+` reads like it could be
75
- # either), so it is its own column rather than inferred.
54
+ # The outer grammar checks `.include?`, comparators and `!` before falling through
55
+ # to the inner arithmetic and dotted-lookup grammar. The symbol alone does not say
56
+ # which one an operator belongs to, so it is its own column.
76
57
  value_object "Grammar" do
77
58
  attribute :value, String
78
59
  invariant("an operator belongs to one of the two stacked grammars") { !value.to_s.empty? }
79
60
  end
80
61
 
81
- # HOW the check recognizes this operator's text, not WHERE it binds
82
- # (that's precedence) or WHEN it's tried (that's position). Four shapes
83
- # cover every admitted operator: split at a top-level occurrence
84
- # (`||`, comparators), strip a leading marker (`!`), strip a trailing
85
- # suffix (`.empty?`), or match a call-with-argument pattern
86
- # (`.include?(needle)`).
62
+ # How the check recognizes an operator's text: split at a top-level occurrence
63
+ # (`||`), strip a leading marker (`!`) or trailing suffix (`.empty?`), or match a
64
+ # call pattern (`.include?(needle)`).
87
65
  value_object "Strategy" do
88
66
  attribute :value, String
89
67
  invariant("an operator names how its check recognizes it") { !value.to_s.empty? }
90
68
  end
91
69
 
92
- # THE WITHIN-GRAMMAR CHECK ORDER — what precedence alone cannot say,
93
- # since the six comparators all share one precedence tier and something
94
- # still has to break the tie (grammar.md: `>=` before `<=` before `<`
95
- # before `>` before `==` before `!=`, so `<` splitting does not fire
96
- # inside `>=`). Scoped per `grammar`, mirroring Normalisation's own
97
- # Position column below — each grammar starts its own count at 1.
70
+ # The check order within a grammar, counted from 1 per grammar. It breaks the tie
71
+ # precedence cannot: the six comparators share a tier, and `>=` must be tried
72
+ # before `>` so a split on `>` does not fire inside `>=`.
98
73
  value_object "Position" do
99
74
  attribute :value, Integer
100
75
  invariant("an operator sits somewhere in its grammar's check order") { value > 0 }
@@ -18,12 +18,9 @@ Hecks.bluebook "Translation" do
18
18
  transition "Retire" => "retired", from: "admitted"
19
19
  end
20
20
 
21
- # THE CLOSED SET OF RULE KINDS — declared as members, not a hand-rolled
22
- # OR-chain, so the set is data a conformance spec can hold the live
23
- # builder to (spec/translation_vocabulary_conformance_spec.rb). Nine of
24
- # these are TranslationAggregateBuilder's own rule methods ; "retired" is
25
- # the edge-level declaration (TranslationBuilder#retired), in the set
26
- # because it is one admitted way a shape survives — by not surviving.
21
+ # The closed set of rule kinds, kept as data so a conformance spec can hold the
22
+ # builder to it. All but "retired" are TranslationAggregateBuilder rule methods;
23
+ # "retired" is the edge-level declaration (TranslationBuilder#retired).
27
24
  value_object "Kind" do
28
25
  attribute :value, String,
29
26
  one_of: ["rename", "move", "convert", "drop", "retype", "retired", "compute", "rekey",
data/lib/hecks/grammar.rb CHANGED
@@ -1,32 +1,23 @@
1
1
  require "json"
2
2
 
3
- # The whole framework, deliberately: booting a grammar chapter exercises
4
- # the DSL, the meta-validator, and the runtime — and nothing the entry
5
- # point loads ever requires this file back, so the require is acyclic.
3
+ # Loads the whole framework on purpose; nothing the entry point loads
4
+ # requires this file back, so the require is acyclic.
6
5
  require_relative "../hecks"
7
6
 
8
7
  module Hecks
9
- # The sublanguage grammar domains (grammar/*.bluebook) and the one boot
10
- # path for reading them as data — the expression chapter replayed
11
- # through its own admission ledger, so anything derived from it (the
12
- # operator projections, the conformance specs) reads the set that
13
- # actually survived the Admit gates, never a hand-copied list.
8
+ # The sublanguage grammar domains (grammar/*.bluebook) and the one boot path
9
+ # for reading them as data, replayed through the expression admission ledger.
14
10
  #
15
- # Booted on call, never at require: the Prism adapter normalises every
16
- # predicate through CanonicalForm while a bluebook loads, so the
17
- # expression machinery cannot boot the chapter that configures it —
18
- # this module exists precisely so generators and specs boot it in a
19
- # scratch registry instead.
11
+ # Booted on call, never at require: the Prism adapter normalises predicates
12
+ # while a bluebook loads, so the expression machinery cannot boot its own chapter.
20
13
  module Grammar
21
14
  DIR = File.expand_path("grammar", __dir__)
22
15
  LEDGER = File.join(DIR, "expression_operators.json")
23
16
 
24
17
  module_function
25
18
 
26
- # Boot the expression chapter and replay the admission ledger through
27
- # its real commands. A refused step raises — a generator running off
28
- # a half-admitted ledger would project a table the gates never
29
- # accepted.
19
+ # Boots the expression chapter and replays the admission ledger through
20
+ # its real commands; a refused step raises.
30
21
  #
31
22
  # @return [Runtime::Dispatcher] the dispatcher bound to the booted, replayed
32
23
  # expression chapter
@@ -104,16 +95,9 @@ module Hecks
104
95
  registry.repository("Expression", aggregate).all
105
96
  end
106
97
 
107
- # The operators the language stands on. Every guard and invariant in
108
- # the language's own chapters — the meta-domain (Bluebook, World) and
109
- # the grammar chapters beside this file — evaluates through the very
110
- # operator table the ledger admits. An operator one of those
111
- # predicates uses is self-bearing: retire it and the language can no
112
- # longer read its own rules — found the hard way, as a projection
113
- # missing `!=` that could not boot the chapter to fix itself. This
114
- # derives the set, with a usage site per operator, so the generator
115
- # and the conformance spec can refuse the retirement by name instead
116
- # of wedging.
98
+ # The operators the language's own guards and invariants (Bluebook, World and
99
+ # the grammar chapters) evaluate through. Retiring one would leave the
100
+ # language unable to read its own rules, so callers refuse it by name.
117
101
  #
118
102
  # @return [Hash{String => Array<String>}] each self-bearing operator symbol
119
103
  # mapped to the `"Chapter Aggregate.command"`/`"Chapter Aggregate::ValueObject"`
@@ -147,8 +131,7 @@ module Hecks
147
131
  sites.transform_values(&:uniq)
148
132
  end
149
133
 
150
- # Every grammar/*.bluebook chapter, booted the same way the corpus
151
- # boots them — each alone, in a scratch registry.
134
+ # Every grammar/*.bluebook chapter, each booted alone in a scratch registry.
152
135
  #
153
136
  # @return [Array<Class>] each grammar chapter, booted alone in its own scratch
154
137
  # registry
@@ -167,9 +150,8 @@ module Hecks
167
150
  end
168
151
  end
169
152
 
170
- # Which admitted operators one canonical text evaluates through —
171
- # the evaluator's own parse, walked for its operator nodes, leaves
172
- # walked for the resolver's arithmetic.
153
+ # Which admitted operators one canonical text evaluates through, found by
154
+ # walking the evaluator's own parse.
173
155
  #
174
156
  # @param canonical [String] canonical expression text to parse
175
157
  # @return [Array<String>] operator symbols the expression evaluates through, or
@@ -184,15 +166,8 @@ module Hecks
184
166
  walk_operators(node, evaluator).uniq
185
167
  end
186
168
 
187
- # A recursive descent over a closed, declared set of AST node types
188
- # (Evaluator's boolean/compare/include nodes, Resolver's arithmetic
189
- # nodes, and the generic Struct fallback) — each branch does the
190
- # same one thing (name the node's own operator, recurse into its
191
- # children) and the branches don't interact, but the ABC score adds
192
- # every branch's cost together. Splitting the case out per node type
193
- # would trade one place that shows the whole operator vocabulary for
194
- # several that each show a fragment, with no reduction in real
195
- # complexity.
169
+ # One case over the closed set of AST node types, kept together so the whole
170
+ # operator vocabulary reads in one place.
196
171
  # @param node [Object] an evaluator/resolver AST node, or a Struct fallback
197
172
  # @param evaluator [Module] `Bluebook::Expression::Evaluator`, passed through
198
173
  # so nested calls don't re-resolve the constant
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require_relative "ruby_child"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ module Codebase
9
+ # What Codebase's `CodemodRun` asks of the working tree: the mechanical rewrites of the
10
+ # example bluebooks.
11
+ #
12
+ # Each codemod is a script built on `Hecks::Codemod` (`lib/hecks/codemod.rb`), which reboots
13
+ # every bluebook it edits and puts the file back when the rewrite changes what the bluebook
14
+ # means. The script runs in a child process from the checkout's root. Unconfirmed it runs
15
+ # with `--dry-run`, which restores every file it touched, so tracked files stay changed only
16
+ # when the request is confirmed.
17
+ module Codemods
18
+ # Every operation this family carries out.
19
+ OPERATIONS = %w[hoist_local_givens drop_implicit_append_fields].freeze
20
+
21
+ # The script each operation runs.
22
+ SCRIPTS = { "hoist_local_givens" => "codemod_hoist_local_givens",
23
+ "drop_implicit_append_fields" => "codemod_implicit_append_fields" }.freeze
24
+
25
+ module_function
26
+
27
+ # Carries out one codemod.
28
+ #
29
+ # @param operation [String] one of `OPERATIONS`
30
+ # @param held [Hash] the `CodemodRun` record's fields: `confirm`
31
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
32
+ # @param shell [#capture, nil] unused: the codemod runs in this process
33
+ # @return [String] what the script found for each example, and whether it rewrote it
34
+ # @raise [ConsoleCapture::Failure] when the script ends badly
35
+ def call(operation, held, tree, shell: nil)
36
+ confirm = held[:confirm].is_a?(Hash) ? held[:confirm][:value] : held[:confirm]
37
+ child = RubyChild.new(tree)
38
+ return child.answer(SCRIPTS.fetch(operation)) if confirm == true
39
+
40
+ "dry run, nothing kept (add --confirm to rewrite):\n#{child.answer(SCRIPTS.fetch(operation), '--dry-run')}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require_relative "ruby_child"
5
+ require "hecks/engine_agreement"
6
+ require "hecks/doc/reference"
7
+
8
+ module Hecks
9
+ module Adapters
10
+ module Codebase
11
+ # What Codebase's `ConformanceRun` asks of the working tree: the checks on the language
12
+ # itself.
13
+ #
14
+ # The query-engine check and the reference-docs check read the tree in this process, with the
15
+ # code the verbs run elsewhere, and write nothing. The argument-gate matrix boots several
16
+ # throwaway domains and replays them, so it runs in a child process; without `confirm` the
17
+ # script only reports, and with it the script rewrites the committed matrix and its fixtures.
18
+ module Conformance
19
+ # Every operation this family carries out.
20
+ OPERATIONS = %w[check_engine_agreement measure_doc_coverage argument_gate_matrix].freeze
21
+
22
+ module_function
23
+
24
+ # Carries out one operation.
25
+ #
26
+ # @param operation [String] one of `OPERATIONS`
27
+ # @param held [Hash] the `ConformanceRun` record's fields
28
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
29
+ # @return [String] what the check found
30
+ # @raise [ConsoleCapture::Failure] when the check finds a disagreement
31
+ def call(operation, held, tree, shell: nil)
32
+ case operation
33
+ when "check_engine_agreement" then engine_agreement(tree)
34
+ when "measure_doc_coverage" then doc_coverage(tree)
35
+ else gate_matrix(held, tree)
36
+ end
37
+ end
38
+
39
+ # @param tree [Tree] the checkout
40
+ # @return [String] the clean verdict
41
+ # @raise [ConsoleCapture::Failure] with every problem, when the engines disagree
42
+ def engine_agreement(tree)
43
+ finding = EngineAgreement.check(root: tree.root)
44
+ return EngineAgreement.clean_line(finding) if finding.problems.empty?
45
+
46
+ raise ConsoleCapture::Failure, EngineAgreement.problem_lines(finding)
47
+ end
48
+
49
+ # @param tree [Tree] the checkout
50
+ # @return [String] the clean verdict
51
+ # @raise [ConsoleCapture::Failure] with each word that lacks prose or an example
52
+ def doc_coverage(tree)
53
+ clean, report = Doc::Reference.coverage_report(tree.path("docs/implemented/reference"))
54
+ raise ConsoleCapture::Failure, report unless clean
55
+
56
+ report
57
+ end
58
+
59
+ # @param held [Hash] the record's fields; `confirm` makes the script write
60
+ # @param tree [Tree] the checkout
61
+ # @return [String] what the script printed: the rows kept and dropped, and what it wrote
62
+ # @raise [ConsoleCapture::Failure] when the script ends badly
63
+ def gate_matrix(held, tree)
64
+ confirm = held[:confirm].is_a?(Hash) ? held[:confirm][:value] : held[:confirm]
65
+ child = RubyChild.new(tree)
66
+ child.answer("argument_gate_matrix", *("--write" if confirm == true))
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end