hecks 3.10.0 → 3.12.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 (542) hide show
  1. checksums.yaml +4 -4
  2. data/examples/pizzas/bluebook/pizzas.bluebook +29 -0
  3. data/examples/pizzas/bluebook/pizzas.hecksagon +7 -0
  4. data/exe/hecks +4 -4
  5. data/lib/hecks/adapters/driven/d1.rb +2 -10
  6. data/lib/hecks/adapters/driven/heki.adapter +1 -1
  7. data/lib/hecks/adapters/driven/heki.rb +2 -12
  8. data/lib/hecks/adapters/driven/lambda.adapter +1 -1
  9. data/lib/hecks/adapters/driven/lambda.rb +3 -18
  10. data/lib/hecks/adapters/driven/postgres.rb +4 -11
  11. data/lib/hecks/adapters/driven/sqlite.adapter +1 -1
  12. data/lib/hecks/adapters/driven/sqlite.rb +2 -10
  13. data/lib/hecks/adapters/driving/admission.rb +46 -0
  14. data/lib/hecks/adapters/driving/cli/nesting.rb +36 -0
  15. data/lib/hecks/adapters/driving/cli/shorthand.rb +88 -0
  16. data/lib/hecks/adapters/driving/cli.rb +127 -0
  17. data/lib/hecks/adapters/driving/cli_runner/answers.rb +160 -0
  18. data/lib/hecks/adapters/driving/cli_runner/resolution.rb +158 -0
  19. data/lib/hecks/adapters/driving/cli_runner/settling.rb +120 -0
  20. data/lib/hecks/adapters/driving/cli_runner/streaming.rb +93 -0
  21. data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +47 -0
  22. data/lib/hecks/adapters/driving/cli_runner.rb +70 -0
  23. data/lib/hecks/adapters/driving/command_request.rb +121 -0
  24. data/lib/hecks/adapters/driving/handle.rb +214 -0
  25. data/lib/hecks/adapters/driving/json.rb +136 -0
  26. data/lib/hecks/adapters/driving/launcher_options.rb +267 -0
  27. data/lib/hecks/adapters/driving/mcp/properties.rb +49 -0
  28. data/lib/hecks/adapters/driving/mcp/tool_calls.rb +116 -0
  29. data/lib/hecks/adapters/driving/mcp/tool_definitions/auditing.rb +53 -0
  30. data/lib/hecks/adapters/driving/mcp/tool_definitions/calling.rb +71 -0
  31. data/lib/hecks/adapters/driving/mcp/tool_definitions/reading.rb +99 -0
  32. data/lib/hecks/adapters/driving/mcp/tool_definitions.rb +18 -0
  33. data/lib/hecks/adapters/driving/mcp.rb +159 -0
  34. data/lib/hecks/adapters/driving/mcp_guide_cache.rb +78 -0
  35. data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +97 -0
  36. data/lib/hecks/adapters/driving/mcp_scope/env_problems.rb +69 -0
  37. data/lib/hecks/adapters/driving/mcp_scope/presenter.rb +83 -0
  38. data/lib/hecks/adapters/driving/mcp_scope.rb +213 -0
  39. data/lib/hecks/adapters/driving/newcomer.rb +50 -0
  40. data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +171 -0
  41. data/lib/hecks/adapters/driving/ruby/chapter.rb +91 -0
  42. data/lib/hecks/adapters/driving/ruby.rb +83 -0
  43. data/lib/hecks/adapters/driving/usage_cache.rb +144 -0
  44. data/lib/hecks/{doors.rb → adapters/driving.rb} +10 -6
  45. data/lib/hecks/behaviors/expectations/boot.rb +1 -1
  46. data/lib/hecks/bench/ruby_runner.rb +1 -1
  47. data/lib/hecks/bluebook/ask_resolution.rb +130 -0
  48. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +8 -2
  49. data/lib/hecks/bluebook/assembly/contracts/read_models.rb +1 -1
  50. data/lib/hecks/bluebook/assembly/contracts/rules.rb +4 -2
  51. data/lib/hecks/bluebook/assembly/contracts/structure.rb +3 -1
  52. data/lib/hecks/bluebook/assembly/marks.rb +4 -15
  53. data/lib/hecks/bluebook/assembly/scalars.rb +39 -0
  54. data/lib/hecks/bluebook/attribute.rb +1 -1
  55. data/lib/hecks/bluebook/behaviour/command.rb +13 -8
  56. data/lib/hecks/bluebook/behaviour/policy.rb +30 -0
  57. data/lib/hecks/bluebook/capabilities/attribute_values.rb +72 -0
  58. data/lib/hecks/bluebook/capabilities.rb +91 -9
  59. data/lib/hecks/bluebook/domain_port.rb +16 -4
  60. data/lib/hecks/bluebook/dsl/adapter_builder.rb +18 -6
  61. data/lib/hecks/bluebook/dsl/binding_proxy.rb +13 -0
  62. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/computed_sources.rb +98 -0
  63. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/fan_out_rows.rb +42 -0
  64. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +14 -2
  65. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +69 -3
  66. data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +17 -10
  67. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +5 -0
  68. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
  69. data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +8 -1
  70. data/lib/hecks/bluebook/dsl/command_builder/operands.rb +121 -0
  71. data/lib/hecks/bluebook/dsl/command_builder.rb +2 -0
  72. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +10 -1
  73. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +45 -2
  74. data/lib/hecks/bluebook/dsl/policy_builder.rb +47 -10
  75. data/lib/hecks/bluebook/dsl/rule_reference.rb +7 -4
  76. data/lib/hecks/bluebook/dsl/world_builder.rb +1 -1
  77. data/lib/hecks/bluebook/expression/ast_json/emitters.rb +6 -0
  78. data/lib/hecks/bluebook/expression/ast_json.rb +9 -6
  79. data/lib/hecks/bluebook/expression/ast_reader.rb +14 -9
  80. data/lib/hecks/bluebook/expression/projection.json +36 -0
  81. data/lib/hecks/bluebook/expression/resolver/operations.rb +31 -0
  82. data/lib/hecks/bluebook/expression/resolver/parsing.rb +38 -5
  83. data/lib/hecks/bluebook/expression/resolver/scanning.rb +22 -5
  84. data/lib/hecks/bluebook/expression/resolver/values.rb +10 -0
  85. data/lib/hecks/bluebook/expression/resolver.rb +20 -1
  86. data/lib/hecks/bluebook/hecksagon.rb +23 -3
  87. data/lib/hecks/bluebook/lifecycle.rb +22 -3
  88. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +13 -1
  89. data/lib/hecks/bluebook/meta_validator/modes.rb +4 -1
  90. data/lib/hecks/bluebook/meta_validator/readings.rb +24 -1
  91. data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +2 -1
  92. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +6 -3
  93. data/lib/hecks/bluebook/meta_validator/shapes.rb +5 -0
  94. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +1 -1
  95. data/lib/hecks/bluebook/meta_validator.rb +12 -12
  96. data/lib/hecks/bluebook/model_check/ask_checks.rb +71 -0
  97. data/lib/hecks/bluebook/model_check/policy_checks.rb +2 -1
  98. data/lib/hecks/bluebook/model_check/reference_checks.rb +70 -0
  99. data/lib/hecks/bluebook/model_check.rb +8 -2
  100. data/lib/hecks/bluebook/policy.rb +4 -2
  101. data/lib/hecks/bluebook/smoke_test.rb +1 -1
  102. data/lib/hecks/bluebook/synthesizer.rb +2 -0
  103. data/lib/hecks/bluebook.rb +2 -0
  104. data/lib/hecks/cli/command_table.rb +1 -1
  105. data/lib/hecks/cli/console.rb +2 -1
  106. data/lib/hecks/cli/document.rb +1 -1
  107. data/lib/hecks/cli/launcher_words.rb +4 -4
  108. data/lib/hecks/cli/mcp.rb +4 -4
  109. data/lib/hecks/cli/project_cli/launcher_source.rb +2 -2
  110. data/lib/hecks/cli/project_cli/templates.rb +5 -5
  111. data/lib/hecks/cli/project_cli.rb +9 -6
  112. data/lib/hecks/cli/run.rb +2 -2
  113. data/lib/hecks/cli/smoke_http/checks.rb +4 -1
  114. data/lib/hecks/cli/smoke_http/transport.rb +3 -3
  115. data/lib/hecks/cli/smoke_http.rb +3 -0
  116. data/lib/hecks/codemod.rb +5 -2
  117. data/lib/hecks/corpus/routes.rb +7 -0
  118. data/lib/hecks/corpus/rust.rb +3 -2
  119. data/lib/hecks/deploy/bluebook/deploy.bluebook +34 -4
  120. data/lib/hecks/doc/reference/rendering.rb +6 -3
  121. data/lib/hecks/forms/app/commands.rb +8 -7
  122. data/lib/hecks/forms/app/queries.rb +2 -1
  123. data/lib/hecks/forms/app.rb +1 -1
  124. data/lib/hecks/forms/record_renderer.rb +1 -1
  125. data/lib/hecks/framework/bluebook/privacy.bluebook +11 -0
  126. data/lib/hecks/fuzzing/concurrent_dispatch.rb +4 -1
  127. data/lib/hecks/fuzzing/failure_triage.rb +2 -1
  128. data/lib/hecks/fuzzing/mutation/run.rb +11 -4
  129. data/lib/hecks/fuzzing/properties/catalog.rb +6 -4
  130. data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +18 -11
  131. data/lib/hecks/fuzzing/properties/guards.rb +1 -1
  132. data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +1 -1
  133. data/lib/hecks/fuzzing/self_consistency.rb +6 -2
  134. data/lib/hecks/fuzzing/shrinker.rb +3 -1
  135. data/lib/hecks/fuzzing/value_generator.rb +19 -5
  136. data/lib/hecks/gate/stages.yml +33 -7
  137. data/lib/hecks/grammar/evolve.rb +1 -1
  138. data/lib/hecks/grammar/expression_operators.json +372 -0
  139. data/lib/hecks/grammar/operators.rb +3 -1
  140. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +10 -10
  141. data/lib/hecks/hecks/adapters/codebase/inspection/rubycritic.rb +35 -0
  142. data/lib/hecks/hecks/adapters/codebase/inspection.rb +104 -0
  143. data/lib/hecks/hecks/adapters/codebase/publishing.rb +2 -1
  144. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +12 -2
  145. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +2 -1
  146. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +1 -1
  147. data/lib/hecks/hecks/adapters/cost_explorer.rb +8 -5
  148. data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +2 -1
  149. data/lib/hecks/hecks/adapters/finding_github.rb +13 -6
  150. data/lib/hecks/hecks/adapters/first_admin.rb +2 -2
  151. data/lib/hecks/hecks/adapters/github_rulesets.rb +6 -3
  152. data/lib/hecks/hecks/adapters/in_process_boot.rb +1 -1
  153. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +1 -1
  154. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +10 -20
  155. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +28 -5
  156. data/lib/hecks/hecks/adapters/local_files.rb +2 -2
  157. data/lib/hecks/hecks/adapters/rehearsal/audit_report.rb +107 -0
  158. data/lib/hecks/hecks/adapters/rehearsal/census.rb +71 -0
  159. data/lib/hecks/hecks/adapters/rehearsal/declaration.rb +133 -0
  160. data/lib/hecks/hecks/adapters/rehearsal/environment.rb +83 -0
  161. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +142 -0
  162. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +96 -0
  163. data/lib/hecks/hecks/adapters/rehearsal/postgres_census.rb +100 -0
  164. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +69 -0
  165. data/lib/hecks/hecks/adapters/rehearsal/postgres_store.rb +133 -0
  166. data/lib/hecks/hecks/adapters/rehearsal/rows.rb +41 -0
  167. data/lib/hecks/hecks/adapters/rehearsal/rust_audit.rb +83 -0
  168. data/lib/hecks/hecks/adapters/rehearsal/subject.rb +104 -0
  169. data/lib/hecks/hecks/adapters/rehearsal.rb +54 -0
  170. data/lib/hecks/hecks/adapters/rehearsal_store.adapter +7 -0
  171. data/lib/hecks/hecks/adapters/rehearsal_store.rb +81 -0
  172. data/lib/hecks/hecks/adapters/terminal.rb +13 -11
  173. data/lib/hecks/hecks/codebase.behaviors +13 -1
  174. data/lib/hecks/hecks/codebase.bluebook +239 -5
  175. data/lib/hecks/hecks/custodian.behaviors +24 -6
  176. data/lib/hecks/hecks/custodian.bluebook +6 -1227
  177. data/lib/hecks/hecks/deploy.behaviors +1 -1
  178. data/lib/hecks/hecks/deploy.world +1 -3
  179. data/lib/hecks/hecks/hecks.behaviors +1 -1
  180. data/lib/hecks/hecks/hecks.hecksagon +53 -18
  181. data/lib/hecks/hecks/hecks.world +13 -10
  182. data/lib/hecks/hecks/rehearsal.bluebook +477 -0
  183. data/lib/hecks/hecks/site.behaviors +1 -1
  184. data/lib/hecks/hecks/site.world +0 -1
  185. data/lib/hecks/hecks/tooling.bluebook +1238 -0
  186. data/lib/hecks/indifferent_key.rb +20 -0
  187. data/lib/hecks/language/adapter.bluebook +13 -3
  188. data/lib/hecks/language/bluebook/aggregate.bluebook +23 -0
  189. data/lib/hecks/language/bluebook/bluebook.behaviors +23 -0
  190. data/lib/hecks/language/bluebook/bluebook.bluebook +15 -0
  191. data/lib/hecks/language/bluebook/entity.bluebook +18 -0
  192. data/lib/hecks/language/bluebook/policy.behaviors +19 -0
  193. data/lib/hecks/language/bluebook/policy.bluebook +9 -1
  194. data/lib/hecks/language/bluebook/query.bluebook +1 -1
  195. data/lib/hecks/language/bluebook/vocabulary.bluebook +63 -4
  196. data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -1
  197. data/lib/hecks/language/hecksagon/hecksagon.bluebook +22 -0
  198. data/lib/hecks/language/oidc.json +10 -0
  199. data/lib/hecks/language/port.bluebook +4 -4
  200. data/lib/hecks/literal.rb +12 -3
  201. data/lib/hecks/ports/key_vault.rb +7 -2
  202. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +21 -10
  203. data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +4 -2
  204. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +2 -1
  205. data/lib/hecks/ports/persistence/repository_factory.rb +6 -3
  206. data/lib/hecks/projection_files/expression_tables.rb +7 -2
  207. data/lib/hecks/projections/deploy/box/compose.rb +6 -4
  208. data/lib/hecks/projections/deploy/box/edge.rb +62 -0
  209. data/lib/hecks/projections/deploy/box/logging.rb +99 -0
  210. data/lib/hecks/projections/deploy/box/roll_scripts.rb +16 -8
  211. data/lib/hecks/projections/deploy/box/settings/cdn.rb +40 -0
  212. data/lib/hecks/projections/deploy/box/settings/logs.rb +40 -0
  213. data/lib/hecks/projections/deploy/box/settings/patterns.rb +11 -0
  214. data/lib/hecks/projections/deploy/box/settings/types.rb +16 -1
  215. data/lib/hecks/projections/deploy/box/settings.rb +6 -2
  216. data/lib/hecks/projections/deploy/box/stack_yaml.rb +5 -2
  217. data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +16 -0
  218. data/lib/hecks/projections/deploy/box/templates/box.yaml.tmpl +8 -4
  219. data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +32 -0
  220. data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +1 -1
  221. data/lib/hecks/projections/deploy/box/templates/edge.mk.tmpl +17 -0
  222. data/lib/hecks/projections/deploy/box/templates/edge.yaml.tmpl +65 -0
  223. data/lib/hecks/projections/deploy/box/templates/log-group.yaml.tmpl +12 -0
  224. data/lib/hecks/projections/deploy/box/templates/log-policy.yaml.tmpl +7 -0
  225. data/lib/hecks/projections/deploy/box/templates/render-compose-taskdef.sh.tmpl +5 -4
  226. data/lib/hecks/projections/deploy/box/templates/render-compose.sh.tmpl +5 -4
  227. data/lib/hecks/projections/deploy/box.rb +15 -3
  228. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  229. data/lib/hecks/projections/deploy/shared.rb +5 -2
  230. data/lib/hecks/projections/model/deviations.rb +2 -2
  231. data/lib/hecks/projections/model.rb +2 -2
  232. data/lib/hecks/projections/oidc.rb +13 -1
  233. data/lib/hecks/projections/shape.rb +5 -2
  234. data/lib/hecks/projections/site/cms_editor/attributes.rb +26 -6
  235. data/lib/hecks/projections/site/cms_editor/blocks.rb +157 -0
  236. data/lib/hecks/projections/site/cms_editor/checks.rb +14 -1
  237. data/lib/hecks/projections/site/cms_editor/clearing.rb +70 -0
  238. data/lib/hecks/projections/site/cms_editor/color.rb +124 -0
  239. data/lib/hecks/projections/site/cms_editor/composition.rb +42 -0
  240. data/lib/hecks/projections/site/cms_editor/destructive.rb +61 -0
  241. data/lib/hecks/projections/site/cms_editor/drafts.rb +102 -0
  242. data/lib/hecks/projections/site/cms_editor/hints.rb +74 -0
  243. data/lib/hecks/projections/site/cms_editor/icons.rb +86 -0
  244. data/lib/hecks/projections/site/cms_editor/key_kinds.rb +31 -0
  245. data/lib/hecks/projections/site/cms_editor/limits.rb +72 -0
  246. data/lib/hecks/projections/site/cms_editor/media.rb +1 -1
  247. data/lib/hecks/projections/site/cms_editor/moment.rb +34 -0
  248. data/lib/hecks/projections/site/cms_editor/palette.rb +115 -0
  249. data/lib/hecks/projections/site/cms_editor/pickers.rb +85 -0
  250. data/lib/hecks/projections/site/cms_editor/preview.rb +91 -0
  251. data/lib/hecks/projections/site/cms_editor/relations.rb +92 -0
  252. data/lib/hecks/projections/site/cms_editor/scale_checks.rb +66 -0
  253. data/lib/hecks/projections/site/cms_editor/scheduling.rb +150 -0
  254. data/lib/hecks/projections/site/cms_editor/schema.rb +96 -19
  255. data/lib/hecks/projections/site/cms_editor/setting.rb +52 -9
  256. data/lib/hecks/projections/site/cms_editor/targets.rb +86 -0
  257. data/lib/hecks/projections/site/cms_editor/templates/package.json.tmpl +18 -1
  258. data/lib/hecks/projections/site/cms_editor/templates/src/app.ts.tmpl +251 -57
  259. data/lib/hecks/projections/site/cms_editor/templates/src/assets.ts.tmpl +98 -0
  260. data/lib/hecks/projections/site/cms_editor/templates/src/auth/membership.ts.tmpl +32 -24
  261. data/lib/hecks/projections/site/cms_editor/templates/src/browser/app.css.tmpl +412 -0
  262. data/lib/hecks/projections/site/cms_editor/templates/src/browser/autosave.js.tmpl +144 -0
  263. data/lib/hecks/projections/site/cms_editor/templates/src/browser/blocks.js.tmpl +500 -0
  264. data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_doc.js.tmpl +175 -0
  265. data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_editor.js.tmpl +418 -0
  266. data/lib/hecks/projections/site/cms_editor/templates/src/browser/epoch.js.tmpl +61 -0
  267. data/lib/hecks/projections/site/cms_editor/templates/src/browser/forms.js.tmpl +210 -0
  268. data/lib/hecks/projections/site/cms_editor/templates/src/browser/lists.js.tmpl +40 -0
  269. data/lib/hecks/projections/site/cms_editor/templates/src/browser/main.js.tmpl +26 -0
  270. data/lib/hecks/projections/site/cms_editor/templates/src/browser/media_picker.js.tmpl +232 -0
  271. data/lib/hecks/projections/site/cms_editor/templates/src/browser/moments.js.tmpl +73 -0
  272. data/lib/hecks/projections/site/cms_editor/templates/src/browser/pickers.js.tmpl +152 -0
  273. data/lib/hecks/projections/site/cms_editor/templates/src/browser/preview.js.tmpl +98 -0
  274. data/lib/hecks/projections/site/cms_editor/templates/src/browser/shell.js.tmpl +140 -0
  275. data/lib/hecks/projections/site/cms_editor/templates/src/browser/toast.js.tmpl +66 -0
  276. data/lib/hecks/projections/site/cms_editor/templates/src/choices.ts.tmpl +99 -0
  277. data/lib/hecks/projections/site/cms_editor/templates/src/commands.ts.tmpl +78 -24
  278. data/lib/hecks/projections/site/cms_editor/templates/src/config.ts.tmpl +6 -0
  279. data/lib/hecks/projections/site/cms_editor/templates/src/flash.ts.tmpl +52 -0
  280. data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +19 -2
  281. data/lib/hecks/projections/site/cms_editor/templates/src/media/handler.ts.tmpl +31 -8
  282. data/lib/hecks/projections/site/cms_editor/templates/src/names.ts.tmpl +36 -0
  283. data/lib/hecks/projections/site/cms_editor/templates/src/schema.ts.tmpl +131 -2
  284. data/lib/hecks/projections/site/cms_editor/templates/src/ui/availability.ts.tmpl +15 -0
  285. data/lib/hecks/projections/site/cms_editor/templates/src/ui/block_list.js.tmpl +213 -0
  286. data/lib/hecks/projections/site/cms_editor/templates/src/ui/blocks.ts.tmpl +275 -0
  287. data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_model.js.tmpl +8 -5
  288. data/lib/hecks/projections/site/cms_editor/templates/src/ui/detail.ts.tmpl +88 -0
  289. data/lib/hecks/projections/site/cms_editor/templates/src/ui/dialogs.ts.tmpl +43 -0
  290. data/lib/hecks/projections/site/cms_editor/templates/src/ui/fields.ts.tmpl +229 -34
  291. data/lib/hecks/projections/site/cms_editor/templates/src/ui/html.ts.tmpl +40 -81
  292. data/lib/hecks/projections/site/cms_editor/templates/src/ui/icons.ts.tmpl +15 -0
  293. data/lib/hecks/projections/site/cms_editor/templates/src/ui/input.ts.tmpl +29 -12
  294. data/lib/hecks/projections/site/cms_editor/templates/src/ui/links.ts.tmpl +100 -0
  295. data/lib/hecks/projections/site/cms_editor/templates/src/ui/moments.ts.tmpl +44 -0
  296. data/lib/hecks/projections/site/cms_editor/templates/src/ui/outline.ts.tmpl +53 -17
  297. data/lib/hecks/projections/site/cms_editor/templates/src/ui/pages.ts.tmpl +178 -88
  298. data/lib/hecks/projections/site/cms_editor/templates/src/ui/paging.ts.tmpl +82 -0
  299. data/lib/hecks/projections/site/cms_editor/templates/src/ui/pickers.ts.tmpl +110 -0
  300. data/lib/hecks/projections/site/cms_editor/templates/src/ui/preview.ts.tmpl +87 -0
  301. data/lib/hecks/projections/site/cms_editor/templates/src/ui/related.ts.tmpl +97 -0
  302. data/lib/hecks/projections/site/cms_editor/templates/src/ui/schedule.ts.tmpl +160 -0
  303. data/lib/hecks/projections/site/cms_editor/templates/src/ui/shell.ts.tmpl +211 -0
  304. data/lib/hecks/projections/site/cms_editor/templates/src/ui/table.ts.tmpl +151 -0
  305. data/lib/hecks/projections/site/cms_editor/templates/src/ui/theme.js.tmpl +16 -0
  306. data/lib/hecks/projections/site/cms_editor/templates/src/ui/values.ts.tmpl +69 -0
  307. data/lib/hecks/projections/site/cms_editor/templates/src/ui/words.ts.tmpl +97 -0
  308. data/lib/hecks/projections/site/cms_editor/templates/src/ui/world.ts.tmpl +35 -0
  309. data/lib/hecks/projections/site/cms_editor/templates/tsconfig.json.tmpl +2 -1
  310. data/lib/hecks/projections/site/cms_editor/theme.rb +29 -0
  311. data/lib/hecks/projections/site/cms_editor/theme_checks.rb +57 -0
  312. data/lib/hecks/projections/site/cms_editor.rb +49 -23
  313. data/lib/hecks/projections/site/role_probe.rb +2 -0
  314. data/lib/hecks/projections/site/site_root/workflow.rb +5 -0
  315. data/lib/hecks/projector/cli_audience.rb +22 -1
  316. data/lib/hecks/projector/cli_projector/listing.rb +1 -1
  317. data/lib/hecks/projector/cli_projector/option_specs.rb +1 -1
  318. data/lib/hecks/projector/cli_projector/usage.rb +15 -4
  319. data/lib/hecks/projector/docs_projector/closing.rb +1 -1
  320. data/lib/hecks/projector/docs_projector.rb +1 -1
  321. data/lib/hecks/projector/exporter/bindings.rb +40 -10
  322. data/lib/hecks/projector/exporter/capability_values.rb +55 -0
  323. data/lib/hecks/projector/narrate_projector/reactions.rb +1 -1
  324. data/lib/hecks/projector/target.rb +11 -0
  325. data/lib/hecks/projector.rb +32 -5
  326. data/lib/hecks/quality_control/adapters/github_checks.rb +12 -8
  327. data/lib/hecks/quality_control/adapters/github_issues.rb +8 -4
  328. data/lib/hecks/quality_control/cli/qa_open_pr.rb +2 -2
  329. data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +1 -1
  330. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +1 -1
  331. data/lib/hecks/quality_control/cli/qa_sweep.rb +1 -1
  332. data/lib/hecks/quality_control/quality_control.bluebook +6 -2
  333. data/lib/hecks/release/approval.rb +64 -0
  334. data/lib/hecks/router/{door.rb → aggregate_reader.rb} +5 -4
  335. data/lib/hecks/router/namespace_installer.rb +16 -16
  336. data/lib/hecks/router.rb +1 -1
  337. data/lib/hecks/runtime/best_effort.rb +22 -0
  338. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -2
  339. data/lib/hecks/runtime/command_interpreter.rb +3 -2
  340. data/lib/hecks/runtime/command_rules/emission.rb +1 -1
  341. data/lib/hecks/runtime/dispatcher.rb +4 -4
  342. data/lib/hecks/runtime/entity_element/location.rb +1 -1
  343. data/lib/hecks/runtime/event.rb +5 -0
  344. data/lib/hecks/runtime/identity.rb +7 -6
  345. data/lib/hecks/runtime/interpreting.rb +2 -1
  346. data/lib/hecks/runtime/invocation_builder.rb +1 -1
  347. data/lib/hecks/runtime/loader/boot_steps.rb +8 -5
  348. data/lib/hecks/runtime/loader.rb +10 -10
  349. data/lib/hecks/runtime/policy_interpreter/arguments.rb +7 -4
  350. data/lib/hecks/runtime/policy_interpreter/fan_out.rb +3 -3
  351. data/lib/hecks/runtime/policy_interpreter.rb +6 -6
  352. data/lib/hecks/runtime/port_operation_interpreter.rb +1 -1
  353. data/lib/hecks/runtime/reaction_invocation.rb +1 -1
  354. data/lib/hecks/runtime/rebuild_sweep.rb +11 -1
  355. data/lib/hecks/runtime/registry/ask_verification.rb +35 -0
  356. data/lib/hecks/runtime/registry/hecksagon_rules.rb +10 -0
  357. data/lib/hecks/runtime/registry/merging.rb +1 -1
  358. data/lib/hecks/runtime/registry/providers.rb +16 -0
  359. data/lib/hecks/runtime/registry/read_repository.rb +6 -4
  360. data/lib/hecks/runtime/registry/verification.rb +4 -1
  361. data/lib/hecks/runtime/registry/world_defaults.rb +29 -0
  362. data/lib/hecks/runtime/registry.rb +1 -1
  363. data/lib/hecks/runtime/saga_interpreter/compensation.rb +1 -1
  364. data/lib/hecks/runtime/saga_interpreter/delivery.rb +4 -4
  365. data/lib/hecks/runtime/saga_interpreter/transitions.rb +1 -1
  366. data/lib/hecks/runtime/saga_interpreter.rb +3 -3
  367. data/lib/hecks/runtime/tenant_check.rb +5 -4
  368. data/lib/hecks/runtime/value/coercion.rb +2 -2
  369. data/lib/hecks/runtime/value/validation.rb +16 -4
  370. data/lib/hecks/runtime.rb +9 -9
  371. data/lib/hecks/rust_build/host.rb +11 -4
  372. data/lib/hecks/rust_build/prebuilt_binary.rb +101 -0
  373. data/lib/hecks/rust_build/project_rust/target_ir.rb +1 -1
  374. data/lib/hecks/rust_build/wasm.rb +1 -1
  375. data/lib/hecks/rust_build/wasm_browser.rb +1 -1
  376. data/lib/hecks/rust_build.rb +11 -0
  377. data/lib/hecks/served_options.rb +53 -0
  378. data/lib/hecks/site/bluebook/site.bluebook +1 -0
  379. data/lib/hecks/storehouse/audit.rb +1 -1
  380. data/lib/hecks/storehouse/dispatching.rb +8 -6
  381. data/lib/hecks/storehouse/introspection.rb +2 -2
  382. data/lib/hecks/storehouse/querying.rb +6 -4
  383. data/lib/hecks/storehouse.rb +4 -4
  384. data/lib/hecks/tools/ci_gate_decision.rb +35 -0
  385. data/lib/hecks/tools/ci_gates.rb +20 -1
  386. data/lib/hecks/tools/comment_style/source_file.rb +4 -1
  387. data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +4 -1
  388. data/lib/hecks/tools/lanes/files.rb +8 -0
  389. data/lib/hecks/tools/lanes/prebuilt_workflow.rb +81 -0
  390. data/lib/hecks/tools/lanes/rows.rb +6 -0
  391. data/lib/hecks/tools/lanes.rb +1 -0
  392. data/lib/hecks/tools/oidc_manifests.rb +4 -5
  393. data/lib/hecks/tools/regeneration_run.rb +11 -4
  394. data/lib/hecks/tools/release_only.rb +111 -0
  395. data/lib/hecks/tools/site_routes/editor_files.rb +12 -5
  396. data/lib/hecks/tools/tenant_provisioning.rb +2 -2
  397. data/lib/hecks/tools/tools_doc.rb +4 -4
  398. data/lib/hecks/version.rb +1 -1
  399. data/lib/hecks/vocabulary.rb +19 -5
  400. data/lib/hecks.rb +15 -15
  401. data/lib/rubocop/cop/hecks/env_dump.rb +69 -0
  402. data/lib/rubocop/cop/hecks/monotonic_duration.rb +53 -0
  403. data/lib/rubocop/cop/hecks/no_wall_clock_in_runtime.rb +34 -0
  404. data/lib/rubocop/cop/hecks/raw_shell_interpolation.rb +79 -0
  405. data/lib/rubocop/cop/hecks/sleep_in_spec.rb +34 -0
  406. data/lib/rubocop/cop/hecks/swallowed_rescue.rb +37 -0
  407. data/lib/rubocop/cop/hecks/symbol_string_key_mix.rb +50 -0
  408. data/lib/rubocop/cop/hecks/untyped_raise.rb +37 -0
  409. data/prebuilt/9ee54e2f0d4d6d3fe046827779b221e02de665fba911a048ae5dd8b8fbfb7d90.marshal +0 -0
  410. data/prebuilt/d74a00e996222c1d8b676d5959092effc46b4dc59e0555f3bf9554ac58e3094a.marshal +0 -0
  411. data/prebuilt/verdicts-df19f35868d3284a70f55e42dcef87ef4e65e6a678e5135f72e1f6cff4c1357b.json +1 -0
  412. data/rust/.gitignore +6 -0
  413. data/rust/Cargo.toml +6 -0
  414. data/rust/build/src/binding_pass.rs +103 -0
  415. data/rust/build/src/cargo_sync.rs +6 -0
  416. data/rust/build/src/lineage_pass.rs +3 -3
  417. data/rust/build/src/main.rs +17 -5
  418. data/rust/build/src/pipeline.rs +48 -5
  419. data/rust/build/src/seams_pass.rs +123 -0
  420. data/rust/build/src/translation_pass.rs +167 -0
  421. data/rust/codegen/src/asks.rs +103 -0
  422. data/rust/codegen/src/commands.rs +13 -8
  423. data/rust/codegen/src/constraints.rs +25 -0
  424. data/rust/codegen/src/domain_generator.rs +2 -0
  425. data/rust/codegen/src/expr_emitter.rs +13 -0
  426. data/rust/codegen/src/json_codec.rs +54 -15
  427. data/rust/codegen/src/main.rs +1 -0
  428. data/rust/codegen/src/mutations.rs +128 -3
  429. data/rust/codegen/src/queries.rs +11 -2
  430. data/rust/codegen/src/reactions.rs +1 -1
  431. data/rust/codegen/src/types.rs +166 -8
  432. data/rust/host/HECKS_RELEASE +1 -1
  433. data/rust/host/src/api.rs +4 -4
  434. data/rust/host/src/bin/validate_harness.rs +43 -0
  435. data/rust/host/src/boundary_fuzz/expr_json.rs +2 -2
  436. data/rust/host/src/boundary_fuzz/ir.rs +1 -0
  437. data/rust/host/src/boundary_fuzz/server.rs +1 -1
  438. data/rust/host/src/checkout.rs +35 -19
  439. data/rust/host/src/commerce_ir.rs +408 -2
  440. data/rust/host/src/expr_json.rs +118 -0
  441. data/rust/host/src/extension.rs +13 -1
  442. data/rust/host/src/lib.rs +1 -0
  443. data/rust/host/src/mint.rs +1 -1
  444. data/rust/host/src/payments/tests.rs +27 -1
  445. data/rust/host/src/payments.rs +12 -4
  446. data/rust/host/src/platform_signin/attack_tests.rs +1100 -0
  447. data/rust/host/src/platform_signin/config.rs +512 -0
  448. data/rust/host/src/platform_signin/cookie.rs +237 -0
  449. data/rust/host/src/platform_signin/extension.rs +190 -0
  450. data/rust/host/src/platform_signin/fetcher.rs +322 -0
  451. data/rust/host/src/platform_signin/handler.rs +251 -0
  452. data/rust/host/src/platform_signin/handler_tests.rs +554 -0
  453. data/rust/host/src/platform_signin/jti.rs +196 -0
  454. data/rust/host/src/platform_signin/jwks.rs +542 -0
  455. data/rust/host/src/platform_signin/jws.rs +249 -0
  456. data/rust/host/src/platform_signin/known_answer_tests.rs +237 -0
  457. data/rust/host/src/platform_signin/mapping_tests.rs +254 -0
  458. data/rust/host/src/platform_signin/mod.rs +75 -0
  459. data/rust/host/src/platform_signin/mode_tests.rs +382 -0
  460. data/rust/host/src/platform_signin/pages.rs +204 -0
  461. data/rust/host/src/platform_signin/query.rs +233 -0
  462. data/rust/host/src/platform_signin/session.rs +151 -0
  463. data/rust/host/src/platform_signin/settings.rs +385 -0
  464. data/rust/host/src/platform_signin/strict_json.rs +351 -0
  465. data/rust/host/src/platform_signin/test_support.rs +235 -0
  466. data/rust/host/src/platform_signin/ttl_tests.rs +94 -0
  467. data/rust/host/src/platform_signin/verify.rs +604 -0
  468. data/rust/host/src/platform_signin/wiring_support.rs +319 -0
  469. data/rust/host/src/query_step.rs +22 -4
  470. data/rust/host/src/reference_validate.rs +653 -108
  471. data/rust/host/src/resend.rs +2 -0
  472. data/rust/host/src/server.rs +19 -6
  473. data/rust/host/src/ui_schema.rs +132 -5
  474. data/rust/host/src/web/newsletter.rs +7 -8
  475. data/rust/host/src/web/newsletter_send.rs +38 -13
  476. data/rust/host/src/web/registrations.rs +229 -26
  477. data/rust/host/src/web.rs +53 -9
  478. data/rust/parser/src/emit.rs +38 -6
  479. data/rust/parser/src/expr/ast_json.rs +7 -1
  480. data/rust/parser/src/expr/resolver.rs +171 -6
  481. data/rust/parser/src/ir.rs +7 -0
  482. data/rust/parser/src/keywords.rs +24 -0
  483. data/rust/parser/src/main.rs +3 -0
  484. data/rust/parser/src/parse/aggregate.rs +2 -1
  485. data/rust/parser/src/parse/chapter.rs +2 -2
  486. data/rust/parser/src/parse/command.rs +2 -0
  487. data/rust/parser/src/parse/hecksagon.rs +5 -2
  488. data/rust/parser/src/parse/lifecycle.rs +81 -0
  489. data/rust/parser/src/parse/mod.rs +15 -1
  490. data/rust/parser/src/parse/policy.rs +13 -2
  491. data/rust/parser/src/parse/value_object.rs +34 -17
  492. data/rust/parser/src/ruby_value.rs +1 -1
  493. data/rust/src/exemplar/commands.rs +4 -4
  494. data/rust/src/exemplar/constraints.rs +1 -1
  495. data/rust/src/exemplar/json.rs +43 -1
  496. data/rust/src/kernel/cli.rs +7 -5
  497. data/rust/src/kernel/dispatch.rs +2 -2
  498. data/rust/src/kernel/dispatch_guard_tests.rs +1 -1
  499. data/rust/src/kernel/expr.rs +66 -3
  500. data/rust/src/kernel/expression_operators/arithmetic.rs +130 -5
  501. data/rust/src/kernel/expression_operators/text.rs +26 -2
  502. data/rust/src/kernel/json.rs +15 -0
  503. data/rust/src/kernel/mod.rs +1 -1
  504. data/rust/src/kernel/orchestrate.rs +54 -5
  505. data/rust/src/kernel/orchestrate_guard_tests.rs +67 -0
  506. data/rust/src/kernel/pattern.rs +60 -0
  507. data/rust/src/kernel/reference_lookup.rs +90 -7
  508. metadata +178 -38
  509. data/lib/hecks/doors/cli_door/nesting.rb +0 -34
  510. data/lib/hecks/doors/cli_door/shorthand.rb +0 -85
  511. data/lib/hecks/doors/cli_door.rb +0 -124
  512. data/lib/hecks/doors/cli_runner/answers.rb +0 -138
  513. data/lib/hecks/doors/cli_runner/resolution.rb +0 -146
  514. data/lib/hecks/doors/cli_runner/settling.rb +0 -115
  515. data/lib/hecks/doors/cli_runner/streaming.rb +0 -90
  516. data/lib/hecks/doors/cli_runner/suggestions.rb +0 -43
  517. data/lib/hecks/doors/cli_runner.rb +0 -66
  518. data/lib/hecks/doors/command_request.rb +0 -119
  519. data/lib/hecks/doors/handle.rb +0 -208
  520. data/lib/hecks/doors/json_door.rb +0 -132
  521. data/lib/hecks/doors/launcher_options.rb +0 -247
  522. data/lib/hecks/doors/mcp_door/properties.rb +0 -47
  523. data/lib/hecks/doors/mcp_door/tool_calls.rb +0 -113
  524. data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +0 -51
  525. data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +0 -69
  526. data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +0 -97
  527. data/lib/hecks/doors/mcp_door/tool_definitions.rb +0 -15
  528. data/lib/hecks/doors/mcp_door.rb +0 -156
  529. data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +0 -92
  530. data/lib/hecks/doors/mcp_door_scope/env_problems.rb +0 -55
  531. data/lib/hecks/doors/mcp_door_scope/presenter.rb +0 -78
  532. data/lib/hecks/doors/mcp_door_scope.rb +0 -201
  533. data/lib/hecks/doors/mcp_guide_cache.rb +0 -75
  534. data/lib/hecks/doors/ruby_door/aggregate_door.rb +0 -162
  535. data/lib/hecks/doors/ruby_door/chapter.rb +0 -89
  536. data/lib/hecks/doors/ruby_door.rb +0 -80
  537. data/lib/hecks/doors/usage_cache.rb +0 -139
  538. data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_widget.js.tmpl +0 -282
  539. data/lib/hecks/projections/site/cms_editor/templates/src/ui/media_picker.js.tmpl +0 -109
  540. data/prebuilt/c28d6d9db14eea3e17161e9d9c262efee30b256cf97693a7cfd552bce24b2f7f.marshal +0 -0
  541. data/prebuilt/cb375cba61ca0dbe8ddb9739c306510fe05e5f4b7a9b6955caff8224c63ea0e0.marshal +0 -0
  542. data/prebuilt/verdicts-d6d584ad43b5f3cebf88aafbbdbf024c38574acf18e06adffbc555f7786b1c2f.json +0 -1
