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.
- checksums.yaml +4 -4
- data/examples/pizzas/adapters/fake_processor.rb +34 -0
- data/examples/pizzas/adapters/payment_signature.rb +66 -0
- data/examples/pizzas/adapters/payment_webhook.rb +87 -0
- data/examples/pizzas/bluebook/pizzas.behaviors +33 -0
- data/examples/pizzas/bluebook/pizzas.hecksagon +5 -3
- data/examples/pizzas/config.ru +22 -0
- data/exe/hecks +1 -1
- data/lib/hecks/adapters/driven/prism.rb +0 -2
- data/lib/hecks/adapters/driven.rb +0 -2
- data/lib/hecks/adapters/driving/json.rb +9 -16
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -2
- data/lib/hecks/bluebook/dsl/derivation_words.rb +58 -0
- data/lib/hecks/bluebook/dsl/translation_builder.rb +6 -37
- data/lib/hecks/bluebook/expression/ast_json.rb +0 -9
- data/lib/hecks/bluebook/hecksagon.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/translation_judge/rules.rb +7 -10
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +4 -8
- data/lib/hecks/bluebook/meta_validator.rb +0 -11
- data/lib/hecks/bluebook/translation.rb +18 -10
- data/lib/hecks/bluebook/translation_expression/evaluator.rb +63 -0
- data/lib/hecks/bluebook/translation_expression/parser.rb +127 -0
- data/lib/hecks/bluebook/translation_expression.rb +39 -0
- data/lib/hecks/bluebook/translation_plan.rb +70 -0
- data/lib/hecks/bluebook.rb +2 -0
- data/lib/hecks/chapters.rb +3 -3
- data/lib/hecks/cli/project_cli/launcher_source.rb +1 -1
- data/lib/hecks/composer/adapters/claude_composer.adapter +3 -0
- data/lib/hecks/composer/adapters/claude_composer.rb +83 -0
- data/lib/hecks/composer/adapters/fake_agent.adapter +3 -0
- data/lib/hecks/composer/adapters/fake_agent.rb +55 -0
- data/lib/hecks/composer/adapters/jev.adapter +3 -0
- data/lib/hecks/composer/adapters/jev.rb +66 -0
- data/lib/hecks/composer/agent.rb +113 -0
- data/lib/hecks/composer/assistant.rb +110 -0
- data/lib/hecks/composer/behavior_run.rb +53 -0
- data/lib/hecks/composer/bluebook/composer.bluebook +178 -0
- data/lib/hecks/composer/bluebook/composer.hecksagon +16 -0
- data/lib/hecks/composer/board.rb +65 -0
- data/lib/hecks/composer/board_edit/command_text.rb +39 -0
- data/lib/hecks/composer/board_edit/source.rb +84 -0
- data/lib/hecks/composer/board_edit.rb +144 -0
- data/lib/hecks/composer/check.rb +89 -0
- data/lib/hecks/composer/domains.rb +81 -0
- data/lib/hecks/composer/jobs.rb +134 -0
- data/lib/hecks/composer/layout.rb +37 -0
- data/lib/hecks/composer/live.rb +150 -0
- data/lib/hecks/composer/outline.rb +48 -0
- data/lib/hecks/composer/page.html +989 -0
- data/lib/hecks/composer/panels.rb +142 -0
- data/lib/hecks/composer/parse.rb +83 -0
- data/lib/hecks/composer/plain.rb +28 -0
- data/lib/hecks/composer/ports/composer_agent.port +7 -0
- data/lib/hecks/composer/session.rb +141 -0
- data/lib/hecks/composer/toolbox.rb +166 -0
- data/lib/hecks/composer/web.rb +156 -0
- data/lib/hecks/composer/workbench.rb +51 -0
- data/lib/hecks/composer/workspace.rb +81 -0
- data/lib/hecks/composer.rb +17 -0
- data/lib/hecks/corpus/adapters.rb +22 -0
- data/lib/hecks/corpus/rust.rb +1 -1
- data/lib/hecks/corpus/worlds.rb +19 -0
- data/lib/hecks/corpus.rb +5 -0
- data/lib/hecks/forms/app/commands.rb +2 -3
- data/lib/hecks/forms/app/queries.rb +2 -3
- data/lib/hecks/forms/app/records.rb +17 -5
- data/lib/hecks/forms/app/responses.rb +3 -1
- data/lib/hecks/forms/command_form_renderer.rb +42 -16
- data/lib/hecks/forms/field_controls.rb +2 -2
- data/lib/hecks/forms/field_renderer.rb +1 -1
- data/lib/hecks/forms/field_shape.rb +36 -17
- data/lib/hecks/forms/index_renderer.rb +2 -1
- data/lib/hecks/forms/page.rb +1 -1
- data/lib/hecks/forms/params.rb +0 -13
- data/lib/hecks/forms/query_form_renderer.rb +7 -6
- data/lib/hecks/forms/record_renderer.rb +11 -7
- data/lib/hecks/forms/rule_words.rb +100 -0
- data/lib/hecks/forms/value_object_shape.rb +2 -1
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -3
- data/lib/hecks/fuzzing/isolated_boot/worlds.rb +3 -6
- data/lib/hecks/fuzzing/replay/filters.rb +2 -6
- data/lib/hecks/gate/stages.yml +25 -0
- data/lib/hecks/grammar/evolve/seeds.rb +0 -6
- data/lib/hecks/grammar/evolve.rb +0 -3
- data/lib/hecks/grammar/translation.bluebook +1 -1
- data/lib/hecks/hecks/adapters/codebase/composing.rb +56 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +3 -1
- data/lib/hecks/hecks/adapters/first_admin.rb +3 -3
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +0 -26
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +2 -23
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +3 -11
- data/lib/hecks/hecks/adapters/journal_store.rb +0 -11
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +4 -11
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +0 -9
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +0 -4
- data/lib/hecks/hecks/codebase.behaviors +6 -0
- data/lib/hecks/hecks/codebase.bluebook +21 -0
- data/lib/hecks/hecks/composer.behaviors +68 -0
- data/lib/hecks/hecks/context_map.hecksagon +1 -1
- data/lib/hecks/hecks/custodian.behaviors +0 -6
- data/lib/hecks/hecks/custodian.bluebook +3 -80
- data/lib/hecks/hecks/hecks.hecksagon +2 -2
- data/lib/hecks/hecks/hecks.world +1 -1
- data/lib/hecks/hecks/rehearsal.bluebook +7 -13
- data/lib/hecks/kernel_capabilities/templates.rb +4 -4
- data/lib/hecks/kernel_capabilities.rb +1 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +2 -3
- data/lib/hecks/language/translation/translation_aggregate.bluebook +21 -24
- data/lib/hecks/ports/access_control.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +3 -41
- data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +7 -7
- data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +25 -2
- data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +4 -4
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +17 -25
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +0 -12
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +2 -22
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +0 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +9 -3
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +3 -29
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +2 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +6 -33
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -3
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +2 -4
- data/lib/hecks/ports/persistence/plugins/era/translation/expression_sql.rb +52 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +23 -29
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +0 -1
- data/lib/hecks/ports/persistence/plugins/era.rb +3 -6
- data/lib/hecks/ports.rb +0 -1
- data/lib/hecks/projection_files.rb +3 -1
- data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +1 -1
- data/lib/hecks/projections/glossary/entries.rb +10 -4
- data/lib/hecks/projections/glossary/groups.rb +42 -0
- data/lib/hecks/projections/glossary/html/page.rb +7 -2
- data/lib/hecks/projections/glossary/html/parser.rb +1 -1
- data/lib/hecks/projections/glossary/html/sections.rb +31 -11
- data/lib/hecks/projections/glossary/html.rb +1 -2
- data/lib/hecks/projections/glossary/markdown.rb +31 -28
- data/lib/hecks/projections/glossary/mermaid.rb +3 -0
- data/lib/hecks/projections/glossary/page.css +143 -153
- data/lib/hecks/projections/glossary/page.js +63 -3
- data/lib/hecks/projections/glossary/sentences/actions.rb +88 -0
- data/lib/hecks/projections/glossary/sentences/paths.rb +77 -0
- data/lib/hecks/projections/glossary/sentences/queries.rb +90 -0
- data/lib/hecks/projections/glossary/sentences/value_objects.rb +32 -5
- data/lib/hecks/projections/glossary/sentences.rb +13 -3
- data/lib/hecks/projections/glossary/slugs.rb +4 -1
- data/lib/hecks/projections/glossary.rb +2 -1
- data/lib/hecks/projections/plain_english.rb +97 -0
- data/lib/hecks/projections/rust_vocabulary/arguments.rb +2 -2
- data/lib/hecks/projections/rust_vocabulary/enum_body.rb +20 -25
- data/lib/hecks/projections/rust_vocabulary/tests.rb +2 -2
- data/lib/hecks/projections/rust_vocabulary.rb +14 -6
- data/lib/hecks/projections/site/cms_editor/color.rb +0 -6
- data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +7 -2
- data/lib/hecks/projections/statements/actions.rb +99 -0
- data/lib/hecks/projections/statements/relationships.rb +86 -0
- data/lib/hecks/projections/statements.rb +15 -24
- data/lib/hecks/projector/exporter/adapters.rb +112 -0
- data/lib/hecks/projector/exporter/translations.rb +18 -35
- data/lib/hecks/projector/exporter/worlds.rb +103 -0
- data/lib/hecks/projector/exporter.rb +5 -1
- data/lib/hecks/quality_control/adapters/agent.rb +6 -7
- data/lib/hecks/quality_control/adapters/agent_profile.rb +16 -114
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +1 -1
- data/lib/hecks/runtime/loader/boot_steps.rb +0 -20
- data/lib/hecks/runtime/outbox.rb +2 -9
- data/lib/hecks/runtime/port_operation_interpreter.rb +1 -9
- data/lib/hecks/runtime/remote_dispatcher.rb +2 -2
- data/lib/hecks/runtime/value/unwrapping.rb +60 -0
- data/lib/hecks/runtime/value.rb +10 -21
- data/lib/hecks/rust_build/project_rust/target_ir.rb +23 -4
- data/lib/hecks/rust_build/wasm.rb +0 -12
- data/lib/hecks/rust_build/write_if_changed.rb +12 -12
- data/lib/hecks/rust_format.rb +77 -0
- data/lib/hecks/tools/fuzz_sweep/findings.rb +3 -9
- data/lib/hecks/tools/fuzz_sweep.rb +1 -3
- data/lib/hecks/tools/translation_audit/verdicts.rb +3 -28
- data/lib/hecks/tools/translation_audit.rb +8 -10
- data/lib/hecks/tools/translation_scaffold/reporting.rb +1 -1
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +2 -1
- data/lib/hecks.rb +3 -0
- data/prebuilt/{1a6f596be124228be93eba1d86dbc9d2933190fa389b284331241cb9f27115a0.marshal → ad68f9e06c8068c2a4176b57abf3083d591d5d8980c2b3e897b97331f965b643.marshal} +0 -0
- data/prebuilt/{a883a7e568667aa5ac904c82daff356bdf9e996252a36af6def4a4a43efb967e.marshal → ee22ec8642c4006717ba2b80f46e5efb81de459eef9dfec043e838c0ad4fd720.marshal} +0 -0
- data/prebuilt/{verdicts-872993b1aa26d73fe48f28251374b8585fed145d02aab42be0f00de386b6ff80.json → verdicts-b69f5dcbba79c20daa0493476fa7c317004a30aa2bc3d3dc6a722ea70ae2b43b.json} +1 -1
- data/rust/Cargo.toml +40 -0
- data/rust/build/Cargo.toml +36 -0
- data/rust/build/clippy.toml +4 -0
- data/rust/build/src/adapters_pass.rs +196 -0
- data/rust/build/src/binding_pass.rs +54 -13
- data/rust/build/src/build_artifact.rs +23 -5
- data/rust/build/src/cargo_sync.rs +69 -26
- data/rust/build/src/lineage_pass.rs +101 -87
- data/rust/build/src/main.rs +11 -2
- data/rust/build/src/pipeline.rs +80 -19
- data/rust/build/src/reserved_names.rs +6 -50
- data/rust/build/src/resolve.rs +82 -35
- data/rust/build/src/rustfmt.rs +100 -0
- data/rust/build/src/seams_pass.rs +85 -16
- data/rust/build/src/subprocess.rs +30 -6
- data/rust/build/src/tmp.rs +5 -2
- data/rust/build/src/translation_pass.rs +72 -22
- data/rust/build/src/world_pass.rs +109 -0
- data/rust/clippy.toml +4 -0
- data/rust/codegen/Cargo.toml +36 -0
- data/rust/codegen/clippy.toml +4 -0
- data/rust/codegen/src/asks.rs +40 -14
- data/rust/codegen/src/attr.rs +2 -2
- data/rust/codegen/src/bridging.rs +676 -117
- data/rust/codegen/src/commands.rs +979 -373
- data/rust/codegen/src/constraints.rs +88 -25
- data/rust/codegen/src/dependency_planning.rs +128 -34
- data/rust/codegen/src/domain_generator.rs +306 -170
- data/rust/codegen/src/exemplar.rs +87 -32
- data/rust/codegen/src/expr_emitter.rs +54 -6
- data/rust/codegen/src/fielded.rs +193 -41
- data/rust/codegen/src/hecks_naming.rs +124 -16
- data/rust/codegen/src/hecks_naming_tests.rs +81 -0
- data/rust/codegen/src/json.rs +80 -44
- data/rust/codegen/src/json_codec.rs +585 -149
- data/rust/codegen/src/literal.rs +104 -138
- data/rust/codegen/src/main.rs +151 -52
- data/rust/codegen/src/manifest.rs +76 -14
- data/rust/codegen/src/mutations.rs +1212 -239
- data/rust/codegen/src/naming.rs +111 -60
- data/rust/codegen/src/optional_pass.rs +90 -28
- data/rust/codegen/src/ports.rs +5 -4
- data/rust/codegen/src/prelude.rs +139 -49
- data/rust/codegen/src/presenters.rs +335 -0
- data/rust/codegen/src/queries.rs +601 -226
- data/rust/codegen/src/reactions.rs +268 -74
- data/rust/codegen/src/read_models.rs +574 -229
- data/rust/codegen/src/reference_specs.rs +16 -3
- data/rust/codegen/src/registry.rs +128 -79
- data/rust/codegen/src/reserved_names.rs +6 -50
- data/rust/codegen/src/shared.rs +71 -22
- data/rust/codegen/src/sidecars.rs +15 -5
- data/rust/codegen/src/skip_reason.rs +8 -2
- data/rust/codegen/src/types.rs +306 -108
- data/rust/host/Cargo.lock +1 -0
- data/rust/host/Cargo.toml +40 -4
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/clippy.toml +4 -0
- data/rust/host/src/api.rs +698 -218
- data/rust/host/src/auth.rs +491 -214
- data/rust/host/src/b64.rs +91 -0
- data/rust/host/src/bin/expr_harness.rs +6 -2
- data/rust/host/src/bin/lineage_harness.rs +47 -11
- data/rust/host/src/bin/mint_harness.rs +70 -37
- data/rust/host/src/bin/validate_harness.rs +16 -8
- data/rust/host/src/boot.rs +144 -68
- data/rust/host/src/boundary_fuzz/api.rs +130 -32
- data/rust/host/src/boundary_fuzz/auth.rs +108 -23
- data/rust/host/src/boundary_fuzz/expr_json.rs +85 -11
- data/rust/host/src/boundary_fuzz/ir.rs +164 -12
- data/rust/host/src/boundary_fuzz/server.rs +283 -36
- data/rust/host/src/boundary_fuzz/web.rs +56 -8
- data/rust/host/src/checkout.rs +78 -32
- data/rust/host/src/clock.rs +8 -0
- data/rust/host/src/commerce_ir.rs +333 -95
- data/rust/host/src/crypto.rs +33 -0
- data/rust/host/src/dispatch.rs +1037 -331
- data/rust/host/src/expr_json.rs +1021 -273
- data/rust/host/src/extension.rs +24 -4
- data/rust/host/src/field_hints.rs +11 -7
- data/rust/host/src/fuzz_support.rs +85 -13
- data/rust/host/src/host.rs +100 -0
- data/rust/host/src/http.rs +22 -0
- data/rust/host/src/ir.rs +326 -16
- data/rust/host/src/journal.rs +277 -176
- data/rust/host/src/lambda_client.rs +219 -53
- data/rust/host/src/lib.rs +16 -4
- data/rust/host/src/log.rs +62 -11
- data/rust/host/src/mint.rs +1153 -326
- data/rust/host/src/needs.rs +185 -44
- data/rust/host/src/payments/keystore.rs +197 -45
- data/rust/host/src/payments/roles.rs +39 -7
- data/rust/host/src/payments/tests.rs +1427 -282
- data/rust/host/src/payments.rs +391 -112
- data/rust/host/src/platform_signin/attack_tests.rs +5 -5
- data/rust/host/src/platform_signin/config.rs +11 -11
- data/rust/host/src/platform_signin/cookie.rs +2 -2
- data/rust/host/src/platform_signin/extension.rs +2 -1
- data/rust/host/src/platform_signin/handler.rs +9 -8
- data/rust/host/src/platform_signin/jti.rs +4 -2
- data/rust/host/src/platform_signin/jwks.rs +2 -1
- data/rust/host/src/platform_signin/jws.rs +2 -37
- data/rust/host/src/platform_signin/known_answer_tests.rs +5 -1
- data/rust/host/src/platform_signin/mode_tests.rs +5 -3
- data/rust/host/src/platform_signin/pages.rs +20 -20
- data/rust/host/src/platform_signin/session.rs +8 -1
- data/rust/host/src/platform_signin/settings.rs +6 -6
- data/rust/host/src/platform_signin/strict_json.rs +12 -9
- data/rust/host/src/platform_signin/verify.rs +41 -41
- data/rust/host/src/platform_signin/wiring_support.rs +13 -18
- data/rust/host/src/presentation.rs +207 -63
- data/rust/host/src/presentation_write.rs +502 -187
- data/rust/host/src/query_step.rs +69 -18
- data/rust/host/src/rate_limit.rs +541 -142
- data/rust/host/src/reference_transform.rs +77 -25
- data/rust/host/src/reference_validate.rs +443 -104
- data/rust/host/src/resend.rs +190 -55
- data/rust/host/src/secrets.rs +116 -21
- data/rust/host/src/server.rs +555 -104
- data/rust/host/src/storage_shape.rs +88 -21
- data/rust/host/src/test_pg.rs +17 -7
- data/rust/host/src/ui_schema.rs +495 -207
- data/rust/host/src/wasm_runner.rs +21 -6
- data/rust/host/src/web/commerce.rs +101 -23
- data/rust/host/src/web/newsletter/cooldown.rs +10 -3
- data/rust/host/src/web/newsletter/template.rs +26 -7
- data/rust/host/src/web/newsletter/tests.rs +112 -23
- data/rust/host/src/web/newsletter.rs +209 -59
- data/rust/host/src/web/newsletter_send.rs +251 -79
- data/rust/host/src/web/registration_receipt/tests.rs +16 -4
- data/rust/host/src/web/registration_receipt.rs +100 -24
- data/rust/host/src/web/registrations.rs +1384 -332
- data/rust/host/src/web/resend_webhook.rs +138 -80
- data/rust/host/src/web.rs +2416 -508
- data/rust/lsp/Cargo.toml +36 -0
- data/rust/lsp/clippy.toml +4 -0
- data/rust/lsp/src/json.rs +29 -22
- data/rust/lsp/src/main.rs +81 -31
- data/rust/lsp/src/outline.rs +23 -7
- data/rust/lsp/src/rpc.rs +17 -4
- data/rust/parser/Cargo.toml +36 -0
- data/rust/parser/clippy.toml +4 -0
- data/rust/parser/src/build/closed_sets.rs +6 -1
- data/rust/parser/src/build/identity.rs +4 -3
- data/rust/parser/src/build/mod.rs +1 -1
- data/rust/parser/src/build/named_pattern.rs +4 -1
- data/rust/parser/src/build/naming.rs +2 -80
- data/rust/parser/src/build/pattern_subset.rs +6 -8
- data/rust/parser/src/build/query_derive.rs +3 -1
- data/rust/parser/src/build/query_inference.rs +14 -5
- data/rust/parser/src/build/read_model.rs +4 -1
- data/rust/parser/src/build/references.rs +4 -3
- data/rust/parser/src/canonical.rs +34 -15
- data/rust/parser/src/emit.rs +187 -105
- data/rust/parser/src/expr/ast_json.rs +134 -42
- data/rust/parser/src/expr/evaluator.rs +27 -9
- data/rust/parser/src/expr/mod.rs +54 -13
- data/rust/parser/src/expr/resolver.rs +299 -92
- data/rust/parser/src/ir.rs +35 -3
- data/rust/parser/src/keywords.rs +7168 -516
- data/rust/parser/src/lex.rs +11 -25
- data/rust/parser/src/lib.rs +1 -0
- data/rust/parser/src/main.rs +65 -6
- data/rust/parser/src/parse/adapter.rs +157 -0
- data/rust/parser/src/parse/aggregate.rs +19 -10
- data/rust/parser/src/parse/chapter.rs +16 -17
- data/rust/parser/src/parse/command.rs +35 -16
- data/rust/parser/src/parse/domain_port.rs +4 -7
- data/rust/parser/src/parse/entity.rs +21 -11
- data/rust/parser/src/parse/hecksagon.rs +10 -4
- data/rust/parser/src/parse/lifecycle.rs +9 -5
- data/rust/parser/src/parse/mod.rs +22 -91
- data/rust/parser/src/parse/needs.rs +21 -12
- data/rust/parser/src/parse/policy.rs +2 -2
- data/rust/parser/src/parse/process_manager.rs +9 -11
- data/rust/parser/src/parse/query.rs +8 -4
- data/rust/parser/src/parse/read_model.rs +57 -16
- data/rust/parser/src/parse/value_object.rs +7 -2
- data/rust/parser/src/parse/world.rs +322 -0
- data/rust/parser/src/ruby_value.rs +7 -6
- data/rust/src/exemplar/json.rs +4 -4
- data/rust/src/exemplar/mutations.rs +18 -0
- data/rust/src/exemplar/read_models.rs +1 -10
- data/rust/src/kernel/attribute_shapes/composite.rs +54 -14
- data/rust/src/kernel/attribute_shapes/list.rs +2 -2
- data/rust/src/kernel/attribute_shapes/mod.rs +8 -8
- data/rust/src/kernel/attribute_shapes/scalar.rs +2 -2
- data/rust/src/kernel/cli.rs +244 -114
- data/rust/src/kernel/dispatch.rs +323 -115
- data/rust/src/kernel/dispatch_guard_tests.rs +327 -65
- data/rust/src/kernel/expr.rs +203 -86
- data/rust/src/kernel/expression_operators/arithmetic.rs +138 -25
- data/rust/src/kernel/expression_operators/comparison.rs +87 -2
- data/rust/src/kernel/expression_operators/enumeration.rs +106 -22
- data/rust/src/kernel/expression_operators/logical.rs +9 -3
- data/rust/src/kernel/expression_operators/membership.rs +3 -1
- data/rust/src/kernel/expression_operators/mod.rs +34 -21
- data/rust/src/kernel/expression_operators/pattern_match.rs +46 -11
- data/rust/src/kernel/expression_operators/positional.rs +84 -30
- data/rust/src/kernel/expression_operators/presence.rs +52 -13
- data/rust/src/kernel/expression_operators/sign_test.rs +3 -1
- data/rust/src/kernel/expression_operators/sized.rs +24 -8
- data/rust/src/kernel/expression_operators/text.rs +120 -27
- data/rust/src/kernel/expression_operators/to_string.rs +10 -4
- data/rust/src/kernel/json.rs +244 -148
- data/rust/src/kernel/mod.rs +47 -33
- data/rust/src/kernel/named_query.rs +63 -15
- data/rust/src/kernel/needs.rs +112 -25
- data/rust/src/kernel/orchestrate.rs +980 -581
- data/rust/src/kernel/orchestrate_guard_tests.rs +538 -140
- data/rust/src/kernel/pattern.rs +107 -34
- data/rust/src/kernel/present.rs +261 -0
- data/rust/src/kernel/query_comparators.rs +118 -41
- data/rust/src/kernel/query_ordering.rs +13 -5
- data/rust/src/kernel/read_model.rs +479 -181
- data/rust/src/kernel/reference_lookup.rs +122 -26
- data/rust/src/kernel/repository.rs +293 -66
- data/rust/src/kernel/routing.rs +58 -42
- data/rust/src/kernel/ruby_float.rs +139 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +57 -57
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +54 -54
- data/rust/src/kernel/vocab/field_hint.rs +19 -25
- data/rust/src/kernel/vocab/mod.rs +6 -6
- data/rust/src/kernel/vocab/query_comparator.rs +23 -24
- data/rust/src/kernel/vocab/refusal_template.rs +501 -297
- data/rust/src/lib.rs +50 -0
- data/rust/src/main.rs +4 -1
- data/rust/web/Cargo.toml +36 -0
- data/rust/web/clippy.toml +4 -0
- metadata +85 -15
- data/examples/pizzas/bluebook/hecksagon/mock_stripe_payment_adapter.rb +0 -36
- data/lib/hecks/adapters/driven/google_authentication.adapter +0 -3
- data/lib/hecks/adapters/driven/google_authentication.rb +0 -99
- data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +0 -3
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +0 -32
- data/lib/hecks/ports/authentication.port +0 -6
- data/lib/hecks/ports/authentication.rb +0 -67
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +0 -255
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +0 -22
- data/rust/host/src/approval.rs +0 -652
data/rust/host/src/extension.rs
CHANGED
|
@@ -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|
|
|
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(
|
|
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()
|
|
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()
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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")
|
|
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) =>
|
|
66
|
+
Err(mpsc::RecvTimeoutError::Timeout) => {
|
|
67
|
+
panic!("{label}: no answer within {LIMIT:?} (hang)")
|
|
68
|
+
}
|
|
64
69
|
Err(mpsc::RecvTimeoutError::Disconnected) => {
|
|
65
|
-
let panic = handle
|
|
66
|
-
|
|
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",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
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.
|
|
101
|
-
json!(
|
|
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(
|
|
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
|
-
|
|
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
|
+
}
|