hecks 3.13.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. checksums.yaml +4 -4
  2. data/examples/pizzas/adapters/fake_processor.rb +34 -0
  3. data/examples/pizzas/adapters/payment_signature.rb +66 -0
  4. data/examples/pizzas/adapters/payment_webhook.rb +87 -0
  5. data/examples/pizzas/bluebook/pizzas.behaviors +33 -0
  6. data/examples/pizzas/bluebook/pizzas.bluebook +4 -4
  7. data/examples/pizzas/bluebook/pizzas.hecksagon +5 -3
  8. data/examples/pizzas/config.ru +22 -0
  9. data/lib/hecks/adapters/driven/prism.rb +0 -2
  10. data/lib/hecks/adapters/driven.rb +0 -2
  11. data/lib/hecks/adapters/driving/json.rb +1 -7
  12. data/lib/hecks/bluebook/dsl/attribute_collector.rb +15 -5
  13. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -2
  14. data/lib/hecks/bluebook/dsl/derivation_words.rb +58 -0
  15. data/lib/hecks/bluebook/dsl/translation_builder.rb +6 -37
  16. data/lib/hecks/bluebook/expression/ast_json.rb +0 -9
  17. data/lib/hecks/bluebook/hecksagon.rb +1 -1
  18. data/lib/hecks/bluebook/meta_validator/translation_judge/rules.rb +7 -10
  19. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +4 -8
  20. data/lib/hecks/bluebook/meta_validator.rb +0 -11
  21. data/lib/hecks/bluebook/named_pattern.rb +33 -0
  22. data/lib/hecks/bluebook/translation.rb +18 -10
  23. data/lib/hecks/bluebook/translation_expression/evaluator.rb +63 -0
  24. data/lib/hecks/bluebook/translation_expression/parser.rb +127 -0
  25. data/lib/hecks/bluebook/translation_expression.rb +39 -0
  26. data/lib/hecks/bluebook/translation_plan.rb +70 -0
  27. data/lib/hecks/bluebook.rb +3 -0
  28. data/lib/hecks/chapters.rb +3 -3
  29. data/lib/hecks/cli/domain_stub.rb +1 -1
  30. data/lib/hecks/cli/interview_aggregate.rb +4 -4
  31. data/lib/hecks/composer/adapters/claude_composer.adapter +3 -0
  32. data/lib/hecks/composer/adapters/claude_composer.rb +83 -0
  33. data/lib/hecks/composer/adapters/fake_agent.adapter +3 -0
  34. data/lib/hecks/composer/adapters/fake_agent.rb +55 -0
  35. data/lib/hecks/composer/adapters/jev.adapter +3 -0
  36. data/lib/hecks/composer/adapters/jev.rb +66 -0
  37. data/lib/hecks/composer/agent.rb +113 -0
  38. data/lib/hecks/composer/assistant.rb +110 -0
  39. data/lib/hecks/composer/behavior_run.rb +53 -0
  40. data/lib/hecks/composer/bluebook/composer.bluebook +178 -0
  41. data/lib/hecks/composer/bluebook/composer.hecksagon +16 -0
  42. data/lib/hecks/composer/board.rb +65 -0
  43. data/lib/hecks/composer/board_edit/command_text.rb +39 -0
  44. data/lib/hecks/composer/board_edit/source.rb +84 -0
  45. data/lib/hecks/composer/board_edit.rb +144 -0
  46. data/lib/hecks/composer/check.rb +89 -0
  47. data/lib/hecks/composer/domains.rb +81 -0
  48. data/lib/hecks/composer/jobs.rb +134 -0
  49. data/lib/hecks/composer/layout.rb +37 -0
  50. data/lib/hecks/composer/live.rb +150 -0
  51. data/lib/hecks/composer/outline.rb +48 -0
  52. data/lib/hecks/composer/page.html +989 -0
  53. data/lib/hecks/composer/panels.rb +142 -0
  54. data/lib/hecks/composer/parse.rb +83 -0
  55. data/lib/hecks/composer/plain.rb +28 -0
  56. data/lib/hecks/composer/ports/composer_agent.port +7 -0
  57. data/lib/hecks/composer/session.rb +141 -0
  58. data/lib/hecks/composer/toolbox.rb +166 -0
  59. data/lib/hecks/composer/web.rb +156 -0
  60. data/lib/hecks/composer/workbench.rb +51 -0
  61. data/lib/hecks/composer/workspace.rb +81 -0
  62. data/lib/hecks/composer.rb +17 -0
  63. data/lib/hecks/corpus/adapters.rb +22 -0
  64. data/lib/hecks/corpus/rust.rb +1 -1
  65. data/lib/hecks/corpus/worlds.rb +19 -0
  66. data/lib/hecks/corpus.rb +5 -0
  67. data/lib/hecks/deploy/bluebook/deploy.bluebook +34 -34
  68. data/lib/hecks/forms/app/commands.rb +2 -3
  69. data/lib/hecks/forms/app/queries.rb +2 -3
  70. data/lib/hecks/forms/app/records.rb +17 -5
  71. data/lib/hecks/forms/command_form_renderer.rb +42 -16
  72. data/lib/hecks/forms/field_controls.rb +2 -2
  73. data/lib/hecks/forms/field_renderer.rb +1 -1
  74. data/lib/hecks/forms/field_shape.rb +36 -17
  75. data/lib/hecks/forms/index_renderer.rb +2 -1
  76. data/lib/hecks/forms/page.rb +1 -1
  77. data/lib/hecks/forms/params.rb +0 -13
  78. data/lib/hecks/forms/query_form_renderer.rb +7 -6
  79. data/lib/hecks/forms/record_renderer.rb +11 -7
  80. data/lib/hecks/forms/rule_words.rb +100 -0
  81. data/lib/hecks/forms/value_object_shape.rb +2 -1
  82. data/lib/hecks/framework/bluebook/change.bluebook +2 -2
  83. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -3
  84. data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +1 -1
  85. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +3 -6
  86. data/lib/hecks/fuzzing/replay/filters.rb +2 -6
  87. data/lib/hecks/gate/stages.yml +25 -0
  88. data/lib/hecks/grammar/evolve/seeds.rb +0 -6
  89. data/lib/hecks/grammar/evolve.rb +0 -3
  90. data/lib/hecks/grammar/translation.bluebook +1 -1
  91. data/lib/hecks/hecks/adapters/codebase/composing.rb +56 -0
  92. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +3 -1
  93. data/lib/hecks/hecks/adapters/journal_store/changes.rb +0 -26
  94. data/lib/hecks/hecks/adapters/journal_store/examination.rb +2 -23
  95. data/lib/hecks/hecks/adapters/journal_store/readings.rb +3 -11
  96. data/lib/hecks/hecks/adapters/journal_store.rb +0 -11
  97. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +4 -11
  98. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +0 -9
  99. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +0 -4
  100. data/lib/hecks/hecks/codebase.behaviors +6 -0
  101. data/lib/hecks/hecks/codebase.bluebook +58 -37
  102. data/lib/hecks/hecks/composer.behaviors +68 -0
  103. data/lib/hecks/hecks/context_map.hecksagon +1 -1
  104. data/lib/hecks/hecks/custodian.behaviors +0 -6
  105. data/lib/hecks/hecks/custodian.bluebook +15 -92
  106. data/lib/hecks/hecks/hecks.bluebook +2 -2
  107. data/lib/hecks/hecks/hecks.hecksagon +2 -2
  108. data/lib/hecks/hecks/hecks.world +1 -1
  109. data/lib/hecks/hecks/rehearsal.bluebook +10 -16
  110. data/lib/hecks/hecks/tooling.bluebook +22 -22
  111. data/lib/hecks/kernel_capabilities/templates.rb +4 -4
  112. data/lib/hecks/kernel_capabilities.rb +1 -1
  113. data/lib/hecks/language/bluebook/aggregate.bluebook +1 -0
  114. data/lib/hecks/language/bluebook/command.bluebook +1 -0
  115. data/lib/hecks/language/bluebook/entity.bluebook +1 -0
  116. data/lib/hecks/language/bluebook/query.bluebook +1 -0
  117. data/lib/hecks/language/bluebook/shape.bluebook +8 -7
  118. data/lib/hecks/language/bluebook/vocabulary.bluebook +2 -3
  119. data/lib/hecks/language/hecksagon/port_operation.bluebook +1 -0
  120. data/lib/hecks/language/translation/translation_aggregate.bluebook +21 -24
  121. data/lib/hecks/ports/access_control.rb +2 -2
  122. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +3 -41
  123. data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +7 -7
  124. data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +25 -2
  125. data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +4 -4
  126. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +17 -25
  127. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +0 -12
  128. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +1 -1
  129. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +2 -22
  130. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +0 -1
  131. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +9 -3
  132. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +3 -29
  133. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +2 -26
  134. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +6 -33
  135. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -3
  136. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +2 -4
  137. data/lib/hecks/ports/persistence/plugins/era/translation/expression_sql.rb +52 -0
  138. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +23 -29
  139. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +1 -1
  140. data/lib/hecks/ports/persistence/plugins/era/translation.rb +0 -1
  141. data/lib/hecks/ports/persistence/plugins/era.rb +3 -6
  142. data/lib/hecks/ports.rb +0 -1
  143. data/lib/hecks/projection_files.rb +3 -1
  144. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +1 -1
  145. data/lib/hecks/projections/glossary/entries.rb +10 -4
  146. data/lib/hecks/projections/glossary/groups.rb +42 -0
  147. data/lib/hecks/projections/glossary/html/page.rb +7 -2
  148. data/lib/hecks/projections/glossary/html/parser.rb +1 -1
  149. data/lib/hecks/projections/glossary/html/sections.rb +31 -11
  150. data/lib/hecks/projections/glossary/html.rb +1 -2
  151. data/lib/hecks/projections/glossary/markdown.rb +31 -28
  152. data/lib/hecks/projections/glossary/mermaid.rb +3 -0
  153. data/lib/hecks/projections/glossary/page.css +143 -153
  154. data/lib/hecks/projections/glossary/page.js +63 -3
  155. data/lib/hecks/projections/glossary/sentences/actions.rb +88 -0
  156. data/lib/hecks/projections/glossary/sentences/paths.rb +77 -0
  157. data/lib/hecks/projections/glossary/sentences/queries.rb +90 -0
  158. data/lib/hecks/projections/glossary/sentences/value_objects.rb +32 -5
  159. data/lib/hecks/projections/glossary/sentences.rb +13 -3
  160. data/lib/hecks/projections/glossary/slugs.rb +4 -1
  161. data/lib/hecks/projections/glossary.rb +2 -1
  162. data/lib/hecks/projections/plain_english.rb +97 -0
  163. data/lib/hecks/projections/rust_vocabulary/arguments.rb +2 -2
  164. data/lib/hecks/projections/rust_vocabulary/enum_body.rb +20 -25
  165. data/lib/hecks/projections/rust_vocabulary/tests.rb +2 -2
  166. data/lib/hecks/projections/rust_vocabulary.rb +14 -6
  167. data/lib/hecks/projections/site/cms_editor/color.rb +0 -6
  168. data/lib/hecks/projections/statements/actions.rb +99 -0
  169. data/lib/hecks/projections/statements/relationships.rb +86 -0
  170. data/lib/hecks/projections/statements.rb +15 -24
  171. data/lib/hecks/projector/exporter/adapters.rb +112 -0
  172. data/lib/hecks/projector/exporter/translations.rb +18 -35
  173. data/lib/hecks/projector/exporter/worlds.rb +103 -0
  174. data/lib/hecks/projector/exporter.rb +5 -1
  175. data/lib/hecks/quality_control/adapters/agent.rb +6 -7
  176. data/lib/hecks/quality_control/adapters/agent_profile.rb +16 -114
  177. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +1 -1
  178. data/lib/hecks/quality_control/quality_control.bluebook +51 -51
  179. data/lib/hecks/runtime/loader/boot_steps.rb +0 -20
  180. data/lib/hecks/runtime/outbox.rb +2 -9
  181. data/lib/hecks/runtime/port_operation_interpreter.rb +1 -9
  182. data/lib/hecks/runtime/remote_dispatcher.rb +2 -2
  183. data/lib/hecks/runtime/value.rb +13 -0
  184. data/lib/hecks/rust_build/project_rust/target_ir.rb +23 -4
  185. data/lib/hecks/rust_build/wasm.rb +0 -12
  186. data/lib/hecks/rust_build/write_if_changed.rb +12 -12
  187. data/lib/hecks/rust_format.rb +77 -0
  188. data/lib/hecks/site/bluebook/site.bluebook +5 -5
  189. data/lib/hecks/sme/bluebook/sme.bluebook +12 -12
  190. data/lib/hecks/tickets/bluebook/tickets.bluebook +3 -3
  191. data/lib/hecks/tools/fuzz_sweep/findings.rb +3 -9
  192. data/lib/hecks/tools/fuzz_sweep.rb +1 -3
  193. data/lib/hecks/tools/translation_audit/verdicts.rb +3 -28
  194. data/lib/hecks/tools/translation_audit.rb +8 -10
  195. data/lib/hecks/tools/translation_scaffold/reporting.rb +1 -1
  196. data/lib/hecks/version.rb +1 -1
  197. data/lib/hecks/vocabulary.rb +2 -1
  198. data/lib/hecks.rb +3 -0
  199. data/prebuilt/{58208399bada10b0db99928c48e38789288fc58f7b71a72b21bfa386680e32ed.marshal → 02c09c73b272c1fb5a9ae6d87bb5e5e529208e00f6b4b597dc2c0fd70a9c0964.marshal} +0 -0
  200. data/prebuilt/{2b59737fbdbd5f44edda0fddce2611f45d76087b3a7c782d1f1a17ea58c77948.marshal → bb84a835cf6a15136bad5ca03aa5bf93a5b92f5f72444618d3ef2412b987fb32.marshal} +0 -0
  201. data/prebuilt/verdicts-f1f10da14c8e8f01b4c9b7e3e2d74be8cd2bf4676364ed17fa16975d2a076d75.json +1 -0
  202. data/rust/Cargo.toml +40 -0
  203. data/rust/build/Cargo.toml +36 -0
  204. data/rust/build/clippy.toml +4 -0
  205. data/rust/build/src/adapters_pass.rs +196 -0
  206. data/rust/build/src/binding_pass.rs +54 -13
  207. data/rust/build/src/build_artifact.rs +23 -5
  208. data/rust/build/src/cargo_sync.rs +69 -26
  209. data/rust/build/src/lineage_pass.rs +101 -87
  210. data/rust/build/src/main.rs +11 -2
  211. data/rust/build/src/pipeline.rs +80 -19
  212. data/rust/build/src/reserved_names.rs +6 -50
  213. data/rust/build/src/resolve.rs +82 -35
  214. data/rust/build/src/rustfmt.rs +100 -0
  215. data/rust/build/src/seams_pass.rs +85 -16
  216. data/rust/build/src/subprocess.rs +30 -6
  217. data/rust/build/src/tmp.rs +5 -2
  218. data/rust/build/src/translation_pass.rs +72 -22
  219. data/rust/build/src/world_pass.rs +109 -0
  220. data/rust/clippy.toml +4 -0
  221. data/rust/codegen/Cargo.toml +36 -0
  222. data/rust/codegen/clippy.toml +4 -0
  223. data/rust/codegen/src/asks.rs +40 -14
  224. data/rust/codegen/src/attr.rs +2 -2
  225. data/rust/codegen/src/bridging.rs +676 -117
  226. data/rust/codegen/src/commands.rs +979 -373
  227. data/rust/codegen/src/constraints.rs +88 -25
  228. data/rust/codegen/src/dependency_planning.rs +128 -34
  229. data/rust/codegen/src/domain_generator.rs +300 -170
  230. data/rust/codegen/src/exemplar.rs +87 -32
  231. data/rust/codegen/src/expr_emitter.rs +54 -6
  232. data/rust/codegen/src/fielded.rs +193 -41
  233. data/rust/codegen/src/hecks_naming.rs +124 -16
  234. data/rust/codegen/src/hecks_naming_tests.rs +81 -0
  235. data/rust/codegen/src/json.rs +80 -44
  236. data/rust/codegen/src/json_codec.rs +585 -149
  237. data/rust/codegen/src/literal.rs +104 -138
  238. data/rust/codegen/src/main.rs +145 -52
  239. data/rust/codegen/src/manifest.rs +76 -14
  240. data/rust/codegen/src/mutations.rs +1212 -239
  241. data/rust/codegen/src/naming.rs +111 -60
  242. data/rust/codegen/src/optional_pass.rs +90 -28
  243. data/rust/codegen/src/ports.rs +5 -4
  244. data/rust/codegen/src/prelude.rs +139 -49
  245. data/rust/codegen/src/queries.rs +601 -226
  246. data/rust/codegen/src/reactions.rs +268 -74
  247. data/rust/codegen/src/read_models.rs +606 -205
  248. data/rust/codegen/src/reference_specs.rs +16 -3
  249. data/rust/codegen/src/registry.rs +128 -79
  250. data/rust/codegen/src/reserved_names.rs +6 -50
  251. data/rust/codegen/src/shared.rs +71 -22
  252. data/rust/codegen/src/sidecars.rs +15 -5
  253. data/rust/codegen/src/skip_reason.rs +8 -2
  254. data/rust/codegen/src/types.rs +306 -108
  255. data/rust/host/Cargo.lock +1 -0
  256. data/rust/host/Cargo.toml +40 -4
  257. data/rust/host/HECKS_RELEASE +1 -1
  258. data/rust/host/clippy.toml +4 -0
  259. data/rust/host/src/api.rs +698 -218
  260. data/rust/host/src/auth.rs +491 -214
  261. data/rust/host/src/b64.rs +91 -0
  262. data/rust/host/src/bin/expr_harness.rs +6 -2
  263. data/rust/host/src/bin/lineage_harness.rs +47 -11
  264. data/rust/host/src/bin/mint_harness.rs +70 -37
  265. data/rust/host/src/bin/validate_harness.rs +16 -8
  266. data/rust/host/src/boot.rs +144 -68
  267. data/rust/host/src/boundary_fuzz/api.rs +130 -32
  268. data/rust/host/src/boundary_fuzz/auth.rs +108 -23
  269. data/rust/host/src/boundary_fuzz/expr_json.rs +85 -11
  270. data/rust/host/src/boundary_fuzz/ir.rs +164 -12
  271. data/rust/host/src/boundary_fuzz/server.rs +283 -36
  272. data/rust/host/src/boundary_fuzz/web.rs +56 -8
  273. data/rust/host/src/checkout.rs +78 -32
  274. data/rust/host/src/clock.rs +8 -0
  275. data/rust/host/src/commerce_ir.rs +333 -95
  276. data/rust/host/src/crypto.rs +33 -0
  277. data/rust/host/src/dispatch.rs +990 -331
  278. data/rust/host/src/expr_json.rs +1021 -273
  279. data/rust/host/src/extension.rs +24 -4
  280. data/rust/host/src/field_hints.rs +11 -7
  281. data/rust/host/src/fuzz_support.rs +85 -13
  282. data/rust/host/src/host.rs +100 -0
  283. data/rust/host/src/http.rs +22 -0
  284. data/rust/host/src/ir.rs +326 -16
  285. data/rust/host/src/journal.rs +277 -176
  286. data/rust/host/src/lambda_client.rs +219 -53
  287. data/rust/host/src/lib.rs +16 -4
  288. data/rust/host/src/log.rs +62 -11
  289. data/rust/host/src/mint.rs +1153 -326
  290. data/rust/host/src/needs.rs +185 -44
  291. data/rust/host/src/payments/keystore.rs +197 -45
  292. data/rust/host/src/payments/roles.rs +191 -0
  293. data/rust/host/src/payments/tests.rs +1445 -275
  294. data/rust/host/src/payments.rs +409 -121
  295. data/rust/host/src/platform_signin/attack_tests.rs +5 -5
  296. data/rust/host/src/platform_signin/config.rs +11 -11
  297. data/rust/host/src/platform_signin/cookie.rs +2 -2
  298. data/rust/host/src/platform_signin/extension.rs +2 -1
  299. data/rust/host/src/platform_signin/handler.rs +9 -8
  300. data/rust/host/src/platform_signin/jti.rs +4 -2
  301. data/rust/host/src/platform_signin/jwks.rs +2 -1
  302. data/rust/host/src/platform_signin/jws.rs +2 -37
  303. data/rust/host/src/platform_signin/known_answer_tests.rs +5 -1
  304. data/rust/host/src/platform_signin/mode_tests.rs +5 -3
  305. data/rust/host/src/platform_signin/pages.rs +20 -20
  306. data/rust/host/src/platform_signin/session.rs +8 -1
  307. data/rust/host/src/platform_signin/settings.rs +6 -6
  308. data/rust/host/src/platform_signin/strict_json.rs +12 -9
  309. data/rust/host/src/platform_signin/verify.rs +41 -41
  310. data/rust/host/src/platform_signin/wiring_support.rs +13 -18
  311. data/rust/host/src/presentation.rs +207 -63
  312. data/rust/host/src/presentation_write.rs +502 -187
  313. data/rust/host/src/query_step.rs +69 -18
  314. data/rust/host/src/rate_limit.rs +541 -142
  315. data/rust/host/src/reference_transform.rs +77 -25
  316. data/rust/host/src/reference_validate.rs +443 -104
  317. data/rust/host/src/resend.rs +190 -55
  318. data/rust/host/src/secrets.rs +116 -21
  319. data/rust/host/src/server.rs +483 -104
  320. data/rust/host/src/storage_shape.rs +88 -21
  321. data/rust/host/src/test_pg.rs +17 -7
  322. data/rust/host/src/ui_schema.rs +495 -207
  323. data/rust/host/src/wasm_runner.rs +21 -6
  324. data/rust/host/src/web/commerce.rs +101 -23
  325. data/rust/host/src/web/newsletter/cooldown.rs +10 -3
  326. data/rust/host/src/web/newsletter/template.rs +26 -7
  327. data/rust/host/src/web/newsletter/tests.rs +112 -23
  328. data/rust/host/src/web/newsletter.rs +209 -59
  329. data/rust/host/src/web/newsletter_send.rs +251 -79
  330. data/rust/host/src/web/registration_receipt/tests.rs +16 -4
  331. data/rust/host/src/web/registration_receipt.rs +100 -24
  332. data/rust/host/src/web/registrations.rs +1384 -332
  333. data/rust/host/src/web/resend_webhook.rs +138 -80
  334. data/rust/host/src/web.rs +2416 -508
  335. data/rust/lsp/Cargo.toml +36 -0
  336. data/rust/lsp/clippy.toml +4 -0
  337. data/rust/lsp/src/json.rs +29 -22
  338. data/rust/lsp/src/main.rs +81 -31
  339. data/rust/lsp/src/outline.rs +23 -7
  340. data/rust/lsp/src/rpc.rs +17 -4
  341. data/rust/parser/Cargo.toml +36 -0
  342. data/rust/parser/clippy.toml +4 -0
  343. data/rust/parser/src/build/closed_sets.rs +6 -1
  344. data/rust/parser/src/build/identity.rs +4 -3
  345. data/rust/parser/src/build/mod.rs +1 -0
  346. data/rust/parser/src/build/named_pattern.rs +26 -0
  347. data/rust/parser/src/build/naming.rs +2 -80
  348. data/rust/parser/src/build/pattern_subset.rs +6 -8
  349. data/rust/parser/src/build/query_derive.rs +3 -1
  350. data/rust/parser/src/build/query_inference.rs +14 -5
  351. data/rust/parser/src/build/read_model.rs +4 -1
  352. data/rust/parser/src/build/references.rs +4 -3
  353. data/rust/parser/src/canonical.rs +34 -15
  354. data/rust/parser/src/emit.rs +187 -105
  355. data/rust/parser/src/expr/ast_json.rs +134 -42
  356. data/rust/parser/src/expr/evaluator.rs +27 -9
  357. data/rust/parser/src/expr/mod.rs +54 -13
  358. data/rust/parser/src/expr/resolver.rs +299 -92
  359. data/rust/parser/src/ir.rs +35 -3
  360. data/rust/parser/src/keywords.rs +7168 -510
  361. data/rust/parser/src/lex.rs +11 -25
  362. data/rust/parser/src/lib.rs +1 -0
  363. data/rust/parser/src/main.rs +65 -6
  364. data/rust/parser/src/parse/adapter.rs +157 -0
  365. data/rust/parser/src/parse/aggregate.rs +19 -10
  366. data/rust/parser/src/parse/chapter.rs +16 -17
  367. data/rust/parser/src/parse/command.rs +35 -16
  368. data/rust/parser/src/parse/domain_port.rs +4 -7
  369. data/rust/parser/src/parse/entity.rs +21 -11
  370. data/rust/parser/src/parse/hecksagon.rs +10 -4
  371. data/rust/parser/src/parse/lifecycle.rs +9 -5
  372. data/rust/parser/src/parse/mod.rs +43 -91
  373. data/rust/parser/src/parse/needs.rs +21 -12
  374. data/rust/parser/src/parse/policy.rs +2 -2
  375. data/rust/parser/src/parse/process_manager.rs +9 -11
  376. data/rust/parser/src/parse/query.rs +8 -4
  377. data/rust/parser/src/parse/read_model.rs +57 -16
  378. data/rust/parser/src/parse/value_object.rs +7 -2
  379. data/rust/parser/src/parse/world.rs +322 -0
  380. data/rust/parser/src/ruby_value.rs +7 -6
  381. data/rust/src/exemplar/json.rs +4 -4
  382. data/rust/src/exemplar/mutations.rs +18 -0
  383. data/rust/src/exemplar/read_models.rs +1 -10
  384. data/rust/src/kernel/attribute_shapes/composite.rs +54 -14
  385. data/rust/src/kernel/attribute_shapes/list.rs +2 -2
  386. data/rust/src/kernel/attribute_shapes/mod.rs +8 -8
  387. data/rust/src/kernel/attribute_shapes/scalar.rs +2 -2
  388. data/rust/src/kernel/cli.rs +229 -112
  389. data/rust/src/kernel/dispatch.rs +323 -115
  390. data/rust/src/kernel/dispatch_guard_tests.rs +327 -65
  391. data/rust/src/kernel/expr.rs +203 -86
  392. data/rust/src/kernel/expression_operators/arithmetic.rs +138 -25
  393. data/rust/src/kernel/expression_operators/comparison.rs +87 -2
  394. data/rust/src/kernel/expression_operators/enumeration.rs +106 -22
  395. data/rust/src/kernel/expression_operators/logical.rs +9 -3
  396. data/rust/src/kernel/expression_operators/membership.rs +3 -1
  397. data/rust/src/kernel/expression_operators/mod.rs +34 -21
  398. data/rust/src/kernel/expression_operators/pattern_match.rs +46 -11
  399. data/rust/src/kernel/expression_operators/positional.rs +84 -30
  400. data/rust/src/kernel/expression_operators/presence.rs +52 -13
  401. data/rust/src/kernel/expression_operators/sign_test.rs +3 -1
  402. data/rust/src/kernel/expression_operators/sized.rs +24 -8
  403. data/rust/src/kernel/expression_operators/text.rs +120 -27
  404. data/rust/src/kernel/expression_operators/to_string.rs +10 -4
  405. data/rust/src/kernel/json.rs +230 -148
  406. data/rust/src/kernel/mod.rs +46 -33
  407. data/rust/src/kernel/named_query.rs +63 -15
  408. data/rust/src/kernel/needs.rs +112 -25
  409. data/rust/src/kernel/orchestrate.rs +980 -581
  410. data/rust/src/kernel/orchestrate_guard_tests.rs +538 -140
  411. data/rust/src/kernel/pattern.rs +107 -34
  412. data/rust/src/kernel/query_comparators.rs +118 -41
  413. data/rust/src/kernel/query_ordering.rs +13 -5
  414. data/rust/src/kernel/read_model.rs +479 -181
  415. data/rust/src/kernel/reference_lookup.rs +122 -26
  416. data/rust/src/kernel/repository.rs +293 -66
  417. data/rust/src/kernel/routing.rs +58 -42
  418. data/rust/src/kernel/ruby_float.rs +139 -0
  419. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +57 -57
  420. data/rust/src/kernel/vocab/entity_dispatch_order.rs +54 -54
  421. data/rust/src/kernel/vocab/field_hint.rs +19 -25
  422. data/rust/src/kernel/vocab/mod.rs +6 -6
  423. data/rust/src/kernel/vocab/query_comparator.rs +23 -24
  424. data/rust/src/kernel/vocab/refusal_template.rs +501 -297
  425. data/rust/src/lib.rs +50 -0
  426. data/rust/src/main.rs +4 -1
  427. data/rust/web/Cargo.toml +36 -0
  428. data/rust/web/clippy.toml +4 -0
  429. metadata +85 -15
  430. data/examples/pizzas/bluebook/hecksagon/mock_stripe_payment_adapter.rb +0 -36
  431. data/lib/hecks/adapters/driven/google_authentication.adapter +0 -3
  432. data/lib/hecks/adapters/driven/google_authentication.rb +0 -99
  433. data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +0 -3
  434. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +0 -32
  435. data/lib/hecks/ports/authentication.port +0 -6
  436. data/lib/hecks/ports/authentication.rb +0 -67
  437. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +0 -255
  438. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +0 -22
  439. data/prebuilt/verdicts-48318ca172edd21443b1ad02801c697fff100b746e828f09db987647641a5df2.json +0 -1
  440. data/rust/host/src/approval.rs +0 -652
