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.
- 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.bluebook +4 -4
- data/examples/pizzas/bluebook/pizzas.hecksagon +5 -3
- data/examples/pizzas/config.ru +22 -0
- data/lib/hecks/adapters/driven/prism.rb +0 -2
- data/lib/hecks/adapters/driven.rb +0 -2
- data/lib/hecks/adapters/driving/json.rb +1 -7
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +15 -5
- 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/named_pattern.rb +33 -0
- 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 +3 -0
- data/lib/hecks/chapters.rb +3 -3
- data/lib/hecks/cli/domain_stub.rb +1 -1
- data/lib/hecks/cli/interview_aggregate.rb +4 -4
- 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/deploy/bluebook/deploy.bluebook +34 -34
- 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/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/framework/bluebook/change.bluebook +2 -2
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -3
- data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +1 -1
- 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/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 +58 -37
- 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 +15 -92
- data/lib/hecks/hecks/hecks.bluebook +2 -2
- data/lib/hecks/hecks/hecks.hecksagon +2 -2
- data/lib/hecks/hecks/hecks.world +1 -1
- data/lib/hecks/hecks/rehearsal.bluebook +10 -16
- data/lib/hecks/hecks/tooling.bluebook +22 -22
- data/lib/hecks/kernel_capabilities/templates.rb +4 -4
- data/lib/hecks/kernel_capabilities.rb +1 -1
- data/lib/hecks/language/bluebook/aggregate.bluebook +1 -0
- data/lib/hecks/language/bluebook/command.bluebook +1 -0
- data/lib/hecks/language/bluebook/entity.bluebook +1 -0
- data/lib/hecks/language/bluebook/query.bluebook +1 -0
- data/lib/hecks/language/bluebook/shape.bluebook +8 -7
- data/lib/hecks/language/bluebook/vocabulary.bluebook +2 -3
- data/lib/hecks/language/hecksagon/port_operation.bluebook +1 -0
- 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/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/quality_control/quality_control.bluebook +51 -51
- 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.rb +13 -0
- 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/site/bluebook/site.bluebook +5 -5
- data/lib/hecks/sme/bluebook/sme.bluebook +12 -12
- data/lib/hecks/tickets/bluebook/tickets.bluebook +3 -3
- 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/{58208399bada10b0db99928c48e38789288fc58f7b71a72b21bfa386680e32ed.marshal → 02c09c73b272c1fb5a9ae6d87bb5e5e529208e00f6b4b597dc2c0fd70a9c0964.marshal} +0 -0
- data/prebuilt/{2b59737fbdbd5f44edda0fddce2611f45d76087b3a7c782d1f1a17ea58c77948.marshal → bb84a835cf6a15136bad5ca03aa5bf93a5b92f5f72444618d3ef2412b987fb32.marshal} +0 -0
- data/prebuilt/verdicts-f1f10da14c8e8f01b4c9b7e3e2d74be8cd2bf4676364ed17fa16975d2a076d75.json +1 -0
- 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 +300 -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 +145 -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/queries.rs +601 -226
- data/rust/codegen/src/reactions.rs +268 -74
- data/rust/codegen/src/read_models.rs +606 -205
- 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 +990 -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 +191 -0
- data/rust/host/src/payments/tests.rs +1445 -275
- data/rust/host/src/payments.rs +409 -121
- 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 +483 -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 -0
- data/rust/parser/src/build/named_pattern.rs +26 -0
- 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 -510
- 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 +43 -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 +229 -112
- 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 +230 -148
- data/rust/src/kernel/mod.rs +46 -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/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/prebuilt/verdicts-48318ca172edd21443b1ad02801c697fff100b746e828f09db987647641a5df2.json +0 -1
- data/rust/host/src/approval.rs +0 -652
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "rack"
|
|
3
|
+
require_relative "../composer"
|
|
4
|
+
require_relative "domains"
|
|
5
|
+
require_relative "workbench"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Composer
|
|
9
|
+
# The Composer's driving side, on the hecksagon side: a Rack app that serves the editor page
|
|
10
|
+
# and the JSON routes it speaks to, over one workspace directory at a time. It binds no
|
|
11
|
+
# business meaning. The routes are the tables below: the page and files, the editor's own
|
|
12
|
+
# (save, remove, parse, check, ask), the domain list, and the lower panels', which {Panels}
|
|
13
|
+
# answers.
|
|
14
|
+
class Web
|
|
15
|
+
PAGE = File.expand_path("page.html", __dir__).freeze
|
|
16
|
+
PREFIX = "/composer".freeze
|
|
17
|
+
|
|
18
|
+
# @param workspace [String] the domain directory the editor opens
|
|
19
|
+
# @param agents [Runtime::Registry, nil] see {Workbench#initialize}
|
|
20
|
+
# @param root [String] the checkout whose domains the picker lists
|
|
21
|
+
# @return [Web] a Rack app
|
|
22
|
+
def self.app(workspace:, agents: nil, root: Parse::ROOT) = new(workspace: workspace, agents: agents, root: root)
|
|
23
|
+
|
|
24
|
+
# @param workspace [String] the domain directory the editor opens
|
|
25
|
+
# @param agents [Runtime::Registry, nil] see {Workbench#initialize}
|
|
26
|
+
# @param root [String] the checkout whose domains the picker lists
|
|
27
|
+
def initialize(workspace:, agents: nil, root: Parse::ROOT)
|
|
28
|
+
@agents = agents
|
|
29
|
+
@root = File.expand_path(root)
|
|
30
|
+
@bench = Workbench.new(workspace: workspace, agents: agents)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param env [Hash] the Rack environment
|
|
34
|
+
# @return [Array] the Rack response triple
|
|
35
|
+
def call(env)
|
|
36
|
+
request = Rack::Request.new(env)
|
|
37
|
+
route(request)
|
|
38
|
+
rescue Workspace::OutsideWorkspace, KeyError, JSON::ParserError => e
|
|
39
|
+
json(400, error: e.message)
|
|
40
|
+
rescue Domains::Unknown => e
|
|
41
|
+
json(404, error: e.message)
|
|
42
|
+
rescue Parse::ParserMissing => e
|
|
43
|
+
json(503, error: e.message)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# Routes that answer from the workspace alone, those that read a JSON body first, and those
|
|
49
|
+
# the lower panels ask (answered by {Panels}).
|
|
50
|
+
READS = { "GET " => :page, "GET #{PREFIX}" => :page, "GET #{PREFIX}/files" => :listing,
|
|
51
|
+
"GET #{PREFIX}/draft" => :conversation, "GET #{PREFIX}/domains" => :domains }.freeze
|
|
52
|
+
WRITES = { "PUT #{PREFIX}/file" => :save, "DELETE #{PREFIX}/file" => :remove,
|
|
53
|
+
"POST #{PREFIX}/parse" => :parse, "POST #{PREFIX}/check" => :check,
|
|
54
|
+
"POST #{PREFIX}/ask" => :ask, "POST #{PREFIX}/open" => :open_domain }.freeze
|
|
55
|
+
PANEL_ROUTES = { "POST #{PREFIX}/live/commands" => :commands, "POST #{PREFIX}/live/dispatch" => :dispatch,
|
|
56
|
+
"POST #{PREFIX}/live/records" => :records, "POST #{PREFIX}/behaviors" => :behaviors,
|
|
57
|
+
"POST #{PREFIX}/timeline" => :timeline, "POST #{PREFIX}/board/edit" => :board_edit,
|
|
58
|
+
"GET #{PREFIX}/catalog" => :catalog,
|
|
59
|
+
"POST #{PREFIX}/help" => :help, "POST #{PREFIX}/run" => :run,
|
|
60
|
+
"GET #{PREFIX}/eras" => :eras, "POST #{PREFIX}/job" => :start_job,
|
|
61
|
+
"GET #{PREFIX}/job" => :job_state, "DELETE #{PREFIX}/job" => :cancel_job }.freeze
|
|
62
|
+
private_constant :READS, :WRITES, :PANEL_ROUTES
|
|
63
|
+
|
|
64
|
+
def route(request)
|
|
65
|
+
key = "#{request.request_method} #{request.path_info.chomp("/")}"
|
|
66
|
+
answer_for(key, request) || json(404, error: "no such route")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# The response the key's table gives, or nil when no table has the key.
|
|
70
|
+
def answer_for(key, request)
|
|
71
|
+
return send(READS[key]) if READS.key?(key)
|
|
72
|
+
return send(WRITES[key], body(request)) if WRITES.key?(key)
|
|
73
|
+
|
|
74
|
+
json(200, @bench.panels.public_send(PANEL_ROUTES[key], body(request))) if PANEL_ROUTES.key?(key)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def workspace = @bench.workspace
|
|
78
|
+
|
|
79
|
+
def listing = json(200, files: files)
|
|
80
|
+
|
|
81
|
+
def conversation = json(200, draft: @bench.session.summary(@bench.slug))
|
|
82
|
+
|
|
83
|
+
# The known domains, and the directory the editor has open now.
|
|
84
|
+
def domains = json(200, domains: Domains.known(root: @root), current: File.basename(workspace))
|
|
85
|
+
|
|
86
|
+
# Opens a known domain as a scratch copy, replacing everything kept for the old workspace.
|
|
87
|
+
def open_domain(body)
|
|
88
|
+
id = body.fetch("id")
|
|
89
|
+
opened = Domains.open(root: @root, id: id)
|
|
90
|
+
@bench.close
|
|
91
|
+
@bench = Workbench.new(workspace: opened, agents: @agents)
|
|
92
|
+
json(200, opened: id, current: File.basename(opened))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def ask(body)
|
|
96
|
+
json(200, @bench.assistant.ask(body.fetch("prompt")))
|
|
97
|
+
rescue Agent::Unavailable => e
|
|
98
|
+
json(503, error: e.message)
|
|
99
|
+
rescue Agent::ValidationError => e
|
|
100
|
+
json(502, error: e.message)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def page = [200, { "content-type" => "text/html; charset=utf-8" }, [File.read(PAGE)]]
|
|
104
|
+
|
|
105
|
+
def files
|
|
106
|
+
Workspace.files(workspace).map { |path| { path: path, text: File.read(File.join(workspace, path)) } }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def save(body)
|
|
110
|
+
path = domain_path(body) or return refused(body)
|
|
111
|
+
|
|
112
|
+
target = File.join(workspace, path)
|
|
113
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
114
|
+
File.write(target, body.fetch("text"))
|
|
115
|
+
@bench.session.record(path: path, text: body.fetch("text"))
|
|
116
|
+
json(200, saved: path)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def remove(body)
|
|
120
|
+
path = domain_path(body) or return refused(body)
|
|
121
|
+
|
|
122
|
+
FileUtils.rm_f(File.join(workspace, path))
|
|
123
|
+
json(200, removed: path)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# The request's path when it names a domain file inside the workspace, else nil.
|
|
127
|
+
def domain_path(body)
|
|
128
|
+
path = body.fetch("path")
|
|
129
|
+
Workspace.refuse_escapes!([path])
|
|
130
|
+
path if Workspace::EXTENSIONS.include?(File.extname(path).delete_prefix("."))
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def refused(body) = json(400, error: "#{body["path"].inspect} is not a domain file")
|
|
134
|
+
|
|
135
|
+
def parse(body)
|
|
136
|
+
refusal = Workspace.stage(dir: workspace, buffers: buffers(body)) { |stage| Parse.call(stage) }
|
|
137
|
+
json(200, diagnostic: refusal)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def check(body)
|
|
141
|
+
json(200, Check.call(dir: workspace, buffers: buffers(body), chapter_name: body["chapter_name"]))
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def buffers(body) = body.fetch("buffers", {})
|
|
145
|
+
|
|
146
|
+
def body(request)
|
|
147
|
+
raw = request.body&.read.to_s
|
|
148
|
+
raw.empty? ? {} : JSON.parse(raw)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def json(status, payload)
|
|
152
|
+
[status, { "content-type" => "application/json" }, [JSON.generate(payload)]]
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require_relative "agent"
|
|
2
|
+
require_relative "assistant"
|
|
3
|
+
require_relative "panels"
|
|
4
|
+
require_relative "session"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Composer
|
|
8
|
+
# Everything the editor keeps for one workspace, on the hecksagon side: the draft bookkeeping,
|
|
9
|
+
# the agent that edits it and the panels beneath the editor. Opening another domain builds a
|
|
10
|
+
# new workbench, so nothing of the old workspace carries over.
|
|
11
|
+
class Workbench
|
|
12
|
+
# @return [String] the domain directory this workbench is for
|
|
13
|
+
attr_reader :workspace
|
|
14
|
+
|
|
15
|
+
# @param workspace [String] the domain directory
|
|
16
|
+
# @param agents [Runtime::Registry, nil] a registry holding the `composer_agent` port and one
|
|
17
|
+
# adapter; the one `HECKS_COMPOSER_AGENT` names (`claude`, the default, or `fake`) when nil
|
|
18
|
+
def initialize(workspace:, agents: nil)
|
|
19
|
+
@workspace = File.expand_path(workspace)
|
|
20
|
+
@agents = agents
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [String] the workspace's directory name, which names its draft
|
|
24
|
+
def slug = File.basename(workspace)
|
|
25
|
+
|
|
26
|
+
# @return [Session] the draft bookkeeping, booted on first use
|
|
27
|
+
def session = @session ||= Session.new
|
|
28
|
+
|
|
29
|
+
# @return [Assistant] the agent loop over this workspace
|
|
30
|
+
def assistant = @assistant ||= Assistant.new(workspace: workspace, agents: agents, session: session)
|
|
31
|
+
|
|
32
|
+
# @return [Panels] what answers the lower panels
|
|
33
|
+
def panels = @panels ||= Panels.new(workspace: workspace, session: session)
|
|
34
|
+
|
|
35
|
+
# Releases what the panels booted.
|
|
36
|
+
# @return [void]
|
|
37
|
+
def close = @panels&.close
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def agents = @agents ||= default_agents
|
|
42
|
+
|
|
43
|
+
# The adapter `HECKS_COMPOSER_AGENT` names: the real `claude`, or a scripted `fake`.
|
|
44
|
+
def default_agents
|
|
45
|
+
name = ENV.fetch("HECKS_COMPOSER_AGENT", "claude") == "fake" ? "fake_agent" : "claude_composer"
|
|
46
|
+
require_relative "adapters/#{name}"
|
|
47
|
+
Agent.registry_with(File.join(Agent::ADAPTERS, "#{name}.adapter"))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "tmpdir"
|
|
3
|
+
|
|
4
|
+
module Hecks
|
|
5
|
+
module Composer
|
|
6
|
+
# A workspace is a directory of domain files; an editor holds unsaved text for some of them.
|
|
7
|
+
# Staging lays that text over a copy of the files on disk so a check sees what is on screen
|
|
8
|
+
# and the directory itself stays untouched.
|
|
9
|
+
module Workspace
|
|
10
|
+
# The files a domain is made of; anything else in the directory is data, not declaration.
|
|
11
|
+
EXTENSIONS = %w[bluebook hecksagon world adapter port behaviors].freeze
|
|
12
|
+
|
|
13
|
+
# Raised when an unsaved buffer names a path outside the workspace.
|
|
14
|
+
class OutsideWorkspace < ArgumentError; end
|
|
15
|
+
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
# Copies the workspace's declaration files into a temporary directory, lays the buffers over
|
|
19
|
+
# them, and yields that directory.
|
|
20
|
+
#
|
|
21
|
+
# @param dir [String] the workspace directory
|
|
22
|
+
# @param buffers [Hash{String => String}] unsaved text by path relative to `dir`; a path
|
|
23
|
+
# with no file on disk yet is created
|
|
24
|
+
# @yieldparam stage [String] the temporary directory holding the staged files
|
|
25
|
+
# @return [Object] what the block returned
|
|
26
|
+
# @raise [OutsideWorkspace] if a buffer's path is absolute or climbs out of the workspace
|
|
27
|
+
def stage(dir:, buffers: {})
|
|
28
|
+
stage = materialize(dir: dir, buffers: buffers)
|
|
29
|
+
yield stage
|
|
30
|
+
ensure
|
|
31
|
+
FileUtils.rm_rf(stage) if stage
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Stages as {stage} does, but leaves the directory for the caller to remove, so a booted
|
|
35
|
+
# domain can keep reading its files after this returns.
|
|
36
|
+
#
|
|
37
|
+
# @param dir [String] the workspace directory
|
|
38
|
+
# @param buffers [Hash{String => String}] unsaved text by path relative to `dir`
|
|
39
|
+
# @return [String] the temporary directory holding the staged files
|
|
40
|
+
# @raise [OutsideWorkspace] if a buffer's path is absolute or climbs out of the workspace
|
|
41
|
+
def materialize(dir:, buffers: {})
|
|
42
|
+
refuse_escapes!(buffers.keys)
|
|
43
|
+
stage = Dir.mktmpdir("hecks-composer")
|
|
44
|
+
copy_declarations(dir, stage)
|
|
45
|
+
buffers.each { |path, text| write(File.join(stage, path), text) }
|
|
46
|
+
stage
|
|
47
|
+
rescue StandardError
|
|
48
|
+
FileUtils.rm_rf(stage) if stage
|
|
49
|
+
raise
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param stage [String] a staged directory
|
|
53
|
+
# @return [Array<String>] the declaration files in it, relative and sorted
|
|
54
|
+
def files(stage)
|
|
55
|
+
Dir.glob("**/*.{#{EXTENSIONS.join(",")}}", base: stage).sort
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @api private
|
|
59
|
+
def copy_declarations(dir, stage)
|
|
60
|
+
files(dir).each do |relative|
|
|
61
|
+
FileUtils.mkdir_p(File.dirname(File.join(stage, relative)))
|
|
62
|
+
FileUtils.cp(File.join(dir, relative), File.join(stage, relative))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api private
|
|
67
|
+
def write(path, text)
|
|
68
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
69
|
+
File.write(path, text)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @api private
|
|
73
|
+
def refuse_escapes!(paths)
|
|
74
|
+
offender = paths.find { |path| path.start_with?("/") || path.split("/").include?("..") }
|
|
75
|
+
return unless offender
|
|
76
|
+
|
|
77
|
+
raise OutsideWorkspace, "#{offender.inspect} is not inside the workspace"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative "composer/plain"
|
|
2
|
+
require_relative "composer/workspace"
|
|
3
|
+
require_relative "composer/parse"
|
|
4
|
+
require_relative "composer/outline"
|
|
5
|
+
require_relative "composer/layout"
|
|
6
|
+
require_relative "composer/behavior_run"
|
|
7
|
+
require_relative "composer/live"
|
|
8
|
+
require_relative "composer/toolbox"
|
|
9
|
+
require_relative "composer/jobs"
|
|
10
|
+
require_relative "composer/check"
|
|
11
|
+
|
|
12
|
+
module Hecks
|
|
13
|
+
# The Composer's outside, on the hecksagon side: staging a workspace, judging its text and
|
|
14
|
+
# projecting what it declares. The Composer chapter's bluebook is in `composer/bluebook/`.
|
|
15
|
+
module Composer
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Corpus
|
|
3
|
+
# Where `.adapter` files live, for the parser parity check. Extended onto `Corpus`.
|
|
4
|
+
module Adapters
|
|
5
|
+
# Directories that hold copies or build output, never a source `.adapter`.
|
|
6
|
+
EXCLUDED_DIRS = %w[vendor node_modules target tmp .git .aws-sam].freeze
|
|
7
|
+
|
|
8
|
+
ADAPTER_GLOBS = %w[lib/**/*.adapter examples/**/*.adapter spec/fixtures/**/*.adapter].freeze
|
|
9
|
+
|
|
10
|
+
# Every `.adapter` file the repo carries.
|
|
11
|
+
#
|
|
12
|
+
# @param root [String] repository root to search under
|
|
13
|
+
# @return [Array<String>] absolute paths, sorted, none under a vendored, `node_modules`,
|
|
14
|
+
# `target` or scratch directory
|
|
15
|
+
def adapter_files(root: Corpus::ROOT)
|
|
16
|
+
ADAPTER_GLOBS.flat_map { |glob| Dir.glob(File.join(root, glob)) }.uniq.sort.reject do |path|
|
|
17
|
+
path.delete_prefix("#{root}/").split("/").intersect?(EXCLUDED_DIRS)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/hecks/corpus/rust.rb
CHANGED
|
@@ -3,7 +3,7 @@ module Hecks
|
|
|
3
3
|
# Every Rust-facing list reads `rust/Cargo.toml`'s `[features]` as its
|
|
4
4
|
# one source, rather than each consumer typing it out by hand.
|
|
5
5
|
GENERATED_DIR = "rust/src/generated".freeze
|
|
6
|
-
RUST_DOMAIN_KINDS = %i[example stress fixture].freeze
|
|
6
|
+
RUST_DOMAIN_KINDS = %i[example stress semantics fixture].freeze
|
|
7
7
|
|
|
8
8
|
RustDomain = Struct.new(:feature, :dir, :kind)
|
|
9
9
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Corpus
|
|
3
|
+
# Where `.world` files live, for the parser parity check. Extended onto `Corpus`.
|
|
4
|
+
module Worlds
|
|
5
|
+
WORLD_GLOBS = %w[lib/**/*.world examples/**/*.world qa/**/*.world spec/fixtures/**/*.world].freeze
|
|
6
|
+
|
|
7
|
+
# Every `.world` file the repo carries.
|
|
8
|
+
#
|
|
9
|
+
# @param root [String] repository root to search under
|
|
10
|
+
# @return [Array<String>] absolute paths, sorted, none under a vendored, `node_modules`,
|
|
11
|
+
# `target` or scratch directory
|
|
12
|
+
def world_files(root: Corpus::ROOT)
|
|
13
|
+
WORLD_GLOBS.flat_map { |glob| Dir.glob(File.join(root, glob)) }.uniq.sort.reject do |path|
|
|
14
|
+
path.delete_prefix("#{root}/").split("/").intersect?(Adapters::EXCLUDED_DIRS)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/hecks/corpus.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require_relative "fuzzing/target_capabilities"
|
|
2
|
+
require_relative "corpus/adapters"
|
|
2
3
|
require_relative "corpus/routes"
|
|
3
4
|
require_relative "corpus/rust"
|
|
4
5
|
require_relative "corpus/sources"
|
|
6
|
+
require_relative "corpus/worlds"
|
|
5
7
|
|
|
6
8
|
module Hecks
|
|
7
9
|
# The corpus: every place in this repo that holds a real domain, named once.
|
|
@@ -36,6 +38,7 @@ module Hecks
|
|
|
36
38
|
deploy: "lib/hecks/deploy/bluebook/*.bluebook",
|
|
37
39
|
site: "lib/hecks/site/bluebook/*.bluebook",
|
|
38
40
|
tickets: "lib/hecks/tickets/bluebook/*.bluebook",
|
|
41
|
+
composer: "lib/hecks/composer/bluebook/*.bluebook",
|
|
39
42
|
tenancy: "lib/hecks/tenancy/bluebook/*.bluebook",
|
|
40
43
|
sme: "lib/hecks/sme/bluebook/*.bluebook",
|
|
41
44
|
fixture: "spec/fixtures/**/*.bluebook"
|
|
@@ -43,8 +46,10 @@ module Hecks
|
|
|
43
46
|
|
|
44
47
|
KINDS = (DIRECTORY_KINDS.keys + FILE_KINDS.keys).freeze
|
|
45
48
|
|
|
49
|
+
extend Adapters
|
|
46
50
|
extend Rust
|
|
47
51
|
extend Sources
|
|
52
|
+
extend Worlds
|
|
48
53
|
|
|
49
54
|
module_function
|
|
50
55
|
|
|
@@ -451,7 +451,7 @@ Hecks.bluebook "Deploy" do
|
|
|
451
451
|
|
|
452
452
|
# The domain's own directory on disk, where `environments/<slug>.world` is written.
|
|
453
453
|
value_object "DirectoryPath" do
|
|
454
|
-
attribute :value, String,
|
|
454
|
+
attribute :value, String, matches: :not_empty
|
|
455
455
|
end
|
|
456
456
|
|
|
457
457
|
value_object "Report" do
|
|
@@ -581,14 +581,14 @@ Hecks.bluebook "Deploy" do
|
|
|
581
581
|
identified_by :run
|
|
582
582
|
|
|
583
583
|
value_object "RunKey" do
|
|
584
|
-
attribute :value, String,
|
|
584
|
+
attribute :value, String, matches: :present
|
|
585
585
|
|
|
586
586
|
invariant("a run is named") { !value.to_s.empty? }
|
|
587
587
|
end
|
|
588
588
|
|
|
589
589
|
# A domain directory, whose `bluebook/` holds the `.world` that declares `deployed_to`.
|
|
590
590
|
value_object "DomainPath" do
|
|
591
|
-
attribute :value, String,
|
|
591
|
+
attribute :value, String, matches: :not_empty
|
|
592
592
|
|
|
593
593
|
invariant("a domain is named by its path") { !value.to_s.empty? }
|
|
594
594
|
end
|
|
@@ -604,7 +604,7 @@ Hecks.bluebook "Deploy" do
|
|
|
604
604
|
|
|
605
605
|
# Where the recipe is written, for a domain that lives in a client's repository.
|
|
606
606
|
value_object "Location" do
|
|
607
|
-
attribute :value, String,
|
|
607
|
+
attribute :value, String, matches: :not_empty
|
|
608
608
|
end
|
|
609
609
|
|
|
610
610
|
# An `environments/<name>.world` overlay of the domain, which must exist.
|
|
@@ -707,14 +707,14 @@ Hecks.bluebook "Deploy" do
|
|
|
707
707
|
identified_by :run
|
|
708
708
|
|
|
709
709
|
value_object "RunKey" do
|
|
710
|
-
attribute :value, String,
|
|
710
|
+
attribute :value, String, matches: :present
|
|
711
711
|
|
|
712
712
|
invariant("a run is named") { !value.to_s.empty? }
|
|
713
713
|
end
|
|
714
714
|
|
|
715
715
|
# A domain directory, whose `bluebook/` holds the `.world` that declares `deployed_to`.
|
|
716
716
|
value_object "DomainPath" do
|
|
717
|
-
attribute :value, String,
|
|
717
|
+
attribute :value, String, matches: :not_empty
|
|
718
718
|
|
|
719
719
|
invariant("a domain is named by its path") { !value.to_s.empty? }
|
|
720
720
|
end
|
|
@@ -722,7 +722,7 @@ Hecks.bluebook "Deploy" do
|
|
|
722
722
|
# A directory the cleared worlds are written to, at their paths below `bluebook/`, instead of
|
|
723
723
|
# over the originals.
|
|
724
724
|
value_object "Location" do
|
|
725
|
-
attribute :value, String,
|
|
725
|
+
attribute :value, String, matches: :not_empty
|
|
726
726
|
end
|
|
727
727
|
|
|
728
728
|
value_object "Report" do
|
|
@@ -813,14 +813,14 @@ Hecks.bluebook "Deploy" do
|
|
|
813
813
|
identified_by :run
|
|
814
814
|
|
|
815
815
|
value_object "RunKey" do
|
|
816
|
-
attribute :value, String,
|
|
816
|
+
attribute :value, String, matches: :present
|
|
817
817
|
|
|
818
818
|
invariant("a run is named") { !value.to_s.empty? }
|
|
819
819
|
end
|
|
820
820
|
|
|
821
821
|
# Makefile paths, comma separated; three generated fixture domains when absent.
|
|
822
822
|
value_object "PathList" do
|
|
823
|
-
attribute :value, String,
|
|
823
|
+
attribute :value, String, matches: :not_empty
|
|
824
824
|
end
|
|
825
825
|
|
|
826
826
|
value_object "Report" do
|
|
@@ -909,7 +909,7 @@ Hecks.bluebook "Deploy" do
|
|
|
909
909
|
identified_by :run
|
|
910
910
|
|
|
911
911
|
value_object "RunKey" do
|
|
912
|
-
attribute :value, String,
|
|
912
|
+
attribute :value, String, matches: :present
|
|
913
913
|
|
|
914
914
|
invariant("a run is named") { !value.to_s.empty? }
|
|
915
915
|
end
|
|
@@ -1020,13 +1020,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1020
1020
|
identified_by :run
|
|
1021
1021
|
|
|
1022
1022
|
value_object "RunKey" do
|
|
1023
|
-
attribute :value, String,
|
|
1023
|
+
attribute :value, String, matches: :present
|
|
1024
1024
|
|
|
1025
1025
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1026
1026
|
end
|
|
1027
1027
|
|
|
1028
1028
|
value_object "Location" do
|
|
1029
|
-
attribute :value, String,
|
|
1029
|
+
attribute :value, String, matches: :not_empty
|
|
1030
1030
|
|
|
1031
1031
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
1032
1032
|
end
|
|
@@ -1159,13 +1159,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1159
1159
|
identified_by :run
|
|
1160
1160
|
|
|
1161
1161
|
value_object "RunKey" do
|
|
1162
|
-
attribute :value, String,
|
|
1162
|
+
attribute :value, String, matches: :present
|
|
1163
1163
|
|
|
1164
1164
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1165
1165
|
end
|
|
1166
1166
|
|
|
1167
1167
|
value_object "Location" do
|
|
1168
|
-
attribute :value, String,
|
|
1168
|
+
attribute :value, String, matches: :not_empty
|
|
1169
1169
|
|
|
1170
1170
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
1171
1171
|
end
|
|
@@ -1187,7 +1187,7 @@ Hecks.bluebook "Deploy" do
|
|
|
1187
1187
|
|
|
1188
1188
|
# A local image reference to push, as the script's LOCAL_IMAGE takes it.
|
|
1189
1189
|
value_object "ImageName" do
|
|
1190
|
-
attribute :value, String,
|
|
1190
|
+
attribute :value, String, matches: :no_whitespace
|
|
1191
1191
|
end
|
|
1192
1192
|
|
|
1193
1193
|
value_object "Switch" do
|
|
@@ -1352,13 +1352,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1352
1352
|
identified_by :run
|
|
1353
1353
|
|
|
1354
1354
|
value_object "RunKey" do
|
|
1355
|
-
attribute :value, String,
|
|
1355
|
+
attribute :value, String, matches: :present
|
|
1356
1356
|
|
|
1357
1357
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1358
1358
|
end
|
|
1359
1359
|
|
|
1360
1360
|
value_object "Location" do
|
|
1361
|
-
attribute :value, String,
|
|
1361
|
+
attribute :value, String, matches: :not_empty
|
|
1362
1362
|
|
|
1363
1363
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
1364
1364
|
end
|
|
@@ -1538,13 +1538,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1538
1538
|
identified_by :run
|
|
1539
1539
|
|
|
1540
1540
|
value_object "RunKey" do
|
|
1541
|
-
attribute :value, String,
|
|
1541
|
+
attribute :value, String, matches: :present
|
|
1542
1542
|
|
|
1543
1543
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1544
1544
|
end
|
|
1545
1545
|
|
|
1546
1546
|
value_object "Location" do
|
|
1547
|
-
attribute :value, String,
|
|
1547
|
+
attribute :value, String, matches: :not_empty
|
|
1548
1548
|
|
|
1549
1549
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
1550
1550
|
end
|
|
@@ -1560,7 +1560,7 @@ Hecks.bluebook "Deploy" do
|
|
|
1560
1560
|
|
|
1561
1561
|
# A Secrets Manager id or ARN; the script reads the password from it, so no value travels here.
|
|
1562
1562
|
value_object "Secret" do
|
|
1563
|
-
attribute :value, String,
|
|
1563
|
+
attribute :value, String, matches: :no_whitespace
|
|
1564
1564
|
end
|
|
1565
1565
|
|
|
1566
1566
|
# A database's name; empty leaves it to the generated script's own default.
|
|
@@ -1826,13 +1826,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1826
1826
|
identified_by :run
|
|
1827
1827
|
|
|
1828
1828
|
value_object "RunKey" do
|
|
1829
|
-
attribute :value, String,
|
|
1829
|
+
attribute :value, String, matches: :present
|
|
1830
1830
|
|
|
1831
1831
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1832
1832
|
end
|
|
1833
1833
|
|
|
1834
1834
|
value_object "Location" do
|
|
1835
|
-
attribute :value, String,
|
|
1835
|
+
attribute :value, String, matches: :not_empty
|
|
1836
1836
|
|
|
1837
1837
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
1838
1838
|
end
|
|
@@ -1846,7 +1846,7 @@ Hecks.bluebook "Deploy" do
|
|
|
1846
1846
|
end
|
|
1847
1847
|
|
|
1848
1848
|
value_object "Secret" do
|
|
1849
|
-
attribute :value, String,
|
|
1849
|
+
attribute :value, String, matches: :no_whitespace
|
|
1850
1850
|
end
|
|
1851
1851
|
|
|
1852
1852
|
# A database's name; empty leaves it to the generated script's own default.
|
|
@@ -1984,13 +1984,13 @@ Hecks.bluebook "Deploy" do
|
|
|
1984
1984
|
identified_by :run
|
|
1985
1985
|
|
|
1986
1986
|
value_object "RunKey" do
|
|
1987
|
-
attribute :value, String,
|
|
1987
|
+
attribute :value, String, matches: :present
|
|
1988
1988
|
|
|
1989
1989
|
invariant("a run is named") { !value.to_s.empty? }
|
|
1990
1990
|
end
|
|
1991
1991
|
|
|
1992
1992
|
value_object "Location" do
|
|
1993
|
-
attribute :value, String,
|
|
1993
|
+
attribute :value, String, matches: :not_empty
|
|
1994
1994
|
|
|
1995
1995
|
invariant("a project, script or file is named by its path") { !value.to_s.empty? }
|
|
1996
1996
|
end
|
|
@@ -2134,13 +2134,13 @@ Hecks.bluebook "Deploy" do
|
|
|
2134
2134
|
identified_by :run
|
|
2135
2135
|
|
|
2136
2136
|
value_object "RunKey" do
|
|
2137
|
-
attribute :value, String,
|
|
2137
|
+
attribute :value, String, matches: :present
|
|
2138
2138
|
|
|
2139
2139
|
invariant("a run is named") { !value.to_s.empty? }
|
|
2140
2140
|
end
|
|
2141
2141
|
|
|
2142
2142
|
value_object "Location" do
|
|
2143
|
-
attribute :value, String,
|
|
2143
|
+
attribute :value, String, matches: :not_empty
|
|
2144
2144
|
|
|
2145
2145
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
2146
2146
|
end
|
|
@@ -2152,7 +2152,7 @@ Hecks.bluebook "Deploy" do
|
|
|
2152
2152
|
|
|
2153
2153
|
# A git branch name. A preview is never of a production branch.
|
|
2154
2154
|
value_object "Branch" do
|
|
2155
|
-
attribute :value, String,
|
|
2155
|
+
attribute :value, String, matches: :no_whitespace
|
|
2156
2156
|
|
|
2157
2157
|
invariant("a preview is never of main or master") { value != "main" && value != "master" }
|
|
2158
2158
|
end
|
|
@@ -2510,13 +2510,13 @@ Hecks.bluebook "Deploy" do
|
|
|
2510
2510
|
identified_by :run
|
|
2511
2511
|
|
|
2512
2512
|
value_object "RunKey" do
|
|
2513
|
-
attribute :value, String,
|
|
2513
|
+
attribute :value, String, matches: :present
|
|
2514
2514
|
|
|
2515
2515
|
invariant("a run is named") { !value.to_s.empty? }
|
|
2516
2516
|
end
|
|
2517
2517
|
|
|
2518
2518
|
value_object "Location" do
|
|
2519
|
-
attribute :value, String,
|
|
2519
|
+
attribute :value, String, matches: :not_empty
|
|
2520
2520
|
|
|
2521
2521
|
invariant("a project or script is named by its path") { !value.to_s.empty? }
|
|
2522
2522
|
end
|
|
@@ -2656,13 +2656,13 @@ Hecks.bluebook "Deploy" do
|
|
|
2656
2656
|
identified_by :run
|
|
2657
2657
|
|
|
2658
2658
|
value_object "RunKey" do
|
|
2659
|
-
attribute :value, String,
|
|
2659
|
+
attribute :value, String, matches: :present
|
|
2660
2660
|
|
|
2661
2661
|
invariant("a run is named") { !value.to_s.empty? }
|
|
2662
2662
|
end
|
|
2663
2663
|
|
|
2664
2664
|
value_object "Location" do
|
|
2665
|
-
attribute :value, String,
|
|
2665
|
+
attribute :value, String, matches: :not_empty
|
|
2666
2666
|
|
|
2667
2667
|
invariant("a template is named by its path") { !value.to_s.empty? }
|
|
2668
2668
|
end
|
|
@@ -2785,14 +2785,14 @@ Hecks.bluebook "Deploy" do
|
|
|
2785
2785
|
identified_by :run
|
|
2786
2786
|
|
|
2787
2787
|
value_object "RunKey" do
|
|
2788
|
-
attribute :value, String,
|
|
2788
|
+
attribute :value, String, matches: :present
|
|
2789
2789
|
|
|
2790
2790
|
invariant("a run is named") { !value.to_s.empty? }
|
|
2791
2791
|
end
|
|
2792
2792
|
|
|
2793
2793
|
# Domain directories, comma separated; every domain of the checkout when absent.
|
|
2794
2794
|
value_object "DomainList" do
|
|
2795
|
-
attribute :value, String,
|
|
2795
|
+
attribute :value, String, matches: :not_empty
|
|
2796
2796
|
end
|
|
2797
2797
|
|
|
2798
2798
|
value_object "Report" do
|