hecks 2.9.0 → 3.0.1
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/exe/hecks +51 -6
- data/lib/hecks/adapters/driven/heki/journal.rb +1 -1
- data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +1 -1
- data/lib/hecks/adapters/driven/memory.rb +16 -3
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +6 -2
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +13 -4
- data/lib/hecks/adapters/driven/prism.rb +41 -8
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +73 -16
- data/lib/hecks/behaviors/expectations.rb +1 -1
- data/lib/hecks/behaviors.rb +1 -1
- data/lib/hecks/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +2 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/aggregate.rb +30 -1
- data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -0
- data/lib/hecks/bluebook/chapter.rb +6 -2
- data/lib/hecks/bluebook/domain_port.rb +36 -5
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +10 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +8 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -1
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +31 -3
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +122 -3
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/query_builder.rb +27 -1
- data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -1
- data/lib/hecks/bluebook/dsl/world_builder.rb +29 -2
- data/lib/hecks/bluebook/expression/canonical_form.rb +1 -1
- data/lib/hecks/bluebook/expression/resolver.rb +3 -2
- data/lib/hecks/bluebook/hexagon.rb +13 -5
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator.rb +9 -4
- data/lib/hecks/bluebook/model_check.rb +23 -0
- data/lib/hecks/bluebook/pattern_subset.rb +38 -0
- data/lib/hecks/bluebook/query.rb +20 -5
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- data/lib/hecks/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +2 -2
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +1 -1
- data/lib/hecks/cli/mcp.rb +3 -3
- data/lib/hecks/cli/model_check.rb +15 -8
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +224 -32
- data/lib/hecks/cli/project_diagrams.rb +4 -3
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +3 -3
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +5 -3
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -5
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +201 -52
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +591 -23
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -4
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +1 -1
- data/lib/hecks/{facade → doors}/handle.rb +2 -2
- data/lib/hecks/{facade → doors}/json_door.rb +4 -4
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +7 -7
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/{facade/surface → doors/ruby_door}/aggregate_door.rb +8 -3
- data/lib/hecks/{facade/surface → doors/ruby_door}/chapter.rb +3 -3
- data/lib/hecks/{facade/surface.rb → doors/ruby_door.rb} +36 -5
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +1 -1
- data/lib/hecks/embryonaut_bluebook.rb +1 -1
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +24 -37
- data/lib/hecks/forms/app.rb +6 -6
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/field_shape.rb +2 -1
- data/lib/hecks/forms/port_argument.rb +1 -1
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +11 -0
- data/lib/hecks/language/bluebook/query.bluebook +7 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +4 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +10 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +20 -0
- data/lib/hecks/mcp_stdio_guard.rb +2 -2
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +8 -5
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +4 -1
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +15 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +32 -15
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +15 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +43 -24
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/state_codec.rb +24 -5
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +1 -1
- data/lib/hecks/projections/deploy/fargate.rb +5 -5
- data/lib/hecks/projections/deploy/lambda.rb +43 -32
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/template.rb +1 -1
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/shared.rb +1 -1
- data/lib/hecks/projections/diagrams.rb +3 -3
- data/lib/hecks/projections/model/deviations.rb +1 -1
- data/lib/hecks/projections/parser_table.rb +4 -4
- data/lib/hecks/projections/reference.rb +2 -3
- data/lib/hecks/projections/rust_vocabulary.rb +1 -1
- data/lib/hecks/projector/cli_projector.rb +106 -37
- data/lib/hecks/projector.rb +1 -1
- data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- data/lib/hecks/release/runner/ci_publisher.rb +2 -2
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +14 -7
- data/lib/hecks/release/runner/npm_publisher.rb +6 -36
- data/lib/hecks/release/runner/preflight.rb +26 -2
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +30 -15
- data/lib/hecks/release/runner.rb +57 -6
- data/lib/hecks/router/namespace_installer.rb +3 -3
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +4 -0
- data/lib/hecks/runtime/dependency_planning.rb +20 -2
- data/lib/hecks/runtime/dispatcher.rb +53 -3
- data/lib/hecks/runtime/interpreting.rb +3 -0
- data/lib/hecks/runtime/loader.rb +65 -12
- data/lib/hecks/runtime/outbox.rb +1 -1
- data/lib/hecks/runtime/policy_interpreter.rb +5 -2
- data/lib/hecks/runtime/port_operation_interpreter.rb +2 -10
- data/lib/hecks/runtime/query_interpreter.rb +77 -0
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/refusal_wording.rb +23 -1
- data/lib/hecks/runtime/registry/verification.rb +163 -4
- data/lib/hecks/runtime/registry.rb +57 -3
- data/lib/hecks/runtime/remote_dispatcher.rb +31 -2
- data/lib/hecks/runtime/value/coercion.rb +23 -135
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +4 -1
- data/lib/hecks/runtime.rb +20 -6
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +16 -16
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +2 -2
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +1 -1
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks.rb +32 -15
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +477 -12
- data/lib/hecks/facade/cli_door.rb +0 -96
- data/lib/hecks/facade/cli_runner.rb +0 -127
- data/lib/hecks/mcp_door_scope.rb +0 -95
|
@@ -282,7 +282,7 @@ module Hecks
|
|
|
282
282
|
end
|
|
283
283
|
|
|
284
284
|
template_yaml = <<~YAML
|
|
285
|
-
# GENERATED by
|
|
285
|
+
# GENERATED by hecks deploy project #{domain} — re-run it to refresh
|
|
286
286
|
# this file rather than hand-editing. Source: #{world_file}'s own
|
|
287
287
|
# deployed_to("AwsLambda") block.
|
|
288
288
|
#
|
|
@@ -338,8 +338,8 @@ module Hecks
|
|
|
338
338
|
# targets, below) via the SAME `aws cloudformation describe-stacks`
|
|
339
339
|
# pattern `mint-era` already used for a bastion, one stack over
|
|
340
340
|
# instead of one sibling stack over. Never a CloudFormation
|
|
341
|
-
# Export/ImportValue -- this codebase uses none anywhere (
|
|
342
|
-
#
|
|
341
|
+
# Export/ImportValue -- this codebase uses none anywhere (hecks
|
|
342
|
+
# deploy project's own header on why: a live shell lookup keeps
|
|
343
343
|
# this stack independently deployable/deletable, never coupled to
|
|
344
344
|
# #{owner_domain_name}'s own stack through CloudFormation itself).
|
|
345
345
|
OwningVpcId:
|
|
@@ -485,13 +485,13 @@ module Hecks
|
|
|
485
485
|
" DB_SECRET_ARN: !Sub \"${#{secret_sub}}\""
|
|
486
486
|
end}
|
|
487
487
|
# `domain_name`, NOT `infra_name` — this names the actual
|
|
488
|
-
# .wasm FILE
|
|
488
|
+
# .wasm FILE `hecks build_wasm` writes (rust/dist/#{domain_name}.wasm,
|
|
489
489
|
# its own target_mod_name convention, a Rust-build-pipeline
|
|
490
490
|
# concern unrelated to AWS resource identity) and what the
|
|
491
491
|
# Makefile below actually bundles into the Lambda package
|
|
492
492
|
# under. Confirmed the hard way: pinning this to infra_name
|
|
493
493
|
# alongside the real AWS-identity fields left it looking for
|
|
494
|
-
# a file
|
|
494
|
+
# a file `hecks build_wasm` never produces.
|
|
495
495
|
HECKS_WASM_PATH: !Sub "/var/task/#{domain_name}.wasm"
|
|
496
496
|
# STATIC, not a deploy-time parameter — HECKS_DOMAIN is this
|
|
497
497
|
# domain's own declared name, known at generation time the
|
|
@@ -636,7 +636,7 @@ module Hecks
|
|
|
636
636
|
PasswordLength: 64
|
|
637
637
|
ExcludePunctuation: true
|
|
638
638
|
|
|
639
|
-
#{webhook_secret_env ?
|
|
639
|
+
#{webhook_secret_env ? <<~WEBHOOKSECRET.rstrip : ""}
|
|
640
640
|
# Auto-generated, never typed or seen — the SAME
|
|
641
641
|
# ManageMasterUserPassword/SessionSecret pattern above, applied to
|
|
642
642
|
# `secret_env`'s own webhook secret instead (deploy_settings' own
|
|
@@ -822,7 +822,7 @@ module Hecks
|
|
|
822
822
|
Outputs:
|
|
823
823
|
FunctionUrl:
|
|
824
824
|
Value: !GetAtt #{logical_id}Url.FunctionUrl#{web_handler_present ? "\n WebFunctionUrl:\n Value: !GetAtt #{web_logical_id}Url.FunctionUrl" : ""}
|
|
825
|
-
# stack_outputs (
|
|
825
|
+
# stack_outputs (hecks deploy project, above the heredocs) is the ONE
|
|
826
826
|
# place these four names live — DatabaseEndpoint/DatabaseSecretArn
|
|
827
827
|
# feed `make mint-era`'s own boot step directly; VpcId/
|
|
828
828
|
# DbSecurityGroupId ALSO feed bastion.yaml's own Parameters (a
|
|
@@ -831,7 +831,7 @@ module Hecks
|
|
|
831
831
|
# network without this main template ever knowing a bastion
|
|
832
832
|
# exists) and the Makefile's own --parameter-overrides. Rename a
|
|
833
833
|
# key in that table and every consumer follows; reference one that
|
|
834
|
-
# doesn't exist there and
|
|
834
|
+
# doesn't exist there and hecks deploy project refuses before
|
|
835
835
|
# writing a single file, instead of a bastion.yaml whose Parameter
|
|
836
836
|
# nothing could ever fill. (`PrivateSubnetId` used to sit here too
|
|
837
837
|
# — dropped, nothing ever consumed it; bastion.yaml mints its own
|
|
@@ -899,7 +899,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
899
899
|
<<~SHAREDMINT.rstrip
|
|
900
900
|
# NOT AUTOMATED YET for a Shared-mode domain — it has no RDS/VPC
|
|
901
901
|
# of its own to stand a temporary bastion next to (bastion.yaml
|
|
902
|
-
# itself isn't even generated here —
|
|
902
|
+
# itself isn't even generated here — hecks deploy project's own
|
|
903
903
|
# comment on why). Minting era 1 for #{infra_name}'s own schema
|
|
904
904
|
# needs a tunnel to #{owner_domain_name}'s ALREADY-EXISTING RDS
|
|
905
905
|
# instance instead -- reuse #{owner_domain_name}'s own deploy
|
|
@@ -948,7 +948,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
948
948
|
else
|
|
949
949
|
<<~OWNMINT.rstrip
|
|
950
950
|
\t@echo "Looking up $(STACK)'s VPC/security group..."
|
|
951
|
-
# stack_outputs/bastion_parameters (
|
|
951
|
+
# stack_outputs/bastion_parameters (hecks deploy project) are the ONE
|
|
952
952
|
# place these OutputKey strings and parameter names live — this eval
|
|
953
953
|
# chain and the --parameter-overrides line just below are both
|
|
954
954
|
# generated from the SAME table template.yaml's Outputs and
|
|
@@ -1067,13 +1067,13 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1067
1067
|
\techo "Tearing down the temporary bastion stack..."; \\
|
|
1068
1068
|
\taws cloudformation delete-stack --stack-name $(BASTION_STACK); \\
|
|
1069
1069
|
\taws cloudformation wait stack-delete-complete --stack-name $(BASTION_STACK); \\
|
|
1070
|
-
\techo "$(BASTION_STACK) deleted. Era 1 should now be held if BOOT_STATUS was 0 — verify with
|
|
1070
|
+
\techo "$(BASTION_STACK) deleted. Era 1 should now be held if BOOT_STATUS was 0 — verify with hecks console or a Postgres query against hecks_eras."; \\
|
|
1071
1071
|
\texit $$BOOT_STATUS
|
|
1072
1072
|
OWNMINT
|
|
1073
1073
|
end
|
|
1074
1074
|
|
|
1075
1075
|
# Shares mint_era_recipe's bastion/tunnel/retry/teardown chain but
|
|
1076
|
-
# runs
|
|
1076
|
+
# runs `hecks ask scaffold_translation` or `hecks ask audit_translation` over it.
|
|
1077
1077
|
#
|
|
1078
1078
|
# Neither script actually reads DATABASE_URL/HECKS_SCHEMA (both call
|
|
1079
1079
|
# `registry.binding_settings`, a lookup against the literal `database
|
|
@@ -1081,7 +1081,8 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1081
1081
|
# recipe would open a real tunnel to production and silently
|
|
1082
1082
|
# scaffold/audit the local dev database instead, reporting success.
|
|
1083
1083
|
# `db_env_blind` refuses unless `ALLOW_LOCAL_DB=1` is set.
|
|
1084
|
-
translation_recipe = lambda do |verb, script, extra_args = "", cwd: "$(ROOT)", run_prefix: "ruby -Ilib", db_env_blind: false
|
|
1084
|
+
translation_recipe = lambda do |verb, script, extra_args = "", cwd: "$(ROOT)", run_prefix: "ruby -Ilib", db_env_blind: false,
|
|
1085
|
+
domain_arg: "$(DOMAIN) "|
|
|
1085
1086
|
if shared
|
|
1086
1087
|
<<~SHAREDTRANSLATION.rstrip
|
|
1087
1088
|
\t@echo "#{verb} isn't automated yet for a Shared-mode domain (database \\"Shared\\") -- see mint-era's own comment in the generated Makefile for the manual path through #{owner_domain_name}'s own tunnel."; \\
|
|
@@ -1130,7 +1131,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1130
1131
|
\t\t\tnc -z localhost 15432 2>/dev/null && break; \\
|
|
1131
1132
|
\t\t\tsleep 1; \\
|
|
1132
1133
|
\t\tdone; \\
|
|
1133
|
-
\t\tcd #{cwd} && DATABASE_URL="postgres://postgres:$$DB_PASS_URLENC@localhost:15432/#{db_name}" HECKS_SCHEMA="#{hecks_schema}" #{run_prefix} #{script} #{cwd == "$(ROOT)" ?
|
|
1134
|
+
\t\tcd #{cwd} && DATABASE_URL="postgres://postgres:$$DB_PASS_URLENC@localhost:15432/#{db_name}" HECKS_SCHEMA="#{hecks_schema}" #{run_prefix} #{script} #{cwd == "$(ROOT)" ? domain_arg : ""}#{extra_args}&& { RUN_STATUS=0; break; }; \\
|
|
1134
1135
|
\t\tRUN_STATUS=$$?; \\
|
|
1135
1136
|
\t\techo "#{verb} attempt $$attempt/5 failed (exit $$RUN_STATUS) -- restarting the tunnel and retrying in 3s..."; \\
|
|
1136
1137
|
\t\tsleep 3; \\
|
|
@@ -1145,12 +1146,22 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1145
1146
|
end
|
|
1146
1147
|
end
|
|
1147
1148
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1149
|
+
# `hecks ask` answers the scaffold as text, and refuses (exit 1) where the script aborted.
|
|
1150
|
+
scaffold_translation_recipe = translation_recipe.call(
|
|
1151
|
+
"scaffold-translation", "exe/hecks ask scaffold_translation", db_env_blind: true,
|
|
1152
|
+
run_prefix: "HECKS_ENVIRONMENT=memory ruby", domain_arg: "domain=$(DOMAIN) "
|
|
1153
|
+
)
|
|
1154
|
+
# A refused audit is a refused query: `hecks ask` exits 1, so the target fails too.
|
|
1155
|
+
translation_audit_recipe = translation_recipe.call(
|
|
1156
|
+
"translation-audit", "exe/hecks ask audit_translation", db_env_blind: true,
|
|
1157
|
+
run_prefix: "HECKS_ENVIRONMENT=memory ruby", domain_arg: "domain=$(DOMAIN) "
|
|
1158
|
+
)
|
|
1150
1159
|
|
|
1151
1160
|
# Same chain, running an app-owned one-time migration script instead
|
|
1152
|
-
# of a hecks bin/
|
|
1153
|
-
#
|
|
1161
|
+
# of a hecks tool. `bin/migrate_console_settings` belongs to the domain's own
|
|
1162
|
+
# application, not to hecks, so it stays a `bin/` path when hecks drops its own.
|
|
1163
|
+
# Harmless when the domain has none: `bundle exec ruby` on a missing file just fails
|
|
1164
|
+
# loudly.
|
|
1154
1165
|
migrate_console_settings_recipe = translation_recipe.call(
|
|
1155
1166
|
"migrate-console-settings", "bin/migrate_console_settings", "",
|
|
1156
1167
|
cwd: "$(DOMAIN)", run_prefix: "bundle exec ruby"
|
|
@@ -1354,7 +1365,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1354
1365
|
).map { |l| "\t#{l}" }.join("\n")
|
|
1355
1366
|
|
|
1356
1367
|
makefile_content = <<~MAKE
|
|
1357
|
-
# GENERATED by
|
|
1368
|
+
# GENERATED by hecks deploy project #{domain} — re-run it to refresh
|
|
1358
1369
|
# this file rather than hand-editing.
|
|
1359
1370
|
#
|
|
1360
1371
|
# `sam build` invokes the build-<LogicalId> target below (SAM's own
|
|
@@ -1365,7 +1376,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1365
1376
|
# `brew install cargo-lambda`.
|
|
1366
1377
|
|
|
1367
1378
|
HOST_DIR := #{File.join(root, "rust", "host")}
|
|
1368
|
-
# `domain_name`, matching
|
|
1379
|
+
# `domain_name`, matching `hecks build_wasm`'s own target_mod_name
|
|
1369
1380
|
# (a Rust-build-pipeline naming convention, not AWS resource
|
|
1370
1381
|
# identity — see HECKS_WASM_PATH's own comment above).
|
|
1371
1382
|
WASM := #{File.join(root, "rust", "dist", "#{domain_name}.wasm")}
|
|
@@ -1380,13 +1391,13 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1380
1391
|
# start of a work session silently kept getting deployed through
|
|
1381
1392
|
# every later kernel change (a real, live bug: this cost a stale
|
|
1382
1393
|
# deploy against a wasm that predated the kernel's own "mutations"
|
|
1383
|
-
# field). `
|
|
1394
|
+
# field). `hecks build_wasm` recompiles fast enough that "always
|
|
1384
1395
|
# rebuild" is the safe default, matching rust/host's own bootstrap
|
|
1385
1396
|
# build just below, which was never guarded this way to begin with.
|
|
1386
|
-
\tcd #{root} &&
|
|
1397
|
+
\tcd #{root} && HECKS_ENVIRONMENT=memory ruby exe/hecks build_wasm domain=#{domain} --wait
|
|
1387
1398
|
\t@rustup target list --installed 2>/dev/null | grep -qx aarch64-unknown-linux-gnu || rustup target add aarch64-unknown-linux-gnu
|
|
1388
1399
|
# `rustup run stable`, not a bare `cargo lambda` — same reasoning
|
|
1389
|
-
#
|
|
1400
|
+
# `hecks build_wasm`'s own Makefile-equivalent line holds itself to: a
|
|
1390
1401
|
# `cargo`/`rustc` earlier on PATH than rustup's own shims (Homebrew
|
|
1391
1402
|
# installs one; common on this kind of machine) is a DIFFERENT
|
|
1392
1403
|
# toolchain that never saw `rustup target add`, and fails with
|
|
@@ -1452,26 +1463,26 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1452
1463
|
# `make verify-parity-#{logical_id}` — closes the exact gap the
|
|
1453
1464
|
# equivalence-gap plan's own Phase 8 named: parity was checked ONLY
|
|
1454
1465
|
# against CI's fixed test corpus, completely decoupled from what a
|
|
1455
|
-
# real `sam deploy` actually ships — `
|
|
1466
|
+
# real `sam deploy` actually ships — `hecks check_conformance` (the
|
|
1456
1467
|
# differential harness, docs/decisions/0010-ruby-is-the-reference-
|
|
1457
1468
|
# implementation.md) had never once been run against a specific
|
|
1458
1469
|
# compiled deploy artifact. Runs it here, for real, against
|
|
1459
1470
|
# $(WASM) -- the EXACT file `build-#{logical_id}` (above) just built
|
|
1460
1471
|
# and `deploy:` (below) is about to ship -- not a corpus-wide `cargo
|
|
1461
|
-
# build`'s own separate binary. `
|
|
1472
|
+
# build`'s own separate binary. `hecks check_conformance --wait` exits non-zero
|
|
1462
1473
|
# on any mismatch, which this target lets propagate uncaught: a real
|
|
1463
1474
|
# divergence between THIS artifact and Ruby's own reading of the
|
|
1464
1475
|
# identical source blocks `make deploy` before `sam deploy` ever
|
|
1465
1476
|
# runs, the same way a failing build already would.
|
|
1466
1477
|
#
|
|
1467
1478
|
# `spec/corpus/#{domain_name}.json` is this domain's OWN pinned
|
|
1468
|
-
# fuzzer-replay script (the same shape `
|
|
1479
|
+
# fuzzer-replay script (the same shape `hecks fuzz`/`hecks run` already
|
|
1469
1480
|
# use) -- if a domain doesn't have one yet, this warns LOUDLY and
|
|
1470
1481
|
# continues rather than either silently skipping (this project's own
|
|
1471
1482
|
# standing rule against a silent gap reading as full coverage) or
|
|
1472
1483
|
# blocking every deploy of a domain nobody has written one for yet.
|
|
1473
1484
|
#
|
|
1474
|
-
# SECOND HALF, BELOW — `
|
|
1485
|
+
# SECOND HALF, BELOW — `hecks fuzz_conformance`, ADR 0037's own fuzz
|
|
1475
1486
|
# bridge pointed at this exact $(WASM). A pinned script only proves
|
|
1476
1487
|
# "matches Ruby on the cases we thought to write down" (ADR 0039's own
|
|
1477
1488
|
# honest framing); the fuzz bridge is what actually FOUND Findings 1-6.
|
|
@@ -1485,12 +1496,12 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1485
1496
|
.PHONY: verify-parity-#{logical_id}
|
|
1486
1497
|
verify-parity-#{logical_id}:
|
|
1487
1498
|
\t@if [ -f #{root}/spec/corpus/#{domain_name}.json ]; then \\
|
|
1488
|
-
\t\tcd #{root} &&
|
|
1499
|
+
\t\tcd #{root} && HECKS_ENVIRONMENT=memory ruby exe/hecks check_conformance domain=#{domain} script=spec/corpus/#{domain_name}.json artifact=$(WASM) --wait; \\
|
|
1489
1500
|
\telse \\
|
|
1490
|
-
\t\techo "verify-parity-#{logical_id}: no spec/corpus/#{domain_name}.json -- SKIPPING the pre-deploy Ruby/Rust parity check, nothing to compare $(WASM) against. Write one (
|
|
1501
|
+
\t\techo "verify-parity-#{logical_id}: no spec/corpus/#{domain_name}.json -- SKIPPING the pre-deploy Ruby/Rust parity check, nothing to compare $(WASM) against. Write one (hecks fuzz/hecks run's own script shape) before this domain's next deploy."; \\
|
|
1491
1502
|
\tfi
|
|
1492
1503
|
\t@echo "verify-parity-#{logical_id}: fuzzing $(WASM) against generated sequences (ADR 0037's bridge, WARN-ONLY -- see this target's own comment)..."
|
|
1493
|
-
\t-@cd #{root} &&
|
|
1504
|
+
\t-@cd #{root} && HECKS_ENVIRONMENT=memory ruby exe/hecks fuzz_conformance domain=#{domain} artifact=$(WASM) --wait
|
|
1494
1505
|
|
|
1495
1506
|
# `make mint-era` — takes #{stack_name}'s RDS instance from freshly
|
|
1496
1507
|
# created to "era 1 minted, ready for HECKS_DOMAIN/HECKS_ERA to
|
|
@@ -1713,7 +1724,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1713
1724
|
# safe either way, since mint-era's own quiet-reboot path is a
|
|
1714
1725
|
# no-op the moment nothing has actually changed.
|
|
1715
1726
|
#
|
|
1716
|
-
# See predeploy_bridge_shell's own comment (
|
|
1727
|
+
# See predeploy_bridge_shell's own comment (hecks deploy project,
|
|
1717
1728
|
# above, right before deploy_recipe_lines) for why this branches
|
|
1718
1729
|
# on google_oauth_present at all -- the short version: adding
|
|
1719
1730
|
# Google OAuth to an EXISTING stack would otherwise deadlock this
|
|
@@ -1729,7 +1740,7 @@ bastion_yaml = shared ? nil : Shared.bastion_yaml(
|
|
|
1729
1740
|
# Everything `sam deploy --guided` would ask interactively is already
|
|
1730
1741
|
# known from the domain's own `deployed_to("AwsLambda")` block.
|
|
1731
1742
|
samconfig_toml = <<~TOML
|
|
1732
|
-
# GENERATED by
|
|
1743
|
+
# GENERATED by hecks deploy project #{domain} — re-run it to refresh
|
|
1733
1744
|
# this file rather than hand-editing.
|
|
1734
1745
|
version = 0.1
|
|
1735
1746
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# GENERATED by
|
|
2
|
+
# GENERATED by hecks deploy project - re-run it to refresh this file rather than
|
|
3
3
|
# hand-editing. Source: the `preview` block of the domain's deployed_to("AwsFargate").
|
|
4
4
|
#
|
|
5
5
|
# Feature-branch previews of <%= s.infra_name %>: one isolated stack per git branch,
|
|
@@ -28,7 +28,7 @@ module Hecks
|
|
|
28
28
|
|
|
29
29
|
def header(settings)
|
|
30
30
|
<<~YAML.chomp
|
|
31
|
-
# GENERATED by
|
|
31
|
+
# GENERATED by hecks deploy project - re-run it to refresh this file rather than
|
|
32
32
|
# hand-editing. Source: the `preview` block of the domain's deployed_to("AwsFargate").
|
|
33
33
|
#
|
|
34
34
|
# One stack per git branch, driven by preview.sh. A separate template from the main
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# GENERATED by
|
|
2
|
+
# GENERATED by hecks deploy project -- re-run it to refresh this file rather
|
|
3
3
|
# than hand-editing. Settings come from the domain's deployed_to("AwsFargate")
|
|
4
4
|
# block; see Hecks::Projections::Deploy::Scripts for each key.
|
|
5
5
|
#
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
# The id is what the host reports at GET /version, the same id the era mint
|
|
14
14
|
# prints. Compare a live host with this file:
|
|
15
15
|
#
|
|
16
|
-
#
|
|
16
|
+
# hecks check_era host=https://host.example expected=expected-era --wait
|
|
17
17
|
# make check-era URL=https://host.example
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GENERATED by
|
|
1
|
+
# GENERATED by hecks deploy project -- re-run it to refresh this file rather
|
|
2
2
|
# than hand-editing. Included by the Makefile beside it; settings come from the
|
|
3
3
|
# domain's deployed_to("AwsFargate") block (see
|
|
4
4
|
# Hecks::Projections::Deploy::Scripts for each key).
|
|
@@ -24,7 +24,7 @@ build: hecks-release
|
|
|
24
24
|
# Fetches the pinned release's tag into HECKS_ROOT unless it is already there,
|
|
25
25
|
# and refuses a checkout that is not exactly that tag.
|
|
26
26
|
hecks-release:
|
|
27
|
-
@if [ -f "$(HECKS_ROOT)/
|
|
27
|
+
@if [ -f "$(HECKS_ROOT)/exe/hecks" ]; then \
|
|
28
28
|
echo "hecks v$(HECKS_VERSION) is already at $(HECKS_ROOT)"; \
|
|
29
29
|
else \
|
|
30
30
|
echo "Fetching hecks v$(HECKS_VERSION) from $(HECKS_SOURCE) into $(HECKS_ROOT)..."; \
|
|
@@ -51,4 +51,4 @@ smoke-after-deploy:
|
|
|
51
51
|
# Compares the era a live host reports at GET /version with expected-era.
|
|
52
52
|
check-era:
|
|
53
53
|
@test -n "$(URL)" || { echo "usage: make check-era URL=https://host.example"; exit 1; }
|
|
54
|
-
ruby "$(HECKS_ROOT)/
|
|
54
|
+
HECKS_ENVIRONMENT=memory ruby "$(HECKS_ROOT)/exe/hecks" check_era host="$(URL)" expected=expected-era --wait
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# GENERATED by
|
|
2
|
+
# GENERATED by hecks deploy project -- re-run it to refresh this file rather
|
|
3
3
|
# than hand-editing. Settings come from the domain's deployed_to("AwsFargate")
|
|
4
4
|
# block; see Hecks::Projections::Deploy::Scripts for each key.
|
|
5
5
|
#
|
|
@@ -390,7 +390,7 @@ module Hecks
|
|
|
390
390
|
# @return [String] the rendered CloudFormation template
|
|
391
391
|
def bastion_yaml(domain:, infra_name:, stack_name:, db_id:, google_oauth_present:, bastion_parameters:)
|
|
392
392
|
<<~YAML
|
|
393
|
-
# GENERATED by
|
|
393
|
+
# GENERATED by hecks deploy project #{domain} — re-run it to refresh
|
|
394
394
|
# this file rather than hand-editing. Deployed and destroyed by
|
|
395
395
|
# `make mint-era` (this directory's own Makefile) — never left
|
|
396
396
|
# running: it exists only long enough for one Ruby boot to reach
|
|
@@ -70,12 +70,12 @@ module Hecks
|
|
|
70
70
|
|
|
71
71
|
def holders_with_lifecycle(bluebook) = holders(bluebook).select(&:lifecycle)
|
|
72
72
|
|
|
73
|
-
# `chapter_name` drives the re-run hint: `
|
|
73
|
+
# `chapter_name` drives the re-run hint: `hecks project_diagrams` takes a chapter
|
|
74
74
|
# name, not the subject's.
|
|
75
75
|
def header(chapter_name, subject)
|
|
76
76
|
<<~HEADER
|
|
77
|
-
%% GENERATED by
|
|
78
|
-
%% Re-run `
|
|
77
|
+
%% GENERATED by hecks project_diagrams from #{subject} — DO NOT EDIT BY HAND.
|
|
78
|
+
%% Re-run `hecks project_diagrams <domain-path> #{chapter_name}` after any change.
|
|
79
79
|
HEADER
|
|
80
80
|
end
|
|
81
81
|
|
|
@@ -48,7 +48,7 @@ module Hecks
|
|
|
48
48
|
# Fields emitted by `to_h`'s own merge rather than `emits_ir`, for constructs
|
|
49
49
|
# whose shape is not fixed.
|
|
50
50
|
DYNAMIC_TAIL = {
|
|
51
|
-
"Query" => %i[options],
|
|
51
|
+
"Query" => %i[options returns],
|
|
52
52
|
"ReadModel" => %i[options group_by aggregate_heads count median_field sum_field avg_field
|
|
53
53
|
min_field max_field percentile_field percentile_at any_field all_field]
|
|
54
54
|
}.freeze
|
|
@@ -13,7 +13,7 @@ module Hecks
|
|
|
13
13
|
# Projects the Rust parser's keyword and closed-set tables for one chapter.
|
|
14
14
|
#
|
|
15
15
|
# @param bluebook [Bluebook::Chapter] the chapter to project; the language's own
|
|
16
|
-
# for the ordinary `
|
|
16
|
+
# for the ordinary `hecks project_parser_table` run
|
|
17
17
|
# @param options [Hash{Symbol => Object}] ignored; present to satisfy the
|
|
18
18
|
# `Projector::Target` calling convention
|
|
19
19
|
# @return [String] the rendered Rust source
|
|
@@ -98,14 +98,14 @@ module Hecks
|
|
|
98
98
|
arguments = table[:arguments]
|
|
99
99
|
|
|
100
100
|
<<~RUST
|
|
101
|
-
// GENERATED by
|
|
101
|
+
// GENERATED by hecks project_parser_table from
|
|
102
102
|
// aggregate-local syntax tables under lib/hecks/language/ — DO NOT EDIT BY HAND.
|
|
103
103
|
//
|
|
104
|
-
// Re-run `
|
|
104
|
+
// Re-run `hecks project_parser_table` after any syntax-table change.
|
|
105
105
|
// spec/parser_table_spec.rb regenerates this into memory and fails the
|
|
106
106
|
// normal `bundle exec rspec` suite the moment this file drifts from what
|
|
107
107
|
// the language currently declares — see that spec and
|
|
108
|
-
//
|
|
108
|
+
// hecks project_parser_table's own header for why this file is never
|
|
109
109
|
// hand-edited.
|
|
110
110
|
|
|
111
111
|
#[derive(Debug, Clone, Copy)]
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
require_relative "../projector"
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# packaged gem leaves it out (ADR 0066).
|
|
4
|
+
# `Doc::Reference` reads the committed pages under `docs/`, which only a
|
|
5
|
+
# checkout has, so it loads on first use.
|
|
7
6
|
module Doc
|
|
8
7
|
autoload :Reference, File.expand_path("../doc/reference", __dir__)
|
|
9
8
|
end
|
|
@@ -14,7 +14,7 @@ module Hecks
|
|
|
14
14
|
|
|
15
15
|
projects_as :rust_vocabulary, declares: "Vocabulary", emits: :files
|
|
16
16
|
|
|
17
|
-
GENERATOR = "
|
|
17
|
+
GENERATOR = "hecks project_rust_vocabulary".freeze
|
|
18
18
|
SOURCE = "lib/hecks/language/bluebook/vocabulary.bluebook".freeze
|
|
19
19
|
|
|
20
20
|
# Table name => enum name, variant-naming fields, file stem and kind.
|
|
@@ -3,21 +3,21 @@ require_relative "../naming"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projector
|
|
5
5
|
# Projects a bluebook as its own command-line surface: the verb tree, argument spec
|
|
6
|
-
# and usage text. Nothing executes here; the generic runner (`
|
|
6
|
+
# and usage text. Nothing executes here; the generic runner (`hecks run`) parses against it.
|
|
7
7
|
#
|
|
8
8
|
# Argument types come from the declared field types, never from guessing at the
|
|
9
9
|
# string: `sequence.value=99` must become 99, and a version "99" must stay a String.
|
|
10
10
|
module CliProjector
|
|
11
11
|
module_function
|
|
12
12
|
|
|
13
|
-
# Projects the verb and question tables and the usage text.
|
|
14
|
-
#
|
|
15
|
-
# Commands and queries are separate namespaces because a chapter may declare both
|
|
16
|
-
# under one name; questions are asked with `ask`.
|
|
13
|
+
# Projects the verb and question tables and the usage text. Commands and queries are
|
|
14
|
+
# separate namespaces (a chapter may declare both under one name); ask a query with `ask`.
|
|
17
15
|
#
|
|
18
16
|
# @param bluebook [Bluebook::Chapter] the booted domain to project
|
|
19
|
-
# @param options [Hash{Symbol => Object}] `:program` (default `"
|
|
20
|
-
# text; `:verb` and `:ask` select one verb's `--help` text
|
|
17
|
+
# @param options [Hash{Symbol => Object}] `:program` (default `"hecks run"`) for the usage
|
|
18
|
+
# text; `:verb` and `:ask` select one verb's `--help` text; `:names` maps a launcher
|
|
19
|
+
# name to the command it stands for (`{ "mcp" => "serve_mcp" }`); `:mint_run_keys` makes a
|
|
20
|
+
# creating verb's `run` key optional, since the launcher mints it
|
|
21
21
|
# @return [Hash{Symbol => Object}] `:verbs`, `:questions`, `:names` (alias tables) and
|
|
22
22
|
# `:usage` (pre-rendered help text)
|
|
23
23
|
# @raise [Bluebook::DSL::Malformed] if two verbs project to the same command-line name
|
|
@@ -25,24 +25,7 @@ module Hecks
|
|
|
25
25
|
verbs = {}
|
|
26
26
|
questions = {}
|
|
27
27
|
|
|
28
|
-
bluebook.aggregates.each
|
|
29
|
-
aggregate.commands.each { |c| claim(verbs, name_for(aggregate, c), command_spec(bluebook, aggregate, nil, c)) }
|
|
30
|
-
aggregate.queries.each { |q| claim(questions, name_for(aggregate, q), query_spec(bluebook, aggregate, nil, q)) }
|
|
31
|
-
|
|
32
|
-
aggregate.entities.each do |entity|
|
|
33
|
-
entity.commands.each do |c|
|
|
34
|
-
claim(verbs, name_for(aggregate, c, entity), command_spec(bluebook, aggregate, entity, c))
|
|
35
|
-
end
|
|
36
|
-
entity.queries.each do |q|
|
|
37
|
-
claim(questions, name_for(aggregate, q, entity), query_spec(bluebook, aggregate, entity, q))
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Port operations dispatch by the same name as a command, so they are verbs too.
|
|
42
|
-
aggregate.ports.each do |port|
|
|
43
|
-
port.operations.each { |o| claim(verbs, name_for(aggregate, o), port_spec(bluebook, aggregate, port, o)) }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
28
|
+
bluebook.aggregates.each { |aggregate| claim_aggregate(verbs, questions, bluebook, aggregate) }
|
|
46
29
|
|
|
47
30
|
# A report belongs to the chapter, not an aggregate, so it is addressed
|
|
48
31
|
# `Chapter.Report` (one dot) where a query is `Chapter::Aggregate.Query`.
|
|
@@ -50,15 +33,42 @@ module Hecks
|
|
|
50
33
|
claim(questions, Naming.snake(model.hecks_name), report_spec(bluebook, model))
|
|
51
34
|
end
|
|
52
35
|
|
|
36
|
+
mint_run_keys(verbs) if options[:mint_run_keys]
|
|
37
|
+
|
|
53
38
|
# The display name is the shortest unambiguous one; both spellings are accepted.
|
|
54
|
-
|
|
55
|
-
shorten(questions)
|
|
39
|
+
display_names([verbs, questions], options[:names])
|
|
56
40
|
|
|
57
41
|
{ verbs: verbs, questions: questions,
|
|
58
42
|
names: { command: aliases(verbs), question: aliases(questions) },
|
|
59
43
|
usage: usage(bluebook, verbs, questions, options) }
|
|
60
44
|
end
|
|
61
45
|
|
|
46
|
+
# Claims the verbs and questions of one aggregate and its entities and ports.
|
|
47
|
+
#
|
|
48
|
+
# @param verbs [Hash{String => Hash}] the verb map, mutated in place
|
|
49
|
+
# @param questions [Hash{String => Hash}] the question map, mutated in place
|
|
50
|
+
# @param bluebook [Bluebook::Chapter] the booted domain
|
|
51
|
+
# @param aggregate [Bluebook::Aggregate] the aggregate to claim
|
|
52
|
+
# @return [void]
|
|
53
|
+
def claim_aggregate(verbs, questions, bluebook, aggregate)
|
|
54
|
+
aggregate.commands.each { |c| claim(verbs, name_for(aggregate, c), command_spec(bluebook, aggregate, nil, c)) }
|
|
55
|
+
aggregate.queries.each { |q| claim(questions, name_for(aggregate, q), query_spec(bluebook, aggregate, nil, q)) }
|
|
56
|
+
|
|
57
|
+
aggregate.entities.each do |entity|
|
|
58
|
+
entity.commands.each do |c|
|
|
59
|
+
claim(verbs, name_for(aggregate, c, entity), command_spec(bluebook, aggregate, entity, c))
|
|
60
|
+
end
|
|
61
|
+
entity.queries.each do |q|
|
|
62
|
+
claim(questions, name_for(aggregate, q, entity), query_spec(bluebook, aggregate, entity, q))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Port operations dispatch by the same name as a command, so they are verbs too.
|
|
67
|
+
aggregate.ports.each do |port|
|
|
68
|
+
port.operations.each { |o| claim(verbs, name_for(aggregate, o), port_spec(bluebook, aggregate, port, o)) }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
62
72
|
# Sets `:short` on each spec: the last segment when exactly one verb ends in it,
|
|
63
73
|
# else the full name (two aggregates both declaring `Close` keep both spellings).
|
|
64
74
|
#
|
|
@@ -72,11 +82,62 @@ module Hecks
|
|
|
72
82
|
end
|
|
73
83
|
end
|
|
74
84
|
|
|
75
|
-
#
|
|
85
|
+
# Marks the `run` key of each creating verb `minted`: optional, and never filled by a bare
|
|
86
|
+
# word, since the launcher makes one when it is left out.
|
|
87
|
+
def mint_run_keys(verbs)
|
|
88
|
+
verbs.each_value do |spec|
|
|
89
|
+
next unless spec[:creates]
|
|
90
|
+
|
|
91
|
+
spec[:arguments] = spec[:arguments].map do |argument|
|
|
92
|
+
next argument unless argument[:path] == "run.value"
|
|
93
|
+
|
|
94
|
+
argument.merge(required: false, minted: true, note: "minted when omitted")
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Sets the display name of every spec in each map: shortened, then renamed by `names`.
|
|
100
|
+
#
|
|
101
|
+
# @param maps [Array<Hash{String => Hash}>] the verb and question maps, mutated in place
|
|
102
|
+
# @param names [Hash, nil] the chapter's launcher names
|
|
103
|
+
# @return [void]
|
|
104
|
+
def display_names(maps, names)
|
|
105
|
+
maps.each do |specs|
|
|
106
|
+
shorten(specs)
|
|
107
|
+
rename(specs, names)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Gives a command the launcher name a chapter's `names` table assigns it.
|
|
112
|
+
#
|
|
113
|
+
# The alias replaces the short name in help, so it is listed once; the spelling it
|
|
114
|
+
# replaced keeps working (`:short_was`, read by `aliases`). A table entry naming no
|
|
115
|
+
# command in `specs` belongs to the other namespace and is skipped.
|
|
116
|
+
#
|
|
117
|
+
# @param specs [Hash{String => Hash}] the verb or question map, mutated in place
|
|
118
|
+
# @param names [Hash{String, Symbol => String, Symbol}, nil] launcher name to command name
|
|
119
|
+
# @return [void]
|
|
120
|
+
# @raise [Bluebook::DSL::Malformed] if a launcher name is already another command's name
|
|
121
|
+
def rename(specs, names)
|
|
122
|
+
Hash(names).each do |launcher_name, command|
|
|
123
|
+
found = specs.find { |key, spec| [key, spec[:short]].include?(command.to_s) }
|
|
124
|
+
next unless found
|
|
125
|
+
|
|
126
|
+
taken = specs.values.any? { |spec| spec[:short] == launcher_name.to_s }
|
|
127
|
+
raise Bluebook::DSL::Malformed, "launcher name #{launcher_name.to_s.inspect} is already a command" if taken
|
|
128
|
+
|
|
129
|
+
found.last[:short_was] = found.last[:short]
|
|
130
|
+
found.last[:short] = launcher_name.to_s
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Maps every accepted spelling (full name, `:short` and a renamed command's old short
|
|
135
|
+
# name) to the full name.
|
|
76
136
|
def aliases(specs)
|
|
77
137
|
specs.each_with_object({}) do |(name, spec), map|
|
|
78
138
|
map[name] = name
|
|
79
139
|
map[spec[:short]] = name
|
|
140
|
+
map[spec[:short_was]] = name if spec[:short_was]
|
|
80
141
|
end
|
|
81
142
|
end
|
|
82
143
|
|
|
@@ -148,7 +209,8 @@ module Hecks
|
|
|
148
209
|
creates: command.creates?,
|
|
149
210
|
receiver: receiver, legacy_receiver: (receiver == :aggregate ? :id : nil),
|
|
150
211
|
legacy_arguments: legacy_arguments,
|
|
151
|
-
refusals: refusals(command, holder),
|
|
212
|
+
refusals: refusals(command, holder), requirements: requirements(command),
|
|
213
|
+
arguments: arguments }
|
|
152
214
|
end
|
|
153
215
|
|
|
154
216
|
# A port operation reads as a verb but reports as a boundary: it creates no
|
|
@@ -202,7 +264,7 @@ module Hecks
|
|
|
202
264
|
end
|
|
203
265
|
|
|
204
266
|
{ verb: fqn(bluebook, aggregate, query, entity), kind: :query,
|
|
205
|
-
summary: query.description, arguments: arguments }
|
|
267
|
+
summary: query.description, arguments: arguments, returns: query.returns }
|
|
206
268
|
end
|
|
207
269
|
|
|
208
270
|
# Flattens an attribute into one option per leaf field. A value object becomes
|
|
@@ -243,8 +305,11 @@ module Hecks
|
|
|
243
305
|
note: "id of a #{attribute.type.target_name}" }
|
|
244
306
|
end
|
|
245
307
|
|
|
308
|
+
# A `list_of` scalar carries `list: true, words: true`: the launcher reads a comma-separated
|
|
309
|
+
# value or a repeated name as the list's elements, since the runtime refuses a lone scalar.
|
|
246
310
|
def scalar_option(path, field, optional, enum: [])
|
|
247
311
|
option = { path: path, type: field.type.to_s, required: !optional }
|
|
312
|
+
option.merge!(list: true, words: true, note: "list: comma-separated or repeated") if field.list?
|
|
248
313
|
option[:enum] = enum unless enum.empty?
|
|
249
314
|
option[:pattern] = field.pattern if field.respond_to?(:pattern) && field.pattern
|
|
250
315
|
option[:default] = field.default if field.respond_to?(:default) && !field.default.nil?
|
|
@@ -270,8 +335,8 @@ module Hecks
|
|
|
270
335
|
nil
|
|
271
336
|
end
|
|
272
337
|
|
|
273
|
-
#
|
|
274
|
-
# mismatch
|
|
338
|
+
# The conditions that refuse the verb when they hold, in the chapter's own words: a
|
|
339
|
+
# lifecycle state mismatch and a missing referenced record per `reference_to`.
|
|
275
340
|
def refusals(command, holder)
|
|
276
341
|
out = []
|
|
277
342
|
lifecycle = holder.lifecycle
|
|
@@ -280,13 +345,17 @@ module Hecks
|
|
|
280
345
|
end.flatten.uniq
|
|
281
346
|
out << "#{lifecycle.field} is not #{froms.join(' or ')}" if froms && !froms.empty?
|
|
282
347
|
out += command.attributes.select(&:reference?).map { |r| "no #{r.type.target_name} has that #{r.name}" }
|
|
283
|
-
out
|
|
348
|
+
out
|
|
284
349
|
end
|
|
285
350
|
|
|
351
|
+
# The conditions the verb needs: each `given` states what must hold, so the verb is
|
|
352
|
+
# refused unless it does.
|
|
353
|
+
def requirements(command) = command.givens.map(&:description)
|
|
354
|
+
|
|
286
355
|
# Renders the full verb/question table, or one verb's `--help` text when
|
|
287
356
|
# `options[:verb]` names one.
|
|
288
357
|
def usage(bluebook, verbs, questions, options)
|
|
289
|
-
program = options[:program] || "
|
|
358
|
+
program = options[:program] || "hecks run"
|
|
290
359
|
only = options[:verb]
|
|
291
360
|
|
|
292
361
|
# `options[:ask]` picks the namespace when both hold the name; without it a
|
|
@@ -366,9 +435,9 @@ module Hecks
|
|
|
366
435
|
end
|
|
367
436
|
|
|
368
437
|
def verb_help_refusal_lines(spec)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
438
|
+
[["refused when:", spec[:refusals]], ["refused unless:", spec[:requirements]]].flat_map do |heading, items|
|
|
439
|
+
Array(items).empty? ? [] : [heading, *items.map { |item| " #{item}" }, ""]
|
|
440
|
+
end
|
|
372
441
|
end
|
|
373
442
|
end
|
|
374
443
|
end
|
data/lib/hecks/projector.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Hecks
|
|
|
6
6
|
#
|
|
7
7
|
# A projection is inert and derived from a chapter's declaration. An export
|
|
8
8
|
# (rust crate, WASM, CloudFormation) also needs `.world` bindings and declares
|
|
9
|
-
# `needs_world: true`. State projections (`
|
|
9
|
+
# `needs_world: true`. State projections (`hecks project_expression_tables`) and
|
|
10
10
|
# `Ports::Projection` read-model catch-up are different things and not registered.
|
|
11
11
|
module Projector
|
|
12
12
|
class UnknownProjector < StandardError; end
|