hecks 2.8.0 → 3.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/exe/hecks +50 -7
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +32 -100
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +149 -136
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +48 -38
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- 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/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +16 -50
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +49 -67
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +39 -661
- data/lib/hecks/bluebook/hexagon.rb +18 -33
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +87 -352
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +122 -596
- data/lib/hecks/bluebook/pattern_subset.rb +49 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +27 -51
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +9 -99
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- 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 +5 -23
- 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 +4 -6
- data/lib/hecks/cli/mcp.rb +5 -6
- data/lib/hecks/cli/model_check.rb +24 -88
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +223 -64
- data/lib/hecks/cli/project_diagrams.rb +4 -10
- 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 +15 -61
- 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 +7 -19
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -6
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +216 -73
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
- 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 +14 -34
- data/lib/hecks/doors/handle.rb +206 -0
- data/lib/hecks/doors/json_door.rb +132 -0
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
- data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
- data/lib/hecks/doors/ruby_door.rb +77 -0
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +5 -72
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +23 -51
- data/lib/hecks/forms/app.rb +21 -76
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +31 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- 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/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- 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/ir.rb +14 -83
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +19 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- 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 +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +47 -108
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +12 -44
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +40 -207
- data/lib/hecks/projections/deploy/lambda.rb +191 -708
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +3 -59
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- 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/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +48 -147
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +22 -584
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +16 -43
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +13 -32
- data/lib/hecks/projections/reference.rb +4 -18
- data/lib/hecks/projections/rust_vocabulary.rb +13 -251
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +154 -400
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- 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/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +5 -8
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +15 -9
- data/lib/hecks/release/runner/npm_publisher.rb +9 -53
- data/lib/hecks/release/runner/preflight.rb +29 -20
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +31 -23
- data/lib/hecks/release/runner.rb +60 -38
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +15 -39
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +50 -104
- data/lib/hecks/runtime/dispatcher.rb +134 -243
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +14 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +109 -194
- data/lib/hecks/runtime/outbox.rb +39 -262
- data/lib/hecks/runtime/policy_interpreter.rb +43 -202
- data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
- data/lib/hecks/runtime/query_interpreter.rb +122 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +28 -87
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +213 -227
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +156 -247
- data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +162 -760
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +15 -84
- data/lib/hecks/runtime.rb +35 -69
- 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 +155 -582
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- 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/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +52 -90
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- 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 +478 -12
- data/lib/hecks/facade/cli_door.rb +0 -178
- data/lib/hecks/facade/cli_runner.rb +0 -271
- data/lib/hecks/facade/handle.rb +0 -293
- data/lib/hecks/facade/json_door.rb +0 -247
- data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
- data/lib/hecks/facade/surface/chapter.rb +0 -116
- data/lib/hecks/facade/surface.rb +0 -61
- data/lib/hecks/mcp_door_scope.rb +0 -176
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "errors"
|
|
2
2
|
require_relative "refusal_wording"
|
|
3
|
+
require_relative "reaction_outcome"
|
|
3
4
|
require_relative "caller"
|
|
4
5
|
require_relative "invocation"
|
|
5
6
|
require_relative "command_rules"
|
|
@@ -14,36 +15,49 @@ require_relative "../naming"
|
|
|
14
15
|
|
|
15
16
|
module Hecks
|
|
16
17
|
module Runtime
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# sub-interpreter (command, entity, port operation, query, read
|
|
20
|
-
# model), then runs every policy and saga reaction the resulting
|
|
21
|
-
# events trigger. Also the door reactions dispatch back through
|
|
22
|
-
# (#reenter), and the one place reaction-cascade depth is tracked, to
|
|
23
|
-
# keep a policy/saga loop from re-triggering itself without bound.
|
|
18
|
+
# Routes a "Domain::Aggregate.Command" verb to its interpreter, then runs the policy
|
|
19
|
+
# and saga reactions its events trigger; tracks reaction depth to bound cascades.
|
|
24
20
|
class Dispatcher
|
|
25
21
|
MAX_REACTION_DEPTH = 5
|
|
26
22
|
|
|
27
|
-
Result = Struct.new(:verb, :instance, :events, :execution_plan, :persistence_outcome,
|
|
28
|
-
|
|
23
|
+
Result = Struct.new(:verb, :instance, :events, :execution_plan, :persistence_outcome,
|
|
24
|
+
:refused_reactions, :blocking_reactions, :reaction_defects,
|
|
25
|
+
keyword_init: true) do
|
|
26
|
+
# Lists the policy reactions this dispatch caused that the domain refused.
|
|
27
|
+
#
|
|
28
|
+
# A policy's trigger that a `given` or invariant refuses does not undo the command that
|
|
29
|
+
# fired it, which has already persisted, so the outcome above stays a success. The
|
|
30
|
+
# refusal is recorded here instead of vanishing into the reaction log.
|
|
31
|
+
#
|
|
32
|
+
# @return [Array<Hash{Symbol => Object}>] one `{ policy:, trigger:, reason: }` per refused
|
|
33
|
+
# reaction, oldest first; empty when every reaction was delivered
|
|
34
|
+
def refused_reactions = self[:refused_reactions] || []
|
|
35
|
+
|
|
36
|
+
# Lists the refused reactions that block the run, as opposed to a benign non-match.
|
|
37
|
+
#
|
|
38
|
+
# See `ReactionOutcome`: a refusal is benign when a sibling reaction to the same event
|
|
39
|
+
# delivered another command on the same aggregate. `--wait` exits 1 on any that remain.
|
|
40
|
+
#
|
|
41
|
+
# @return [Array<Hash{Symbol => Object}>] the subset of `refused_reactions` that blocks
|
|
42
|
+
def blocking_reactions = self[:blocking_reactions] || []
|
|
43
|
+
|
|
44
|
+
# Lists the reactions that crashed, as opposed to being refused by the domain.
|
|
29
45
|
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# `PortOperationInterpreter#emit`'s own comment gives for sourcing
|
|
33
|
-
# `id:` off the operation's reference attribute instead. `&.`, not
|
|
34
|
-
# a raised error: a caller that dispatches a port verb and then
|
|
35
|
-
# asks this Result for `.id`/`.state` made a category error the
|
|
36
|
-
# domain itself already told it about (there is no record here),
|
|
37
|
-
# not a crash-worthy one.
|
|
46
|
+
# A crash is warned and never re-raised, since the emitting command has persisted; it is
|
|
47
|
+
# recorded here so `--wait` can fail on a chain that stopped halfway.
|
|
38
48
|
#
|
|
39
|
-
# @return [
|
|
40
|
-
#
|
|
49
|
+
# @return [Array<Hash{Symbol => Object}>] `{ policy:, trigger:, reason:, error_class: }`
|
|
50
|
+
# per crashed reaction; empty when none crashed
|
|
51
|
+
def reaction_defects = self[:reaction_defects] || []
|
|
52
|
+
|
|
53
|
+
# Reads the identity of the record the dispatch settled on.
|
|
54
|
+
#
|
|
55
|
+
# @return [String, nil] the record's identity; nil for a port operation (no record)
|
|
41
56
|
def id = instance&.id
|
|
42
57
|
|
|
43
|
-
# Reads the settled record's attributes as one Hash
|
|
58
|
+
# Reads the settled record's attributes as one Hash.
|
|
44
59
|
#
|
|
45
|
-
# @return [Hash{Symbol => Object}, nil] the record's state
|
|
46
|
-
# last; nil for a port operation, which hydrates no record
|
|
60
|
+
# @return [Hash{Symbol => Object}, nil] the record's state; nil for a port operation
|
|
47
61
|
def state = instance&.to_h
|
|
48
62
|
|
|
49
63
|
def to_s
|
|
@@ -56,8 +70,7 @@ module Hecks
|
|
|
56
70
|
|
|
57
71
|
attr_reader :registry
|
|
58
72
|
|
|
59
|
-
# @param registry [Runtime::Registry] the booted registry every interpreter reads
|
|
60
|
-
# outbox is attached to this dispatcher's policy and saga interpreters
|
|
73
|
+
# @param registry [Runtime::Registry] the booted registry every interpreter reads
|
|
61
74
|
def initialize(registry)
|
|
62
75
|
@registry = registry
|
|
63
76
|
rules = CommandRules.new(registry)
|
|
@@ -68,108 +81,72 @@ module Hecks
|
|
|
68
81
|
@read_models = ReadModelInterpreter.new(registry)
|
|
69
82
|
@policies = PolicyInterpreter.new(registry, door: self)
|
|
70
83
|
@sagas = SagaInterpreter.new(registry, door: self)
|
|
71
|
-
#
|
|
72
|
-
# interpreters enqueue through `@registry.outbox` from inside
|
|
73
|
-
# the save transaction, and this dispatcher drains through the
|
|
74
|
-
# same object, so there is exactly one relay per registry no
|
|
75
|
-
# matter how many dispatchers front it. What it borrows from
|
|
76
|
-
# here is the pair of interpreters a consumer runs through.
|
|
84
|
+
# One relay per registry: interpreters enqueue through it inside the save transaction.
|
|
77
85
|
@registry.outbox.attach(policies: @policies, sagas: @sagas)
|
|
78
86
|
end
|
|
79
87
|
|
|
80
|
-
# Exposes the registry's outbox relay,
|
|
88
|
+
# Exposes the registry's outbox relay, through which this dispatcher drains reactions.
|
|
81
89
|
#
|
|
82
|
-
#
|
|
83
|
-
# `.log` — see `Runtime::Outbox`.
|
|
84
|
-
#
|
|
85
|
-
# @return [Runtime::Outbox::Relay] the registry's one relay, shared by every dispatcher
|
|
86
|
-
# fronting that registry
|
|
90
|
+
# @return [Runtime::Outbox::Relay] the registry's one relay
|
|
87
91
|
def outbox = @registry.outbox
|
|
88
92
|
|
|
89
|
-
# Exposes every event emitted through this registry
|
|
93
|
+
# Exposes every event emitted through this registry, oldest first.
|
|
90
94
|
#
|
|
91
|
-
# @return [Array<Runtime::Event>]
|
|
95
|
+
# @return [Array<Runtime::Event>]
|
|
92
96
|
def events = @registry.event_log
|
|
93
97
|
|
|
94
|
-
# Exposes one record per policy reaction
|
|
98
|
+
# Exposes one record per policy reaction delivered, refused or left undelivered.
|
|
95
99
|
#
|
|
96
|
-
# @return [Array<Hash{Symbol => Object}>]
|
|
100
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
97
101
|
def reactions = @registry.reaction_log
|
|
98
102
|
|
|
99
103
|
# Exposes one record per process-manager step: a start, an advance, a delivery, a refusal.
|
|
100
104
|
#
|
|
101
|
-
# @return [Array<Hash{Symbol => Object}>]
|
|
105
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
102
106
|
def sagas = @registry.saga_log
|
|
103
107
|
|
|
104
|
-
# Exposes the raw inputs each saga dispatch bound its arguments from
|
|
108
|
+
# Exposes the raw inputs each saga dispatch bound its arguments from (Ruby-only).
|
|
105
109
|
#
|
|
106
|
-
# @return [Array<Hash{Symbol => Object}>]
|
|
110
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
107
111
|
def saga_dispatches = @registry.saga_dispatch_log
|
|
108
112
|
|
|
109
|
-
# Exposes the raw inputs each policy trigger bound its arguments from
|
|
113
|
+
# Exposes the raw inputs each policy trigger bound its arguments from (Ruby-only).
|
|
110
114
|
#
|
|
111
|
-
# @return [Array<Hash{Symbol => Object}>]
|
|
112
|
-
#
|
|
115
|
+
# @return [Array<Hash{Symbol => Object}>] entries keyed `:policy`, `:on`, `:payload`,
|
|
116
|
+
# `:with_spec` and `:args`
|
|
113
117
|
def policy_dispatches = @registry.policy_dispatch_log
|
|
114
118
|
|
|
115
119
|
# Lists every verb the loaded bluebooks declare.
|
|
116
120
|
#
|
|
117
|
-
# @return [Array<String>]
|
|
121
|
+
# @return [Array<String>] sorted
|
|
118
122
|
def verbs = @registry.verbs
|
|
119
123
|
|
|
120
|
-
# Runs one command, entity command or port operation, then
|
|
121
|
-
# its events are owed.
|
|
122
|
-
#
|
|
123
|
-
# The receiver in `to:`, the facts in `with:`, and nothing else.
|
|
124
|
-
# Loose keyword facts — `dispatch(verb, amount: 5)`, one bag holding
|
|
125
|
-
# both the route and the payload — were deprecated in 1.3.x and are
|
|
126
|
-
# gone: Ruby now refuses them itself, by name ("unknown keyword:
|
|
127
|
-
# :amount"). Code holding a bag of data rather than written keywords
|
|
128
|
-
# calls `dispatch_flat` below; that door is not going anywhere.
|
|
124
|
+
# Runs one command, entity command or port operation, then the reactions its events owe.
|
|
129
125
|
#
|
|
130
|
-
# @param verb [String]
|
|
131
|
-
#
|
|
132
|
-
# @param to [String, Hash, nil] the receiver: an aggregate identity, or an entity route
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# @param
|
|
136
|
-
# @
|
|
137
|
-
#
|
|
138
|
-
# @
|
|
139
|
-
#
|
|
140
|
-
# @raise [Runtime::UnknownVerb] if the verb is not fully qualified, or names a domain,
|
|
141
|
-
# aggregate, command, entity or port operation that is not declared
|
|
142
|
-
# @raise [StandardError] any class in `Runtime::DOMAIN_REFUSALS` when the domain refuses
|
|
143
|
-
# the call (`GivenNotMet`, `TypeMismatch`, `Unauthorized`, `NotFound`, …)
|
|
144
|
-
# @raise [Runtime::StaleWrite] if concurrent writers beat this one through every retry
|
|
145
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
126
|
+
# @param verb [String] `"Domain::Aggregate.Command"`, `"Domain::Aggregate.Entity.Command"`
|
|
127
|
+
# or `"Domain::Aggregate.Port.Operation"`
|
|
128
|
+
# @param to [String, Hash, nil] the receiver: an aggregate identity, or an entity route Hash
|
|
129
|
+
# with `:aggregate` and `:entity`/`:entities`
|
|
130
|
+
# @param with [Hash, nil] the command's facts, keyed by argument name
|
|
131
|
+
# @param saga_correlation [Hash, nil] stamped on emitted events when a saga leg dispatches
|
|
132
|
+
# @return [Runtime::Dispatcher::Result] the instance is nil for a port operation
|
|
133
|
+
# @raise [Runtime::UnknownVerb] if the verb is malformed or names something undeclared
|
|
134
|
+
# @raise [StandardError] a `Runtime::DOMAIN_REFUSALS` class when the domain refuses
|
|
135
|
+
# @raise [Runtime::StaleWrite] if concurrent writers win every retry
|
|
146
136
|
def dispatch(verb, to: nil, with: nil, saga_correlation: nil)
|
|
147
137
|
dispatch_invocation(verb, to: to, with: with, saga_correlation: saga_correlation, flat: {})
|
|
148
138
|
end
|
|
149
139
|
|
|
150
140
|
# Dispatches a verb whose receiver and facts arrive together in one flat Hash.
|
|
151
141
|
#
|
|
152
|
-
#
|
|
153
|
-
# `
|
|
154
|
-
# reaction without a `with:` projection, and the self-hosted
|
|
155
|
-
# meta-domain all carry, where the receiver's identity is one of the
|
|
156
|
-
# keys because that is how the wire spells it. Routes exactly as the
|
|
157
|
-
# removed keyword door did: a Symbol `:to`, `:with` or
|
|
158
|
-
# `:saga_correlation` key is lifted out as that keyword, everything
|
|
159
|
-
# else is a fact (so a String "to" key stays a fact, as it did).
|
|
160
|
-
# Framework code that replays data calls this; application code
|
|
161
|
-
# calls `dispatch(verb, to:, with:)`.
|
|
142
|
+
# The wire form: Symbol keys `:to`, `:with` and `:saga_correlation` are lifted out as
|
|
143
|
+
# the keywords of `dispatch`; every other key, including a String "to", is a fact.
|
|
162
144
|
#
|
|
163
145
|
# @param verb [String] the fully qualified verb, in any shape `dispatch` accepts
|
|
164
|
-
# @param args [Hash] the facts
|
|
165
|
-
# `:saga_correlation`, read as `dispatch`'s keywords of the same names; not mutated
|
|
146
|
+
# @param args [Hash] the facts plus the optional Symbol keys above; not mutated
|
|
166
147
|
# @return [Runtime::Dispatcher::Result] the same result `dispatch` returns
|
|
167
|
-
# @raise [Runtime::UnknownVerb] if the verb is
|
|
168
|
-
#
|
|
169
|
-
# @raise [StandardError] any class in `Runtime::DOMAIN_REFUSALS` when the domain refuses
|
|
170
|
-
# the call
|
|
171
|
-
# @raise [Runtime::StaleWrite] if concurrent writers beat this one through every retry
|
|
172
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
148
|
+
# @raise [Runtime::UnknownVerb] if the verb is malformed or names something undeclared
|
|
149
|
+
# @raise [StandardError] a `Runtime::DOMAIN_REFUSALS` class when the domain refuses
|
|
173
150
|
def dispatch_flat(verb, args = {})
|
|
174
151
|
facts = args.dup
|
|
175
152
|
to = facts.delete(:to)
|
|
@@ -179,6 +156,14 @@ module Hecks
|
|
|
179
156
|
end
|
|
180
157
|
|
|
181
158
|
def dispatch_invocation(verb, to:, with:, saga_correlation:, flat:)
|
|
159
|
+
@registry.collecting_reactions do |reactions|
|
|
160
|
+
dispatch_collecting(verb, reactions, to: to, with: with, saga_correlation: saga_correlation, flat: flat)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
private :dispatch_invocation
|
|
164
|
+
|
|
165
|
+
# One dispatch, with `reactions` receiving every reaction its events cause.
|
|
166
|
+
def dispatch_collecting(verb, reactions, to:, with:, saga_correlation:, flat:)
|
|
182
167
|
domain, aggregate_name, command_name = parse(verb)
|
|
183
168
|
aggregate = resolve_aggregate(domain, aggregate_name, verb)
|
|
184
169
|
|
|
@@ -186,17 +171,8 @@ module Hecks
|
|
|
186
171
|
if command_name.include?(".")
|
|
187
172
|
head, sub = command_name.split(".", 2)
|
|
188
173
|
port = aggregate.port(head)
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
# are checked first, so an aggregate that ever declared both a
|
|
192
|
-
# port and an entity of the same name would resolve to the
|
|
193
|
-
# port; no domain in this corpus does, and `dispatch_port`'s
|
|
194
|
-
# own header already named this as an open wire-spelling
|
|
195
|
-
# question this resolves, not silently avoids. No `instance`
|
|
196
|
-
# comes back — nothing is hydrated or saved by a port
|
|
197
|
-
# operation (`PortOperationInterpreter`'s own header) — so
|
|
198
|
-
# `Result#id`/`#state` are nil-safe (above) for exactly this
|
|
199
|
-
# path.
|
|
174
|
+
# Ports are checked before entities, so a port wins a name an entity also declares.
|
|
175
|
+
# No instance comes back: a port operation hydrates and saves nothing.
|
|
200
176
|
if port
|
|
201
177
|
operation = port.operation(sub) ||
|
|
202
178
|
raise(UnknownVerb, RefusalWording.render_site("UnknownVerb", "port_no_operation",
|
|
@@ -218,37 +194,31 @@ module Hecks
|
|
|
218
194
|
@commands.call(domain, aggregate, command, invocation, saga_correlation)
|
|
219
195
|
end
|
|
220
196
|
|
|
221
|
-
# Correlation is
|
|
222
|
-
# here — it is part of the transaction, known from this method's
|
|
223
|
-
# own argument before a single event exists. Stamping it onto
|
|
224
|
-
# already-emitted events would keep an event mutable after it had
|
|
225
|
-
# happened.
|
|
226
|
-
#
|
|
227
|
-
# The ordering that depends on it holds for the same reason:
|
|
228
|
-
# `SagaInterpreter#advance` runs on this domain's `announced`
|
|
229
|
-
# events within this very call, and finds the correlation already
|
|
230
|
-
# there because it was never absent.
|
|
197
|
+
# Correlation is stamped as each event is built, so emitted events are never mutated.
|
|
231
198
|
|
|
232
199
|
react(announced, domain, aggregate, outbox_rows)
|
|
233
200
|
|
|
234
201
|
Result.new(verb: verb, instance: instance, events: announced,
|
|
235
|
-
execution_plan: execution_plan, persistence_outcome: persistence_outcome
|
|
202
|
+
execution_plan: execution_plan, persistence_outcome: persistence_outcome,
|
|
203
|
+
refused_reactions: refused_from(reactions),
|
|
204
|
+
blocking_reactions: ReactionOutcome.blocking(reactions, event_of: @registry.method(:reaction_event)),
|
|
205
|
+
reaction_defects: ReactionOutcome.defects(reactions))
|
|
236
206
|
end
|
|
207
|
+
private :dispatch_collecting
|
|
237
208
|
|
|
238
|
-
#
|
|
239
|
-
#
|
|
240
|
-
#
|
|
241
|
-
|
|
209
|
+
# The reactions among `logged` that the domain refused, as plain facts.
|
|
210
|
+
#
|
|
211
|
+
# A crash in a reaction is a defect, not a refusal, and is warned where it happens.
|
|
212
|
+
def refused_from(logged)
|
|
213
|
+
logged.select { |entry| entry[:delivered] == false && !entry[:defect] }
|
|
214
|
+
.map { |entry| entry.slice(:policy, :trigger, :reason) }
|
|
215
|
+
end
|
|
216
|
+
private :refused_from
|
|
242
217
|
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
#
|
|
246
|
-
#
|
|
247
|
-
# run_dispatch_order`); a port operation saves nothing, so its
|
|
248
|
-
# rows are enqueued here, after the fact (`:enqueue`) — durable
|
|
249
|
-
# still, just not transactional with anything, because there is
|
|
250
|
-
# nothing for them to be transactional with. `nil` rows mean the
|
|
251
|
-
# repository has no outbox: react directly, exactly as before.
|
|
218
|
+
# Runs the policy and saga reactions owed because `announced` committed.
|
|
219
|
+
#
|
|
220
|
+
# A port operation saves nothing, so its outbox rows are enqueued here (`:enqueue`);
|
|
221
|
+
# nil rows mean the repository has no outbox and reactions run directly.
|
|
252
222
|
def react(announced, domain, aggregate, outbox_rows)
|
|
253
223
|
return if announced.empty?
|
|
254
224
|
|
|
@@ -260,38 +230,16 @@ module Hecks
|
|
|
260
230
|
|
|
261
231
|
# Answers whether a command would succeed right now, without saving, emitting or reacting.
|
|
262
232
|
#
|
|
263
|
-
#
|
|
264
|
-
#
|
|
265
|
-
# mutations applied in memory, ensures checked against the settled
|
|
266
|
-
# result), except `step_save`/`step_emit` never run, and neither do
|
|
267
|
-
# policies or sagas afterward: nothing here is committed, so nothing
|
|
268
|
-
# should react to it. Built for exactly the shape a whole-board
|
|
269
|
-
# postcondition needs to be tested against (a downstream project's
|
|
270
|
-
# own chess domain, checking "does this move leave my own king in
|
|
271
|
-
# check" — the alternative was dispatching a real, unrelated piece's
|
|
272
|
-
# own move purely to trigger the check, which then had to avoid
|
|
273
|
-
# interfering with the very position being tested).
|
|
274
|
-
#
|
|
275
|
-
# Raises the same refusals #dispatch does — a DomainRefusal
|
|
276
|
-
# subclass propagates normally, so a caller checking "would this be
|
|
277
|
-
# legal" writes the identical rescue clause a real dispatch already
|
|
278
|
-
# needs; this returns `true` only when nothing was refused.
|
|
279
|
-
#
|
|
280
|
-
# **Never a port verb** — `PortOperationInterpreter`'s own side effects
|
|
281
|
-
# (an external gateway call, say) have no meaningful in-memory-only
|
|
282
|
-
# form, so this refuses one outright rather than silently running
|
|
283
|
-
# it for real, which "dry" would otherwise quietly lie about.
|
|
233
|
+
# Runs the dispatch pipeline in memory only; refusals raise exactly as `dispatch` raises
|
|
234
|
+
# them. A port verb is refused: its side effects have no in-memory form.
|
|
284
235
|
#
|
|
285
236
|
# @param verb [String] the fully qualified aggregate or entity command verb
|
|
286
|
-
# @param args [Hash{Symbol => Object}] the
|
|
287
|
-
#
|
|
288
|
-
# @return [true] whenever nothing refused
|
|
289
|
-
# @raise [Runtime::WiringError] if the verb names a port operation
|
|
290
|
-
#
|
|
291
|
-
# @raise [Runtime::
|
|
292
|
-
# aggregate, command or entity that is not declared
|
|
293
|
-
# @raise [StandardError] any class in `Runtime::DOMAIN_REFUSALS` that the real dispatch
|
|
294
|
-
# would raise
|
|
237
|
+
# @param args [Hash{Symbol => Object}] the facts as flat keywords; `to` and `with` are
|
|
238
|
+
# ordinary facts here, never routing
|
|
239
|
+
# @return [true] whenever nothing refused
|
|
240
|
+
# @raise [Runtime::WiringError] if the verb names a port operation
|
|
241
|
+
# @raise [Runtime::UnknownVerb] if the verb is malformed or names something undeclared
|
|
242
|
+
# @raise [StandardError] any `Runtime::DOMAIN_REFUSALS` class the real dispatch would raise
|
|
295
243
|
def dry_run?(verb, **args)
|
|
296
244
|
domain, aggregate_name, command_name = parse(verb)
|
|
297
245
|
aggregate = resolve_aggregate(domain, aggregate_name, verb)
|
|
@@ -304,8 +252,7 @@ module Hecks
|
|
|
304
252
|
"only for aggregate and entity commands"
|
|
305
253
|
end
|
|
306
254
|
|
|
307
|
-
# `to:`/`with:` are not keywords
|
|
308
|
-
# either is an ordinary fact here (BUG#131), so both go in as nil.
|
|
255
|
+
# `to:`/`with:` are not keywords here; a key named either is an ordinary fact.
|
|
309
256
|
resolution = nil
|
|
310
257
|
invocation = Invocation.from_call(verb, to: nil, with: nil, flat: args, receiver: :entity) do
|
|
311
258
|
(resolution = EntityInterpreter::Resolution.of(aggregate, command_name)).command
|
|
@@ -320,36 +267,18 @@ module Hecks
|
|
|
320
267
|
true
|
|
321
268
|
end
|
|
322
269
|
|
|
323
|
-
# Runs one port operation named by its parts, then the reactions its events
|
|
270
|
+
# Runs one port operation named by its parts, then the reactions its events owe.
|
|
324
271
|
#
|
|
325
|
-
# The door an adapter outside the bluebook
|
|
326
|
-
#
|
|
327
|
-
# rather than one packed verb string on purpose: there is no established
|
|
328
|
-
# wire spelling for "domain, aggregate, port, operation" yet, and
|
|
329
|
-
# inventing one is a bigger decision than this call needs to make.
|
|
272
|
+
# The door for an adapter outside the bluebook; the parts are separate arguments because
|
|
273
|
+
# no wire spelling for a packed port verb exists.
|
|
330
274
|
#
|
|
331
|
-
#
|
|
332
|
-
# `Hecks.adapter`'s existing job (unchanged by this), and wiring "which
|
|
333
|
-
# adapter may call this port" through is the next piece, not this one.
|
|
334
|
-
#
|
|
335
|
-
# @param domain [String, Symbol] name of the domain the aggregate belongs to
|
|
336
|
-
# @param aggregate_name [String, Symbol] name of the aggregate that declares the port
|
|
337
|
-
# @param port_name [String] name of the port, as the aggregate declares it
|
|
338
|
-
# @param operation_name [String] name of the operation on that port
|
|
339
|
-
# @param to [String, Hash, nil] the receiving aggregate's identity; when nil it is read
|
|
340
|
-
# from the facts, by the operation's reference or identity attribute
|
|
275
|
+
# @param to [String, Hash, nil] the receiver; when nil it is read from the facts
|
|
341
276
|
# @param with [Hash, nil] the operation's facts, keyed by argument name
|
|
342
|
-
# @param flat [Hash] the
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
# @
|
|
346
|
-
#
|
|
347
|
-
# outbound one
|
|
348
|
-
# @raise [Runtime::UnknownVerb] if the domain, aggregate, port or operation is not declared
|
|
349
|
-
# @raise [Runtime::TypeMismatch] if no receiving identity can be found, or `to:`/`with:`
|
|
350
|
-
# is malformed
|
|
351
|
-
# @raise [Runtime::NotFound] if the receiving aggregate record does not exist
|
|
352
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
277
|
+
# @param flat [Hash] the `dispatch_flat` wire form, for an adapter holding a decoded webhook
|
|
278
|
+
# @return [Array<Runtime::Event>] the events the operation announced
|
|
279
|
+
# @raise [Runtime::UnknownVerb] if the domain, aggregate, port or operation is undeclared
|
|
280
|
+
# @raise [Runtime::TypeMismatch] if no receiving identity is found, or `to:`/`with:` is bad
|
|
281
|
+
# @raise [Runtime::NotFound] if the receiving record does not exist
|
|
353
282
|
def dispatch_port(domain, aggregate_name, port_name, operation_name, to: nil, with: nil, flat: {})
|
|
354
283
|
aggregate = resolve_aggregate(domain, aggregate_name, "#{domain}::#{aggregate_name}.#{port_name}.#{operation_name}")
|
|
355
284
|
port = aggregate.port(port_name) ||
|
|
@@ -369,22 +298,16 @@ module Hecks
|
|
|
369
298
|
|
|
370
299
|
# Answers a declared query: an aggregate query, an entity query, or a read model.
|
|
371
300
|
#
|
|
372
|
-
#
|
|
373
|
-
#
|
|
374
|
-
# `"Domain::Aggregate.Entity.Query"` an entity query.
|
|
301
|
+
# `"Domain.ReadModel"` (no `::`) is a read model; `"Domain::Aggregate.Query"` and
|
|
302
|
+
# `"Domain::Aggregate.Entity.Query"` are aggregate and entity queries.
|
|
375
303
|
#
|
|
376
304
|
# @param verb [String, Symbol] the query's verb, in one of the three shapes above
|
|
377
305
|
# @param args [Hash{Symbol => Object}] the query's declared arguments
|
|
378
|
-
# @return [Array<Hash>]
|
|
379
|
-
# its state with `:id` merged in last; for an entity query, one Hash per matching
|
|
380
|
-
# element with the parent's reference key merged in first; for a read model, a
|
|
306
|
+
# @return [Array<Hash>] one Hash per matching record or element; a read model returns a
|
|
381
307
|
# one-element Array holding a Hash of head name to projected rows
|
|
382
|
-
# @raise [Runtime::UnknownVerb] if the verb is
|
|
383
|
-
# aggregate, entity, query or read model that is not declared
|
|
308
|
+
# @raise [Runtime::UnknownVerb] if the verb is malformed or names something undeclared
|
|
384
309
|
# @raise [Runtime::NotFound] if a read model's root reference names no record
|
|
385
310
|
# @raise [Runtime::TypeMismatch] if an argument cannot be coerced to its declared type
|
|
386
|
-
# @raise [KeyError] if a rooted read model is asked without its reference argument
|
|
387
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
388
311
|
def query(verb, **args)
|
|
389
312
|
domain, query_name = verb.to_s.split(".", 2)
|
|
390
313
|
if query_name && !domain.include?("::")
|
|
@@ -404,20 +327,14 @@ module Hecks
|
|
|
404
327
|
|
|
405
328
|
# Answers an aggregate or entity query through the reference interpreter alone.
|
|
406
329
|
#
|
|
407
|
-
#
|
|
408
|
-
#
|
|
409
|
-
# `"Domain::Aggregate.Query"` forms answer here; the fuzzer's
|
|
410
|
-
# query oracle diffs this against `#query`'s answer.
|
|
330
|
+
# Never answered by the bound adapter's native hook; the fuzzer's query oracle diffs it
|
|
331
|
+
# against `#query`. Read models have no reference twin.
|
|
411
332
|
#
|
|
412
|
-
# @param verb [String]
|
|
413
|
-
# `"Domain::Aggregate.Entity.Query"`
|
|
333
|
+
# @param verb [String] `"Domain::Aggregate.Query"` or `"Domain::Aggregate.Entity.Query"`
|
|
414
334
|
# @param args [Hash{Symbol => Object}] the query's declared arguments
|
|
415
|
-
# @return [Array<Hash>] one Hash per matching record
|
|
416
|
-
#
|
|
417
|
-
# @raise [Runtime::UnknownVerb] if the verb is not fully qualified, or names a domain,
|
|
418
|
-
# aggregate, entity or query that is not declared
|
|
335
|
+
# @return [Array<Hash>] one Hash per matching record or element
|
|
336
|
+
# @raise [Runtime::UnknownVerb] if the verb is malformed or names something undeclared
|
|
419
337
|
# @raise [Runtime::TypeMismatch] if an argument cannot be coerced to its declared type
|
|
420
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
421
338
|
def reference_query(verb, **args)
|
|
422
339
|
domain, aggregate_name, query_name = parse(verb)
|
|
423
340
|
aggregate = resolve_aggregate(domain, aggregate_name, verb)
|
|
@@ -425,43 +342,18 @@ module Hecks
|
|
|
425
342
|
@queries.reference_call(domain, aggregate, query_name, args)
|
|
426
343
|
end
|
|
427
344
|
|
|
428
|
-
# Dispatches a reaction's command one level deeper in the cascade, as the system
|
|
429
|
-
# than as the triggering caller.
|
|
430
|
-
#
|
|
431
|
-
# A reaction is the system acting, not the caller who happened to be
|
|
432
|
-
# on the stack when the triggering command ran — the ambient caller
|
|
433
|
-
# is cleared for the reaction's own dispatch, so a triggering
|
|
434
|
-
# caller's role can neither satisfy nor block a reaction command it
|
|
435
|
-
# has nothing to do with (Runtime::Caller.without).
|
|
436
|
-
#
|
|
437
|
-
# `Thread.current[:hecks_reaction_depth]`, not a plain ivar — this
|
|
438
|
-
# `Dispatcher` instance is a single object shared by every thread
|
|
439
|
-
# dispatching through it (a Puma worker pool, say), so a plain ivar
|
|
440
|
-
# here is exactly the known Puma-concurrency bug class: two
|
|
441
|
-
# concurrent top-level dispatches on different threads would
|
|
442
|
-
# increment/decrement the same counter, letting one thread's nested
|
|
443
|
-
# reaction depth leak into another thread's unrelated dispatch. A
|
|
444
|
-
# `Mutex` is not the answer either — a reaction cascade re-enters
|
|
445
|
-
# `reenter` on the same thread (see `SagaInterpreter#advance_saga`'s
|
|
446
|
-
# own comment on why a non-reentrant `Mutex` can't guard this).
|
|
447
|
-
# `Thread.current`-backed, saved/restored around the call with a
|
|
448
|
-
# plain local + `ensure`, is the same idiom `Runtime::Caller`
|
|
449
|
-
# (`caller.rb`) already established for exactly this shape of
|
|
450
|
-
# per-thread ambient state.
|
|
345
|
+
# Dispatches a reaction's command one level deeper in the cascade, as the system.
|
|
451
346
|
#
|
|
452
|
-
# The
|
|
453
|
-
#
|
|
454
|
-
#
|
|
347
|
+
# The ambient caller is cleared (Runtime::Caller.without) so the triggering caller's role
|
|
348
|
+
# neither satisfies nor blocks the reaction. Depth lives in `Thread.current`, not an ivar
|
|
349
|
+
# or Mutex: the dispatcher is shared across threads and cascades re-enter on one thread.
|
|
350
|
+
# The depth limit is checked by the reacting interpreter, not here.
|
|
455
351
|
#
|
|
456
352
|
# @param verb [String] the fully qualified verb of the reaction's target command
|
|
457
|
-
# @param saga_correlation [Hash{String => Object}, nil]
|
|
458
|
-
#
|
|
459
|
-
# @
|
|
460
|
-
#
|
|
461
|
-
# @return [Runtime::Dispatcher::Result] the result of the nested dispatch
|
|
462
|
-
# @raise [Runtime::UnknownVerb] if the verb names nothing declared
|
|
463
|
-
# @raise [StandardError] any class in `Runtime::DOMAIN_REFUSALS` when the target
|
|
464
|
-
# refuses; the policy and saga interpreters rescue these as recorded outcomes
|
|
353
|
+
# @param saga_correlation [Hash{String => Object}, nil] set when a saga leg dispatches
|
|
354
|
+
# @param args [Hash{Symbol => Object}] flat facts, read as `dispatch_flat` reads them
|
|
355
|
+
# @return [Runtime::Dispatcher::Result] the nested dispatch's result
|
|
356
|
+
# @raise [StandardError] any `Runtime::DOMAIN_REFUSALS` class; interpreters rescue these
|
|
465
357
|
def reenter(verb, saga_correlation: nil, **args)
|
|
466
358
|
depth = Thread.current[:hecks_reaction_depth].to_i
|
|
467
359
|
Thread.current[:hecks_reaction_depth] = depth + 1
|
|
@@ -472,13 +364,12 @@ module Hecks
|
|
|
472
364
|
|
|
473
365
|
# Answers whether the calling thread's reaction cascade is as deep as it may go.
|
|
474
366
|
#
|
|
475
|
-
# @return [Boolean] true once
|
|
476
|
-
# `MAX_REACTION_DEPTH` or more; other threads' cascades are not counted
|
|
367
|
+
# @return [Boolean] true once nested `reenter` calls on this thread reach the limit
|
|
477
368
|
def reaction_depth_reached? = Thread.current[:hecks_reaction_depth].to_i >= MAX_REACTION_DEPTH
|
|
478
369
|
|
|
479
|
-
# Reads the cascade limit
|
|
370
|
+
# Reads the cascade limit an interpreter records when it declines to react.
|
|
480
371
|
#
|
|
481
|
-
# @return [Integer] `MAX_REACTION_DEPTH
|
|
372
|
+
# @return [Integer] `MAX_REACTION_DEPTH`
|
|
482
373
|
def max_reaction_depth = MAX_REACTION_DEPTH
|
|
483
374
|
|
|
484
375
|
private
|