hecks 2.9.0 → 3.0.1

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 +13 -4
  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 +15 -8
  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 +15 -5
  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,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require_relative "ruby_child"
5
+
6
+ module Hecks
7
+ module Adapters
8
+ module Codebase
9
+ # What Codebase's `RegenerationRun` asks of the working tree: regenerating every corpus
10
+ # domain's committed Rust output.
11
+ #
12
+ # It runs `Hecks::Tools::RegenerationRun` in this process: the run forks once for each
13
+ # domain, in a fixed order, because the domains share the files they stamp. With `check` it
14
+ # projects into a scratch copy of the crate and compares, and never writes the tree. Without
15
+ # `confirm` the run is that same check, so a regeneration that would rewrite tracked generated
16
+ # files reports drift and writes only when it is confirmed.
17
+ module Regeneration
18
+ # Every operation this family carries out.
19
+ OPERATIONS = %w[regenerate_corpus].freeze
20
+
21
+ # How many lines of a script's output a refusal keeps.
22
+ KEPT_LINES = 60
23
+
24
+ module_function
25
+
26
+ # Carries out the regeneration.
27
+ #
28
+ # @param _operation [String] `regenerate_corpus`
29
+ # @param held [Hash] the `RegenerationRun` record's fields: `check`, `confirm`
30
+ # @param tree [Tree] the working tree, already known to be a hecks checkout
31
+ # @param shell [#capture, nil] unused: the tool runs in this process
32
+ # @return [String] how many domains were checked or regenerated
33
+ # @raise [ConsoleCapture::Failure] with the difference, when a check finds drift, or with
34
+ # what the script printed when it ends badly
35
+ def call(_operation, held, tree, shell: nil)
36
+ flag = ->(name) { (held[name].is_a?(Hash) ? held[name][:value] : held[name]) == true }
37
+ check = flag.call(:check) || !flag.call(:confirm)
38
+ child = RubyChild.new(tree)
39
+ result = child.capture("regen_codegen_domains", *("--check" if check))
40
+ raise ConsoleCapture::Failure, refusal(result) unless result.ok?
41
+
42
+ summary(result.out, check)
43
+ end
44
+
45
+ # @param output [String] what the script printed
46
+ # @param check [Boolean] whether it only compared
47
+ # @return [String] the verdict, with how many domains it covered
48
+ def summary(output, check)
49
+ count = output[/regenerating ([0-9]+) domain/, 1]
50
+ return "regenerated #{count} corpus domains into the checkout" unless check
51
+
52
+ "checked #{count} corpus domains against a scratch crate: no drift " \
53
+ "(add --confirm to regenerate into the checkout)"
54
+ end
55
+
56
+ # @param result [Shell::Result] how the script ended
57
+ # @return [String] the last lines it printed: the difference, or why it stopped
58
+ def refusal(result)
59
+ lines = [result.out, result.err].join.lines.map(&:chomp).reject(&:empty?)
60
+ shown = lines.last(KEPT_LINES)
61
+ note = lines.size > shown.size ? ["(the last #{shown.size} of #{lines.size} lines)"] : []
62
+ [*note, *shown].join("\n")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "hecks/release/runner"
5
+ require_relative "tree"
6
+ require_relative "../console_capture"
7
+
8
+ module Hecks
9
+ module Adapters
10
+ module Codebase
11
+ # The facts a release is judged by, read from git and the checkout's files and judged by
12
+ # nothing here: the rules are the givens of the `Clear` command of `PublishingRun`.
13
+ #
14
+ # It reads the branch, whether `HEAD` is `origin/main` (after a fetch), whether the tree is
15
+ # clean, the gem's version and the client package's, whether the changelog has a heading for
16
+ # the version, and where a tag for the version already points. Nothing is changed but the
17
+ # remote-tracking refs a fetch updates.
18
+ class ReleaseFacts
19
+ # The line of `lib/hecks/version.rb` that declares the version.
20
+ VERSION_LINE = /^\s*VERSION\s*=\s*"(?<version>[^"]+)"/
21
+
22
+ # Where the client package declares its version, relative to the checkout.
23
+ CLIENT_PACKAGE = "packages/hecks-client/package.json"
24
+
25
+ # @param tree [Tree] the checkout
26
+ # @param commands [#capture, #run!] starts each process, as `Release::Runner::Commands` does
27
+ def initialize(tree, commands:)
28
+ @tree = tree
29
+ @git = Release::Runner::Git.new(root: tree.root, commands: commands)
30
+ end
31
+
32
+ # Reads the facts a run of the operation needs.
33
+ #
34
+ # @param operation [String] `publish` (every fact) or `publish_gem` (the versions only)
35
+ # @return [Hash] each fact as the run holds it: every one a value object
36
+ # as a hash, and `ships_from` the checkout's path
37
+ # @raise [ConsoleCapture::Failure] when git or a file cannot be read
38
+ def gather(operation)
39
+ version = declared_version
40
+ facts = { operation: word(operation), version: word(version), client_version: word(client_version),
41
+ ir_version: word("#{Bluebook::Chapter::IR_VERSION}.0.0"), ships_from: { path: @tree.root } }
42
+ return facts if operation == "publish_gem"
43
+
44
+ facts.merge(git_facts(version)).merge(changelog: flag(changelog?(version)))
45
+ rescue Release::Runner::Refusal, Errno::ENOENT, JSON::ParserError, KeyError => e
46
+ raise ConsoleCapture::Failure, e.message
47
+ end
48
+
49
+ private
50
+
51
+ def git_facts(version)
52
+ fetch = @git.capture("fetch", "origin")
53
+ raise ConsoleCapture::Failure, "git fetch origin failed (#{fetch.stderr.strip})" unless fetch.success?
54
+
55
+ head = read("rev-parse", "HEAD")
56
+ { branch: word(read("rev-parse", "--abbrev-ref", "HEAD")), head: word(head),
57
+ on_origin: flag(head == read("rev-parse", "origin/main")),
58
+ clean: flag(read("status", "--porcelain").empty?), tag_state: word(tag_state("v#{version}", head)) }
59
+ end
60
+
61
+ def tag_state(tag, head)
62
+ tagger = Release::Runner::Tagger.new(git: @git, console: nil, dry_run: true)
63
+ commits = [tagger.local_commit(tag), tagger.remote_commit(tag)].compact
64
+ return "none" if commits.empty?
65
+
66
+ commits.all?(head) ? "at_release_commit" : "elsewhere"
67
+ end
68
+
69
+ def read(*) = @git.read(*).strip
70
+
71
+ def declared_version
72
+ match = File.read(@tree.path("lib/hecks/version.rb")).match(VERSION_LINE)
73
+ raise Release::Runner::Refusal, "lib/hecks/version.rb declares no VERSION; restore it" unless match
74
+
75
+ match[:version]
76
+ end
77
+
78
+ def client_version = JSON.parse(File.read(@tree.path(CLIENT_PACKAGE))).fetch("version")
79
+
80
+ def changelog?(version)
81
+ File.read(@tree.path("CHANGELOG.md")).match?(/^## \[#{Regexp.escape(version)}\]/)
82
+ end
83
+
84
+ def word(text) = { value: text }
85
+
86
+ def flag(truth) = { value: truth }
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../shell"
4
+ require_relative "../console_capture"
5
+ require "hecks/tools"
6
+
7
+ module Hecks
8
+ module Adapters
9
+ module Codebase
10
+ # Runs one of this repository's own tools, by its name in `Hecks::Tools::REGISTRY`.
11
+ #
12
+ # The tool runs in this process from the checkout's root, its output and exit status
13
+ # captured: the gem carries every tool, so nothing is started as a child.
14
+ class RubyChild
15
+ # @param tree [Tree] the checkout the tool belongs to
16
+ def initialize(tree)
17
+ @tree = tree
18
+ end
19
+
20
+ # Runs the tool with the arguments and answers what it printed.
21
+ #
22
+ # @param script [String] the tool's name in `Hecks::Tools::REGISTRY`
23
+ # @param args [Array<String>] its arguments
24
+ # @param env [Hash{String => String}] unused; a tool reads this process's environment
25
+ # @return [String] what it wrote to stdout, and to stderr when there was any
26
+ # @raise [ConsoleCapture::Failure] when it ends with a non-zero status; the message is
27
+ # everything it printed
28
+ def answer(script, *, env: {})
29
+ result = capture(script, *, env: env)
30
+ return printed(result) if result.ok?
31
+
32
+ raise ConsoleCapture::Failure, printed(result, "ended with status #{result.status.exitstatus}")
33
+ end
34
+
35
+ # Runs the tool with the arguments and answers only what it printed to stdout, for a tool
36
+ # whose stdout is its data and whose stderr is progress.
37
+ #
38
+ # @param script [String] the tool's name in `Hecks::Tools::REGISTRY`
39
+ # @param args [Array<String>] its arguments
40
+ # @param env [Hash{String => String}] unused; a tool reads this process's environment
41
+ # @return [String] its stdout, without the trailing newline
42
+ # @raise [ConsoleCapture::Failure] when it ends with a non-zero status; the message is
43
+ # everything it printed
44
+ def read(script, *, env: {})
45
+ result = capture(script, *, env: env)
46
+ return result.out.chomp if result.ok?
47
+
48
+ raise ConsoleCapture::Failure, printed(result, "ended with status #{result.status.exitstatus}")
49
+ end
50
+
51
+ # Runs the tool with the arguments and hands back how it ended.
52
+ #
53
+ # @param script [String] the tool's name in `Hecks::Tools::REGISTRY`
54
+ # @param args [Array<String>] its arguments
55
+ # @param env [Hash{String => String}] unused; a tool reads this process's environment
56
+ # @return [Shell::Result] its output (stderr included) and status
57
+ # @raise [KeyError] when no tool has that name
58
+ def capture(script, *args, env: {})
59
+ in_process(script, args)
60
+ end
61
+
62
+ private
63
+
64
+ def in_process(script, args)
65
+ code = nil
66
+ outcome = ConsoleCapture.capture { code = Tools.run(script, args, root: @tree.root) }
67
+ Shell::Result.new(outcome.output, "", Status.new(code))
68
+ end
69
+
70
+ # How a tool run in this process ended, answering as a `Process::Status` does.
71
+ Status = Struct.new(:exitstatus) do
72
+ # @return [Boolean] whether it ended with status 0
73
+ def success? = exitstatus.zero?
74
+ end
75
+
76
+ def printed(result, otherwise = "")
77
+ text = [result.out, result.err].map(&:strip).reject(&:empty?).join("\n")
78
+ text.empty? ? otherwise : text
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Adapters
5
+ module Codebase
6
+ # The `SecretVault` adapter: runs a program with the secrets a 1Password `op run` env file
7
+ # names, so a key or token never sits in a file, a variable of ours or a command line.
8
+ #
9
+ # It starts `op` through the object it is given, which answers `capture` and `run!` as
10
+ # `Hecks::Release::Runner::Commands` does; a spec hands it a recorder.
11
+ class SecretVault
12
+ # @param commands [#capture, #run!] starts each process
13
+ def initialize(commands:)
14
+ @commands = commands
15
+ end
16
+
17
+ # @return [Boolean] whether the 1Password CLI is installed
18
+ def installed?
19
+ @commands.capture("op", "--version").success?
20
+ end
21
+
22
+ # Runs a program with the env file's secrets in its environment, its output going to the
23
+ # terminal so a prompt (Touch ID, an approval link) reaches the person.
24
+ #
25
+ # @param env_file [String] the env file `op run` reads, absolute or relative to `chdir`
26
+ # @param argv [Array<String>] the program and its arguments
27
+ # @param chdir [String, nil] the directory to run in
28
+ # @return [true] when the program exits zero
29
+ # @raise [Hecks::Release::Runner::CommandFailed] when it does not
30
+ def run!(env_file, *argv, chdir: nil)
31
+ @commands.run!("op", "run", "--env-file=#{env_file}", "--", *argv, chdir: chdir)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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/codebase/source_tree"
4
+
5
+ Hecks.adapter "SourceTree" do
6
+ port "SourceTree"
7
+ end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require_relative "language"
5
+ require_relative "kernel_tables"
6
+ require_relative "conformance"
7
+ require_relative "regeneration"
8
+ require_relative "style"
9
+ require_relative "codemods"
10
+ require_relative "test_suite"
11
+ require_relative "corpus_tasks"
12
+ require_relative "publishing"
13
+ require_relative "../git"
14
+
15
+ module Hecks
16
+ module Adapters
17
+ # The `SourceTree` port's adapter: everything Codebase does to the working tree of this
18
+ # repository.
19
+ #
20
+ # It answers the one fact every Codebase request needs (`examine`: is the tree a hecks
21
+ # checkout?), carries out an accepted request (`perform`), and answers Codebase's queries. Each
22
+ # of them refuses "needs a hecks checkout" outside a checkout, so an installed gem never touches
23
+ # an absent `rust/` or rewrites its own `lib/`, even when the journaled guard is bypassed.
24
+ # `perform` finds the task family that carries an operation out; a family lives beside this
25
+ # file and does the work with the existing generators, linters and tools.
26
+ class SourceTree
27
+ class << self
28
+ # @return [#capture, nil] starts each child process; a `Shell` when nil. A spec replaces it
29
+ # so no gate has to run to test what is asked of it.
30
+ attr_accessor :shell
31
+ end
32
+
33
+ # Accepts the arguments every driven adapter is built with and keeps none of them.
34
+ #
35
+ # @param aggregate [Object, nil] unused
36
+ # @param settings [Hash] unused
37
+ # @param root [String, nil] unused
38
+ def initialize(aggregate: nil, settings: {}, root: nil); end
39
+
40
+ # Reports whether the working tree is a hecks checkout. For a release it also reports the
41
+ # facts the Git adapter surveys, since a release's rules are judged with the checkout rule.
42
+ #
43
+ # @param held [Hash] the record: `operation`
44
+ # @return [Hash{Symbol => Hash}] `checkout:` whether hecks.gemspec stands beside lib/, and for
45
+ # a release the facts to judge
46
+ def examine(**held)
47
+ answer = { checkout: { value: tree.checkout? } }
48
+ operation = plain(held[:operation])
49
+ return answer unless Codebase::Publishing::OPERATIONS.include?(operation)
50
+
51
+ facts = tree.checkout? ? Git.new.survey(**held) : Codebase::Publishing.no_facts(operation)
52
+ answer.merge(facts)
53
+ end
54
+
55
+ # Carries out the operation an accepted request names.
56
+ #
57
+ # @param held [Hash] the record: `operation` and every argument the request set
58
+ # @return [Hash{Symbol => Hash}] `report:` what was found, or done; a task that does more
59
+ # than report (a release) answers its own fields, `report:` among them
60
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
61
+ # @raise [ConsoleCapture::Failure] when no family carries the operation out, or it refuses
62
+ def perform(**held)
63
+ tree.require_checkout!
64
+ operation = plain(held[:operation])
65
+ family = FAMILIES.find { |candidate| candidate::OPERATIONS.include?(operation) }
66
+ raise ConsoleCapture::Failure, "no task carries out #{operation.inspect}" unless family
67
+
68
+ args = held.except(:operation)
69
+ done = family.call(operation, args, tree, shell: self.class.shell || Shell.new)
70
+ done.is_a?(Hash) ? done : { report: { value: done } }
71
+ end
72
+
73
+ # @return [Hash] `text:` where every word of the language stands
74
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
75
+ def word_status(**)
76
+ tree.require_checkout!
77
+ { text: Codebase::Language.word_status }
78
+ end
79
+
80
+ # @param args [Hash] the query's arguments: `paths`, `only`, `json`, `top`
81
+ # @return [Hash] `text:` the Ruby comment violations, as the linter reports them
82
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
83
+ # @raise [ConsoleCapture::Failure] when the linter refuses its arguments
84
+ def report_comments(**args)
85
+ { text: report("report_comments", args) }
86
+ end
87
+
88
+ # @param args [Hash] the query's arguments: `paths`, `only`, `json`, `top`
89
+ # @return [Hash] `text:` the Rust comment violations, as the linter reports them
90
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
91
+ # @raise [ConsoleCapture::Failure] when the linter refuses its arguments
92
+ def report_rust_comments(**args)
93
+ { text: report("report_rust_comments", args) }
94
+ end
95
+
96
+ # @param args [Hash] the query's arguments: `group`, `groups`, `runtime_log`
97
+ # @return [Hash] `text:` the spec files one group of a runtime-balanced split runs
98
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
99
+ # @raise [ConsoleCapture::Failure] when the script refuses its arguments
100
+ def shard_specs(**args)
101
+ { text: test_suite("shard_specs", args) }
102
+ end
103
+
104
+ # @param args [Hash] the query's arguments: `exclude`, `tags`, `check`
105
+ # @return [Hash] `text:` the spec files with an example the tag filter selects, one per line
106
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
107
+ # @raise [ConsoleCapture::Failure] when the list is stale, or the script refuses its arguments
108
+ def list_io_parallel_specs(**args)
109
+ { text: test_suite("list_io_parallel_specs", args) }
110
+ end
111
+
112
+ # @return [Hash] `text:` the expected match results of the pattern cases, as JSON
113
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
114
+ def record_pattern_cases(**)
115
+ { text: test_suite("record_pattern_cases", {}) }
116
+ end
117
+
118
+ # @return [Hash] `text:` the feature and directory of every domain with a Rust feature
119
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
120
+ def rust_domains(**)
121
+ { text: corpus("rust_domains", {}) }
122
+ end
123
+
124
+ # @return [Hash] `text:` the directories regeneration walks, in the order it walks them
125
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
126
+ def regen_order(**)
127
+ { text: corpus("regen_order", {}) }
128
+ end
129
+
130
+ # @return [Hash] `text:` whether each generated Rust module is covered
131
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
132
+ # @raise [ConsoleCapture::Failure] when a module is not covered
133
+ def corpus_rust_coverage(**)
134
+ { text: corpus("corpus_rust_coverage", {}) }
135
+ end
136
+
137
+ # @param args [Hash] the query's arguments: `names`
138
+ # @return [Hash] `text:` each IR construct's diff from its meta-domain
139
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
140
+ def ir_constructs(**args)
141
+ { text: corpus("ir_constructs", args) }
142
+ end
143
+
144
+ # @param args [Hash] the query's arguments: `domains`, `meta`
145
+ # @return [Hash] `text:` the rules declared more than once
146
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
147
+ def ir_duplicates(**args)
148
+ { text: corpus("ir_duplicates", args) }
149
+ end
150
+
151
+ # @param args [Hash] the query's arguments: `name`, `field`
152
+ # @return [Hash] `text:` which propagation touchpoints already show the field
153
+ # @raise [Codebase::Tree::NeedsCheckout] when the tree is not a hecks checkout
154
+ # @raise [ConsoleCapture::Failure] when the construct is not one
155
+ def ir_impact(**args)
156
+ { text: corpus("ir_impact", args) }
157
+ end
158
+
159
+ private
160
+
161
+ def test_suite(operation, args)
162
+ tree.require_checkout!
163
+ plain_args = args.transform_values { |value| plain(value) }
164
+ Codebase::TestSuite.report(operation, plain_args, tree, shell: self.class.shell)
165
+ end
166
+
167
+ def corpus(operation, args)
168
+ tree.require_checkout!
169
+ plain_args = args.transform_values { |value| plain(value) }
170
+ Codebase::CorpusTasks.report(operation, plain_args, tree, shell: self.class.shell)
171
+ end
172
+
173
+ def report(operation, args)
174
+ tree.require_checkout!
175
+ plain_args = args.transform_values { |value| plain(value) }
176
+ Codebase::Style.report(operation, plain_args, tree, shell: self.class.shell)
177
+ end
178
+
179
+ # The task families, each carrying out the operations it lists.
180
+ FAMILIES = [Codebase::Language, Codebase::KernelTables, Codebase::Conformance, Codebase::Regeneration,
181
+ Codebase::Style, Codebase::Codemods, Codebase::TestSuite, Codebase::CorpusTasks, Codebase::Publishing].freeze
182
+ private_constant :FAMILIES
183
+
184
+ def tree = Codebase::Tree.new
185
+
186
+ def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tree"
4
+ require_relative "../shell"
5
+ require_relative "../console_capture"
6
+
7
+ module Hecks
8
+ module Adapters
9
+ module Codebase
10
+ # The `SqliteFixture` adapter: regenerates the persistence legacy fixtures
11
+ # (`spec/fixtures/persistence_legacy/`) by writing through the real adapters.
12
+ #
13
+ # The fixtures are a baseline that later adapters are compared with, so the run is never
14
+ # started by accident: unconfirmed it reports what it would rewrite and whether the `sqlite3`
15
+ # program it dumps a database with is installed, and writes nothing. Confirmed, it runs
16
+ # `PersistenceLegacyFixture::Regenerate` in this process, which needs a reachable Postgres as
17
+ # well.
18
+ class SqliteFixture
19
+ # Where the fixtures stand, relative to the checkout.
20
+ DIRECTORY = "spec/fixtures/persistence_legacy"
21
+
22
+ # The stores each fixture set is written for.
23
+ STORES = %w[heki sqlite d1 postgres postgres_era].freeze
24
+
25
+ # @param tree [Tree] the checkout whose fixtures are rewritten
26
+ # @param shell [#capture, nil] starts the `sqlite3` probe; a `Shell` when nil
27
+ # @param regenerator [#call, nil] rewrites the fixtures, as `call(dir:)` answering what was
28
+ # written; `PersistenceLegacyFixture::Regenerate` when nil
29
+ def initialize(tree, shell: nil, regenerator: nil)
30
+ @tree = tree
31
+ @shell = shell || Shell.new
32
+ @regenerator = regenerator
33
+ end
34
+
35
+ # Regenerates the fixtures, or reports what a regeneration would rewrite.
36
+ #
37
+ # @param confirm [Boolean] whether to rewrite
38
+ # @return [String] what was written, or (unconfirmed) what would be
39
+ # @raise [ConsoleCapture::Failure] when a fixture cannot be written
40
+ def regenerate(confirm:)
41
+ return rewrite if confirm
42
+
43
+ "dry run, would rewrite #{DIRECTORY}/ for #{STORES.join(', ')} through the real adapters " \
44
+ "(#{installed}; add --confirm)"
45
+ end
46
+
47
+ # @return [Boolean] whether the `sqlite3` program answers
48
+ def sqlite_installed?
49
+ @shell.capture("sqlite3", "--version").ok?
50
+ end
51
+
52
+ private
53
+
54
+ def rewrite
55
+ regenerator.call(dir: @tree.path(DIRECTORY))
56
+ rescue LoadError, StandardError => e
57
+ raise ConsoleCapture::Failure, "#{e.class}: #{e.message}"
58
+ end
59
+
60
+ def regenerator
61
+ @regenerator ||= begin
62
+ require "hecks/persistence_legacy_fixture"
63
+ PersistenceLegacyFixture::Regenerate
64
+ end
65
+ end
66
+
67
+ def installed = sqlite_installed? ? "sqlite3 is installed" : "sqlite3 is not installed"
68
+ end
69
+ end
70
+ end
71
+ end