@@ -29,6 +29,15 @@ pub struct Ctx<'a> {
29
29
  pub wasm_path: &'a Path,
30
30
  pub config: &'a LineageConfig,
31
31
  pub invoker: &'a dyn LambdaInvoker,
32
+ /// The four above as one value, for the host's own handlers.
33
+ pub host: crate::host::Host<'a>,
34
+ }
35
+
36
+ impl<'a> Ctx<'a> {
37
+ /// The request's journal connection, module, lineage and invoker, as one value.
38
+ pub const fn host(&self) -> crate::host::Host<'a> {
39
+ self.host
40
+ }
32
41
  }
33
42
 
34
43
  /// A public write an extension wants limited per client: `limit_env` names the budget setting.
@@ -83,14 +92,20 @@ pub fn installed() -> &'static [Arc<dyn HostExtension>] {
83
92
  fn default_extensions() -> Vec<Arc<dyn HostExtension>> {
84
93
  let vars = crate::platform_signin::settings::PROCESS_VARIABLES
85
94
  .iter()
86
- .filter_map(|name| std::env::var(name).ok().map(|value| (name.to_string(), value)))
95
+ .filter_map(|name| {
96
+ crate::secrets::var(name)
97
+ .ok()
98
+ .map(|value| (name.to_string(), value))
99
+ })
87
100
  .collect();
88
101
  default_extensions_from(&vars)
89
102
  }
