hecks 3.14.0 → 5.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 (427) 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.hecksagon +5 -3
  7. data/examples/pizzas/config.ru +22 -0
  8. data/exe/hecks +1 -1
  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 +9 -16
  12. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -2
  13. data/lib/hecks/bluebook/dsl/derivation_words.rb +58 -0
  14. data/lib/hecks/bluebook/dsl/translation_builder.rb +6 -37
  15. data/lib/hecks/bluebook/expression/ast_json.rb +0 -9
  16. data/lib/hecks/bluebook/hecksagon.rb +1 -1
  17. data/lib/hecks/bluebook/meta_validator/translation_judge/rules.rb +7 -10
  18. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +4 -8
  19. data/lib/hecks/bluebook/meta_validator.rb +0 -11
  20. data/lib/hecks/bluebook/translation.rb +18 -10
  21. data/lib/hecks/bluebook/translation_expression/evaluator.rb +63 -0
  22. data/lib/hecks/bluebook/translation_expression/parser.rb +127 -0
  23. data/lib/hecks/bluebook/translation_expression.rb +39 -0
  24. data/lib/hecks/bluebook/translation_plan.rb +70 -0
  25. data/lib/hecks/bluebook.rb +2 -0
  26. data/lib/hecks/chapters.rb +3 -3
  27. data/lib/hecks/cli/project_cli/launcher_source.rb +1 -1
  28. data/lib/hecks/composer/adapters/claude_composer.adapter +3 -0
  29. data/lib/hecks/composer/adapters/claude_composer.rb +83 -0
  30. data/lib/hecks/composer/adapters/fake_agent.adapter +3 -0
  31. data/lib/hecks/composer/adapters/fake_agent.rb +55 -0
  32. data/lib/hecks/composer/adapters/jev.adapter +3 -0
  33. data/lib/hecks/composer/adapters/jev.rb +66 -0
  34. data/lib/hecks/composer/agent.rb +113 -0
  35. data/lib/hecks/composer/assistant.rb +110 -0
  36. data/lib/hecks/composer/behavior_run.rb +53 -0
  37. data/lib/hecks/composer/bluebook/composer.bluebook +178 -0
  38. data/lib/hecks/composer/bluebook/composer.hecksagon +16 -0
  39. data/lib/hecks/composer/board.rb +65 -0
  40. data/lib/hecks/composer/board_edit/command_text.rb +39 -0
  41. data/lib/hecks/composer/board_edit/source.rb +84 -0
  42. data/lib/hecks/composer/board_edit.rb +144 -0
  43. data/lib/hecks/composer/check.rb +89 -0
  44. data/lib/hecks/composer/domains.rb +81 -0
  45. data/lib/hecks/composer/jobs.rb +134 -0
  46. data/lib/hecks/composer/layout.rb +37 -0
  47. data/lib/hecks/composer/live.rb +150 -0
  48. data/lib/hecks/composer/outline.rb +48 -0
  49. data/lib/hecks/composer/page.html +989 -0
  50. data/lib/hecks/composer/panels.rb +142 -0
  51. data/lib/hecks/composer/parse.rb +83 -0
  52. data/lib/hecks/composer/plain.rb +28 -0
  53. data/lib/hecks/composer/ports/composer_agent.port +7 -0
  54. data/lib/hecks/composer/session.rb +141 -0
  55. data/lib/hecks/composer/toolbox.rb +166 -0
  56. data/lib/hecks/composer/web.rb +156 -0
  57. data/lib/hecks/composer/workbench.rb +51 -0
  58. data/lib/hecks/composer/workspace.rb +81 -0
  59. data/lib/hecks/composer.rb +17 -0
  60. data/lib/hecks/corpus/adapters.rb +22 -0
  61. data/lib/hecks/corpus/rust.rb +1 -1
  62. data/lib/hecks/corpus/worlds.rb +19 -0
  63. data/lib/hecks/corpus.rb +5 -0
  64. data/lib/hecks/forms/app/commands.rb +2 -3
  65. data/lib/hecks/forms/app/queries.rb +2 -3
  66. data/lib/hecks/forms/app/records.rb +17 -5
  67. data/lib/hecks/forms/app/responses.rb +3 -1
  68. data/lib/hecks/forms/command_form_renderer.rb +42 -16
  69. data/lib/hecks/forms/field_controls.rb +2 -2
  70. data/lib/hecks/forms/field_renderer.rb +1 -1
  71. data/lib/hecks/forms/field_shape.rb +36 -17
  72. data/lib/hecks/forms/index_renderer.rb +2 -1
  73. data/lib/hecks/forms/page.rb +1 -1
  74. data/lib/hecks/forms/params.rb +0 -13
  75. data/lib/hecks/forms/query_form_renderer.rb +7 -6
  76. data/lib/hecks/forms/record_renderer.rb +11 -7
  77. data/lib/hecks/forms/rule_words.rb +100 -0
  78. data/lib/hecks/forms/value_object_shape.rb +2 -1
  79. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -3
  80. data/lib/hecks/fuzzing/isolated_boot/worlds.rb +3 -6
  81. data/lib/hecks/fuzzing/replay/filters.rb +2 -6
  82. data/lib/hecks/gate/stages.yml +25 -0
  83. data/lib/hecks/grammar/evolve/seeds.rb +0 -6
  84. data/lib/hecks/grammar/evolve.rb +0 -3
  85. data/lib/hecks/grammar/translation.bluebook +1 -1
  86. data/lib/hecks/hecks/adapters/codebase/composing.rb +56 -0
  87. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +3 -1
  88. data/lib/hecks/hecks/adapters/first_admin.rb +3 -3
  89. data/lib/hecks/hecks/adapters/journal_store/changes.rb +0 -26
  90. data/lib/hecks/hecks/adapters/journal_store/examination.rb +2 -23
  91. data/lib/hecks/hecks/adapters/journal_store/readings.rb +3 -11
  92. data/lib/hecks/hecks/adapters/journal_store.rb +0 -11
  93. data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +4 -11
  94. data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +0 -9
  95. data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +0 -4
  96. data/lib/hecks/hecks/codebase.behaviors +6 -0
  97. data/lib/hecks/hecks/codebase.bluebook +21 -0
  98. data/lib/hecks/hecks/composer.behaviors +68 -0
  99. data/lib/hecks/hecks/context_map.hecksagon +1 -1
  100. data/lib/hecks/hecks/custodian.behaviors +0 -6
  101. data/lib/hecks/hecks/custodian.bluebook +3 -80
  102. data/lib/hecks/hecks/hecks.hecksagon +2 -2
  103. data/lib/hecks/hecks/hecks.world +1 -1
  104. data/lib/hecks/hecks/rehearsal.bluebook +7 -13
  105. data/lib/hecks/kernel_capabilities/templates.rb +4 -4
  106. data/lib/hecks/kernel_capabilities.rb +1 -1
  107. data/lib/hecks/language/bluebook/vocabulary.bluebook +2 -3
  108. data/lib/hecks/language/translation/translation_aggregate.bluebook +21 -24
  109. data/lib/hecks/ports/access_control.rb +2 -2
  110. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +3 -41
  111. data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +7 -7
  112. data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +25 -2
  113. data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +4 -4
  114. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +17 -25
  115. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +0 -12
  116. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +1 -1
  117. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +2 -22
  118. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +0 -1
  119. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +9 -3
  120. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +3 -29
  121. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +2 -26
  122. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +6 -33
  123. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -3
  124. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +2 -4
  125. data/lib/hecks/ports/persistence/plugins/era/translation/expression_sql.rb +52 -0
  126. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +23 -29
  127. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +1 -1
  128. data/lib/hecks/ports/persistence/plugins/era/translation.rb +0 -1
  129. data/lib/hecks/ports/persistence/plugins/era.rb +3 -6
  130. data/lib/hecks/ports.rb +0 -1
  131. data/lib/hecks/projection_files.rb +3 -1
  132. data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +1 -1
  133. data/lib/hecks/projections/glossary/entries.rb +10 -4
  134. data/lib/hecks/projections/glossary/groups.rb +42 -0
  135. data/lib/hecks/projections/glossary/html/page.rb +7 -2
  136. data/lib/hecks/projections/glossary/html/parser.rb +1 -1
  137. data/lib/hecks/projections/glossary/html/sections.rb +31 -11
  138. data/lib/hecks/projections/glossary/html.rb +1 -2
  139. data/lib/hecks/projections/glossary/markdown.rb +31 -28
  140. data/lib/hecks/projections/glossary/mermaid.rb +3 -0
  141. data/lib/hecks/projections/glossary/page.css +143 -153
  142. data/lib/hecks/projections/glossary/page.js +63 -3
  143. data/lib/hecks/projections/glossary/sentences/actions.rb +88 -0
  144. data/lib/hecks/projections/glossary/sentences/paths.rb +77 -0
  145. data/lib/hecks/projections/glossary/sentences/queries.rb +90 -0
  146. data/lib/hecks/projections/glossary/sentences/value_objects.rb +32 -5
  147. data/lib/hecks/projections/glossary/sentences.rb +13 -3
  148. data/lib/hecks/projections/glossary/slugs.rb +4 -1
  149. data/lib/hecks/projections/glossary.rb +2 -1
  150. data/lib/hecks/projections/plain_english.rb +97 -0
  151. data/lib/hecks/projections/rust_vocabulary/arguments.rb +2 -2
  152. data/lib/hecks/projections/rust_vocabulary/enum_body.rb +20 -25
  153. data/lib/hecks/projections/rust_vocabulary/tests.rb +2 -2
  154. data/lib/hecks/projections/rust_vocabulary.rb +14 -6
  155. data/lib/hecks/projections/site/cms_editor/color.rb +0 -6
  156. data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +7 -2
  157. data/lib/hecks/projections/statements/actions.rb +99 -0
  158. data/lib/hecks/projections/statements/relationships.rb +86 -0
  159. data/lib/hecks/projections/statements.rb +15 -24
  160. data/lib/hecks/projector/exporter/adapters.rb +112 -0
  161. data/lib/hecks/projector/exporter/translations.rb +18 -35
  162. data/lib/hecks/projector/exporter/worlds.rb +103 -0
  163. data/lib/hecks/projector/exporter.rb +5 -1
  164. data/lib/hecks/quality_control/adapters/agent.rb +6 -7
  165. data/lib/hecks/quality_control/adapters/agent_profile.rb +16 -114
  166. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +1 -1
  167. data/lib/hecks/runtime/loader/boot_steps.rb +0 -20
  168. data/lib/hecks/runtime/outbox.rb +2 -9
  169. data/lib/hecks/runtime/port_operation_interpreter.rb +1 -9
  170. data/lib/hecks/runtime/remote_dispatcher.rb +2 -2
  171. data/lib/hecks/runtime/value/unwrapping.rb +60 -0
  172. data/lib/hecks/runtime/value.rb +10 -21
  173. data/lib/hecks/rust_build/project_rust/target_ir.rb +23 -4
  174. data/lib/hecks/rust_build/wasm.rb +0 -12
  175. data/lib/hecks/rust_build/write_if_changed.rb +12 -12
  176. data/lib/hecks/rust_format.rb +77 -0
  177. data/lib/hecks/tools/fuzz_sweep/findings.rb +3 -9
  178. data/lib/hecks/tools/fuzz_sweep.rb +1 -3
  179. data/lib/hecks/tools/translation_audit/verdicts.rb +3 -28
  180. data/lib/hecks/tools/translation_audit.rb +8 -10
  181. data/lib/hecks/tools/translation_scaffold/reporting.rb +1 -1
  182. data/lib/hecks/version.rb +1 -1
  183. data/lib/hecks/vocabulary.rb +2 -1
  184. data/lib/hecks.rb +3 -0
  185. data/prebuilt/{1a6f596be124228be93eba1d86dbc9d2933190fa389b284331241cb9f27115a0.marshal → ad68f9e06c8068c2a4176b57abf3083d591d5d8980c2b3e897b97331f965b643.marshal} +0 -0
  186. data/prebuilt/{a883a7e568667aa5ac904c82daff356bdf9e996252a36af6def4a4a43efb967e.marshal → ee22ec8642c4006717ba2b80f46e5efb81de459eef9dfec043e838c0ad4fd720.marshal} +0 -0
  187. data/prebuilt/{verdicts-872993b1aa26d73fe48f28251374b8585fed145d02aab42be0f00de386b6ff80.json → verdicts-b69f5dcbba79c20daa0493476fa7c317004a30aa2bc3d3dc6a722ea70ae2b43b.json} +1 -1
  188. data/rust/Cargo.toml +40 -0
  189. data/rust/build/Cargo.toml +36 -0
  190. data/rust/build/clippy.toml +4 -0
  191. data/rust/build/src/adapters_pass.rs +196 -0
  192. data/rust/build/src/binding_pass.rs +54 -13
  193. data/rust/build/src/build_artifact.rs +23 -5
  194. data/rust/build/src/cargo_sync.rs +69 -26
  195. data/rust/build/src/lineage_pass.rs +101 -87
  196. data/rust/build/src/main.rs +11 -2
  197. data/rust/build/src/pipeline.rs +80 -19
  198. data/rust/build/src/reserved_names.rs +6 -50
  199. data/rust/build/src/resolve.rs +82 -35
  200. data/rust/build/src/rustfmt.rs +100 -0
  201. data/rust/build/src/seams_pass.rs +85 -16
  202. data/rust/build/src/subprocess.rs +30 -6
  203. data/rust/build/src/tmp.rs +5 -2
  204. data/rust/build/src/translation_pass.rs +72 -22
  205. data/rust/build/src/world_pass.rs +109 -0
  206. data/rust/clippy.toml +4 -0
  207. data/rust/codegen/Cargo.toml +36 -0
  208. data/rust/codegen/clippy.toml +4 -0
  209. data/rust/codegen/src/asks.rs +40 -14
  210. data/rust/codegen/src/attr.rs +2 -2
  211. data/rust/codegen/src/bridging.rs +676 -117
  212. data/rust/codegen/src/commands.rs +979 -373
  213. data/rust/codegen/src/constraints.rs +88 -25
  214. data/rust/codegen/src/dependency_planning.rs +128 -34
  215. data/rust/codegen/src/domain_generator.rs +306 -170
  216. data/rust/codegen/src/exemplar.rs +87 -32
  217. data/rust/codegen/src/expr_emitter.rs +54 -6
  218. data/rust/codegen/src/fielded.rs +193 -41
  219. data/rust/codegen/src/hecks_naming.rs +124 -16
  220. data/rust/codegen/src/hecks_naming_tests.rs +81 -0
  221. data/rust/codegen/src/json.rs +80 -44
  222. data/rust/codegen/src/json_codec.rs +585 -149
  223. data/rust/codegen/src/literal.rs +104 -138
  224. data/rust/codegen/src/main.rs +151 -52
  225. data/rust/codegen/src/manifest.rs +76 -14
  226. data/rust/codegen/src/mutations.rs +1212 -239
  227. data/rust/codegen/src/naming.rs +111 -60
  228. data/rust/codegen/src/optional_pass.rs +90 -28
  229. data/rust/codegen/src/ports.rs +5 -4
  230. data/rust/codegen/src/prelude.rs +139 -49
  231. data/rust/codegen/src/presenters.rs +335 -0
  232. data/rust/codegen/src/queries.rs +601 -226
  233. data/rust/codegen/src/reactions.rs +268 -74
  234. data/rust/codegen/src/read_models.rs +574 -229
  235. data/rust/codegen/src/reference_specs.rs +16 -3
  236. data/rust/codegen/src/registry.rs +128 -79
  237. data/rust/codegen/src/reserved_names.rs +6 -50
  238. data/rust/codegen/src/shared.rs +71 -22
  239. data/rust/codegen/src/sidecars.rs +15 -5
  240. data/rust/codegen/src/skip_reason.rs +8 -2
  241. data/rust/codegen/src/types.rs +306 -108
  242. data/rust/host/Cargo.lock +1 -0
  243. data/rust/host/Cargo.toml +40 -4
  244. data/rust/host/HECKS_RELEASE +1 -1
  245. data/rust/host/clippy.toml +4 -0
  246. data/rust/host/src/api.rs +698 -218
  247. data/rust/host/src/auth.rs +491 -214
  248. data/rust/host/src/b64.rs +91 -0
  249. data/rust/host/src/bin/expr_harness.rs +6 -2
  250. data/rust/host/src/bin/lineage_harness.rs +47 -11
  251. data/rust/host/src/bin/mint_harness.rs +70 -37
  252. data/rust/host/src/bin/validate_harness.rs +16 -8
  253. data/rust/host/src/boot.rs +144 -68
  254. data/rust/host/src/boundary_fuzz/api.rs +130 -32
  255. data/rust/host/src/boundary_fuzz/auth.rs +108 -23
  256. data/rust/host/src/boundary_fuzz/expr_json.rs +85 -11
  257. data/rust/host/src/boundary_fuzz/ir.rs +164 -12
  258. data/rust/host/src/boundary_fuzz/server.rs +283 -36
  259. data/rust/host/src/boundary_fuzz/web.rs +56 -8
  260. data/rust/host/src/checkout.rs +78 -32
  261. data/rust/host/src/clock.rs +8 -0
  262. data/rust/host/src/commerce_ir.rs +333 -95
  263. data/rust/host/src/crypto.rs +33 -0
  264. data/rust/host/src/dispatch.rs +1037 -331
  265. data/rust/host/src/expr_json.rs +1021 -273
  266. data/rust/host/src/extension.rs +24 -4
  267. data/rust/host/src/field_hints.rs +11 -7
  268. data/rust/host/src/fuzz_support.rs +85 -13
  269. data/rust/host/src/host.rs +100 -0
  270. data/rust/host/src/http.rs +22 -0
  271. data/rust/host/src/ir.rs +326 -16
  272. data/rust/host/src/journal.rs +277 -176
  273. data/rust/host/src/lambda_client.rs +219 -53
  274. data/rust/host/src/lib.rs +16 -4
  275. data/rust/host/src/log.rs +62 -11
  276. data/rust/host/src/mint.rs +1153 -326
  277. data/rust/host/src/needs.rs +185 -44
  278. data/rust/host/src/payments/keystore.rs +197 -45
  279. data/rust/host/src/payments/roles.rs +39 -7
  280. data/rust/host/src/payments/tests.rs +1427 -282
  281. data/rust/host/src/payments.rs +391 -112
  282. data/rust/host/src/platform_signin/attack_tests.rs +5 -5
  283. data/rust/host/src/platform_signin/config.rs +11 -11
  284. data/rust/host/src/platform_signin/cookie.rs +2 -2
  285. data/rust/host/src/platform_signin/extension.rs +2 -1
  286. data/rust/host/src/platform_signin/handler.rs +9 -8
  287. data/rust/host/src/platform_signin/jti.rs +4 -2
  288. data/rust/host/src/platform_signin/jwks.rs +2 -1
  289. data/rust/host/src/platform_signin/jws.rs +2 -37
  290. data/rust/host/src/platform_signin/known_answer_tests.rs +5 -1
  291. data/rust/host/src/platform_signin/mode_tests.rs +5 -3
  292. data/rust/host/src/platform_signin/pages.rs +20 -20
  293. data/rust/host/src/platform_signin/session.rs +8 -1
  294. data/rust/host/src/platform_signin/settings.rs +6 -6
  295. data/rust/host/src/platform_signin/strict_json.rs +12 -9
  296. data/rust/host/src/platform_signin/verify.rs +41 -41
  297. data/rust/host/src/platform_signin/wiring_support.rs +13 -18
  298. data/rust/host/src/presentation.rs +207 -63
  299. data/rust/host/src/presentation_write.rs +502 -187
  300. data/rust/host/src/query_step.rs +69 -18
  301. data/rust/host/src/rate_limit.rs +541 -142
  302. data/rust/host/src/reference_transform.rs +77 -25
  303. data/rust/host/src/reference_validate.rs +443 -104
  304. data/rust/host/src/resend.rs +190 -55
  305. data/rust/host/src/secrets.rs +116 -21
  306. data/rust/host/src/server.rs +555 -104
  307. data/rust/host/src/storage_shape.rs +88 -21
  308. data/rust/host/src/test_pg.rs +17 -7
  309. data/rust/host/src/ui_schema.rs +495 -207
  310. data/rust/host/src/wasm_runner.rs +21 -6
  311. data/rust/host/src/web/commerce.rs +101 -23
  312. data/rust/host/src/web/newsletter/cooldown.rs +10 -3
  313. data/rust/host/src/web/newsletter/template.rs +26 -7
  314. data/rust/host/src/web/newsletter/tests.rs +112 -23
  315. data/rust/host/src/web/newsletter.rs +209 -59
  316. data/rust/host/src/web/newsletter_send.rs +251 -79
  317. data/rust/host/src/web/registration_receipt/tests.rs +16 -4
  318. data/rust/host/src/web/registration_receipt.rs +100 -24
  319. data/rust/host/src/web/registrations.rs +1384 -332
  320. data/rust/host/src/web/resend_webhook.rs +138 -80
  321. data/rust/host/src/web.rs +2416 -508
  322. data/rust/lsp/Cargo.toml +36 -0
  323. data/rust/lsp/clippy.toml +4 -0
  324. data/rust/lsp/src/json.rs +29 -22
  325. data/rust/lsp/src/main.rs +81 -31
  326. data/rust/lsp/src/outline.rs +23 -7
  327. data/rust/lsp/src/rpc.rs +17 -4
  328. data/rust/parser/Cargo.toml +36 -0
  329. data/rust/parser/clippy.toml +4 -0
  330. data/rust/parser/src/build/closed_sets.rs +6 -1
  331. data/rust/parser/src/build/identity.rs +4 -3
  332. data/rust/parser/src/build/mod.rs +1 -1
  333. data/rust/parser/src/build/named_pattern.rs +4 -1
  334. data/rust/parser/src/build/naming.rs +2 -80
  335. data/rust/parser/src/build/pattern_subset.rs +6 -8
  336. data/rust/parser/src/build/query_derive.rs +3 -1
  337. data/rust/parser/src/build/query_inference.rs +14 -5
  338. data/rust/parser/src/build/read_model.rs +4 -1
  339. data/rust/parser/src/build/references.rs +4 -3
  340. data/rust/parser/src/canonical.rs +34 -15
  341. data/rust/parser/src/emit.rs +187 -105
  342. data/rust/parser/src/expr/ast_json.rs +134 -42
  343. data/rust/parser/src/expr/evaluator.rs +27 -9
  344. data/rust/parser/src/expr/mod.rs +54 -13
  345. data/rust/parser/src/expr/resolver.rs +299 -92
  346. data/rust/parser/src/ir.rs +35 -3
  347. data/rust/parser/src/keywords.rs +7168 -516
  348. data/rust/parser/src/lex.rs +11 -25
  349. data/rust/parser/src/lib.rs +1 -0
  350. data/rust/parser/src/main.rs +65 -6
  351. data/rust/parser/src/parse/adapter.rs +157 -0
  352. data/rust/parser/src/parse/aggregate.rs +19 -10
  353. data/rust/parser/src/parse/chapter.rs +16 -17
  354. data/rust/parser/src/parse/command.rs +35 -16
  355. data/rust/parser/src/parse/domain_port.rs +4 -7
  356. data/rust/parser/src/parse/entity.rs +21 -11
  357. data/rust/parser/src/parse/hecksagon.rs +10 -4
  358. data/rust/parser/src/parse/lifecycle.rs +9 -5
  359. data/rust/parser/src/parse/mod.rs +22 -91
  360. data/rust/parser/src/parse/needs.rs +21 -12
  361. data/rust/parser/src/parse/policy.rs +2 -2
  362. data/rust/parser/src/parse/process_manager.rs +9 -11
  363. data/rust/parser/src/parse/query.rs +8 -4
  364. data/rust/parser/src/parse/read_model.rs +57 -16
  365. data/rust/parser/src/parse/value_object.rs +7 -2
  366. data/rust/parser/src/parse/world.rs +322 -0
  367. data/rust/parser/src/ruby_value.rs +7 -6
  368. data/rust/src/exemplar/json.rs +4 -4
  369. data/rust/src/exemplar/mutations.rs +18 -0
  370. data/rust/src/exemplar/read_models.rs +1 -10
  371. data/rust/src/kernel/attribute_shapes/composite.rs +54 -14
  372. data/rust/src/kernel/attribute_shapes/list.rs +2 -2
  373. data/rust/src/kernel/attribute_shapes/mod.rs +8 -8
  374. data/rust/src/kernel/attribute_shapes/scalar.rs +2 -2
  375. data/rust/src/kernel/cli.rs +244 -114
  376. data/rust/src/kernel/dispatch.rs +323 -115
  377. data/rust/src/kernel/dispatch_guard_tests.rs +327 -65
  378. data/rust/src/kernel/expr.rs +203 -86
  379. data/rust/src/kernel/expression_operators/arithmetic.rs +138 -25
  380. data/rust/src/kernel/expression_operators/comparison.rs +87 -2
  381. data/rust/src/kernel/expression_operators/enumeration.rs +106 -22
  382. data/rust/src/kernel/expression_operators/logical.rs +9 -3
  383. data/rust/src/kernel/expression_operators/membership.rs +3 -1
  384. data/rust/src/kernel/expression_operators/mod.rs +34 -21
  385. data/rust/src/kernel/expression_operators/pattern_match.rs +46 -11
  386. data/rust/src/kernel/expression_operators/positional.rs +84 -30
  387. data/rust/src/kernel/expression_operators/presence.rs +52 -13
  388. data/rust/src/kernel/expression_operators/sign_test.rs +3 -1
  389. data/rust/src/kernel/expression_operators/sized.rs +24 -8
  390. data/rust/src/kernel/expression_operators/text.rs +120 -27
  391. data/rust/src/kernel/expression_operators/to_string.rs +10 -4
  392. data/rust/src/kernel/json.rs +244 -148
  393. data/rust/src/kernel/mod.rs +47 -33
  394. data/rust/src/kernel/named_query.rs +63 -15
  395. data/rust/src/kernel/needs.rs +112 -25
  396. data/rust/src/kernel/orchestrate.rs +980 -581
  397. data/rust/src/kernel/orchestrate_guard_tests.rs +538 -140
  398. data/rust/src/kernel/pattern.rs +107 -34
  399. data/rust/src/kernel/present.rs +261 -0
  400. data/rust/src/kernel/query_comparators.rs +118 -41
  401. data/rust/src/kernel/query_ordering.rs +13 -5
  402. data/rust/src/kernel/read_model.rs +479 -181
  403. data/rust/src/kernel/reference_lookup.rs +122 -26
  404. data/rust/src/kernel/repository.rs +293 -66
  405. data/rust/src/kernel/routing.rs +58 -42
  406. data/rust/src/kernel/ruby_float.rs +139 -0
  407. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +57 -57
  408. data/rust/src/kernel/vocab/entity_dispatch_order.rs +54 -54
  409. data/rust/src/kernel/vocab/field_hint.rs +19 -25
  410. data/rust/src/kernel/vocab/mod.rs +6 -6
  411. data/rust/src/kernel/vocab/query_comparator.rs +23 -24
  412. data/rust/src/kernel/vocab/refusal_template.rs +501 -297
  413. data/rust/src/lib.rs +50 -0
  414. data/rust/src/main.rs +4 -1
  415. data/rust/web/Cargo.toml +36 -0
  416. data/rust/web/clippy.toml +4 -0
  417. metadata +85 -15
  418. data/examples/pizzas/bluebook/hecksagon/mock_stripe_payment_adapter.rb +0 -36
  419. data/lib/hecks/adapters/driven/google_authentication.adapter +0 -3
  420. data/lib/hecks/adapters/driven/google_authentication.rb +0 -99
  421. data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +0 -3
  422. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +0 -32
  423. data/lib/hecks/ports/authentication.port +0 -6
  424. data/lib/hecks/ports/authentication.rb +0 -67
  425. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +0 -255
  426. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +0 -22
  427. 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
+ }