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
|
@@ -14,88 +14,43 @@ require_relative "command_interpreter/argument_gate"
|
|
|
14
14
|
|
|
15
15
|
module Hecks
|
|
16
16
|
module Runtime
|
|
17
|
-
# Interprets a command dispatched against a nested entity (a dotted
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# the command's own DISPATCH_ORDER of steps against the located
|
|
21
|
-
# element, then saves and emits through the same parent record a
|
|
22
|
-
# plain aggregate command would. CommandInterpreter's sibling for
|
|
23
|
-
# entity-owned commands.
|
|
17
|
+
# Interprets a command dispatched against a nested entity (a dotted verb
|
|
18
|
+
# like "Handler.Dispatch.Bind") rather than an aggregate root directly.
|
|
19
|
+
# CommandInterpreter's sibling for entity-owned commands.
|
|
24
20
|
class EntityInterpreter
|
|
25
21
|
include Interpreting
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# this, this class runs neither refuse_unknown_arguments nor
|
|
29
|
-
# refuse_absent_arguments, on a comment claiming "an entity inherits
|
|
30
|
-
# its aggregate's own gate." Nothing on the entity dispatch path ever
|
|
31
|
-
# ran one — confirmed live, `LedgerEntry.Reverse` accepted an
|
|
32
|
-
# unrecognized `bogus_arg:` outright, and dispatching it with no
|
|
33
|
-
# `narrative:` silently overwrote the stored narrative with `nil`
|
|
34
|
-
# (`sets :narrative`'s bare self-referential form reads `args[:narrative]`
|
|
35
|
-
# unconditionally). See `step_refuse_unknown_arguments`/
|
|
36
|
-
# `step_refuse_absent_arguments`, below, for how the shared gate is
|
|
37
|
-
# reused rather than reimplemented.
|
|
22
|
+
# Same argument gate aggregate commands and port operations run —
|
|
23
|
+
# without it, entity commands skip unknown/absent-argument checks.
|
|
38
24
|
include CommandInterpreter::ArgumentGate
|
|
39
25
|
|
|
40
26
|
attr_reader :registry
|
|
41
27
|
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# `refuse_unknown_arguments`/`refuse_absent_arguments` now lead it, same
|
|
46
|
-
# position `AggregateDispatchOrder` holds them at (H1, above) — the only
|
|
47
|
-
# remaining difference from the aggregate order is no
|
|
48
|
-
# `assign_creation_attributes` (an entity is never created through this
|
|
49
|
-
# path).
|
|
28
|
+
# The command-execution steps, in order, generated from
|
|
29
|
+
# Vocabulary::EntityDispatchOrder. Never includes
|
|
30
|
+
# `assign_creation_attributes` — an entity is never created directly.
|
|
50
31
|
DISPATCH_ORDER = Hecks::Vocabulary.symbols("EntityDispatchOrder")
|
|
51
32
|
|
|
52
|
-
#
|
|
53
|
-
#
|
|
33
|
+
# Retry cap for a stale write — same reasoning as
|
|
34
|
+
# `CommandInterpreter::MAX_STALE_WRITE_RETRIES`.
|
|
54
35
|
MAX_STALE_WRITE_RETRIES = 5
|
|
55
36
|
|
|
56
|
-
# `
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# `
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
# `chain` — S17, ADR 0026 — every entity the dotted verb passes
|
|
63
|
-
# through, root-first (`[Handler, Dispatch]` for `Handler.Dispatch.
|
|
64
|
-
# Bind`) ; `entity`/`entity_name` stay the chain's own last entry,
|
|
65
|
-
# the one a command actually belongs to and a mutation actually
|
|
66
|
-
# targets, so every step written before this ADR (enforce_givens,
|
|
67
|
-
# apply_mutations, advance_lifecycle, element_identity, ...) reads
|
|
68
|
-
# exactly as it always has. Only `locate_element` walks the chain.
|
|
69
|
-
# `:chain` shadows Enumerable#chain on purpose — every read is
|
|
70
|
-
# `ctx.chain` fetching the field (an Array of entities), never
|
|
71
|
-
# `ctx.chain(other)` combining enumerables. Verified before disabling
|
|
72
|
-
# this cop for it.
|
|
37
|
+
# `chain` holds every entity a dotted verb passes through, root-first
|
|
38
|
+
# (ADR 0026); `entity`/`entity_name` are always its last entry, the one
|
|
39
|
+
# a command targets. `instance` is the parent aggregate record;
|
|
40
|
+
# `element`/`view` are the entity piece itself, pre- and
|
|
41
|
+
# post-mutation. `:chain` intentionally shadows Enumerable#chain —
|
|
42
|
+
# every read is the struct field, never enumerable-combining.
|
|
73
43
|
# rubocop:disable-next Lint/StructNewOverride
|
|
74
44
|
Context = Struct.new(:domain, :aggregate, :entity, :entity_name, :command, :command_name,
|
|
75
45
|
:args, :repository, :instance, :chain, :element, :view, :transition,
|
|
76
46
|
:old_element, :result, :route, :plan, :persistence_outcome, :dry_run, :outbox_rows,
|
|
77
47
|
:correction_bindings, :invocation)
|
|
78
48
|
|
|
79
|
-
# A dotted entity verb resolved against its aggregate
|
|
80
|
-
#
|
|
81
|
-
# (spec/runtime/command_rules_spec.rb holds each interpreter to one),
|
|
82
|
-
# so `Dispatcher` can resolve it at the point `Invocation.from_call`
|
|
83
|
-
# reads the declaring command — after `to:` is parsed, before the
|
|
84
|
-
# facts are.
|
|
49
|
+
# A dotted entity verb resolved against its aggregate: the entity
|
|
50
|
+
# chain it names and the command located at the end of it.
|
|
85
51
|
Resolution = Data.define(:entity_names, :chain, :command_name, :command) do
|
|
86
|
-
# Resolves a dotted entity verb
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
# Refuses UnknownVerb for an unknown entity or command.
|
|
90
|
-
#
|
|
91
|
-
# @param aggregate [Bluebook::Aggregate] the root aggregate the dotted verb
|
|
92
|
-
# is resolved against
|
|
93
|
-
# @param dotted [String, Symbol] the entity verb, with the leading
|
|
94
|
-
# "Domain::Aggregate." already stripped (e.g. `"Handler.Dispatch.Bind"`)
|
|
95
|
-
# @return [EntityInterpreter::Resolution] the resolved entity names, chain,
|
|
96
|
-
# command name and command class
|
|
97
|
-
# @raise [Runtime::UnknownVerb] if `dotted` names no entity, or the located
|
|
98
|
-
# entity declares no such command
|
|
52
|
+
# Resolves a dotted entity verb into its entity chain and command,
|
|
53
|
+
# raising UnknownVerb if either segment doesn't exist.
|
|
99
54
|
def self.of(aggregate, dotted)
|
|
100
55
|
*entity_names, command_name = dotted.to_s.split(".")
|
|
101
56
|
if entity_names.empty?
|
|
@@ -110,14 +65,8 @@ module Hecks
|
|
|
110
65
|
new(entity_names: entity_names, chain: chain, command_name: command_name, command: command)
|
|
111
66
|
end
|
|
112
67
|
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
# walks Handler off the aggregate, then Dispatch off Handler, each
|
|
116
|
-
# step reading `.entities` exactly the way the single-level case
|
|
117
|
-
# always did — a nested entity is "structurally interchangeable
|
|
118
|
-
# with an aggregate" (Entity's own header) for precisely this
|
|
119
|
-
# reason. Two levels is what Handler/Dispatch need today ; nothing
|
|
120
|
-
# here assumes it stops at two.
|
|
68
|
+
# Walks one hop per dotted segment, resolving each entity name off
|
|
69
|
+
# the previous one — not limited to two levels.
|
|
121
70
|
def self.walk(aggregate, entity_names)
|
|
122
71
|
owner = aggregate
|
|
123
72
|
entity_names.map do |name|
|
|
@@ -139,38 +88,18 @@ module Hecks
|
|
|
139
88
|
@rules = rules
|
|
140
89
|
end
|
|
141
90
|
|
|
142
|
-
#
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
# read it either.
|
|
146
|
-
# Retries the whole method body on `StaleWrite` — same reasoning as
|
|
147
|
-
# `CommandInterpreter#call`'s own retry: a fresh `ctx`, a fresh
|
|
148
|
-
# `step_hydrate_parent`/`step_locate_element` re-reading current
|
|
149
|
-
# state.
|
|
150
|
-
#
|
|
151
|
-
# `resolution` is #resolve's answer; `invocation` the
|
|
152
|
-
# `Runtime::Invocation` `Dispatcher` built — `ctx.args` is its
|
|
153
|
-
# `to_args`, `ctx.route` its `target`.
|
|
154
|
-
#
|
|
91
|
+
# Runs the entity dispatch order for one command, saving and emitting
|
|
92
|
+
# through the parent record. Retries once on `StaleWrite` with a fresh
|
|
93
|
+
# `ctx`, re-reading current state.
|
|
155
94
|
# @param domain [String, Symbol] the domain `aggregate` belongs to
|
|
156
|
-
# @param aggregate [Bluebook::Aggregate] the root aggregate owning the entity
|
|
157
|
-
#
|
|
158
|
-
# @param
|
|
159
|
-
#
|
|
160
|
-
# @
|
|
161
|
-
#
|
|
162
|
-
# @
|
|
163
|
-
#
|
|
164
|
-
# @return [Array(Runtime::Instance, Array<Runtime::Event>,
|
|
165
|
-
# Runtime::DependencyPlanning::Plan, Ports::Persistence::Execution,
|
|
166
|
-
# Array<Runtime::Outbox::Row>)] the settled parent aggregate instance, emitted
|
|
167
|
-
# events, execution plan, persistence outcome and outbox rows — the last
|
|
168
|
-
# three nil on a dry run, which skips save/emit/outbox
|
|
169
|
-
# @raise [StandardError] any class in `Runtime::DOMAIN_REFUSALS` when a
|
|
170
|
-
# given/ensures/invariant/authorization/admissibility rule refuses
|
|
171
|
-
# @raise [Runtime::StaleWrite] if concurrent writers beat this one through every
|
|
172
|
-
# retry (`MAX_STALE_WRITE_RETRIES`)
|
|
173
|
-
# @raise [Runtime::WiringError] if the aggregate's repository cannot be resolved
|
|
95
|
+
# @param aggregate [Bluebook::Aggregate] the root aggregate owning the entity chain
|
|
96
|
+
# @param resolution [EntityInterpreter::Resolution] the resolved entity chain and command
|
|
97
|
+
# @param invocation [Runtime::Invocation] the invocation `Dispatcher` built
|
|
98
|
+
# @param dry_run [Boolean] validate every step without saving, emitting or enqueueing
|
|
99
|
+
# @return [Array] instance, events, plan, persistence outcome, outbox rows — last three
|
|
100
|
+
# nil on a dry run
|
|
101
|
+
# @raise [StandardError] any `Runtime::DOMAIN_REFUSALS` class when a rule refuses
|
|
102
|
+
# @raise [Runtime::StaleWrite, Runtime::WiringError] every retry loses, or resolve fails
|
|
174
103
|
def call(domain, aggregate, resolution, invocation, dry_run: false)
|
|
175
104
|
chain = resolution.chain
|
|
176
105
|
entity = chain.last
|
|
@@ -185,16 +114,12 @@ module Hecks
|
|
|
185
114
|
ctx.chain = chain
|
|
186
115
|
ctx.route = route
|
|
187
116
|
ctx.dry_run = dry_run
|
|
188
|
-
# `root_aggregate:`
|
|
189
|
-
# `
|
|
190
|
-
#
|
|
191
|
-
# aggregate's own field, not the entity's — `aggregate` here is
|
|
192
|
-
# that root (this method's own first parameter, never the
|
|
193
|
-
# entity). See DependencyPlanning::Analyzer.call's own header
|
|
194
|
-
# for the bug this closes.
|
|
117
|
+
# `root_aggregate:` is the true root aggregate (this method's first
|
|
118
|
+
# parameter), never `entity` — a `parent.X` read in this command's
|
|
119
|
+
# given/ensures means the root's field, not the entity's.
|
|
195
120
|
ctx.plan = DependencyPlanning::Analyzer.call(aggregate: entity, command: command, root_aggregate: aggregate)
|
|
196
|
-
#
|
|
197
|
-
#
|
|
121
|
+
# Resolved once, here — `step_hydrate_parent` reuses `ctx.repository`
|
|
122
|
+
# rather than re-fetching it.
|
|
198
123
|
ctx.repository = @registry.repository(domain, aggregate)
|
|
199
124
|
lock_id = Identity.best_effort(aggregate, args, route)
|
|
200
125
|
run_dispatch_order_with_isolation(DISPATCH_ORDER, ctx, lock_key_id: lock_id)
|
|
@@ -208,18 +133,12 @@ module Hecks
|
|
|
208
133
|
|
|
209
134
|
private
|
|
210
135
|
|
|
211
|
-
#
|
|
212
|
-
# decode_arguments. See CommandInterpreter#step_decode_arguments.
|
|
136
|
+
# No-op — entities have no `decode_arguments` step of their own.
|
|
213
137
|
def step_decode_arguments(_ctx); end
|
|
214
138
|
|
|
215
|
-
# `extra_identity_heads:`
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
# hops' own identity, each read straight out of `args` by
|
|
219
|
-
# `EntityElement#element_of` — refusing those as unknown would refuse
|
|
220
|
-
# every legitimate nested-entity dispatch there is, the same reasoning
|
|
221
|
-
# `ArgumentGate#refuse_unknown_arguments`'s own header gives for `:id`/
|
|
222
|
-
# the root's `identity_heads`.
|
|
139
|
+
# `extra_identity_heads:` covers every entity in `ctx.chain`, not just
|
|
140
|
+
# the root — each hop is addressed by its own identity fields, which
|
|
141
|
+
# would otherwise be refused as unknown arguments.
|
|
223
142
|
def step_refuse_unknown_arguments(ctx)
|
|
224
143
|
step(:refuse_unknown_arguments) do
|
|
225
144
|
refuse_unknown_arguments(ctx.domain, ctx.aggregate, ctx.command, ctx.args,
|
|
@@ -227,12 +146,8 @@ module Hecks
|
|
|
227
146
|
end
|
|
228
147
|
end
|
|
229
148
|
|
|
230
|
-
# No `aggregate:` exemption
|
|
231
|
-
#
|
|
232
|
-
# arguments`'s own comment); an entity command's chain identity never
|
|
233
|
-
# reaches `command.attributes` in the first place (resolved as
|
|
234
|
-
# addressing above, not as a declared fact), so there is nothing here
|
|
235
|
-
# for the exemption to need to strip.
|
|
149
|
+
# No `aggregate:` exemption needed — an entity command's chain identity
|
|
150
|
+
# never reaches `command.attributes` in the first place.
|
|
236
151
|
def step_refuse_absent_arguments(ctx)
|
|
237
152
|
step(:refuse_absent_arguments) { refuse_absent_arguments(ctx.command, ctx.args) }
|
|
238
153
|
end
|
|
@@ -268,61 +183,10 @@ module Hecks
|
|
|
268
183
|
state: ctx.element)
|
|
269
184
|
end
|
|
270
185
|
|
|
271
|
-
#
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
#
|
|
275
|
-
# before the entity's own `given`s.
|
|
276
|
-
#
|
|
277
|
-
# Admissibility is checked against the parent/root, not the entity —
|
|
278
|
-
# deliberately `ctx.instance`/`ctx.aggregate` (the parent aggregate
|
|
279
|
-
# record and the root aggregate construct), never `ctx.view`/
|
|
280
|
-
# `ctx.entity` (the entity's own pre-mutation view/construct). This
|
|
281
|
-
# is not a simplification; it is the only choice that lines up with
|
|
282
|
-
# how the event being corrected was actually recorded: an entity has
|
|
283
|
-
# no event stream of its own — `CommandRules::Emission#emit` (called
|
|
284
|
-
# from this class's own `step_emit`, and from `CommandInterpreter`'s
|
|
285
|
-
# `step_emit` for an aggregate-level command alike) always stamps an
|
|
286
|
-
# emitted event with the root aggregate's own qualified name
|
|
287
|
-
# (`"#{domain}::#{aggregate.hecks_name}"`) and the parent record's
|
|
288
|
-
# own id (`ctx.instance.id`), regardless of which level dispatched
|
|
289
|
-
# it. `enforce_correction_target` (CommandRules::Admissibility)
|
|
290
|
-
# looks a correction target up by exactly those two fields plus the
|
|
291
|
-
# event name — asking it in terms of the entity instead would search
|
|
292
|
-
# for an event key/id that no emitted event could ever actually
|
|
293
|
-
# carry, and every entity-level correction would refuse
|
|
294
|
-
# (NothingToCorrect) even against a real, already-emitted event.
|
|
295
|
-
# `qa/stress_domains/corrections`' own `Entry.Amend` (corrects
|
|
296
|
-
# "EntryRecorded", which `Ledger.Record` — an aggregate-level
|
|
297
|
-
# command — actually emits) is exactly this shape: the corrected
|
|
298
|
-
# event's `aggregate`/`id` are the ledger's, never the Entry's own
|
|
299
|
-
# (an Entry has no id an event could be filed under in the first
|
|
300
|
-
# place). `Fuzzing::Properties::Corrections#corrections_reference_
|
|
301
|
-
# an_emitted_event` independently encodes the identical rule
|
|
302
|
-
# (`aggregate_key` built off the outer aggregate for both the
|
|
303
|
-
# `corrects` target and the `emits` produced event, regardless of
|
|
304
|
-
# entity nesting depth) — this is that property's dispatch-time
|
|
305
|
-
# enforcement counterpart, not a new invention.
|
|
306
|
-
#
|
|
307
|
-
# One structural consequence, worth being explicit about for a
|
|
308
|
-
# Rust port: because the lookup is scoped to the parent record
|
|
309
|
-
# (not to any one entity element within it), an entity-level
|
|
310
|
-
# `corrects` only proves "this parent record has emitted the named
|
|
311
|
-
# event at some point" — it does not, and cannot, further narrow
|
|
312
|
-
# to "...specifically for THIS entity element" (a Ledger with three
|
|
313
|
-
# Entries all satisfy the same `EntryRecorded`-was-emitted check).
|
|
314
|
-
# That is not a gap this fix introduces: it is the same granularity
|
|
315
|
-
# the aggregate-level check already has (one record, one event
|
|
316
|
-
# history), just observed from one level down. A command wanting a
|
|
317
|
-
# tighter, element-specific correlation has to encode it itself, in
|
|
318
|
-
# its own `given`s, off `correction`-bound payload fields.
|
|
319
|
-
#
|
|
320
|
-
# `correction:` bindings computed here are threaded through to both
|
|
321
|
-
# halves of the same command's admissibility, same as the
|
|
322
|
-
# aggregate-level path: `ctx.correction_bindings` is read again by
|
|
323
|
-
# `step_enforce_ensures`, below, so an `as:`-named binding is
|
|
324
|
-
# visible to a settled-record `ensures` exactly as freely as it is
|
|
325
|
-
# here, pre-mutation.
|
|
186
|
+
# Enforces this command's `given`s and correction-target admissibility.
|
|
187
|
+
# Checked against the parent aggregate, never the entity view — every
|
|
188
|
+
# emitted event is stamped with the root aggregate's name and the
|
|
189
|
+
# parent record's id, regardless of dispatch level.
|
|
326
190
|
def step_enforce_givens(ctx)
|
|
327
191
|
step(:enforce_givens) do
|
|
328
192
|
ctx.correction_bindings = @rules.enforce_correction_target(ctx.instance, ctx.aggregate, ctx.command, domain: ctx.domain)
|
|
@@ -338,7 +202,7 @@ module Hecks
|
|
|
338
202
|
def step_apply_mutations(ctx)
|
|
339
203
|
ctx.old_element = ctx.element.dup unless ctx.command.ensures.empty?
|
|
340
204
|
step(:apply_mutations) do
|
|
341
|
-
pre = ctx.element.dup #
|
|
205
|
+
pre = ctx.element.dup # the update set reads the element as it stood before mutation
|
|
342
206
|
ctx.command.mutations.each do |mutation|
|
|
343
207
|
EntityElement.apply_to_element(@rules, ctx.aggregate, ctx.entity, ctx.element, mutation, ctx.args, pre)
|
|
344
208
|
end
|
|
@@ -357,46 +221,33 @@ module Hecks
|
|
|
357
221
|
def step_enforce_ensures(ctx)
|
|
358
222
|
step(:enforce_ensures) do
|
|
359
223
|
settled = Instance.new(aggregate: ctx.entity, id: ctx.view.id, state: ctx.element)
|
|
360
|
-
# `correction:`
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
# `ctx.correction_bindings` is `{}` from that call already, or
|
|
364
|
-
# (belt-and-braces, matching `CommandInterpreter#step_enforce_
|
|
365
|
-
# ensures`'s own identical `|| {}`) never set.
|
|
224
|
+
# `correction:` reuses the `as:`-bound bindings `step_enforce_givens`
|
|
225
|
+
# already located; `|| {}` covers a command with no `corrects`
|
|
226
|
+
# mutation, where `ctx.correction_bindings` may be unset.
|
|
366
227
|
@rules.enforce_ensures(settled, ctx.command, ctx.args, old: ctx.old_element, domain: ctx.domain, parent: ctx.instance,
|
|
367
228
|
correction: ctx.correction_bindings || {})
|
|
368
229
|
end
|
|
369
230
|
end
|
|
370
231
|
|
|
371
|
-
#
|
|
372
|
-
#
|
|
373
|
-
# `Context` comment), the same boundary an aggregate-level
|
|
374
|
-
# invariant guards regardless of which interpreter changed it. No
|
|
375
|
-
# separate "entity invariant" exists (S10, ADR 0025 scopes
|
|
376
|
-
# `invariant` to the aggregate only) — see `Admissibility#
|
|
377
|
-
# enforce_invariants`'s own comment.
|
|
232
|
+
# Enforces the parent aggregate's own invariants — there is no separate
|
|
233
|
+
# "entity invariant" concept (ADR 0025 scopes `invariant` to the aggregate).
|
|
378
234
|
def step_enforce_invariants(ctx)
|
|
379
235
|
step(:enforce_invariants) { @rules.enforce_invariants(ctx.instance, ctx.aggregate, domain: ctx.domain) }
|
|
380
236
|
end
|
|
381
237
|
|
|
382
|
-
# `dry_run:` skips the
|
|
383
|
-
#
|
|
384
|
-
# reference-existence check stays unconditional, only the actual
|
|
385
|
-
# persist is behind the early return.
|
|
238
|
+
# `dry_run:` skips only the persist — the reference-existence check
|
|
239
|
+
# above stays unconditional either way.
|
|
386
240
|
def step_save(ctx)
|
|
387
241
|
step(:save) { @rules.resolve_state_references(ctx.domain, ctx.aggregate, ctx.instance.state) }
|
|
388
242
|
|
|
389
243
|
return if ctx.dry_run
|
|
390
244
|
|
|
391
245
|
step(:save) do
|
|
392
|
-
# `expected_version:`
|
|
393
|
-
#
|
|
394
|
-
# instance never read from storage, either of which falls
|
|
395
|
-
# through to a plain save inside `AppendOnly#save`.
|
|
246
|
+
# `expected_version:` is nil for a non-CAS repository or an instance
|
|
247
|
+
# never read from storage — either falls through to a plain save.
|
|
396
248
|
ctx.persistence_outcome = ctx.repository.save(ctx.instance, expected_version: ctx.instance.version)
|
|
397
249
|
if ctx.persistence_outcome.status == :stale
|
|
398
|
-
#
|
|
399
|
-
# `CommandInterpreter#step_save`'s identical branch and
|
|
250
|
+
# Intentionally not a `RefusalWording.render` call — see
|
|
400
251
|
# `Runtime::StaleWrite`'s own comment.
|
|
401
252
|
raise(StaleWrite,
|
|
402
253
|
"#{ctx.command.hecks_name} on #{ctx.aggregate.hecks_name} " \
|
|
@@ -414,10 +265,8 @@ module Hecks
|
|
|
414
265
|
ctx.result = step(:emit) { @rules.emit(ctx.command, ctx.domain, ctx.aggregate, ctx.instance, ctx.args, ctx.repository) }
|
|
415
266
|
end
|
|
416
267
|
|
|
417
|
-
#
|
|
418
|
-
#
|
|
419
|
-
# (`Identity.of`), and let a bare `id:` name an already-derived record when
|
|
420
|
-
# the identity itself is not what the caller is holding.
|
|
268
|
+
# Finds the parent aggregate: the declared identity first, then a bare
|
|
269
|
+
# `id:` for a record the caller derived itself.
|
|
421
270
|
def parent(repository, aggregate, entity_name, command_name, args, route = nil)
|
|
422
271
|
parent_id = route&.aggregate ||
|
|
423
272
|
Identity.of(aggregate, args) ||
|
|
@@ -433,13 +282,9 @@ module Hecks
|
|
|
433
282
|
found.dup
|
|
434
283
|
end
|
|
435
284
|
|
|
436
|
-
# `locate_chain
|
|
437
|
-
#
|
|
438
|
-
#
|
|
439
|
-
# `CommandInterpreter`'s own `delegate_to_entity` step can locate and
|
|
440
|
-
# mutate the same element the same way, against an aggregate record
|
|
441
|
-
# already held in memory. `call`, above, and every `step_*` method
|
|
442
|
-
# reach them through that module.
|
|
285
|
+
# Entity element helpers (`locate_chain`, `element_of`, `element_identity`,
|
|
286
|
+
# `apply_to_element`) live in `Runtime::EntityElement`, shared with
|
|
287
|
+
# `CommandInterpreter#delegate_to_entity`.
|
|
443
288
|
end
|
|
444
289
|
end
|
|
445
290
|
end
|
data/lib/hecks/runtime/errors.rb
CHANGED
|
@@ -7,38 +7,27 @@ module Hecks
|
|
|
7
7
|
# everything downstream of a `.bluebook`/`.hecksagon`/`.world` declaration.
|
|
8
8
|
# See `lib/hecks/runtime.rb` for the module's own facade and boot entry points.
|
|
9
9
|
module Runtime
|
|
10
|
+
# A dispatched verb names no aggregate, entity or command.
|
|
10
11
|
class UnknownVerb < StandardError; end
|
|
12
|
+
# A settled record failed a command's `ensures`.
|
|
11
13
|
class EnsuresNotMet < StandardError; end
|
|
12
14
|
|
|
13
|
-
# `detail`
|
|
14
|
-
# right: Y"
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# that string is pinned byte-for-byte across this corpus's own specs
|
|
18
|
-
# (`raise_error(GivenNotMet, "...")`, command_rules_spec.rb and every
|
|
19
|
-
# domain that vendors this gem) as contract, so changing its shape by
|
|
20
|
-
# default would be a breaking change for every one of them. Riding on
|
|
21
|
-
# `#detailed_message` instead (Ruby 3.2+, what irb/a Rails console's
|
|
22
|
-
# own unhandled-exception banner already calls to show more than
|
|
23
|
-
# `#message`) means the detail actually reaches a human staring at a
|
|
24
|
-
# live refusal, without moving the string anything else asserts on.
|
|
15
|
+
# A command's `given` refused. `detail` holds the failing comparison's resolved operands
|
|
16
|
+
# ("left: X, right: Y") when the given is a bare comparison, else nil.
|
|
17
|
+
#
|
|
18
|
+
# `detail` rides on `#detailed_message`; `#message` stays byte-for-byte, as specs pin it.
|
|
25
19
|
class GivenNotMet < StandardError
|
|
26
20
|
attr_reader :detail
|
|
27
21
|
|
|
28
|
-
# @param message [String, nil] the refusal text
|
|
29
|
-
# @param detail [String, nil] the failing comparison's resolved operands
|
|
30
|
-
# right: Y"), or nil when the given's top-level shape is not a bare comparison
|
|
22
|
+
# @param message [String, nil] the refusal text
|
|
23
|
+
# @param detail [String, nil] the failing comparison's resolved operands, if any
|
|
31
24
|
def initialize(message = nil, detail: nil)
|
|
32
25
|
super(message)
|
|
33
26
|
@detail = detail
|
|
34
27
|
end
|
|
35
28
|
|
|
36
|
-
#
|
|
29
|
+
# Overrides Ruby's own error formatting to append the refusal's detail.
|
|
37
30
|
#
|
|
38
|
-
# @param highlight [Boolean] unused; accepted for compatibility with `Exception#
|
|
39
|
-
# detailed_message`'s own signature
|
|
40
|
-
# @param opts [Hash] unused; accepted for compatibility with `Exception#
|
|
41
|
-
# detailed_message`'s own signature
|
|
42
31
|
# @return [String] `message`, with `" (#{detail})"` appended when `detail` is present
|
|
43
32
|
def detailed_message(highlight: false, **opts)
|
|
44
33
|
base = super
|
|
@@ -46,117 +35,45 @@ module Hecks
|
|
|
46
35
|
end
|
|
47
36
|
end
|
|
48
37
|
|
|
38
|
+
# A command addressed a record that does not exist.
|
|
49
39
|
class NotFound < StandardError; end
|
|
40
|
+
# A command is not admissible from the record's current lifecycle state.
|
|
50
41
|
class LifecycleRefused < StandardError; end
|
|
42
|
+
# An argument carries the wrong kind of value for its declared type.
|
|
51
43
|
class TypeMismatch < StandardError; end
|
|
52
|
-
# An argument the command does not declare.
|
|
53
|
-
# is the right name carrying the wrong thing, this one is a name the command
|
|
54
|
-
# never had. Both are the payload gate refusing before any rule runs.
|
|
44
|
+
# An argument the command does not declare.
|
|
55
45
|
class UnknownArgument < StandardError; end
|
|
56
|
-
#
|
|
57
|
-
# declare, absent. TypeMismatch is the right name carrying the wrong thing,
|
|
58
|
-
# UnknownArgument a name that was never declared, AbsentArgument a declared name
|
|
59
|
-
# that never arrived. Between them they say a command takes exactly the
|
|
60
|
-
# arguments it declares — no others, and all of them.
|
|
46
|
+
# An argument the command declares but the call omitted.
|
|
61
47
|
class AbsentArgument < StandardError; end
|
|
62
|
-
# A creating command whose derived identity already names a record.
|
|
63
|
-
# record it would have overwritten stands ; the dispatch that tried to
|
|
64
|
-
# mint a second one over it is what refuses.
|
|
48
|
+
# A creating command whose derived identity already names a record.
|
|
65
49
|
class AlreadyExists < StandardError; end
|
|
66
|
-
# A
|
|
67
|
-
#
|
|
68
|
-
# declaring what an old record should read there. `GuardState`
|
|
69
|
-
# (command_rules/admissibility.rb) is the one place this is raised: a
|
|
70
|
-
# `given`/`ensures`/`invariant` that reads the field would otherwise
|
|
71
|
-
# evaluate against a value nobody wrote, which is the same silent-
|
|
72
|
-
# wrong-answer class as an unpopulated projection reading "not
|
|
73
|
-
# active" (ADR 0025, "Added attributes and absence"). An optional
|
|
74
|
-
# attribute in the same spot reads nil instead — that is what
|
|
75
|
-
# optional means, and this refusal is deliberately narrower than the
|
|
76
|
-
# nil-read it sits beside, not a replacement for it.
|
|
50
|
+
# A required attribute the stored record predates, with no default or translation to fill it.
|
|
51
|
+
# Raised only by `GuardState`; an optional attribute reads nil instead (ADR 0025).
|
|
77
52
|
class AttributeAbsent < StandardError; end
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
# rebuild sweep has populated yet, read by a `given`/`ensures`/
|
|
81
|
-
# `invariant` as though it carried a real value. `GuardState` is
|
|
82
|
-
# the one place this is raised, the same way AttributeAbsent is —
|
|
83
|
-
# a declared field the record does not yet carry, distinguished
|
|
84
|
-
# from that one only in why: an ordinary attribute is absent
|
|
85
|
-
# because nobody backfilled it, a projected field is absent
|
|
86
|
-
# because nobody has swept it yet.
|
|
53
|
+
# A `projects` field the record predates or no rebuild sweep has populated yet.
|
|
54
|
+
# Raised by `GuardState`.
|
|
87
55
|
class ProjectionAbsent < StandardError; end
|
|
88
|
-
# A query or read model declares `authorize policy, tenant: :field` and
|
|
89
|
-
# the caller did not pass that field — the one half of `authorize` this
|
|
90
|
-
# runtime can enforce without a caller-identity system: the boundary
|
|
91
|
-
# itself, not whether the caller actually holds `policy`. See
|
|
92
|
-
# Runtime::TenantScope.
|
|
56
|
+
# A query or read model declares `authorize policy, tenant: :field` and the caller omitted it.
|
|
93
57
|
class Unauthorized < StandardError; end
|
|
94
|
-
# `corrects`
|
|
95
|
-
#
|
|
96
|
-
# evaluator cannot check (it is not a predicate over the record's own
|
|
97
|
-
# fields, it is "did this exact record ever announce this"), so it is
|
|
98
|
-
# raised structurally, the same way AlreadyExists/NotFound are, rather
|
|
99
|
-
# than being expressible as an ordinary `given`. Raised by
|
|
100
|
-
# `CommandRules::Admissibility#enforce_correction_target`.
|
|
58
|
+
# A `corrects` command whose target event this record never emitted.
|
|
59
|
+
# Raised by `CommandRules::Admissibility#enforce_correction_target`.
|
|
101
60
|
class NothingToCorrect < StandardError; end
|
|
102
61
|
|
|
103
|
-
# A
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
# (`AppendOnly#save`'s `expected_version:`) finds the stored version has
|
|
107
|
-
# moved since this instance was read — someone else's write committed
|
|
108
|
-
# in between. `CommandInterpreter#call`/`EntityInterpreter#call` catch
|
|
109
|
-
# this themselves and retry the whole dispatch from a fresh hydrate, so
|
|
110
|
-
# `enforce_givens` re-evaluates against the now-current state; a caller
|
|
111
|
-
# only ever sees this escape when every retry is exhausted under
|
|
112
|
-
# sustained contention — an operational condition (many concurrent
|
|
113
|
-
# writers hammering one aggregate), not a business rule a domain author
|
|
114
|
-
# declared. See docs/decisions/ (concurrency-control ADR).
|
|
62
|
+
# A CAS write (`expected_version:`) found the stored version moved since the read.
|
|
63
|
+
# A runtime fault, not a domain refusal: the interpreters retry, so it escapes only under
|
|
64
|
+
# sustained contention.
|
|
115
65
|
class StaleWrite < StandardError; end
|
|
116
66
|
|
|
117
|
-
# A Lambda-routed domain's
|
|
118
|
-
#
|
|
119
|
-
# not yet mapped back to the specific matching class above
|
|
120
|
-
# (GivenNotMet vs. EnsuresNotMet vs. ...), a real, known,
|
|
121
|
-
# documented gap: the WASM projector's own event/refusal-wording
|
|
122
|
-
# parity work (ADR 0021) makes the text match Ruby's, but nothing
|
|
123
|
-
# yet parses that text back into a typed Ruby exception the way a
|
|
124
|
-
# local dispatch already raises one directly. Callers that only
|
|
125
|
-
# need "the domain said no" (not which specific rule) are
|
|
126
|
-
# unaffected; callers pattern-matching a specific refusal class
|
|
127
|
-
# against a Lambda-routed domain are the ones this gap would bite.
|
|
67
|
+
# A Lambda-routed domain's refusal (`Runtime::RemoteDispatcher`), with Rust's text verbatim.
|
|
68
|
+
# It is not mapped back to a specific class such as GivenNotMet.
|
|
128
69
|
class RemoteRefusal < StandardError; end
|
|
129
70
|
|
|
130
|
-
# The domain saying no
|
|
131
|
-
#
|
|
132
|
-
# about the domain ; the originating command still stands.
|
|
133
|
-
#
|
|
134
|
-
# Everything else is a defect : a NoMethodError in an interpreter, a
|
|
135
|
-
# NameError from a missing constant, a TypeError from a bad assumption. A
|
|
136
|
-
# blanket `rescue StandardError` would fold both into one line —
|
|
137
|
-
# `delivered: false, reason: "..."` — making a crash in the runtime
|
|
138
|
-
# indistinguishable from a rule doing its job, reading as normal
|
|
139
|
-
# operation in the log.
|
|
71
|
+
# The refusals that are the domain saying no, which a reaction records as undelivered.
|
|
72
|
+
# Anything else is a runtime defect and must propagate rather than read as a refusal.
|
|
140
73
|
#
|
|
141
|
-
# UnknownVerb is
|
|
142
|
-
#
|
|
143
|
-
#
|
|
144
|
-
# design — spec/policy_spec states it in so many words, "records a reaction
|
|
145
|
-
# it cannot deliver rather than swallowing it".
|
|
146
|
-
# InvariantViolation belongs here and was missing. A value object refusing
|
|
147
|
-
# its own rule is the domain saying no as plainly as a given is — but the
|
|
148
|
-
# class is declared over in value.rb and never made the list, so the policy
|
|
149
|
-
# and saga interpreters, which rescue exactly these, would let it propagate
|
|
150
|
-
# as though the runtime had broken. A reaction whose target violates an
|
|
151
|
-
# invariant is declined, not crashed. Found by spec/domain_refusal_spec on
|
|
152
|
-
# its first run : every corpus refusal must be a class named here, and 23
|
|
153
|
-
# of banking's were InvariantViolation.
|
|
154
|
-
# The names come from the language, the classes from this module.
|
|
155
|
-
# `DomainRefusal` declares which refusals are the domain's own —
|
|
156
|
-
# a rule the caller broke — as against a runtime fault. Resolving
|
|
157
|
-
# each name here means a refusal declared but never defined fails
|
|
158
|
-
# at load with a NameError, rather than being quietly absent from
|
|
159
|
-
# a list nothing re-checks.
|
|
74
|
+
# UnknownVerb is included on purpose: a cross-domain policy fires where its target domain is
|
|
75
|
+
# not loaded. InvariantViolation is included too, so a value object's refusal is declined.
|
|
76
|
+
# Names come from the language; resolving them here fails at load if one is undefined.
|
|
160
77
|
DOMAIN_REFUSALS = Hecks::Vocabulary.fetch("DomainRefusal").map { |name| const_get(name) }.freeze
|
|
161
78
|
end
|
|
162
79
|
end
|
data/lib/hecks/runtime/event.rb
CHANGED
|
@@ -2,32 +2,10 @@ require "time"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Runtime
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# bookkeeping stamped by `Dispatcher#dispatch` when a saga leg's own
|
|
8
|
-
# dispatch causes this event (see `SagaInterpreter#deliver_saga_dispatch`
|
|
9
|
-
# and `#saga_correlation`) : a Hash of `correlation_head` -> correlation
|
|
10
|
-
# value, so an event caused by one saga cannot be misread by an unrelated
|
|
11
|
-
# one correlating on a different field. Absent for any event no saga
|
|
12
|
-
# dispatch caused, which is most of them.
|
|
5
|
+
# An emitted domain event. `correlation` (saga head -> value) is runtime bookkeeping
|
|
6
|
+
# and deliberately absent from `to_h`.
|
|
13
7
|
Event = Struct.new(:name, :aggregate, :id, :payload, :occurred_at, :correlation, keyword_init: true) do
|
|
14
|
-
# Freezes the event deep,
|
|
15
|
-
#
|
|
16
|
-
# An emitted event is a record of something that happened, and a
|
|
17
|
-
# mutable audit trail is not one. The payload — the domain fact the
|
|
18
|
-
# event carries — is frozen through on emission: freezing the Hash
|
|
19
|
-
# alone would leave every value in it editable in place, which is
|
|
20
|
-
# the shape all four previous freezing bugs had.
|
|
21
|
-
#
|
|
22
|
-
# The whole event, not just its payload. Correlation is set at
|
|
23
|
-
# construction rather than merged in here by `Dispatcher#dispatch`
|
|
24
|
-
# after the event already exists, because it is part of the
|
|
25
|
-
# transaction and known from `dispatch`'s own argument before
|
|
26
|
-
# anything is emitted — that is what keeps an event immutable once
|
|
27
|
-
# it exists.
|
|
28
|
-
#
|
|
29
|
-
# The log stays appendable: new events are still recorded. It is
|
|
30
|
-
# each event that stops changing once it exists.
|
|
8
|
+
# Freezes the event deep, payload and correlation included.
|
|
31
9
|
#
|
|
32
10
|
# @return [void]
|
|
33
11
|
def emit!
|