90
103
 
91
104
  /// The default extensions for an explicit set of settings: commerce, plus platform sign-in when
92
105
  /// it is switched on (or its boot refusal when its settings are wrong).
93
- pub(crate) fn default_extensions_from(vars: &HashMap<String, String>) -> Vec<Arc<dyn HostExtension>> {
106
+ pub(crate) fn default_extensions_from(
107
+ vars: &HashMap<String, String>,
108
+ ) -> Vec<Arc<dyn HostExtension>> {
94
109
  let mut extensions: Vec<Arc<dyn HostExtension>> = vec![Arc::new(crate::web::Commerce)];
95
110
  extensions.extend(crate::platform_signin::extension::extensions_for(vars));
96
111
  extensions
@@ -103,10 +118,15 @@ pub fn loaded_ir() -> Option<&'static Value> {
103
118
 
104
119
  /// Every installed extension's rate rules.
105
120
  pub fn rate_rules() -> Vec<RateRule> {
106
- installed().iter().flat_map(|extension| extension.rate_rules()).collect()
121
+ installed()
122
+ .iter()
123
+ .flat_map(|extension| extension.rate_rules())
124
+ .collect()
107
125
  }
108
126
 
109
127
  /// The rule that limits this request, if any.
110
128
  pub fn rate_rule_for(method: &str, path: &str) -> Option<RateRule> {
111
- rate_rules().into_iter().find(|rule| rule.method == method && rule.path == path)
129
+ rate_rules()
130
+ .into_iter()
131
+ .find(|rule| rule.method == method && rule.path == path)
112
132
  }
@@ -27,8 +27,10 @@ pub static EMAIL_HINT: LazyLock<Regex> =
27
27
  /// `(?i)` up front is this crate's spelling
28
28
  /// of Ruby's trailing `/i` — the WHOLE pattern is case-insensitive
29
29
  /// on both sides, never partially.
30
- pub static URL_HINT: LazyLock<Regex> =
31
- LazyLock::new(|| Regex::new(r#"(?i)\b(url|uri|website|link)\b"#).expect("declared field-hint pattern must compile"));
30
+ pub static URL_HINT: LazyLock<Regex> = LazyLock::new(|| {
31
+ Regex::new(r#"(?i)\b(url|uri|website|link)\b"#)
32
+ .expect("declared field-hint pattern must compile")
33
+ });
32
34
 
33
35
  /// Tel hint, resolving to `html_type` on a match —
34
36
  /// Vocabulary::FieldHint's own declared pattern, unmodified (the
@@ -37,8 +39,9 @@ pub static URL_HINT: LazyLock<Regex> =
37
39
  /// `(?i)` up front is this crate's spelling
38
40
  /// of Ruby's trailing `/i` — the WHOLE pattern is case-insensitive
39
41
  /// on both sides, never partially.
40
- pub static TEL_HINT: LazyLock<Regex> =
41
- LazyLock::new(|| Regex::new(r#"(?i)phone|\btel(ephone)?\b"#).expect("declared field-hint pattern must compile"));
42
+ pub static TEL_HINT: LazyLock<Regex> = LazyLock::new(|| {
43
+ Regex::new(r#"(?i)phone|\btel(ephone)?\b"#).expect("declared field-hint pattern must compile")
44
+ });
42
45
 
43
46
  /// Textarea hint, resolving to `kind` on a match —
44
47
  /// Vocabulary::FieldHint's own declared pattern, unmodified (the
@@ -47,6 +50,7 @@ pub static TEL_HINT: LazyLock<Regex> =
47
50
  /// `(?i)` up front is this crate's spelling
48
51
  /// of Ruby's trailing `/i` — the WHOLE pattern is case-insensitive
49
52
  /// on both sides, never partially.
50
- pub static TEXTAREA_HINT: LazyLock<Regex> =
51
- LazyLock::new(|| Regex::new(r#"(?i)\b(text|body|note|notes|description|message|comment)\b"#).expect("declared field-hint pattern must compile"));
52
-
53
+ pub static TEXTAREA_HINT: LazyLock<Regex> = LazyLock::new(|| {
54
+ Regex::new(r#"(?i)\b(text|body|note|notes|description|message|comment)\b"#)
55
+ .expect("declared field-hint pattern must compile")
56
+ });
@@ -13,7 +13,7 @@ pub(crate) struct Rng(u64);
13
13
 
14
14
  impl Rng {
15
15
  pub(crate) fn new(seed: u64) -> Self {
16
- Rng(seed.wrapping_mul(0x9E37_79B9_7F4A_7C15) | 1)
16
+ Self(seed.wrapping_mul(0x9E37_79B9_7F4A_7C15) | 1)
17
17
  }
18
18
 
19
19
  pub(crate) fn next(&mut self) -> u64 {
@@ -38,7 +38,10 @@ impl Rng {
38
38
 
39
39
  /// How many seeds each fuzz test runs.
40
40
  pub(crate) fn seeds() -> u64 {
41
- std::env::var("HOST_FUZZ_SEEDS").ok().and_then(|v| v.parse().ok()).unwrap_or(200)
41
+ std::env::var("HOST_FUZZ_SEEDS")
42
+ .ok()
43
+ .and_then(|v| v.parse().ok())
44
+ .unwrap_or(200)
42
45
  }
43
46
 
44
47
  /// The most a single guarded case may take before it counts as a hang.
@@ -60,10 +63,18 @@ pub(crate) fn guarded<T: Send + 'static>(label: &str, f: impl FnOnce() -> T + Se
60
63
  handle.join().expect("guarded thread joined");
61
64
  value
62
65
  }
63
- Err(mpsc::RecvTimeoutError::Timeout) => panic!("{label}: no answer within {LIMIT:?} (hang)"),
66
+ Err(mpsc::RecvTimeoutError::Timeout) => {
67
+ panic!("{label}: no answer within {LIMIT:?} (hang)")
68
+ }
64
69
  Err(mpsc::RecvTimeoutError::Disconnected) => {
65
- let panic = handle.join().expect_err("a guarded thread that sent nothing must have panicked");
66
- let message = panic.downcast_ref::<String>().cloned().or_else(|| panic.downcast_ref::<&str>().map(|s| s.to_string()));
70
+ let panic = handle
71
+ .join()
72
+ .expect_err("a guarded thread that sent nothing must have panicked");
73
+ let message = panic.downcast_ref::<String>().cloned().or_else(|| {
74
+ panic
75
+ .downcast_ref::<&str>()
76
+ .map(std::string::ToString::to_string)
77
+ });
67
78
  panic!("{label}: panicked: {}", message.unwrap_or_default())
68
79
  }
69
80
  }
@@ -73,9 +84,63 @@ pub(crate) fn guarded<T: Send + 'static>(label: &str, f: impl FnOnce() -> T + Se
73
84
  /// shape that slices through a char boundary), control characters, NUL, bidi marks, astral
74
85
  /// planes, combining marks, percent signs, and every JSON/URL/cookie delimiter.
75
86
  const PIECES: &[&str] = &[
76
- "a", "Z", "0", "9", " ", "\"", "'", "\\", "/", "%", "%4", "%41", "%zz", "%+1", "+", "=", "&", ";", "?", "#", ".", "..", "-", "_", ":", ",", "{", "}", "[", "]",
77
- "\n", "\t", "\r", "\u{0}", "\u{1f}", "\u{7f}", "é", "ü", "日本", "🍕", "\u{10FFFF}", "\u{200B}", "\u{FEFF}", "\u{202E}", "\u{FFFD}", "e\u{301}", "__", "::",
78
- "<script>", "../", "%0d%0a", "id", "name", "value", "sort", "direction", "desc",
87
+ "a",
88
+ "Z",
89
+ "0",
90
+ "9",
91
+ " ",
92
+ "\"",
93
+ "'",
94
+ "\\",
95
+ "/",
96
+ "%",
97
+ "%4",
98
+ "%41",
99
+ "%zz",
100
+ "%+1",
101
+ "+",
102
+ "=",
103
+ "&",
104
+ ";",
105
+ "?",
106
+ "#",
107
+ ".",
108
+ "..",
109
+ "-",
110
+ "_",
111
+ ":",
112
+ ",",
113
+ "{",
114
+ "}",
115
+ "[",
116
+ "]",
117
+ "\n",
118
+ "\t",
119
+ "\r",
120
+ "\u{0}",
121
+ "\u{1f}",
122
+ "\u{7f}",
123
+ "é",
124
+ "ü",
125
+ "日本",
126
+ "🍕",
127
+ "\u{10FFFF}",
128
+ "\u{200B}",
129
+ "\u{FEFF}",
130
+ "\u{202E}",
131
+ "\u{FFFD}",
132
+ "e\u{301}",
133
+ "__",
134
+ "::",
135
+ "<script>",
136
+ "../",
137
+ "%0d%0a",
138
+ "id",
139
+ "name",
140
+ "value",
141
+ "sort",
142
+ "direction",
143
+ "desc",
79
144
  ];
80
145
 
81
146
  pub(crate) fn random_text(rng: &mut Rng) -> String {
@@ -97,8 +162,8 @@ pub(crate) fn edge_number(rng: &mut Rng) -> Value {
97
162
  json!(1e308),
98
163
  json!(-1e308),
99
164
  json!(5e-324),
100
- json!(1.7976931348623157e308),
101
- json!(9007199254740993_i64),
165
+ json!(1.797_693_134_862_315_7e308),
166
+ json!(9_007_199_254_740_993_i64),
102
167
  ];
103
168
  rng.pick(&edges).clone()
104
169
  }
@@ -112,7 +177,11 @@ pub(crate) fn random_value(rng: &mut Rng, depth: usize) -> Value {
112
177
  2 => edge_number(rng),
113
178
  3 | 4 => Value::String(random_text(rng)),
114
179
  5 => json!(rng.next() as i64 >> rng.below(63)),
115
- 6 => Value::Array((0..rng.below(4)).map(|_| random_value(rng, depth + 1)).collect()),
180
+ 6 => Value::Array(
181
+ (0..rng.below(4))
182
+ .map(|_| random_value(rng, depth + 1))
183
+ .collect(),
184
+ ),
116
185
  _ => {
117
186
  let mut map = Map::new();
118
187
  for _ in 0..rng.below(4) {
@@ -125,9 +194,12 @@ pub(crate) fn random_value(rng: &mut Rng, depth: usize) -> Value {
125
194
 
126
195
  /// `text` with a few random edits, on char boundaries.
127
196
  pub(crate) fn mutate_text(rng: &mut Rng, text: &str) -> String {
197
+ const JUNK: &[char] = &[
198
+ '{', '}', '[', ']', '"', '\\', ',', ':', '-', '+', '.', 'e', '0', '9', 'n', 't', ' ',
199
+ '\u{0}', '\n', '%', 'é', '🍕',
200
+ ];
128
201
  let mut chars: Vec<char> = text.chars().collect();
129
- const JUNK: &[char] = &['{', '}', '[', ']', '"', '\\', ',', ':', '-', '+', '.', 'e', '0', '9', 'n', 't', ' ', '\u{0}', '\n', '%', 'é', '🍕'];
130
- for _ in 0..1 + rng.below(3) {
202
+ for _ in 0..=rng.below(3) {
131
203
  if chars.is_empty() {
132
204
  chars.push(*rng.pick(JUNK));
133
205
  continue;
@@ -0,0 +1,100 @@
1
+ //! What a request handler needs to reach the domain, travelling as one value.
2
+
3
+ use crate::journal::LineageConfig;
4
+ use crate::lambda_client::LambdaInvoker;
5
+ use std::path::{Path, PathBuf};
6
+ use std::sync::Arc;
7
+ use tokio::sync::Mutex;
8
+ use tokio_postgres::Client;
9
+
10
+ /// The server's own shared handles, when a host is built from them.
11
+ #[derive(Clone, Copy)]
12
+ struct Shared<'a> {
13
+ client: &'a Arc<Mutex<Client>>,
14
+ wasm_path: &'a Arc<PathBuf>,
15
+ config: &'a Arc<LineageConfig>,
16
+ invoker: &'a Arc<dyn LambdaInvoker>,
17
+ }
18
+
19
+ /// The journal connection, the compiled domain module, the lineage it runs under, and the
20
+ /// invoker that delivers a policy's cross-domain reactions. Borrowed from the server's state (or
21
+ /// a test's fixtures) for the length of one call, so it is `Copy`.
22
+ #[derive(Clone, Copy)]
23
+ pub struct Host<'a> {
24
+ /// The one Postgres connection; its mutex serializes every write onto it.
25
+ pub client: &'a Mutex<Client>,
26
+ pub wasm_path: &'a Path,
27
+ pub config: &'a LineageConfig,
28
+ pub invoker: &'a dyn LambdaInvoker,
29
+ shared: Option<Shared<'a>>,
30
+ }
31
+
32
+ impl<'a> Host<'a> {
33
+ /// A host over borrowed pieces. It cannot outlive the call, so work that must outlast the
34
+ /// response stays inline.
35
+ pub fn new(
36
+ client: &'a Mutex<Client>,
37
+ wasm_path: &'a Path,
38
+ config: &'a LineageConfig,
39
+ invoker: &'a dyn LambdaInvoker,
40
+ ) -> Self {
41
+ Self {
42
+ client,
43
+ wasm_path,
44
+ config,
45
+ invoker,
46
+ shared: None,
47
+ }
48
+ }
49
+
50
+ /// A host over the server's own `Arc`s, from which `detach` can hand work an owned copy.
51
+ pub fn shared(
52
+ client: &'a Arc<Mutex<Client>>,
53
+ wasm_path: &'a Arc<PathBuf>,
54
+ config: &'a Arc<LineageConfig>,
55
+ invoker: &'a Arc<dyn LambdaInvoker>,
56
+ ) -> Self {
57
+ Self {
58
+ client,
59
+ wasm_path,
60
+ config,
61
+ invoker: invoker.as_ref(),
62
+ shared: Some(Shared {
63
+ client,
64
+ wasm_path,
65
+ config,
66
+ invoker,
67
+ }),
68
+ }
69
+ }
70
+
71
+ /// An owned copy for a task that outlives this request, or `None` when the host was built
72
+ /// from borrows and so cannot be detached.
73
+ pub fn detach(&self) -> Option<OwnedHost> {
74
+ self.shared.map(|shared| OwnedHost {
75
+ client: Arc::clone(shared.client),
76
+ wasm_path: Arc::clone(shared.wasm_path),
77
+ config: Arc::clone(shared.config),
78
+ invoker: Arc::clone(shared.invoker),
79
+ })
80
+ }
81
+ }
82
+
83
+ /// A `Host` that owns its handles, for work spawned past the end of a request.
84
+ pub struct OwnedHost {
85
+ client: Arc<Mutex<Client>>,
86
+ wasm_path: Arc<PathBuf>,
87
+ config: Arc<LineageConfig>,
88
+ invoker: Arc<dyn LambdaInvoker>,
89
+ }
90
+
91
+ impl OwnedHost {
92
+ pub fn host(&self) -> Host<'_> {
93
+ Host::new(
94
+ &self.client,
95
+ &self.wasm_path,
96
+ &self.config,
97
+ self.invoker.as_ref(),
98
+ )
99
+ }
100
+ }
@@ -0,0 +1,22 @@
1
+ //! The one HTTP client the host's outbound calls share.
2
+
3
+ use std::sync::LazyLock;
4
+
5
+ /// Built once: the TLS configuration and its root certificates are the costly part of a client.
6
+ ///
7
+ /// It keeps no idle connections. The tests run each case on its own runtime, and a connection
8
+ /// opened under one runtime is dead under the next, so reusing connections would fail them; these
9
+ /// calls (sign-in, checkout, receipts, template fetches) are infrequent and go to different
10
+ /// hosts, so reuse would not pay anyway.
11
+ #[allow(clippy::expect_used)] // reason: a client with default TLS settings always builds
12
+ static CLIENT: LazyLock<reqwest::Client> = LazyLock::new(|| {
13
+ reqwest::Client::builder()
14
+ .pool_max_idle_per_host(0)
15
+ .build()
16
+ .expect("a reqwest client with default settings always builds")
17
+ });
18
+
19
+ /// The shared client. Set a per-call timeout on the request, not on the client.
20
+ pub(crate) fn client() -> &'static reqwest::Client {
21
+ &CLIENT
22
+ }