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,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hecks/corpus"
4
+ require "hecks/query_ir"
5
+ require "hecks/query_ir_mcp"
6
+ require_relative "tree"
7
+ require "hecks/rust_build"
8
+ require_relative "../console_capture"
9
+
10
+ module Hecks
11
+ module Adapters
12
+ module Codebase
13
+ # What Codebase's `CorpusRun` asks of the working tree: which committed domains have a Rust
14
+ # feature, what the language's IR holds, and the two doors that serve it.
15
+ #
16
+ # The questions are pure reads and run in this process, with the code `hecks rust_domains` and
17
+ # `hecks ir_constructs` run (`Hecks::Corpus`, `Hecks::QueryIR`); the coverage question runs
18
+ # `Hecks::RustBuild`'s coverage tool over each generated module, also in this process. The
19
+ # two doors run until they are closed: the query MCP server on stdio, and the forms app on a
20
+ # local port.
21
+ module CorpusTasks
22
+ # Every operation this family carries out.
23
+ OPERATIONS = %w[serve_query_ir_mcp present].freeze
24
+
25
+ # The port `present` listens on when none is named.
26
+ DEFAULT_PORT = 4567
27
+
28
+ class << self
29
+ # @return [#call, nil] serves the MCP door; `Hecks::QueryIrMcp.start` when nil. A spec
30
+ # replaces it so no stdio has to be held.
31
+ attr_accessor :mcp_server
32
+
33
+ # @return [#call, nil] takes `app:` and `port:` and serves until stopped; a WEBrick
34
+ # server through Rack when nil.
35
+ attr_accessor :web_server
36
+
37
+ # @return [#capture, nil] runs each coverage check, as `capture(tool, argv, env:)`
38
+ # answering an object with `out`, `err` and `ok?`; `Hecks::RustBuild` when nil.
39
+ attr_accessor :coverage_runner
40
+ end
41
+
42
+ module_function
43
+
44
+ # Opens one of the doors.
45
+ #
46
+ # @param operation [String] `serve_query_ir_mcp` or `present`
47
+ # @param held [Hash] the `CorpusRun` record's fields: `port`
48
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
49
+ # @param shell [#capture, nil] unused
50
+ # @return [String] a note that the door closed
51
+ # @raise [ConsoleCapture::Failure] when the MCP door refuses the process's setup
52
+ def call(operation, held, tree, shell: nil)
53
+ _ = shell
54
+ return serve_mcp if operation == "serve_query_ir_mcp"
55
+
56
+ present(plain(held)[:port] || DEFAULT_PORT, tree)
57
+ end
58
+
59
+ # A pure read.
60
+ #
61
+ # @param operation [String] a query's name in snake case
62
+ # @param args [Hash] the query's plain arguments
63
+ # @param tree [Tree] the checkout
64
+ # @param shell [#capture, nil] unused; the coverage checks run in this process
65
+ # @return [String] the answer, one line for each row
66
+ # @raise [ConsoleCapture::Failure] when a coverage check fails, or a query is refused
67
+ def report(operation, args, tree, shell: nil)
68
+ _ = shell
69
+ case operation
70
+ when "rust_domains" then rust_domains(tree)
71
+ when "regen_order" then regen_order(tree)
72
+ when "corpus_rust_coverage" then coverage(tree)
73
+ else ir_query(operation, args)
74
+ end
75
+ end
76
+
77
+ # @param held [Hash] fields, each perhaps a value object's `{ value: x }`
78
+ # @return [Hash] the same fields as plain values
79
+ def plain(held) = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
80
+
81
+ # @return [String] a note that the MCP door closed
82
+ # @raise [ConsoleCapture::Failure] when the door refuses to start
83
+ def serve_mcp
84
+ server = CorpusTasks.mcp_server || ->(**options) { QueryIrMcp.start(**options) }
85
+ server.call(argv: [])
86
+ "query ir mcp door closed"
87
+ rescue SystemExit => e
88
+ raise ConsoleCapture::Failure, "the query ir mcp door refused to start (status #{e.status}); see stderr"
89
+ end
90
+
91
+ # @param port [Integer] the port to listen on
92
+ # @param tree [Tree] the checkout
93
+ # @return [String] a note that the server stopped
94
+ def present(port, tree)
95
+ require "hecks/forms/banking_presentation"
96
+ app = Forms::BankingPresentation.app(root: tree.root)
97
+ warn "banking forms, in memory, on http://localhost:#{port}/ - no authentication, no CSRF " \
98
+ "protection, no caller identity; do not expose beyond localhost"
99
+ (CorpusTasks.web_server || method(:rack_serve)).call(app: app, port: port)
100
+ "presented on port #{port}, now stopped"
101
+ end
102
+
103
+ # @param app [#call] the Rack app
104
+ # @param port [Integer] the port
105
+ # @return [void]
106
+ def rack_serve(app:, port:)
107
+ require "rackup"
108
+ Rackup::Server.start(app: app, Port: port, server: "webrick")
109
+ end
110
+
111
+ # @param tree [Tree] the checkout
112
+ # @return [String] each domain with a Rust feature: its feature, a tab, and its directory
113
+ def rust_domains(tree)
114
+ Corpus.rust_domains(root: tree.root).map { |domain| "#{domain.feature}\t#{tree.relative(domain.dir)}" }
115
+ .join("\n")
116
+ end
117
+
118
+ # @param tree [Tree] the checkout
119
+ # @return [String] the directories regeneration walks, in order, one for each line
120
+ def regen_order(tree)
121
+ Corpus.rust_regen_order(root: tree.root).map { |domain| tree.relative(domain.dir) }.join("\n")
122
+ end
123
+
124
+ # Runs the coverage tool over every generated module. A module named in
125
+ # `Corpus::RUST_COVERAGE_PENDING` must still fail; every other one must pass.
126
+ #
127
+ # @param tree [Tree] the checkout
128
+ # @return [String] one line for each module, and how many were checked
129
+ # @raise [ConsoleCapture::Failure] with every module that failed, or that passes now while
130
+ # still listed as pending
131
+ def coverage(tree)
132
+ modules = Corpus.generated_modules(root: tree.root)
133
+ pending = Corpus::RUST_COVERAGE_PENDING
134
+ unknown = pending.keys - modules
135
+ raise ConsoleCapture::Failure, "pending names #{unknown.join(', ')}, with no generated module" if unknown.any?
136
+
137
+ lines, problems = judge(modules, pending, coverage_results(modules, tree))
138
+ raise ConsoleCapture::Failure, [*lines, "", *problems].join("\n") if problems.any?
139
+
140
+ [*lines, "#{modules.size} generated modules checked"].join("\n")
141
+ end
142
+
143
+ # @param modules [Array<String>] the generated modules
144
+ # @param pending [Hash{String => String}] the modules known to fail, and why
145
+ # @param results [Hash{String => Array}] each module's `[passed, output]`
146
+ # @return [Array(Array<String>, Array<String>)] the report lines and the problems
147
+ def judge(modules, pending, results)
148
+ problems = []
149
+ lines = modules.map do |name|
150
+ passed, output = results.fetch(name)
151
+ if pending.key?(name)
152
+ problems << "#{name} passes now - delete it from Hecks::Corpus::RUST_COVERAGE_PENDING" if passed
153
+ "#{name}: pending (#{passed ? 'NOW PASSES' : 'still fails'}) - #{pending[name]}"
154
+ else
155
+ problems << "#{name} failed:\n#{output}" unless passed
156
+ "#{name}: #{passed ? 'ok' : 'FAILED'}"
157
+ end
158
+ end
159
+ [lines, problems]
160
+ end
161
+
162
+ # @param modules [Array<String>] the generated modules
163
+ # @param tree [Tree] the checkout
164
+ # @return [Hash{String => Array}] each module's `[passed, output]`
165
+ def coverage_results(modules, tree)
166
+ runner = CorpusTasks.coverage_runner || RustBuild
167
+ env = { "HECKS_RUST_DIR" => tree.path("rust") }
168
+ modules.to_h do |name|
169
+ result = runner.capture("rust_coverage", [name], env: env)
170
+ [name, [result.ok?, [result.out, result.err].join]]
171
+ end
172
+ end
173
+
174
+ # @param operation [String] `ir_constructs`, `ir_duplicates` or `ir_impact`
175
+ # @param args [Hash] the query's plain arguments
176
+ # @return [String] the formatted answer
177
+ # @raise [ConsoleCapture::Failure] when the query refuses its arguments
178
+ def ir_query(operation, args)
179
+ case operation
180
+ when "ir_constructs" then QueryIR.format_constructs(QueryIR.constructs(words(args[:names])))
181
+ when "ir_duplicates" then duplicates(args)
182
+ else QueryIR.format_impact_preview(QueryIR.impact_preview(args[:name], args[:field]))
183
+ end
184
+ rescue ArgumentError => e
185
+ raise ConsoleCapture::Failure, e.message
186
+ end
187
+
188
+ # @param args [Hash] `domains` and `meta`
189
+ # @return [String] the duplicated rules; the meta-domain is included when asked for, or
190
+ # when no domain is named
191
+ def duplicates(args)
192
+ domains = args[:domains] ? words(args[:domains]) : nil
193
+ QueryIR.format_duplicates(QueryIR.duplicates(domains: domains, include_meta: args[:meta] == true || domains.nil?))
194
+ end
195
+
196
+ # @param list [String, nil] a comma-separated list
197
+ # @return [Array<String>] its items
198
+ def words(list) = list.to_s.split(",").map(&:strip).reject(&:empty?)
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "json"
5
+ require "hecks/release/runner/commands"
6
+ require_relative "secret_vault"
7
+
8
+ module Hecks
9
+ module Adapters
10
+ module Codebase
11
+ # The `GemRegistry` adapter: what a release does with rubygems.org and the `gem` program.
12
+ #
13
+ # It asks the registry which versions are out (over `curl`, no credentials), builds the gem
14
+ # from the checkout's gemspec, and pushes it with the key the SecretVault holds. A built gem
15
+ # file is always deleted again, whether the push worked or not.
16
+ class GemRegistry
17
+ # Where RubyGems lists the published versions of the gem.
18
+ VERSIONS_URL = "https://rubygems.org/api/v1/versions/hecks.json"
19
+
20
+ # The env file `op run` reads the push key from, relative to the checkout.
21
+ ENV_FILE = "release/gem_push.env"
22
+
23
+ # @param root [String] the checkout's root
24
+ # @param commands [#capture, #run!] starts each process
25
+ # @param vault [SecretVault, nil] holds the push key; one over `commands` when nil
26
+ def initialize(root:, commands:, vault: nil)
27
+ @root = root
28
+ @commands = commands
29
+ @vault = vault || SecretVault.new(commands: commands)
30
+ end
31
+
32
+ # Says whether RubyGems lists the gem at a version.
33
+ #
34
+ # @param version [String] the version to look for
35
+ # @return [Boolean] true when it is published
36
+ # @raise [Hecks::Release::Runner::Refusal] when RubyGems cannot be reached or answers with
37
+ # something that is not a version list
38
+ def published?(version)
39
+ result = @commands.capture("curl", "-fsS", VERSIONS_URL, chdir: @root)
40
+ unless result.success?
41
+ raise Release::Runner::Refusal, "could not list published hecks versions (#{result.stderr.strip}); " \
42
+ "check the network and re-run"
43
+ end
44
+
45
+ JSON.parse(result.stdout).any? { |entry| entry["number"] == version }
46
+ rescue JSON::ParserError
47
+ raise Release::Runner::Refusal, "RubyGems answered with something other than a version list; " \
48
+ "re-run in a minute"
49
+ end
50
+
51
+ # Builds the gem, to prove it builds, and deletes it again.
52
+ #
53
+ # @param version [String] the version being released
54
+ # @return [void]
55
+ # @raise [Hecks::Release::Runner::CommandFailed] when the build fails
56
+ def build_only!(version)
57
+ @commands.run!("gem", "build", "hecks.gemspec", chdir: @root)
58
+ ensure
59
+ discard(version)
60
+ end
61
+
62
+ # Builds the gem and pushes it to rubygems.org, then deletes the file.
63
+ #
64
+ # @param version [String] the version being released
65
+ # @return [void]
66
+ # @raise [Hecks::Release::Runner::CommandFailed] when the build or the push fails
67
+ def push!(version)
68
+ @commands.run!("gem", "build", "hecks.gemspec", chdir: @root)
69
+ @vault.run!(ENV_FILE, "gem", "push", "hecks-#{version}.gem", chdir: @root)
70
+ ensure
71
+ discard(version)
72
+ end
73
+
74
+ private
75
+
76
+ def discard(version) = FileUtils.rm_f(File.join(@root, "hecks-#{version}.gem"))
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require "hecks/kernel_capabilities"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ module Codebase
9
+ # What Codebase's `KernelRun` asks of the working tree: projecting the capability enums the
10
+ # hand-written Rust kernel is matched against, and checking that each capability the grammar
11
+ # admits has its hand-written file.
12
+ #
13
+ # The projection is built in memory by `KernelCapabilities`, the code
14
+ # `hecks project_kernel_capabilities` runs, and compared with the tree; it writes only when
15
+ # confirmed. The coverage check reads the tree and writes nothing.
16
+ module KernelTables
17
+ # Every operation this family carries out.
18
+ OPERATIONS = %w[project_kernel_capabilities measure_kernel_coverage].freeze
19
+
20
+ module_function
21
+
22
+ # Carries out one operation.
23
+ #
24
+ # @param operation [String] one of `OPERATIONS`
25
+ # @param held [Hash] the `KernelRun` record's fields
26
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
27
+ # @param shell [#capture] unused; the family starts no child process
28
+ # @return [String] the drift report, or the coverage report
29
+ # @raise [ConsoleCapture::Failure] when a capability has no kernel file
30
+ def call(operation, held, tree, shell: nil)
31
+ _ = shell
32
+ confirm = (held[:confirm].is_a?(Hash) ? held[:confirm][:value] : held[:confirm]) == true
33
+ return coverage(tree) if operation == "measure_kernel_coverage"
34
+
35
+ result = KernelCapabilities.build(root: tree.root)
36
+ tree.apply(result.content, stale: result.stale, confirm: confirm)
37
+ end
38
+
39
+ # Lists every capability the live grammar admits with whether its file is there.
40
+ #
41
+ # @param tree [Tree] the checkout
42
+ # @return [String] one line for each capability, and a verdict
43
+ # @raise [ConsoleCapture::Failure] when any capability has no file
44
+ def coverage(tree)
45
+ lines, verdict, complete = KernelCapabilities.coverage_report(root: tree.root)
46
+ report = [lines, "", verdict].join("\n")
47
+ return report if complete
48
+
49
+ raise ConsoleCapture::Failure, report
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require_relative "tree"
5
+ require_relative "../shell"
6
+ require "hecks/projection_files"
7
+ require "hecks/grammar/evolve"
8
+
9
+ module Hecks
10
+ module Adapters
11
+ module Codebase
12
+ # What Codebase's `LanguageRun` asks of the working tree: projecting the language's tables
13
+ # and walking a word through its lifecycle.
14
+ #
15
+ # A projection is built in memory by {ProjectionFiles} (the same code the `hecks project_*`
16
+ # scripts run) and compared with the tree; it writes only when confirmed. An evolution edits
17
+ # the syntax tables through {Grammar::Evolve}: unconfirmed it is rehearsed against an
18
+ # in-memory copy and reports the edit it would make; confirmed it regenerates the golden IR
19
+ # and holds the gates in a child process, and puts every file back if a gate refuses.
20
+ module Language
21
+ # The projection each operation runs.
22
+ PROJECTIONS = {
23
+ "project_model" => :model,
24
+ "project_vocabulary" => :vocabulary,
25
+ "project_rust_vocabulary" => :rust_vocabulary,
26
+ "project_reserved_names" => :reserved_names,
27
+ "project_parser_table" => :parser_table,
28
+ "project_bootstrap_table" => :bootstrap_table,
29
+ "project_field_hints" => :field_hints,
30
+ "project_expression_tables" => :expression_tables,
31
+ "project_reference" => :reference
32
+ }.freeze
33
+
34
+ # The status each word or argument operation moves a row to.
35
+ STATUSES = { "admit" => "admitted", "deprecate" => "deprecated", "retire" => "retired",
36
+ "admit_argument" => "admitted", "deprecate_argument" => "deprecated",
37
+ "retire_argument" => "retired" }.freeze
38
+
39
+ # Every operation this family carries out.
40
+ OPERATIONS = (PROJECTIONS.keys + %w[propose rename propose_argument] + STATUSES.keys).freeze
41
+
42
+ # The specs that hold a grammar edit: the syntax rows agree with the builder, the lifecycle
43
+ # holds, and the golden IR is the one the language produces.
44
+ GATES = %w[spec/syntax_conformance_spec.rb spec/syntax_lifecycle_spec.rb spec/ir_golden_spec.rb].freeze
45
+
46
+ # The golden IR a grammar edit regenerates.
47
+ GOLDEN = "spec/golden/ir/Bluebook.json"
48
+
49
+ # What the tool says after a proposal or a rename, which still needs hand work.
50
+ FOLLOW_UP = {
51
+ "propose" => "Proposed. It reaches no projection until admitted. Before `hecks admit`:\n " \
52
+ "1. teach the %<context>s builder the word (and its spec/dsl_spec example)",
53
+ "rename" => "Renamed. The old spelling keeps parsing — that is the point. Before this holds:\n " \
54
+ "1. alias the new word to the old in the %<context>s builder " \
55
+ "(alias_method :%<new_name>s, :%<word>s)\n " \
56
+ "2. add the identical-IR example to spec/dsl_spec.rb",
57
+ "propose_argument" => "Proposed. It reaches no projection until admitted. Before " \
58
+ "`hecks admit_argument`:\n " \
59
+ "1. teach the %<context>s builder's %<word>s method the argument"
60
+ }.freeze
61
+
62
+ module_function
63
+
64
+ # Carries out one operation.
65
+ #
66
+ # @param operation [String] one of `OPERATIONS`
67
+ # @param held [Hash] the `LanguageRun` record's fields
68
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
69
+ # @param shell [#capture] starts the gates' child process
70
+ # @return [String] what was found, or done
71
+ # @raise [ConsoleCapture::Failure] when the language refuses the edit, or a gate does
72
+ def call(operation, held, tree, shell: Shell.new)
73
+ args = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
74
+ return project(operation, args, tree) if PROJECTIONS.key?(operation)
75
+
76
+ evolve(operation, args, tree, shell)
77
+ end
78
+
79
+ # Where every word stands: the rows not simply admitted, and the renamed ones.
80
+ #
81
+ # @return [String] a count, then a line for each row that is moving or renamed
82
+ def word_status
83
+ rows = Grammar::Evolve.keyword_rows
84
+ moving = rows.reject { |row| row[:status] == "admitted" }
85
+ renamed = rows.reject { |row| row[:was].to_s.empty? }
86
+ lines = ["#{rows.size} keyword rows; #{moving.size} not simply admitted; #{renamed.size} renamed"]
87
+ lines += moving.map { |row| " #{row[:status].ljust(10)} #{row[:context]}.#{row[:word]}" }
88
+ lines += renamed.map { |row| " renamed #{row[:context]}.#{row[:word]} (was #{row[:was]})" }
89
+ lines.join("\n")
90
+ end
91
+
92
+ # @param operation [String] a projection's operation
93
+ # @param args [Hash] the record's plain fields
94
+ # @param tree [Tree] the checkout
95
+ # @return [String] the projected text for `stdout`, or the drift report
96
+ # @raise [ConsoleCapture::Failure] when the language cannot be projected
97
+ def project(operation, args, tree)
98
+ result = ProjectionFiles.build(PROJECTIONS.fetch(operation), root: tree.root)
99
+ return result.content.values.first if args[:stdout]
100
+
101
+ tree.apply(result.content, stale: result.stale, confirm: args[:confirm] == true)
102
+ rescue ProjectionFiles::Refused => e
103
+ raise ConsoleCapture::Failure, e.message
104
+ end
105
+
106
+ # @param operation [String] a word or argument operation
107
+ # @param args [Hash] the record's plain fields
108
+ # @param tree [Tree] the checkout
109
+ # @param shell [#capture] starts the gates
110
+ # @return [String] the rehearsed edit, or the confirmed edit's outcome
111
+ # @raise [ConsoleCapture::Failure] when the language or a gate refuses
112
+ def evolve(operation, args, tree, shell)
113
+ change = -> { edit(operation, args) }
114
+ return rehearse(change, tree) unless args[:confirm] == true
115
+
116
+ guarded(operation, args, tree, shell, change)
117
+ rescue Grammar::Evolve::Refusal => e
118
+ raise ConsoleCapture::Failure, e.message
119
+ end
120
+
121
+ # @param edit [#call] the edit to make
122
+ # @param tree [Tree] the checkout
123
+ # @return [String] each file the edit would change, with its lines added and removed
124
+ def rehearse(edit, tree)
125
+ changed = Grammar::Evolve.rehearse(&edit)
126
+ lines = changed.map do |path, text|
127
+ before = File.read(path).lines
128
+ after = text.lines
129
+ " changed #{tree.relative(path)} (+#{(after - before).size} -#{(before - after).size} lines)"
130
+ end
131
+ ["dry run, #{changed.size} file changes (add --confirm to make them, regenerate the golden and hold the gates):",
132
+ *lines].join("\n")
133
+ end
134
+
135
+ # Makes the edit, regenerates the golden and holds the gates; puts every file back if the
136
+ # edit or a gate refuses.
137
+ #
138
+ # @param operation [String] the operation, for the follow-up it prints
139
+ # @param args [Hash] the record's plain fields
140
+ # @param tree [Tree] the checkout
141
+ # @param shell [#capture] starts the child processes
142
+ # @param edit [#call] the edit to make
143
+ # @return [String] what the gates held, and what is left to do by hand
144
+ # @raise [ConsoleCapture::Failure] when the edit or a gate refuses; nothing was changed
145
+ def guarded(operation, args, tree, shell, edit)
146
+ paths = Grammar::Evolve.syntax_paths + [tree.path(GOLDEN)]
147
+ snapshots = paths.to_h { |path| [path, File.read(path)] }
148
+ Grammar::Evolve.restore_on_raise(paths, &edit)
149
+ regenerate(tree, shell)
150
+ gates = shell.capture("bundle", "exec", "rspec", *GATES, chdir: tree.root)
151
+ unless gates.ok?
152
+ snapshots.each { |path, text| File.write(path, text) }
153
+ raise ConsoleCapture::Failure,
154
+ "RESTORED — the gates refused, and the failures are the checklist. Nothing was " \
155
+ "changed.\n#{[gates.out, gates.err].join.strip}"
156
+ end
157
+ ["#{args[:context]}.#{args[:word]} — the gates hold. Regenerated projections and the golden " \
158
+ "are in the tree.", follow_up(operation, args)].compact.join("\n")
159
+ end
160
+
161
+ # @param tree [Tree] the checkout
162
+ # @param shell [#capture] starts the child process
163
+ # @return [void]
164
+ def regenerate(tree, shell)
165
+ shell.capture("bundle", "exec", "rspec", "spec/ir_golden_spec.rb", env: { "GOLDEN" => "rewrite" },
166
+ chdir: tree.root)
167
+ end
168
+
169
+ # @param operation [String] the operation
170
+ # @param args [Hash] the record's plain fields
171
+ # @return [String, nil] what still needs hand work, if anything
172
+ def follow_up(operation, args)
173
+ text = FOLLOW_UP[operation] or return nil
174
+
175
+ format(text, context: args[:context], new_name: args[:new_name], word: args[:word])
176
+ end
177
+
178
+ # Makes one edit to the syntax tables.
179
+ #
180
+ # @param operation [String] a word or argument operation
181
+ # @param args [Hash] the record's plain fields
182
+ # @return [void]
183
+ # @raise [Grammar::Evolve::Refusal] when the tables refuse the edit
184
+ def edit(operation, args)
185
+ case operation
186
+ when "propose" then propose(args)
187
+ when "rename" then rename(args)
188
+ when "propose_argument" then propose_argument(args)
189
+ when "admit", "deprecate", "retire" then set_status(operation, args)
190
+ else set_argument_status(operation, args)
191
+ end
192
+ end
193
+
194
+ # @param args [Hash] the record's plain fields
195
+ # @return [void]
196
+ def propose(args)
197
+ Grammar::Evolve.propose(word: args[:word], context: args[:context], body: args[:body] || "none",
198
+ inner: args[:inner] || "", opens: args[:opens] || "", fills: args[:fills] || "")
199
+ end
200
+
201
+ # @param args [Hash] the record's plain fields
202
+ # @return [void]
203
+ # @raise [Grammar::Evolve::Refusal] when no new name was given
204
+ def rename(args)
205
+ to = args[:new_name] or refuse("a rename goes somewhere: new_name=")
206
+ Grammar::Evolve.rename(word: args[:word], context: args[:context], to: to)
207
+ end
208
+
209
+ # @param args [Hash] the record's plain fields
210
+ # @return [void]
211
+ def propose_argument(args)
212
+ Grammar::Evolve.propose_argument(keyword: args[:word], context: args[:context], kind: args[:kind],
213
+ required: args[:required] || "false", at: args[:at] || "",
214
+ named: args[:named] || "", fills: args[:fills] || "",
215
+ pairs_shape: args[:pairs_shape])
216
+ end
217
+
218
+ # @param operation [String] `admit`, `deprecate` or `retire`
219
+ # @param args [Hash] the record's plain fields
220
+ # @return [void]
221
+ def set_status(operation, args)
222
+ Grammar::Evolve.set_status(word: args[:word], context: args[:context], to: STATUSES.fetch(operation))
223
+ end
224
+
225
+ # @param operation [String] the argument form of `admit`, `deprecate` or `retire`
226
+ # @param args [Hash] the record's plain fields
227
+ # @return [void]
228
+ def set_argument_status(operation, args)
229
+ Grammar::Evolve.set_argument_status(keyword: args[:word], context: args[:context],
230
+ to: STATUSES.fetch(operation), at: args[:at] || "",
231
+ named: args[:named] || "")
232
+ end
233
+
234
+ # @param message [String] why the edit cannot be made
235
+ # @raise [Grammar::Evolve::Refusal] always
236
+ def refuse(message) = raise(Grammar::Evolve::Refusal, message)
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+ require "hecks/release/runner/commands"
5
+ require_relative "secret_vault"
6
+
7
+ module Hecks
8
+ module Adapters
9
+ module Codebase
10
+ # The `NpmRegistry` adapter: what a release does with npm and the `@hecks/client` package.
11
+ #
12
+ # It asks npm whether a version is out (no credentials), installs the package's
13
+ # dependencies, and publishes it, either as a dry run (a pack, no credentials) or with the
14
+ # token the SecretVault holds. The token bypasses 2FA, so the publish runs with
15
+ # `--auth-type=web` and its output is not captured: the approval link reaches the terminal.
16
+ class NpmRegistry
17
+ # The package, by name.
18
+ PACKAGE = "@hecks/client"
19
+
20
+ # Where the package stands, relative to the checkout.
21
+ PACKAGE_DIR = "packages/hecks-client"
22
+
23
+ # The env file `op run` reads the publish token from, relative to the checkout.
24
+ ENV_FILE = "release/npm_publish.env"
25
+
26
+ # The npmrc line that reads the token from the environment `op run` sets.
27
+ USERCONFIG_LINE = "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}"
28
+
29
+ # @param root [String] the checkout's root
30
+ # @param commands [#capture, #run!] starts each process
31
+ # @param vault [SecretVault, nil] holds the publish token; one over `commands` when nil
32
+ def initialize(root:, commands:, vault: nil)
33
+ @root = root
34
+ @commands = commands
35
+ @vault = vault || SecretVault.new(commands: commands)
36
+ end
37
+
38
+ # Says whether npm lists the package at a version.
39
+ #
40
+ # @param version [String] the version to look for
41
+ # @return [Boolean] true when it is published
42
+ # @raise [Hecks::Release::Runner::Refusal] when npm fails for any reason other than the
43
+ # version not existing
44
+ def published?(version)
45
+ result = @commands.capture("npm", "view", "#{PACKAGE}@#{version}", "version", chdir: @root)
46
+ return result.stdout.strip == version if result.success?
47
+ return false if result.stderr.include?("E404")
48
+
49
+ raise Release::Runner::Refusal,
50
+ "could not check npm for #{PACKAGE}@#{version} (#{result.stderr.strip.lines.first}); " \
51
+ "check the network and re-run"
52
+ end
53
+
54
+ # @return [Boolean] whether the package's dependencies are already installed
55
+ def installed?
56
+ Dir.exist?(File.join(package_dir, "node_modules"))
57
+ end
58
+
59
+ # Installs the package's dependencies with `npm ci`.
60
+ #
61
+ # @return [void]
62
+ # @raise [Hecks::Release::Runner::CommandFailed] when it fails
63
+ def install!
64
+ @commands.run!("npm", "ci", chdir: package_dir)
65
+ end
66
+
67
+ # Packs the package and publishes nothing.
68
+ #
69
+ # @return [void]
70
+ # @raise [Hecks::Release::Runner::CommandFailed] when the pack fails
71
+ def dry_publish!
72
+ @commands.run!("npm", "publish", "--dry-run", "--access", "public", chdir: package_dir)
73
+ end
74
+
75
+ # Publishes the package with the token the vault holds.
76
+ #
77
+ # @return [void]
78
+ # @raise [Hecks::Release::Runner::CommandFailed] when the publish fails
79
+ def publish!
80
+ with_userconfig do |userconfig|
81
+ @vault.run!(File.join(@root, ENV_FILE), "npm", "publish", "--access", "public", "--auth-type=web",
82
+ "--userconfig", userconfig, chdir: package_dir)
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def package_dir = File.join(@root, PACKAGE_DIR)
89
+
90
+ def with_userconfig
91
+ file = Tempfile.new(["hecks-npmrc", ".npmrc"])
92
+ file.chmod(0o600)
93
+ file.write("#{USERCONFIG_LINE}\n")
94
+ file.flush
95
+ yield file.path
96
+ ensure
97
+ file&.close!
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end