hecks 2.9.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 (600) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +51 -6
  3. data/lib/hecks/adapters/driven/heki/journal.rb +1 -1
  4. data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
  5. data/lib/hecks/adapters/driven/lambda.rb +1 -1
  6. data/lib/hecks/adapters/driven/memory.rb +16 -3
  7. data/lib/hecks/adapters/driven/postgres/reconnect.rb +6 -2
  8. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
  9. data/lib/hecks/adapters/driven/postgres.rb +4 -2
  10. data/lib/hecks/adapters/driven/prism.rb +41 -8
  11. data/lib/hecks/adapters/driven/tenant_provisioner.rb +73 -16
  12. data/lib/hecks/behaviors/expectations.rb +1 -1
  13. data/lib/hecks/behaviors.rb +1 -1
  14. data/lib/hecks/bench/cli.rb +62 -0
  15. data/lib/hecks/bench/environment.rb +71 -0
  16. data/lib/hecks/bench/postgres_probe.rb +30 -0
  17. data/lib/hecks/bench/report.rb +76 -0
  18. data/lib/hecks/bench/ruby_runner.rb +93 -0
  19. data/lib/hecks/bench/run.rb +55 -0
  20. data/lib/hecks/bench/rust_runner.rb +101 -0
  21. data/lib/hecks/bench/stats.rb +46 -0
  22. data/lib/hecks/bench/suite.rb +98 -0
  23. data/lib/hecks/bench/workload.rb +89 -0
  24. data/lib/hecks/bench.rb +17 -0
  25. data/lib/hecks/bluebook/assembly/contracts.rb +2 -0
  26. data/lib/hecks/bluebook/attribute.rb +1 -1
  27. data/lib/hecks/bluebook/behaviour/aggregate.rb +30 -1
  28. data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -0
  29. data/lib/hecks/bluebook/chapter.rb +6 -2
  30. data/lib/hecks/bluebook/domain_port.rb +36 -5
  31. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +10 -0
  32. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +8 -0
  33. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -1
  34. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +31 -3
  35. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +122 -3
  36. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +1 -1
  37. data/lib/hecks/bluebook/dsl/query_builder.rb +27 -1
  38. data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -1
  39. data/lib/hecks/bluebook/dsl/world_builder.rb +29 -2
  40. data/lib/hecks/bluebook/expression/canonical_form.rb +1 -1
  41. data/lib/hecks/bluebook/expression/resolver.rb +3 -2
  42. data/lib/hecks/bluebook/hexagon.rb +13 -5
  43. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +1 -0
  44. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +4 -1
  45. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
  46. data/lib/hecks/bluebook/meta_validator.rb +9 -4
  47. data/lib/hecks/bluebook/model_check.rb +23 -0
  48. data/lib/hecks/bluebook/pattern_subset.rb +38 -0
  49. data/lib/hecks/bluebook/query.rb +20 -5
  50. data/lib/hecks/bluebook/smoke_test.rb +1 -1
  51. data/lib/hecks/canonical_json.rb +30 -0
  52. data/lib/hecks/chapters.rb +102 -0
  53. data/lib/hecks/cli/behaviors.rb +61 -0
  54. data/lib/hecks/cli/canonicalise.rb +25 -0
  55. data/lib/hecks/cli/check_engine_agreement.rb +32 -0
  56. data/lib/hecks/cli/check_era.rb +88 -0
  57. data/lib/hecks/cli/console.rb +66 -0
  58. data/lib/hecks/cli/deploy_template_diff.rb +40 -0
  59. data/lib/hecks/cli/doc_coverage.rb +32 -0
  60. data/lib/hecks/cli/document.rb +2 -2
  61. data/lib/hecks/cli/expression_projection.rb +41 -0
  62. data/lib/hecks/cli/follow.rb +88 -0
  63. data/lib/hecks/cli/history.rb +44 -0
  64. data/lib/hecks/cli/ir.rb +1 -1
  65. data/lib/hecks/cli/mcp.rb +3 -3
  66. data/lib/hecks/cli/model_check.rb +7 -4
  67. data/lib/hecks/cli/pattern_cases.rb +47 -0
  68. data/lib/hecks/cli/present.rb +39 -0
  69. data/lib/hecks/cli/project_cli.rb +224 -32
  70. data/lib/hecks/cli/project_diagrams.rb +4 -3
  71. data/lib/hecks/cli/project_glossary.rb +44 -0
  72. data/lib/hecks/cli/reference.rb +46 -0
  73. data/lib/hecks/cli/refresh_projections.rb +44 -0
  74. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
  75. data/lib/hecks/cli/release.rb +70 -0
  76. data/lib/hecks/cli/release_gem.rb +59 -0
  77. data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
  78. data/lib/hecks/cli/rspec_shard_files.rb +66 -0
  79. data/lib/hecks/cli/run.rb +3 -3
  80. data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
  81. data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
  82. data/lib/hecks/cli/shape.rb +70 -0
  83. data/lib/hecks/cli/smoke_http.rb +230 -0
  84. data/lib/hecks/cli/smoke_test.rb +5 -3
  85. data/lib/hecks/cli/spec_example.rb +27 -0
  86. data/lib/hecks/cli/statements.rb +32 -0
  87. data/lib/hecks/cli/stores.rb +4 -5
  88. data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
  89. data/lib/hecks/cli.rb +201 -52
  90. data/lib/hecks/codemod.rb +324 -0
  91. data/lib/hecks/corpus.rb +423 -0
  92. data/lib/hecks/deploy/bluebook/deploy.bluebook +591 -23
  93. data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -4
  94. data/lib/hecks/deploy/oidc.json +82 -2
  95. data/lib/hecks/doc/reference.rb +351 -0
  96. data/lib/hecks/doors/cli_door.rb +196 -0
  97. data/lib/hecks/doors/cli_runner.rb +297 -0
  98. data/lib/hecks/{facade → doors}/command_request.rb +1 -1
  99. data/lib/hecks/{facade → doors}/handle.rb +2 -2
  100. data/lib/hecks/{facade → doors}/json_door.rb +4 -4
  101. data/lib/hecks/doors/launcher_options.rb +129 -0
  102. data/lib/hecks/{cli → doors}/mcp_door.rb +7 -7
  103. data/lib/hecks/doors/mcp_door_scope.rb +97 -0
  104. data/lib/hecks/{facade/surface → doors/ruby_door}/aggregate_door.rb +8 -3
  105. data/lib/hecks/{facade/surface → doors/ruby_door}/chapter.rb +3 -3
  106. data/lib/hecks/{facade/surface.rb → doors/ruby_door.rb} +36 -5
  107. data/lib/hecks/doors.rb +61 -0
  108. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +1 -1
  109. data/lib/hecks/embryonaut_bluebook.rb +1 -1
  110. data/lib/hecks/engine_agreement.rb +156 -0
  111. data/lib/hecks/facade.rb +24 -37
  112. data/lib/hecks/forms/app.rb +6 -6
  113. data/lib/hecks/forms/banking_presentation.rb +50 -0
  114. data/lib/hecks/forms/field_shape.rb +2 -1
  115. data/lib/hecks/forms/port_argument.rb +1 -1
  116. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
  117. data/lib/hecks/fuzzing/combination_miner.rb +86 -0
  118. data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
  119. data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
  120. data/lib/hecks/fuzzing/differential.rb +156 -0
  121. data/lib/hecks/fuzzing/domain_generator.rb +615 -0
  122. data/lib/hecks/fuzzing/era_boundary.rb +71 -0
  123. data/lib/hecks/fuzzing/form_census.rb +136 -0
  124. data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
  125. data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
  126. data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
  127. data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
  128. data/lib/hecks/fuzzing/outside_world.rb +45 -0
  129. data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
  130. data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
  131. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
  132. data/lib/hecks/fuzzing/properties/guards.rb +190 -0
  133. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
  134. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
  135. data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
  136. data/lib/hecks/fuzzing/properties/querying.rb +175 -0
  137. data/lib/hecks/fuzzing/properties.rb +162 -0
  138. data/lib/hecks/fuzzing/qa_settings.rb +123 -0
  139. data/lib/hecks/fuzzing/replay.rb +505 -0
  140. data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
  141. data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
  142. data/lib/hecks/fuzzing/self_consistency.rb +339 -0
  143. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
  144. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
  145. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
  146. data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
  147. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
  148. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
  149. data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
  150. data/lib/hecks/fuzzing/shrinker.rb +166 -0
  151. data/lib/hecks/fuzzing/structural_skips.rb +33 -0
  152. data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
  153. data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
  154. data/lib/hecks/fuzzing/value_generator.rb +216 -0
  155. data/lib/hecks/fuzzing.rb +23 -0
  156. data/lib/hecks/grammar/evolve.rb +336 -0
  157. data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
  158. data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
  159. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
  160. data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
  161. data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
  162. data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
  163. data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
  164. data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
  165. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
  166. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
  167. data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
  168. data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
  169. data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
  170. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
  171. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
  172. data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
  173. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
  174. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
  175. data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
  176. data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
  177. data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
  178. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
  179. data/lib/hecks/hecks/adapters/git.adapter +7 -0
  180. data/lib/hecks/hecks/adapters/git.rb +102 -0
  181. data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
  182. data/lib/hecks/hecks/adapters/host_http.rb +65 -0
  183. data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
  184. data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
  185. data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
  186. data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
  187. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
  188. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
  189. data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
  190. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
  191. data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
  192. data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
  193. data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
  194. data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
  195. data/lib/hecks/hecks/adapters/local_files.rb +46 -0
  196. data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
  197. data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
  198. data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
  199. data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
  200. data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
  201. data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
  202. data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
  203. data/lib/hecks/hecks/adapters/shell.adapter +7 -0
  204. data/lib/hecks/hecks/adapters/shell.rb +49 -0
  205. data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
  206. data/lib/hecks/hecks/adapters/terminal.rb +74 -0
  207. data/lib/hecks/hecks/codebase.behaviors +172 -0
  208. data/lib/hecks/hecks/codebase.bluebook +2453 -0
  209. data/lib/hecks/hecks/context_map.hecksagon +13 -0
  210. data/lib/hecks/hecks/custodian.behaviors +179 -0
  211. data/lib/hecks/hecks/custodian.bluebook +1847 -0
  212. data/lib/hecks/hecks/deploy.behaviors +74 -0
  213. data/lib/hecks/hecks/deploy.world +12 -0
  214. data/lib/hecks/hecks/environments/memory.world +10 -0
  215. data/lib/hecks/hecks/governance.world +7 -0
  216. data/lib/hecks/hecks/hecks.behaviors +62 -0
  217. data/lib/hecks/hecks/hecks.bluebook +124 -0
  218. data/lib/hecks/hecks/hecks.hecksagon +390 -0
  219. data/lib/hecks/hecks/hecks.world +42 -0
  220. data/lib/hecks/kernel_capabilities.rb +194 -0
  221. data/lib/hecks/language/bluebook/bluebook.bluebook +11 -0
  222. data/lib/hecks/language/bluebook/query.bluebook +7 -0
  223. data/lib/hecks/language/bluebook/vocabulary.bluebook +4 -4
  224. data/lib/hecks/language/hecksagon/domain_port.bluebook +10 -0
  225. data/lib/hecks/language/hecksagon/hecksagon.bluebook +20 -0
  226. data/lib/hecks/mcp_stdio_guard.rb +2 -2
  227. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
  228. data/lib/hecks/persistence_legacy_fixture.rb +113 -0
  229. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +8 -5
  230. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +4 -1
  231. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +15 -2
  232. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +1 -1
  233. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +1 -1
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +32 -15
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +6 -3
  237. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
  238. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +1 -1
  239. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +43 -24
  240. data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
  241. data/lib/hecks/ports/persistence/state_codec.rb +24 -5
  242. data/lib/hecks/projection_files.rb +285 -0
  243. data/lib/hecks/projections/bootstrap_table.rb +1 -1
  244. data/lib/hecks/projections/deploy/fargate.rb +5 -5
  245. data/lib/hecks/projections/deploy/lambda.rb +43 -32
  246. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  247. data/lib/hecks/projections/deploy/preview/template.rb +1 -1
  248. data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
  249. data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
  250. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
  251. data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
  252. data/lib/hecks/projections/deploy/shared.rb +1 -1
  253. data/lib/hecks/projections/diagrams.rb +3 -3
  254. data/lib/hecks/projections/model/deviations.rb +1 -1
  255. data/lib/hecks/projections/parser_table.rb +4 -4
  256. data/lib/hecks/projections/reference.rb +2 -3
  257. data/lib/hecks/projections/rust_vocabulary.rb +1 -1
  258. data/lib/hecks/projector/cli_projector.rb +106 -37
  259. data/lib/hecks/projector.rb +1 -1
  260. data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
  261. data/lib/hecks/quality_control/adapters/agent.rb +58 -0
  262. data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
  263. data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
  264. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
  265. data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
  266. data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
  267. data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
  268. data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
  269. data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
  270. data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
  271. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
  272. data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
  273. data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
  274. data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
  275. data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
  276. data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
  277. data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
  278. data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
  279. data/lib/hecks/quality_control/cli/child.rb +45 -0
  280. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
  281. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
  282. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
  283. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
  284. data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
  285. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
  286. data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
  287. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
  288. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
  289. data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
  290. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
  291. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
  292. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
  293. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
  294. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
  295. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
  296. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
  297. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
  298. data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
  299. data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
  300. data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
  301. data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
  302. data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
  303. data/lib/hecks/query_ir.rb +346 -0
  304. data/lib/hecks/query_ir_mcp.rb +198 -0
  305. data/lib/hecks/release/runner/ci_publisher.rb +2 -2
  306. data/lib/hecks/release/runner/clean_tree.rb +42 -0
  307. data/lib/hecks/release/runner/console.rb +6 -0
  308. data/lib/hecks/release/runner/gem_publisher.rb +14 -7
  309. data/lib/hecks/release/runner/npm_publisher.rb +6 -36
  310. data/lib/hecks/release/runner/preflight.rb +26 -2
  311. data/lib/hecks/release/runner/published.rb +8 -26
  312. data/lib/hecks/release/runner/tagger.rb +30 -15
  313. data/lib/hecks/release/runner.rb +57 -6
  314. data/lib/hecks/router/namespace_installer.rb +3 -3
  315. data/lib/hecks/runtime/adapter_lookup.rb +124 -0
  316. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +4 -0
  317. data/lib/hecks/runtime/dependency_planning.rb +20 -2
  318. data/lib/hecks/runtime/dispatcher.rb +53 -3
  319. data/lib/hecks/runtime/interpreting.rb +3 -0
  320. data/lib/hecks/runtime/loader.rb +65 -12
  321. data/lib/hecks/runtime/outbox.rb +1 -1
  322. data/lib/hecks/runtime/policy_interpreter.rb +5 -2
  323. data/lib/hecks/runtime/port_operation_interpreter.rb +2 -10
  324. data/lib/hecks/runtime/query_interpreter.rb +77 -0
  325. data/lib/hecks/runtime/reaction_outcome.rb +89 -0
  326. data/lib/hecks/runtime/refusal_wording.rb +23 -1
  327. data/lib/hecks/runtime/registry/verification.rb +163 -4
  328. data/lib/hecks/runtime/registry.rb +57 -3
  329. data/lib/hecks/runtime/remote_dispatcher.rb +31 -2
  330. data/lib/hecks/runtime/value/coercion.rb +23 -135
  331. data/lib/hecks/runtime/value/field_checks.rb +172 -0
  332. data/lib/hecks/runtime/value.rb +4 -1
  333. data/lib/hecks/runtime.rb +20 -6
  334. data/lib/hecks/rust_build/conformance.rb +158 -0
  335. data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
  336. data/lib/hecks/rust_build/coverage.rb +218 -0
  337. data/lib/hecks/rust_build/native_build.rb +124 -0
  338. data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
  339. data/lib/hecks/rust_build/project_rust.rb +332 -0
  340. data/lib/hecks/rust_build/wasm.rb +105 -0
  341. data/lib/hecks/rust_build/wasm_browser.rb +113 -0
  342. data/lib/hecks/rust_build.rb +144 -0
  343. data/lib/hecks/storehouse.rb +16 -16
  344. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +2 -2
  345. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +1 -1
  346. data/lib/hecks/three_zero/forms.yml +127 -0
  347. data/lib/hecks/three_zero.rb +12 -0
  348. data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
  349. data/lib/hecks/tools/comment_style.rb +1070 -0
  350. data/lib/hecks/tools/corpus_report.rb +87 -0
  351. data/lib/hecks/tools/deploy_recipe.rb +255 -0
  352. data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
  353. data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
  354. data/lib/hecks/tools/era_projection_backfill.rb +94 -0
  355. data/lib/hecks/tools/era_reattest.rb +146 -0
  356. data/lib/hecks/tools/evolve_run.rb +189 -0
  357. data/lib/hecks/tools/fuzz_sweep.rb +373 -0
  358. data/lib/hecks/tools/heki_compaction.rb +100 -0
  359. data/lib/hecks/tools/hoist_local_givens.rb +246 -0
  360. data/lib/hecks/tools/journal_compaction.rb +89 -0
  361. data/lib/hecks/tools/oidc_manifests.rb +70 -0
  362. data/lib/hecks/tools/query_ir_run.rb +81 -0
  363. data/lib/hecks/tools/regeneration_run.rb +166 -0
  364. data/lib/hecks/tools/rust_comment_style.rb +642 -0
  365. data/lib/hecks/tools/sequence_script.rb +62 -0
  366. data/lib/hecks/tools/tail_merge.rb +117 -0
  367. data/lib/hecks/tools/tenant_provisioning.rb +142 -0
  368. data/lib/hecks/tools/translation_audit.rb +208 -0
  369. data/lib/hecks/tools/translation_scaffold.rb +131 -0
  370. data/lib/hecks/tools.rb +86 -0
  371. data/lib/hecks/version.rb +1 -1
  372. data/lib/hecks.rb +32 -15
  373. data/qa/settings.yml +66 -0
  374. data/rust/.cargo/config.toml +6 -0
  375. data/rust/.gitignore +2 -0
  376. data/rust/Cargo.lock +54 -0
  377. data/rust/Cargo.toml +61 -0
  378. data/rust/build/.cargo/config.toml +3 -0
  379. data/rust/build/.gitignore +1 -0
  380. data/rust/build/Cargo.lock +7 -0
  381. data/rust/build/Cargo.toml +19 -0
  382. data/rust/build/src/build_artifact.rs +47 -0
  383. data/rust/build/src/cargo_sync.rs +248 -0
  384. data/rust/build/src/json.rs +421 -0
  385. data/rust/build/src/lineage_pass.rs +285 -0
  386. data/rust/build/src/main.rs +51 -0
  387. data/rust/build/src/optional_pass.rs +150 -0
  388. data/rust/build/src/pipeline.rs +264 -0
  389. data/rust/build/src/reserved_names.rs +76 -0
  390. data/rust/build/src/resolve.rs +124 -0
  391. data/rust/build/src/root.rs +25 -0
  392. data/rust/build/src/sidecars.rs +73 -0
  393. data/rust/build/src/subprocess.rs +51 -0
  394. data/rust/build/src/tmp.rs +31 -0
  395. data/rust/codegen/.cargo/config.toml +3 -0
  396. data/rust/codegen/.gitignore +1 -0
  397. data/rust/codegen/Cargo.lock +7 -0
  398. data/rust/codegen/Cargo.toml +20 -0
  399. data/rust/codegen/src/attr.rs +32 -0
  400. data/rust/codegen/src/bridging.rs +481 -0
  401. data/rust/codegen/src/commands.rs +1226 -0
  402. data/rust/codegen/src/constraints.rs +109 -0
  403. data/rust/codegen/src/dependency_planning.rs +209 -0
  404. data/rust/codegen/src/domain_generator.rs +1288 -0
  405. data/rust/codegen/src/exemplar.rs +230 -0
  406. data/rust/codegen/src/expr_emitter.rs +87 -0
  407. data/rust/codegen/src/fielded.rs +192 -0
  408. data/rust/codegen/src/hecks_naming.rs +33 -0
  409. data/rust/codegen/src/json.rs +335 -0
  410. data/rust/codegen/src/json_codec.rs +697 -0
  411. data/rust/codegen/src/literal.rs +207 -0
  412. data/rust/codegen/src/main.rs +290 -0
  413. data/rust/codegen/src/manifest.rs +227 -0
  414. data/rust/codegen/src/mutations.rs +784 -0
  415. data/rust/codegen/src/naming.rs +286 -0
  416. data/rust/codegen/src/ports.rs +208 -0
  417. data/rust/codegen/src/prelude.rs +116 -0
  418. data/rust/codegen/src/queries.rs +786 -0
  419. data/rust/codegen/src/reactions.rs +532 -0
  420. data/rust/codegen/src/read_models.rs +697 -0
  421. data/rust/codegen/src/reference_specs.rs +40 -0
  422. data/rust/codegen/src/registry.rs +966 -0
  423. data/rust/codegen/src/reserved_names.rs +76 -0
  424. data/rust/codegen/src/shared.rs +93 -0
  425. data/rust/codegen/src/skip_reason.rs +25 -0
  426. data/rust/codegen/src/types.rs +362 -0
  427. data/rust/host/.cargo/config.toml +3 -0
  428. data/rust/host/.gitignore +1 -0
  429. data/rust/host/Cargo.lock +4297 -0
  430. data/rust/host/Cargo.toml +61 -0
  431. data/rust/host/HECKS_RELEASE +1 -0
  432. data/rust/host/rds-ca-bundle.pem +2736 -0
  433. data/rust/host/src/api.rs +1596 -0
  434. data/rust/host/src/approval.rs +652 -0
  435. data/rust/host/src/auth.rs +1287 -0
  436. data/rust/host/src/bin/expr_harness.rs +46 -0
  437. data/rust/host/src/bin/lineage_harness.rs +119 -0
  438. data/rust/host/src/bin/mint_harness.rs +135 -0
  439. data/rust/host/src/checkout.rs +265 -0
  440. data/rust/host/src/dispatch.rs +1443 -0
  441. data/rust/host/src/expr_json.rs +1117 -0
  442. data/rust/host/src/field_hints.rs +52 -0
  443. data/rust/host/src/ir.rs +733 -0
  444. data/rust/host/src/journal.rs +874 -0
  445. data/rust/host/src/lambda_client.rs +378 -0
  446. data/rust/host/src/log.rs +147 -0
  447. data/rust/host/src/main.rs +474 -0
  448. data/rust/host/src/mint.rs +1865 -0
  449. data/rust/host/src/payments/keystore.rs +330 -0
  450. data/rust/host/src/payments/tests.rs +1400 -0
  451. data/rust/host/src/payments.rs +767 -0
  452. data/rust/host/src/presentation.rs +698 -0
  453. data/rust/host/src/presentation_write.rs +1431 -0
  454. data/rust/host/src/query_step.rs +149 -0
  455. data/rust/host/src/rate_limit.rs +904 -0
  456. data/rust/host/src/reference_transform.rs +241 -0
  457. data/rust/host/src/reference_validate.rs +338 -0
  458. data/rust/host/src/resend.rs +296 -0
  459. data/rust/host/src/secrets.rs +106 -0
  460. data/rust/host/src/server.rs +663 -0
  461. data/rust/host/src/storage_shape.rs +175 -0
  462. data/rust/host/src/test_pg.rs +40 -0
  463. data/rust/host/src/ui_schema.rs +1351 -0
  464. data/rust/host/src/wasm_runner.rs +191 -0
  465. data/rust/host/src/web/newsletter/cooldown.rs +126 -0
  466. data/rust/host/src/web/newsletter/tests.rs +104 -0
  467. data/rust/host/src/web/newsletter.rs +310 -0
  468. data/rust/host/src/web/newsletter_send.rs +357 -0
  469. data/rust/host/src/web/registrations.rs +1505 -0
  470. data/rust/host/src/web.rs +2937 -0
  471. data/rust/lsp/.gitignore +1 -0
  472. data/rust/lsp/Cargo.lock +7 -0
  473. data/rust/lsp/Cargo.toml +16 -0
  474. data/rust/lsp/README.md +133 -0
  475. data/rust/lsp/src/diagnostics.rs +165 -0
  476. data/rust/lsp/src/json.rs +385 -0
  477. data/rust/lsp/src/main.rs +399 -0
  478. data/rust/lsp/src/outline.rs +177 -0
  479. data/rust/lsp/src/rpc.rs +67 -0
  480. data/rust/parser/.cargo/config.toml +5 -0
  481. data/rust/parser/.gitignore +1 -0
  482. data/rust/parser/Cargo.lock +7 -0
  483. data/rust/parser/Cargo.toml +21 -0
  484. data/rust/parser/src/build/closed_sets.rs +27 -0
  485. data/rust/parser/src/build/identity.rs +276 -0
  486. data/rust/parser/src/build/mod.rs +12 -0
  487. data/rust/parser/src/build/naming.rs +141 -0
  488. data/rust/parser/src/build/pattern_subset.rs +161 -0
  489. data/rust/parser/src/build/query_derive.rs +72 -0
  490. data/rust/parser/src/build/query_inference.rs +269 -0
  491. data/rust/parser/src/build/query_options.rs +100 -0
  492. data/rust/parser/src/build/read_model.rs +94 -0
  493. data/rust/parser/src/build/references.rs +32 -0
  494. data/rust/parser/src/canonical.rs +114 -0
  495. data/rust/parser/src/diag.rs +55 -0
  496. data/rust/parser/src/emit.rs +953 -0
  497. data/rust/parser/src/expr/ast_json.rs +147 -0
  498. data/rust/parser/src/expr/evaluator.rs +81 -0
  499. data/rust/parser/src/expr/mod.rs +84 -0
  500. data/rust/parser/src/expr/resolver.rs +497 -0
  501. data/rust/parser/src/ir.rs +387 -0
  502. data/rust/parser/src/keywords.rs +585 -0
  503. data/rust/parser/src/lex.rs +662 -0
  504. data/rust/parser/src/main.rs +252 -0
  505. data/rust/parser/src/parse/aggregate.rs +612 -0
  506. data/rust/parser/src/parse/chapter.rs +517 -0
  507. data/rust/parser/src/parse/command.rs +637 -0
  508. data/rust/parser/src/parse/domain_port.rs +127 -0
  509. data/rust/parser/src/parse/entity.rs +527 -0
  510. data/rust/parser/src/parse/file.rs +67 -0
  511. data/rust/parser/src/parse/hecksagon.rs +231 -0
  512. data/rust/parser/src/parse/lifecycle.rs +162 -0
  513. data/rust/parser/src/parse/mod.rs +1262 -0
  514. data/rust/parser/src/parse/policy.rs +87 -0
  515. data/rust/parser/src/parse/process_manager.rs +305 -0
  516. data/rust/parser/src/parse/query.rs +100 -0
  517. data/rust/parser/src/parse/read_model.rs +214 -0
  518. data/rust/parser/src/parse/value_object.rs +250 -0
  519. data/rust/parser/src/ruby_value.rs +422 -0
  520. data/rust/project/bridging.rb +257 -0
  521. data/rust/project/commands.rb +877 -0
  522. data/rust/project/constraints.rb +86 -0
  523. data/rust/project/dependency_planning.rb +178 -0
  524. data/rust/project/domain_generator.rb +980 -0
  525. data/rust/project/exemplar.rb +148 -0
  526. data/rust/project/expr_emitter.rb +72 -0
  527. data/rust/project/fielded.rb +141 -0
  528. data/rust/project/json_codec.rb +641 -0
  529. data/rust/project/mutations.rb +721 -0
  530. data/rust/project/naming.rb +205 -0
  531. data/rust/project/ports.rb +65 -0
  532. data/rust/project/queries.rb +493 -0
  533. data/rust/project/reactions.rb +317 -0
  534. data/rust/project/read_models.rb +690 -0
  535. data/rust/project/reference_specs.rb +27 -0
  536. data/rust/project/registry.rb +396 -0
  537. data/rust/project/skip_reason.rb +29 -0
  538. data/rust/project/types.rb +225 -0
  539. data/rust/project/write_if_changed.rb +83 -0
  540. data/rust/project.rb +30 -0
  541. data/rust/project_rust_pipeline.rb +383 -0
  542. data/rust/src/exemplar/commands.rs +279 -0
  543. data/rust/src/exemplar/constraints.rs +18 -0
  544. data/rust/src/exemplar/fielded.rs +280 -0
  545. data/rust/src/exemplar/json.rs +277 -0
  546. data/rust/src/exemplar/mod.rs +17 -0
  547. data/rust/src/exemplar/mutations.rs +80 -0
  548. data/rust/src/exemplar/queries.rs +33 -0
  549. data/rust/src/exemplar/reactions.rs +88 -0
  550. data/rust/src/exemplar/read_models.rs +48 -0
  551. data/rust/src/exemplar/registry.rs +166 -0
  552. data/rust/src/exemplar/types.rs +44 -0
  553. data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
  554. data/rust/src/kernel/attribute_shapes/list.rs +18 -0
  555. data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
  556. data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
  557. data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
  558. data/rust/src/kernel/cli.rs +585 -0
  559. data/rust/src/kernel/dispatch.rs +1090 -0
  560. data/rust/src/kernel/expr.rs +458 -0
  561. data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
  562. data/rust/src/kernel/expression_operators/comparison.rs +48 -0
  563. data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
  564. data/rust/src/kernel/expression_operators/logical.rs +13 -0
  565. data/rust/src/kernel/expression_operators/membership.rs +18 -0
  566. data/rust/src/kernel/expression_operators/mod.rs +68 -0
  567. data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
  568. data/rust/src/kernel/expression_operators/positional.rs +126 -0
  569. data/rust/src/kernel/expression_operators/presence.rs +101 -0
  570. data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
  571. data/rust/src/kernel/expression_operators/sized.rs +35 -0
  572. data/rust/src/kernel/expression_operators/text.rs +79 -0
  573. data/rust/src/kernel/expression_operators/to_string.rs +18 -0
  574. data/rust/src/kernel/json.rs +779 -0
  575. data/rust/src/kernel/mod.rs +133 -0
  576. data/rust/src/kernel/named_query.rs +219 -0
  577. data/rust/src/kernel/orchestrate.rs +1810 -0
  578. data/rust/src/kernel/pattern.rs +307 -0
  579. data/rust/src/kernel/query_comparators.rs +206 -0
  580. data/rust/src/kernel/query_ordering.rs +103 -0
  581. data/rust/src/kernel/read_model.rs +914 -0
  582. data/rust/src/kernel/reference_lookup.rs +149 -0
  583. data/rust/src/kernel/repository.rs +468 -0
  584. data/rust/src/kernel/routing.rs +612 -0
  585. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
  586. data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
  587. data/rust/src/kernel/vocab/field_hint.rs +70 -0
  588. data/rust/src/kernel/vocab/mod.rs +20 -0
  589. data/rust/src/kernel/vocab/query_comparator.rs +65 -0
  590. data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
  591. data/rust/src/lib.rs +8 -0
  592. data/rust/src/main.rs +16 -0
  593. data/rust/web/.gitignore +1 -0
  594. data/rust/web/Cargo.lock +119 -0
  595. data/rust/web/Cargo.toml +18 -0
  596. data/rust/web/src/lib.rs +8 -0
  597. metadata +477 -12
  598. data/lib/hecks/facade/cli_door.rb +0 -96
  599. data/lib/hecks/facade/cli_runner.rb +0 -127
  600. data/lib/hecks/mcp_door_scope.rb +0 -95
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "find"
5
+ require "securerandom"
6
+ require_relative "../../version"
7
+
8
+ module Hecks
9
+ module Adapters
10
+ # The Rust workspace a build writes into: the checkout's own `rust/` in a hecks checkout, or a
11
+ # copy of the packaged workspace inside the client's project.
12
+ #
13
+ # A build writes generated code and a Cargo feature into the workspace it is given, and Cargo
14
+ # writes `target/` beside it, so an installed gem's files must never be that workspace. The
15
+ # copy is keyed by gem version (`.hecks/rust/<version>/`): a domain built with one release
16
+ # compiles against that release's kernel, and a newer gem gets a fresh copy beside the old.
17
+ #
18
+ # A checkout is a working tree with `hecks.gemspec` beside `lib/`; the package never carries
19
+ # the gemspec, so an install cannot be mistaken for one.
20
+ class RustWorkspace
21
+ # The file whose presence beside `lib/` marks a hecks checkout.
22
+ CHECKOUT_MARKER = "hecks.gemspec"
23
+
24
+ # What a copy holds: the workspace manifest, the kernel and every crate a domain build uses.
25
+ PACKAGED = %w[Cargo.toml Cargo.lock project.rb project_rust_pipeline.rb project src codegen parser
26
+ host build web lsp].freeze
27
+
28
+ # Left out of a copy: build output anywhere, the corpus tests, and the corpus domains.
29
+ SKIPPED = lambda do |relative|
30
+ relative.split("/").include?("target") || relative == "tests" || relative == "src/generated"
31
+ end
32
+
33
+ # The `[features]` table of a Cargo manifest, up to the next table.
34
+ FEATURES_TABLE = /^\[features\](?:\n(?!\[).*)*/
35
+
36
+ # Written into a copy once it is complete, so an interrupted copy is redone, not reused.
37
+ MARKER = ".hecks-workspace"
38
+
39
+ # Raised when there is no Rust workspace to build in.
40
+ class Unavailable < StandardError; end
41
+
42
+ # @return [String] the gem's root directory (where `lib/` and `rust/` live)
43
+ attr_reader :gem_root
44
+
45
+ # @param gem_root [String] the gem's root directory
46
+ # @param project_root [String] the client project a copy is made inside
47
+ # @param version [String] the gem version a copy is keyed by
48
+ def initialize(gem_root: File.expand_path("../../../..", __dir__), project_root: Dir.pwd,
49
+ version: Hecks::VERSION)
50
+ @gem_root = gem_root
51
+ @project_root = project_root
52
+ @version = version
53
+ end
54
+
55
+ # @return [Boolean] whether the gem is a hecks checkout rather than an installed package
56
+ def checkout?
57
+ File.exist?(File.join(@gem_root, CHECKOUT_MARKER)) && Dir.exist?(File.join(@gem_root, "lib"))
58
+ end
59
+
60
+ # The workspace builds write into: the checkout's own `rust/`, or the versioned copy, made
61
+ # on first use.
62
+ #
63
+ # @return [String] the workspace directory
64
+ # @raise [Unavailable] if the install carries no Rust workspace to copy
65
+ def directory
66
+ return File.join(@gem_root, "rust") if checkout?
67
+
68
+ copy
69
+ end
70
+
71
+ # The environment a build child runs with. A checkout keeps its own defaults; a copy points
72
+ # Cargo's output at itself, so nothing is written into the gem.
73
+ #
74
+ # @return [Hash{String => String}] variables to set
75
+ # @raise [Unavailable] if the install carries no Rust workspace to copy
76
+ def environment
77
+ return {} if checkout?
78
+
79
+ dir = directory
80
+ { "HECKS_RUST_DIR" => dir, "CARGO_TARGET_DIR" => File.join(dir, "target") }
81
+ end
82
+
83
+ private
84
+
85
+ def copy
86
+ target = File.join(@project_root, ".hecks", "rust", @version)
87
+ return target if File.exist?(File.join(target, MARKER))
88
+
89
+ source = File.join(@gem_root, "rust")
90
+ unless File.exist?(File.join(source, "Cargo.toml"))
91
+ raise Unavailable, "this hecks #{@version} install carries no Rust workspace to build in"
92
+ end
93
+
94
+ publish(target) { |staging| build(source, staging) }
95
+ end
96
+
97
+ # Builds the copy in a staging directory beside the target and renames it into place, so a
98
+ # second process never sees, or deletes, a half-made copy; the loser of a race discards its
99
+ # own staging directory and uses the winner's.
100
+ def publish(target)
101
+ FileUtils.mkdir_p(File.dirname(target))
102
+ staging = "#{target}.tmp-#{Process.pid}-#{SecureRandom.hex(4)}"
103
+ yield staging
104
+ install(staging, target)
105
+ ensure
106
+ FileUtils.rm_rf(staging) if staging
107
+ end
108
+
109
+ # Only a directory without the marker, left by an older interrupted copy, is cleared away.
110
+ def install(staging, target)
111
+ File.rename(staging, target)
112
+ target
113
+ rescue Errno::ENOTEMPTY, Errno::EEXIST
114
+ return target if File.exist?(File.join(target, MARKER))
115
+
116
+ FileUtils.rm_rf(target)
117
+ File.rename(staging, target)
118
+ target
119
+ end
120
+
121
+ def build(source, staging)
122
+ FileUtils.mkdir_p(staging)
123
+ PACKAGED.each { |entry| copy_entry(source, staging, entry) }
124
+ clean_features(File.join(staging, "Cargo.toml"))
125
+ File.write(File.join(staging, MARKER), "#{@version}\n")
126
+ end
127
+
128
+ # The packaged manifest lists a feature per corpus domain, and `default` names one of them.
129
+ # None of those domains is in a copy, so the list starts empty and the generator adds the
130
+ # client's own.
131
+ def clean_features(manifest)
132
+ return unless File.exist?(manifest)
133
+
134
+ File.write(manifest, File.read(manifest).sub(FEATURES_TABLE, "[features]\ndefault = []\n"))
135
+ end
136
+
137
+ def copy_entry(source, target, entry)
138
+ from = File.join(source, entry)
139
+ return unless File.exist?(from)
140
+
141
+ Find.find(from) do |path|
142
+ relative = path.delete_prefix("#{source}/")
143
+ Find.prune if SKIPPED.call(relative)
144
+ destination = File.join(target, relative)
145
+ File.directory?(path) ? FileUtils.mkdir_p(destination) : FileUtils.cp(path, destination)
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,7 @@
1
+ # Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
2
+ # and the implementation must load once, from `lib/`, not from the copy.
3
+ require "hecks/hecks/adapters/shell"
4
+
5
+ Hecks.adapter "Shell" do
6
+ port "Shell"
7
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Hecks
6
+ module Adapters
7
+ # The `Shell` port's adapter: runs one program with its arguments and hands back what it said.
8
+ #
9
+ # It is the single place a Custodian adapter starts a subprocess through, so `Git` builds on it
10
+ # rather than calling `Open3` itself. The command is an argument list, never a string for a
11
+ # shell to split, so nothing a caller passes is interpreted.
12
+ class Shell
13
+ # What a program said and how it ended.
14
+ #
15
+ # @!attribute [r] out
16
+ # @return [String] what it wrote to stdout
17
+ # @!attribute [r] err
18
+ # @return [String] what it wrote to stderr
19
+ # @!attribute [r] status
20
+ # @return [Process::Status] how it ended
21
+ Result = Struct.new(:out, :err, :status) do
22
+ # @return [Boolean] whether the program ended with status 0
23
+ def ok? = status.success?
24
+ end
25
+
26
+ # Accepts the arguments every driven adapter is built with and keeps none of them.
27
+ #
28
+ # @param aggregate [Object, nil] unused
29
+ # @param settings [Hash] unused
30
+ # @param root [String, nil] unused
31
+ def initialize(aggregate: nil, settings: {}, root: nil); end
32
+
33
+ # Runs a program and waits for it.
34
+ #
35
+ # @param command [Array<String>] the program, then its arguments
36
+ # @param env [Hash{String => String, nil}] variables to set for it; nil unsets one
37
+ # @param chdir [String, nil] the directory to run it in
38
+ # @return [Result] its output and status; a program that is not installed is a `Result` with
39
+ # status 127 and its reason in `err`, not a raise
40
+ def capture(*command, env: {}, chdir: nil)
41
+ options = chdir ? { chdir: chdir } : {}
42
+ out, err, status = Open3.capture3(env, *command, **options)
43
+ Result.new(out, err, status)
44
+ rescue Errno::ENOENT => e
45
+ Result.new("", e.message, Struct.new(:success?, :exitstatus).new(false, 127))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ # Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
2
+ # and the implementation must load once, from `lib/`, not from the copy.
3
+ require "hecks/hecks/adapters/terminal"
4
+
5
+ Hecks.adapter "Terminal" do
6
+ port "Terminal"
7
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "console_capture"
4
+ require "hecks/cli/console"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ # The `Terminal` port's adapter: the sessions an operator or a program drives through stdin and
9
+ # stdout, an IRB console (`open`) or the stdio MCP door (`serve`).
10
+ #
11
+ # The journal records that a session was opened and how it ended, not what was said in it.
12
+ # Each starts here and nowhere else; a caller that must not open a real session (a spec)
13
+ # replaces the launcher with `Terminal.launcher=` or the server with `Terminal.server=`.
14
+ class Terminal
15
+ class << self
16
+ # @return [#call, nil] starts the interactive session; IRB when nil
17
+ attr_accessor :launcher
18
+
19
+ # @return [#call, nil] serves MCP over stdio, given the arguments after the command;
20
+ # `Hecks::CLI::Mcp.call` when nil
21
+ attr_accessor :server
22
+ end
23
+
24
+ # Accepts the arguments every driven adapter is built with and keeps none of them.
25
+ #
26
+ # @param aggregate [Object, nil] unused
27
+ # @param settings [Hash] unused
28
+ # @param root [String, nil] unused
29
+ def initialize(aggregate: nil, settings: {}, root: nil); end
30
+
31
+ # Boots the record's domain and drops into an interactive console; returns when the
32
+ # session ends.
33
+ #
34
+ # @param held [Hash] the `Operation` record: `subject` is the domain directory, or absent
35
+ # for the bundled pizzas domain
36
+ # @return [Hash{Symbol => Hash}] `output:` a one-line note that the session ended
37
+ def open(**held)
38
+ subject = held[:subject]
39
+ domain = subject.is_a?(Hash) ? subject[:value] : subject
40
+ launcher = self.class.launcher
41
+ launcher ? CLI::Console.call(domain, launcher: launcher) : CLI::Console.call(domain)
42
+
43
+ { output: { value: "console session ended (#{domain || 'pizzas'})" } }
44
+ end
45
+
46
+ # Hands the process over to the MCP door until the client closes stdin. The door writes its
47
+ # JSON-RPC on stdout, so nothing here is captured, and the launcher's own answer follows
48
+ # only once the client is gone.
49
+ #
50
+ # @param held [Hash] the `Door` record: `stdio` (whether `--stdio` was given)
51
+ # @return [Hash{Symbol => Hash}] `output:` a one-line note that the door closed
52
+ # @raise [ConsoleCapture::Failure] when the process is not set up for stdio: the door
53
+ # refused to start, and said why on stderr
54
+ def serve(**held)
55
+ argv = plain(held[:stdio]) ? ["--stdio"] : []
56
+ server = self.class.server
57
+ if server
58
+ server.call(argv)
59
+ else
60
+ require "hecks/cli/mcp"
61
+ CLI::Mcp.call(argv)
62
+ end
63
+
64
+ { output: { value: "mcp door closed" } }
65
+ rescue SystemExit => e
66
+ raise ConsoleCapture::Failure, "the mcp door refused to start (status #{e.status}); see stderr"
67
+ end
68
+
69
+ private
70
+
71
+ def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,172 @@
1
+ Hecks.behaviors "Codebase" do
2
+ vision "A request to work on this repository is recorded, the tree is examined, and only a hecks checkout lets it through."
3
+
4
+ loads "hecks.bluebook", "custodian.bluebook", "codebase.bluebook", "context_map.hecksagon", "hecks.hecksagon", "environments/memory.world"
5
+
6
+ test "ProjectModel reports what the language projects, and keeps the answer" do
7
+ tests "ProjectModel", on: "LanguageRun"
8
+ input run: { value: "model" }
9
+ expect emits: %w[ProjectModelRequested LanguageExamined LanguageAccepted LanguageAnswered LanguageCompleted]
10
+ end
11
+
12
+ test "ProjectRefusalWording is a second name that carries out the same projection" do
13
+ tests "ProjectRefusalWording", on: "LanguageRun"
14
+ input run: { value: "wording" }
15
+ expect emits: %w[ProjectRefusalWordingRequested LanguageExamined LanguageAccepted LanguageAnswered LanguageCompleted]
16
+ end
17
+
18
+ test "Propose rehearses a new word and writes nothing without confirm" do
19
+ tests "Propose", on: "LanguageRun"
20
+ input word: { value: "no_such_word" }, context: { value: "Aggregate" }, run: { value: "propose" }
21
+ expect emits: %w[ProposeRequested LanguageExamined LanguageAccepted LanguageAnswered LanguageCompleted]
22
+ end
23
+
24
+ test "Propose refuses a body the language does not have" do
25
+ tests "Propose", on: "LanguageRun"
26
+ input word: { value: "no_such_word" }, context: { value: "Aggregate" }, body: { value: "everything" },
27
+ run: { value: "propose" }
28
+ expect refused: "must match"
29
+ end
30
+
31
+ test "Admit keeps a word that is not declared as a faulted request" do
32
+ tests "Admit", on: "LanguageRun"
33
+ input word: { value: "no_such_word" }, context: { value: "Aggregate" }, run: { value: "admit" }
34
+ expect emits: %w[AdmitRequested LanguageExamined LanguageAccepted LanguageRefused LanguageFaulted]
35
+ end
36
+
37
+ test "ProposeArgument refuses a kind of argument the language does not have" do
38
+ tests "ProposeArgument", on: "LanguageRun"
39
+ input word: { value: "no_such_word" }, context: { value: "Aggregate" }, kind: { value: "blob" },
40
+ run: { value: "argument" }
41
+ expect refused: "must match"
42
+ end
43
+
44
+ test "ProjectKernelCapabilities reports what the grammar projects, and keeps the answer" do
45
+ tests "ProjectKernelCapabilities", on: "KernelRun"
46
+ input run: { value: "kernel" }
47
+ expect emits: %w[ProjectKernelCapabilitiesRequested KernelExamined KernelAccepted KernelAnswered KernelCompleted]
48
+ end
49
+
50
+ test "MeasureKernelCoverage keeps a complete kernel as a completed measure" do
51
+ tests "MeasureKernelCoverage", on: "KernelRun"
52
+ input run: { value: "coverage" }
53
+ expect emits: %w[MeasureKernelCoverageRequested KernelExamined KernelAccepted KernelAnswered KernelCompleted]
54
+ end
55
+
56
+ test "CheckEngineAgreement keeps agreeing engines as a completed check" do
57
+ tests "CheckEngineAgreement", on: "ConformanceRun"
58
+ input run: { value: "engines" }
59
+ expect emits: %w[CheckEngineAgreementRequested ConformanceExamined ConformanceAccepted ConformanceAnswered
60
+ ConformanceCompleted]
61
+ end
62
+
63
+ test "MeasureDocCoverage keeps a covered reference as a completed measure" do
64
+ tests "MeasureDocCoverage", on: "ConformanceRun"
65
+ input run: { value: "docs" }
66
+ expect emits: %w[MeasureDocCoverageRequested ConformanceExamined ConformanceAccepted ConformanceAnswered
67
+ ConformanceCompleted]
68
+ end
69
+
70
+ test "ArgumentGateMatrix refuses a run that is not named" do
71
+ tests "ArgumentGateMatrix", on: "ConformanceRun"
72
+ input run: { value: "" }
73
+ expect refused: "must match"
74
+ end
75
+
76
+ test "RegenerateCorpus refuses a run that is not named" do
77
+ tests "RegenerateCorpus", on: "RegenerationRun"
78
+ input run: { value: "" }
79
+ expect refused: "must match"
80
+ end
81
+
82
+ test "CheckComments keeps a file with no violations as a completed check" do
83
+ tests "CheckComments", on: "StyleRun"
84
+ input paths: { value: "lib/hecks/canonical_json.rb" }, run: { value: "clean" }
85
+ expect emits: %w[CheckCommentsRequested StyleExamined StyleAccepted StyleAnswered StyleCompleted]
86
+ end
87
+
88
+ test "CheckComments refuses a list of paths that is not one" do
89
+ tests "CheckComments", on: "StyleRun"
90
+ input paths: { value: "lib, spec" }, run: { value: "paths" }
91
+ expect refused: "must match"
92
+ end
93
+
94
+ test "FixComments lists what it would rewrite, and writes nothing, without confirm" do
95
+ tests "FixComments", on: "StyleRun"
96
+ input paths: { value: "lib/hecks/canonical_json.rb" }, run: { value: "fix" }
97
+ expect emits: %w[FixCommentsRequested StyleExamined StyleAccepted StyleAnswered StyleCompleted]
98
+ end
99
+
100
+ test "CheckCommentsUnchanged refuses a ref with a space in it" do
101
+ tests "CheckCommentsUnchanged", on: "StyleRun"
102
+ input ref: { value: "not a ref" }, run: { value: "unchanged" }
103
+ expect refused: "must match"
104
+ end
105
+
106
+ test "Canonicalise keeps a file that is not there as a faulted request" do
107
+ tests "Canonicalise", on: "StyleRun"
108
+ input file: { value: "/tmp/hecks-behaviors-absent/file.json" }, run: { value: "canonical" }
109
+ expect emits: %w[CanonicaliseRequested StyleExamined StyleAccepted StyleRefused StyleFaulted]
110
+ end
111
+
112
+ test "HoistLocalGivens refuses a run that is not named" do
113
+ tests "HoistLocalGivens", on: "CodemodRun"
114
+ input run: { value: "" }
115
+ expect refused: "must match"
116
+ end
117
+
118
+ test "RunSpecExample keeps a spec file that is not there as a faulted request" do
119
+ tests "RunSpecExample", on: "TestSuiteRun"
120
+ input file: { value: "spec/no_such_spec.rb" }, example: { value: "works" }, run: { value: "example" }
121
+ expect emits: %w[RunSpecExampleRequested TestSuiteExamined TestSuiteAccepted TestSuiteRefused TestSuiteFaulted]
122
+ end
123
+
124
+ test "StressConcurrency refuses a count of zero runs" do
125
+ tests "StressConcurrency", on: "TestSuiteRun"
126
+ input runs: { value: 0 }, run: { value: "stress" }
127
+ expect refused: "a count is positive"
128
+ end
129
+
130
+ test "RefreshRuntimeBaseline refuses a run that is not a number" do
131
+ tests "RefreshRuntimeBaseline", on: "TestSuiteRun"
132
+ input from_run: { value: "latest" }, run: { value: "baseline" }
133
+ expect refused: "must match"
134
+ end
135
+
136
+ test "RegenerateLegacyFixtures reports what it would rewrite, and rewrites nothing, without confirm" do
137
+ tests "RegenerateLegacyFixtures", on: "TestSuiteRun"
138
+ input run: { value: "fixtures" }
139
+ expect emits: %w[RegenerateLegacyFixturesRequested TestSuiteExamined TestSuiteAccepted TestSuiteAnswered
140
+ TestSuiteCompleted]
141
+ end
142
+
143
+ test "SeedSemanticsCorpus refuses a fixture name that is not a file name" do
144
+ tests "SeedSemanticsCorpus", on: "TestSuiteRun"
145
+ input fixture: { value: "Not A Name" }, run: { value: "seed" }
146
+ expect refused: "must match"
147
+ end
148
+
149
+ test "Present refuses a port that is not one" do
150
+ tests "Present", on: "CorpusRun"
151
+ input port: { value: 70_000 }, run: { value: "present" }
152
+ expect refused: "a port is 1 to 65535"
153
+ end
154
+
155
+ test "ServeQueryIrMcp refuses a run that is not named" do
156
+ tests "ServeQueryIrMcp", on: "CorpusRun"
157
+ input run: { value: "" }
158
+ expect refused: "must match"
159
+ end
160
+
161
+ test "Publish refuses a run that is not named" do
162
+ tests "Publish", on: "PublishingRun"
163
+ input run: { value: "" }
164
+ expect refused: "must match"
165
+ end
166
+
167
+ test "PublishGem refuses a run that is not named" do
168
+ tests "PublishGem", on: "PublishingRun"
169
+ input run: { value: "" }
170
+ expect refused: "must match"
171
+ end
172
+ end