@@ -1,247 +0,0 @@
1
- require "pathname"
2
- require "stringio"
3
- require_relative "../ports/identity_generation"
4
- require_relative "../runtime/errors"
5
- require_relative "cli_door"
6
-
7
- module Hecks
8
- module Doors
9
- # What a domain's world file adds to its generated launcher, all of it opt-in.
10
- #
11
- # A `.world` that declares a `launcher` setting switches these on for that chapter; a
12
- # domain without one keeps the launcher's plain forms exactly:
13
- #
14
- # - **run_keys** mints the `run` key of a creating command that was given none.
15
- # - **failure_states** are the lifecycle states `--wait` reports as a failure (exit 1).
16
- # - **settled** lists the commands (`aggregate.command`) that always act as if given `--wait`.
17
- # - **report** lists the settled commands whose answer is the report they recorded, as text.
18
- # - **names** maps a launcher name to the command it stands for (see `CliProjector`).
19
- # - **streams** lists the questions `--stream` may tail, one JSON line per new entry.
20
- # - **maintainer**, **chapters**, **maintainer_chapters** shape the help for its audience.
21
- module LauncherOptions
22
- SETTING = "launcher".freeze
23
- WAIT = "--wait".freeze
24
- STREAM = "--stream".freeze
25
- RUN_KEY = "run.value".freeze
26
- # What makes a directory a hecks checkout: this file stands beside `lib/`, the same test
27
- # the Codebase aggregate's `Accept` applies before it runs anything.
28
- CHECKOUT_MARKER = "hecks.gemspec".freeze
29
- # `HECKS_MAINTAINER=1` shows the maintainer help anywhere, `0` hides it even in a checkout.
30
- MAINTAINER_VARIABLE = "HECKS_MAINTAINER".freeze
31
-
32
- module_function
33
-
34
- # Reads a chapter's `launcher` setting.
35
- #
36
- # @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
37
- # @param chapter [String] the chapter the command line speaks to
38
- # @return [Hash{Symbol => Object}, nil] the setting, or nil when the chapter did not opt in
39
- def settings(runtime, chapter)
40
- return unless runtime.respond_to?(:registry)
41
-
42
- found = runtime.registry.world(chapter)&.for_verb(SETTING)
43
- found.nil? || found.empty? ? nil : found
44
- end
45
-
46
- # The options the launcher's projection is asked for: the program's name, the chapter's
47
- # launcher names, and whether run keys are minted (so help shows them optional).
48
- #
49
- # @param settings [Hash, nil] the chapter's `launcher` setting
50
- # @param program [String] how the caller was invoked
51
- # @return [Hash{Symbol => Object}] the options `Projector::CliProjector` reads
52
- def projection(settings, program)
53
- { program: program, names: settings && settings[:names], mint_run_keys: settings && settings[:run_keys] }
54
- end
55
-
56
- # Whether the person is working on a hecks checkout: `dir` or a directory above it holds
57
- # `hecks.gemspec` beside `lib/`. `HECKS_MAINTAINER` overrides the look.
58
- #
59
- # @param dir [String] where the command line was typed
60
- # @param env [#[]] the environment
61
- # @return [Boolean] true for the maintainer's view of the help
62
- def maintainer?(dir = Dir.pwd, env = ENV)
63
- forced = env[MAINTAINER_VARIABLE].to_s
64
- return forced != "0" unless forced.empty?
65
-
66
- Pathname.new(File.expand_path(dir)).ascend.any? do |root|
67
- root.join(CHECKOUT_MARKER).exist? && root.join("lib").directory?
68
- end
69
- end
70
-
71
- # The help options one audience gets: the aggregates left out of the lists (`maintainer`,
72
- # shown only in a hecks checkout or to `--maintainer`) and the chapters pointed at
73
- # (`chapters`, plus `maintainer_chapters` in a checkout). A chapter that did not opt in
74
- # gets neither.
75
- #
76
- # @param settings [Hash, nil] the chapter's `launcher` setting
77
- # @param maintainer [Boolean] whether the help is for someone working on a hecks checkout
78
- # @return [Hash{Symbol => Object}] `:hide` and `:chapters`, to merge into the projection
79
- def audience(settings, maintainer)
80
- return {} unless settings
81
-
82
- chapters = Array(settings[:chapters]) + (maintainer ? Array(settings[:maintainer_chapters]) : [])
83
- { hide: maintainer ? [] : Array(settings[:maintainer]).map(&:to_s), chapters: chapters.map(&:to_s) }
84
- end
85
-
86
- # Runs the block with standard error held back, so the wiring notes hecks prints about its own
87
- # chapters (a Memory journal loses sagas on restart) do not open a console session. They are
88
- # for an operator running a stored journal. A raised error still surfaces, unchanged.
89
- #
90
- # @param hold [Boolean] whether to hold standard error back; false runs the block as it is
91
- # @yield the boot
92
- # @return [Object] the block's value
93
- def quietly(hold: true)
94
- return yield unless hold
95
-
96
- shown = $stderr
97
- $stderr = StringIO.new
98
- yield
99
- ensure
100
- $stderr = shown if hold
101
- end
102
-
103
- # Takes `--wait` out of a command's words, unless it declares a `wait` argument of its own.
104
- #
105
- # `--wait=false` (or `no`, `0`, `off`) is a `--wait` that was switched off; a bare `--wait`
106
- # may be followed by its Boolean word.
107
- #
108
- # @param spec [Hash] the command's projected spec
109
- # @param words [Array<String>] the words after the command
110
- # @return [Array(Array<String>, Boolean)] the remaining words, and whether `--wait` was given
111
- # @raise [Runtime::TypeMismatch] if `--wait=` carries something that is not a Boolean word
112
- def take_wait(spec, words)
113
- return [words, false] unless words.any? { |word| wait_word?(word) } && !declares_wait?(spec)
114
-
115
- split_wait(words)
116
- end
117
-
118
- # Whether the command declares an argument of its own named `wait`.
119
- # @api private
120
- def declares_wait?(spec)
121
- spec[:arguments].any? { |argument| argument[:path].split(".").first == "wait" }
122
- end
123
-
124
- # The words without `--wait`, and whether it was given.
125
- # @api private
126
- def split_wait(words)
127
- wait = false
128
- rest = []
129
- queue = words.dup
130
- until queue.empty?
131
- word = queue.shift
132
- wait_word?(word) ? wait ||= CliDoor.boolean(wait_value(word, queue)) : rest << word
133
- end
134
- [rest, wait]
135
- end
136
-
137
- # Whether a command always waits for its reactions, as if `--wait` had been given.
138
- #
139
- # @param launcher [Hash, nil] the chapter's `launcher` setting
140
- # @param spec [Hash] the command's projected spec
141
- # @return [Boolean] true for a command the setting lists under `settled`
142
- def settled?(launcher, spec)
143
- return false unless launcher && spec[:kind] == :command
144
-
145
- Array(launcher[:settled]).map(&:to_s).include?(spec[:short].to_s)
146
- end
147
-
148
- # Whether a command prints the report it recorded instead of its whole record.
149
- #
150
- # @param launcher [Hash, nil] the chapter's `launcher` setting
151
- # @param spec [Hash] the command's projected spec
152
- # @return [Boolean] true for a command the setting lists under `report`
153
- def report?(launcher, spec)
154
- return false unless launcher && spec[:kind] == :command
155
-
156
- Array(launcher[:report]).map(&:to_s).include?(spec[:short].to_s)
157
- end
158
-
159
- # Whether a question may be tailed with `--stream`: the chapter's `launcher` setting lists it
160
- # under `streams`, by the question's own name.
161
- #
162
- # @param launcher [Hash, nil] the chapter's `launcher` setting
163
- # @param spec [Hash] the question's projected spec
164
- # @return [Boolean] true for a question the setting names
165
- def streams?(launcher, spec)
166
- return false unless launcher && spec[:kind] == :query
167
-
168
- Array(launcher[:streams]).map(&:to_s).include?(spec[:command].to_s.split(/[.:]+/).last)
169
- end
170
-
171
- # Takes `--stream` out of a question's words.
172
- #
173
- # @param words [Array<String>] the words after the question
174
- # @return [Array(Array<String>, Boolean)] the remaining words, and whether `--stream` was
175
- # given
176
- def take_stream(words)
177
- [words.reject { |word| word == STREAM }, words.include?(STREAM)]
178
- end
179
-
180
- # @api private
181
- def wait_word?(word) = word == WAIT || word.start_with?("#{WAIT}=")
182
-
183
- # The Boolean word a `--wait` carries: after `=`, or the next word when it is one.
184
- # @api private
185
- def wait_value(word, queue)
186
- return word.split("=", 2).last if word.include?("=")
187
-
188
- CliDoor::BOOLEAN_WORDS.key?(queue.first.to_s.downcase) ? queue.shift : "true"
189
- end
190
-
191
- # Whether a question's text answer reports a gap, which `--wait` turns into a failing exit.
192
- #
193
- # The coverage checks end their report with a `GAP (n)` heading; a non-zero count is a
194
- # finding, and a CI stage that waits on the question fails on it.
195
- #
196
- # @param text [String, nil] the question's text answer
197
- # @return [Boolean] whether a `GAP (n)` heading with n above zero is in the text
198
- def gap_reported?(text)
199
- text.is_a?(String) && text.match?(/^GAP \((?!0\))\d+\)/)
200
- end
201
-
202
- # Mints the `run` key a creating command was not given, when the domain opted in.
203
- #
204
- # An explicit key always wins. Nothing is minted for a command that acts on an existing
205
- # record. When no identity adapter is bound the run is refused, saying to name a key,
206
- # rather than sent on without one.
207
- #
208
- # @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
209
- # @param spec [Hash] the command's projected spec
210
- # @param args [Hash] the parsed arguments
211
- # @param settings [Hash, nil] the chapter's `launcher` setting
212
- # @return [Array(Hash, String)] the arguments, and the key minted (nil when none was)
213
- # @raise [Runtime::NotFound] if a key is owed but no identity adapter is bound
214
- def run_key(runtime, spec, args, settings)
215
- return [args, nil] unless key_owed?(runtime, spec, args, settings)
216
-
217
- key = Ports::IdentityGeneration.uuid(runtime.registry)
218
- [args.merge(run: { value: key }), key]
219
- rescue Runtime::WiringError => e
220
- raise Runtime::NotFound, "cannot mint a run key (#{e.message.lines.first.strip}); name one with run=<key>"
221
- end
222
-
223
- # Whether the command is a creating one of an opted-in chapter, takes a run key and was
224
- # given none.
225
- # @api private
226
- def key_owed?(runtime, spec, args, settings)
227
- return false unless settings && settings[:run_keys] && spec[:creates]
228
- return false unless spec[:arguments].any? { |argument| argument[:path] == RUN_KEY }
229
-
230
- !args.key?(:run) && runtime.respond_to?(:registry)
231
- end
232
-
233
- # Whether a settled record sits in one of the chapter's failure states.
234
- #
235
- # @param aggregate [Bluebook::Aggregate, nil] the record's aggregate
236
- # @param state [Hash, nil] the record's state
237
- # @param settings [Hash, nil] the chapter's `launcher` setting
238
- # @return [Boolean] false when the aggregate has no lifecycle
239
- def failed?(aggregate, state, settings)
240
- field = aggregate&.lifecycle&.field
241
- return false unless field && state
242
-
243
- Array(settings && settings[:failure_states]).map(&:to_s).include?(state[field.to_sym].to_s)
244
- end
245
- end
246
- end
247
- end
@@ -1,47 +0,0 @@
1
- require_relative "../../../hecks"
2
-
3
- module Hecks
4
- module Doors
5
- module McpDoor
6
- # The input-schema properties the MCP door's tools share.
7
- module Properties
8
- SUMMARY_PROPERTY = {
9
- type: "string",
10
- description: "One line: why this call is happening. Required — it is what makes the audit trail legible later."
11
- }.freeze
12
-
13
- DOMAIN_PROPERTY = {
14
- type: "string",
15
- description: "The domain directory, containing a .hecksagon (e.g. \"examples/banking\"). The `domains` tool " \
16
- "lists what's available."
17
- }.freeze
18
-
19
- ARGS_PROPERTY = {
20
- type: "object",
21
- description: "The command/query's declared arguments, nested value-object literals included " \
22
- "(e.g. {\"reference\":{\"value\":\"BUG#1\"}})."
23
- }.freeze
24
-
25
- SOURCE_PROPERTY = {
26
- type: "string",
27
- enum: Hecks::Storehouse::SOURCE_TAGS,
28
- description: "Optional: who is calling, for the audit log `follow` reads back."
29
- }.freeze
30
-
31
- ROLE_PROPERTY = {
32
- type: "string",
33
- description: "Bind a caller identity for the call's duration, so a role-gated command's authorization is " \
34
- "checked rather than merely documented. Required by `dispatch` for any command that declares a " \
35
- "role — omitting it refuses the call rather than running it unchecked. Also required if " \
36
- "`actor_id` is given."
37
- }.freeze
38
-
39
- ACTOR_ID_PROPERTY = {
40
- type: "string",
41
- description: "Optional, alongside `role`: WHO holds that role — once the domain attaches Governance, checked " \
42
- "against a real Governance::RoleAssignment instead of a bare string match. Requires `role`."
43
- }.freeze
44
- end
45
- end
46
- end
47
- end
@@ -1,113 +0,0 @@
1
- require_relative "../../../hecks"
2
-
3
- module Hecks
4
- module Doors
5
- module McpDoor
6
- # Answers one `tools/call`: the tool a name stands for, run against the booted domain the
7
- # call names. A domain refusal is already `{ok: false, ...}` from `Storehouse`.
8
- module ToolCalls
9
- # The method that answers each tool.
10
- HANDLERS = {
11
- "dispatch" => :dispatch_tool,
12
- "query" => :query_tool,
13
- "events" => :events_tool,
14
- "state" => :state_tool,
15
- "catalog" => :catalog_tool,
16
- "describe" => :describe_tool,
17
- "validate" => :validate_tool,
18
- "domains" => :domains_tool,
19
- "history" => :history_tool,
20
- "behaviors" => :behaviors_tool,
21
- "follow" => :follow_tool
22
- }.freeze
23
-
24
- module_function
25
-
26
- # Runs the tool `name` with `args`, so the shared `rescue` catches every tool's escape once.
27
- #
28
- # @param name [String] the tool's name
29
- # @param args [Hash{String => Object}] the call's arguments
30
- # @return [Hash{Symbol => Object}] the tool's answer, or `{ok: false, error: ...}`
31
- def call(name, args)
32
- handler = HANDLERS[name]
33
- return unknown(name) unless handler
34
-
35
- public_send(handler, args)
36
- rescue StandardError => e
37
- # A defect, not a refusal: reaching here means a bad domain path or an
38
- # argument shape `Doors::JsonDoor` could not symbolize.
39
- { ok: false, error: "#{e.class}: #{e.message}" }
40
- end
41
-
42
- # The refusal for a tool the door does not have.
43
- def unknown(name)
44
- { ok: false, error: "no such tool: #{name.inspect} — known: #{HANDLERS.keys.join(", ")}" }
45
- end
46
-
47
- # A question, once the scope has admitted its arguments.
48
- def query_tool(args)
49
- McpDoor.scope.admit_arguments!(args["args"])
50
- Storehouse.query(runtime: McpDoor.boot(args["domain"]), question: args["question"],
51
- summary: args["summary"], args: args["args"] || {}, source: args["source"],
52
- role: args["role"], actor_id: args["actor_id"])
53
- end
54
-
55
- # A single command or a batch, once the scope has admitted every command in it.
56
- def dispatch_tool(args)
57
- runtime = McpDoor.boot(args["domain"])
58
- return dispatch_steps(runtime, args) if args["steps"]
59
-
60
- McpDoor.scope.admit_command!(runtime, args["command"], args["args"])
61
- Storehouse.dispatch(runtime: runtime, command: args["command"], summary: args["summary"],
62
- args: args["args"] || {}, source: args["source"],
63
- dry_run: args["dry_run"] == true, role: args["role"], actor_id: args["actor_id"])
64
- end
65
-
66
- # Several commands in one call.
67
- def dispatch_steps(runtime, args)
68
- McpDoor.scope.admit_steps!(runtime, args["steps"])
69
- Storehouse.dispatch_batch(runtime: runtime, steps: args["steps"], summary: args["summary"],
70
- source: args["source"], role: args["role"], actor_id: args["actor_id"])
71
- end
72
-
73
- def events_tool(args)
74
- Storehouse.events(runtime: McpDoor.boot(args["domain"]), aggregate: args["aggregate"], id: args["id"],
75
- limit: args["limit"])
76
- end
77
-
78
- def state_tool(args)
79
- Storehouse.state(runtime: McpDoor.boot(args["domain"]), aggregate: args["aggregate"],
80
- summary: args["summary"], id: args["id"])
81
- end
82
-
83
- def catalog_tool(args)
84
- Storehouse.catalog(runtime: McpDoor.boot(args["domain"]))
85
- end
86
-
87
- def describe_tool(args)
88
- Storehouse.describe(runtime: McpDoor.boot(args["domain"]), aggregate: args["aggregate"])
89
- end
90
-
91
- def validate_tool(args)
92
- Storehouse.validate(domain: McpDoor.scope.admit_domain!(args["domain"]), deep: args["deep"] == true)
93
- end
94
-
95
- def domains_tool(args)
96
- Storehouse.domains(under: args["under"] || "examples")
97
- end
98
-
99
- def history_tool(args)
100
- Storehouse.history(runtime: McpDoor.boot(args["domain"]))
101
- end
102
-
103
- def behaviors_tool(args)
104
- Storehouse.behaviors(target: args["target"])
105
- end
106
-
107
- def follow_tool(args)
108
- Storehouse.follow(runtime: McpDoor.boot(args["domain"]), limit: args["limit"] || 20)
109
- end
110
- end
111
- end
112
- end
113
- end
@@ -1,51 +0,0 @@
1
- require_relative "../properties"
2
-
3
- module Hecks
4
- module Doors
5
- module McpDoor
6
- module ToolDefinitions
7
- # The tools that read what has been recorded: write history, behaviors and the audit log.
8
- module Auditing
9
- include Properties
10
-
11
- LIST = [
12
- {
13
- name: "history",
14
- description: "The full write history for every aggregate in a domain — every operation an append-only " \
15
- "adapter ever recorded, not just current state. An aggregate on a non-append-only adapter " \
16
- "answers an empty history honestly.",
17
- inputSchema: {
18
- type: "object",
19
- properties: { domain: DOMAIN_PROPERTY },
20
- required: %w[domain]
21
- }
22
- },
23
- {
24
- name: "behaviors",
25
- description: "Run a domain's hand-curated `.behaviors` example tests and report pass/fail/error per test. " \
26
- "`target` is a single `.behaviors` file or a directory to sweep.",
27
- inputSchema: {
28
- type: "object",
29
- properties: { target: { type: "string", description: "A .behaviors file, or a directory to sweep." } },
30
- required: %w[target]
31
- }
32
- },
33
- {
34
- name: "follow",
35
- description: "Tail this door's own audit log for a domain — the last `limit` dispatch/query/state/dry-run " \
36
- "calls made through it, each carrying its summary, source, and outcome.",
37
- inputSchema: {
38
- type: "object",
39
- properties: {
40
- domain: DOMAIN_PROPERTY,
41
- limit: { type: "integer", description: "How many recent entries to return. Defaults to 20." }
42
- },
43
- required: %w[domain]
44
- }
45
- }
46
- ].freeze
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,69 +0,0 @@
1
- require_relative "../properties"
2
-
3
- module Hecks
4
- module Doors
5
- module McpDoor
6
- module ToolDefinitions
7
- # The tools that issue a command or ask a question.
8
- module Calling
9
- include Properties
10
-
11
- LIST = [
12
- {
13
- name: "dispatch",
14
- description: "Issue a command against a booted domain — or, with `steps`, several in one call. `command` is " \
15
- "the short or qualified verb name (the catalog/describe tools show what's available). Set " \
16
- "`dry_run: true` to check whether it WOULD succeed without committing anything. Answers the " \
17
- "record's id, its resulting state, and the events it announced — or a structured refusal, " \
18
- "never a crash.",
19
- inputSchema: {
20
- type: "object",
21
- properties: {
22
- domain: DOMAIN_PROPERTY,
23
- command: { type: "string", description: "The command's short or qualified name, e.g. \"open_account\". " \
24
- "Ignored when `steps` is given." },
25
- args: ARGS_PROPERTY,
26
- summary: SUMMARY_PROPERTY,
27
- source: SOURCE_PROPERTY,
28
- role: ROLE_PROPERTY,
29
- actor_id: ACTOR_ID_PROPERTY,
30
- dry_run: { type: "boolean", description: "Preview only — check the command would succeed, commit nothing. " \
31
- "Ignored when `steps` is given." },
32
- steps: {
33
- type: "array",
34
- description: "Run several commands in one call, in order. Each item: {command, args}. When given, " \
35
- "`command`/`args`/`dry_run` above are ignored.",
36
- items: {
37
- type: "object",
38
- properties: { command: { type: "string" }, args: ARGS_PROPERTY },
39
- required: %w[command]
40
- }
41
- }
42
- },
43
- required: %w[domain summary]
44
- }
45
- },
46
- {
47
- name: "query",
48
- description: "Ask a declared question of a booted domain. `question` is the short or qualified query name. " \
49
- "Answers the row array the query itself declares.",
50
- inputSchema: {
51
- type: "object",
52
- properties: {
53
- domain: DOMAIN_PROPERTY,
54
- question: { type: "string", description: "The query's short or qualified name." },
55
- args: ARGS_PROPERTY,
56
- summary: SUMMARY_PROPERTY,
57
- source: SOURCE_PROPERTY,
58
- role: ROLE_PROPERTY,
59
- actor_id: ACTOR_ID_PROPERTY
60
- },
61
- required: %w[domain question summary]
62
- }
63
- }
64
- ].freeze
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,97 +0,0 @@
1
- require_relative "../properties"
2
-
3
- module Hecks
4
- module Doors
5
- module McpDoor
6
- module ToolDefinitions
7
- # The tools that read a domain: its events, state, shape and wiring.
8
- module Reading
9
- include Properties
10
-
11
- LIST = [
12
- {
13
- name: "events",
14
- description: "What actually HAPPENED, with payloads, to one aggregate/record — events THIS DOOR witnessed " \
15
- "(every real dispatch ever routed through it, sourced from its own audit log — not a full " \
16
- "domain-wide event-sourcing replay). Distinct from `state` (what's stored now) and `history` " \
17
- "(append-only operation snapshots, no payload). Narrow with `aggregate` and (requires " \
18
- "`aggregate`) `id`; `limit` keeps only the most recent.",
19
- inputSchema: {
20
- type: "object",
21
- properties: {
22
- domain: DOMAIN_PROPERTY,
23
- aggregate: { type: "string", description: "Narrow to one aggregate, e.g. \"Account\"." },
24
- id: { type: "string", description: "Narrow to one record's own events. Requires `aggregate`." },
25
- limit: { type: "integer", description: "Keep only the most recent N events. Omit for all of them." }
26
- },
27
- required: %w[domain]
28
- }
29
- },
30
- {
31
- name: "state",
32
- description: "Read what an aggregate actually has stored, no verb involved. Pass `id` for one record; " \
33
- "omit it to list every record the aggregate currently holds.",
34
- inputSchema: {
35
- type: "object",
36
- properties: {
37
- domain: DOMAIN_PROPERTY,
38
- aggregate: { type: "string", description: "The aggregate's name, e.g. \"Account\"." },
39
- id: { type: "string", description: "A specific record's id. Omit to list every record." },
40
- summary: SUMMARY_PROPERTY
41
- },
42
- required: %w[domain aggregate summary]
43
- }
44
- },
45
- {
46
- name: "catalog",
47
- description: "Zoom level one: every aggregate a domain declares, and every command/query name each " \
48
- "answers to. No summary needed — this changes nothing and commits nothing to any log.",
49
- inputSchema: {
50
- type: "object",
51
- properties: { domain: DOMAIN_PROPERTY },
52
- required: %w[domain]
53
- }
54
- },
55
- {
56
- name: "describe",
57
- description: "Zoom level two: one aggregate's full contract — every command's arguments, the states it " \
58
- "may be issued from, and every way it can refuse. Omit `aggregate` for the whole domain.",
59
- inputSchema: {
60
- type: "object",
61
- properties: {
62
- domain: DOMAIN_PROPERTY,
63
- aggregate: { type: "string", description: "Narrow to one aggregate. Omit for the whole domain." }
64
- },
65
- required: %w[domain]
66
- }
67
- },
68
- {
69
- name: "validate",
70
- description: "Zoom level three: is this domain's wiring sound — every bind names a declared aggregate, " \
71
- "every adapter satisfies its port, the default adapter is usable. {valid:false, error:…} " \
72
- "on a real wiring defect, never a bare crash. Set `deep: true` to also model-check the IR " \
73
- "for dead lifecycle transitions, unreachable saga states, and dispatches to nowhere.",
74
- inputSchema: {
75
- type: "object",
76
- properties: {
77
- domain: DOMAIN_PROPERTY,
78
- deep: { type: "boolean", description: "Also run the static model checker (lifecycle/saga/policy IR)." }
79
- },
80
- required: %w[domain]
81
- }
82
- },
83
- {
84
- name: "domains",
85
- description: "Zoom level zero: every domain directory found under a root (default \"examples\"), so a " \
86
- "caller who doesn't already know a path can find one.",
87
- inputSchema: {
88
- type: "object",
89
- properties: { under: { type: "string", description: "Root directory to scan. Defaults to \"examples\"." } }
90
- }
91
- }
92
- ].freeze
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,15 +0,0 @@
1
- require_relative "tool_definitions/calling"
2
- require_relative "tool_definitions/reading"
3
- require_relative "tool_definitions/auditing"
4
-
5
- module Hecks
6
- module Doors
7
- module McpDoor
8
- # The tools the MCP door answers: their names, descriptions and input schemas, in the order
9
- # `tools/list` shows them.
10
- module ToolDefinitions
11
- TOOLS = (Calling::LIST + Reading::LIST + Auditing::LIST).freeze
12
- end
13
- end
14
- end
15
- end