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
|
@@ -8,11 +8,8 @@ require_relative "../bluebook/expression/evaluator"
|
|
|
8
8
|
|
|
9
9
|
module Hecks
|
|
10
10
|
module Runtime
|
|
11
|
-
# Fires the declared `policy` reactions triggered by one just-emitted
|
|
12
|
-
#
|
|
13
|
-
# different domain than the event it reacts to), checks each
|
|
14
|
-
# candidate's `where` guard, and re-enters the dispatcher for each
|
|
15
|
-
# delivery — recording every outcome on the reaction log.
|
|
11
|
+
# Fires the declared `policy` reactions triggered by one just-emitted event,
|
|
12
|
+
# recording every outcome on the reaction log.
|
|
16
13
|
class PolicyInterpreter
|
|
17
14
|
attr_reader :registry
|
|
18
15
|
|
|
@@ -26,61 +23,35 @@ module Hecks
|
|
|
26
23
|
end
|
|
27
24
|
|
|
28
25
|
# Fires every declared policy `event` triggers, recording each outcome on
|
|
29
|
-
# the registry's reaction log.
|
|
30
|
-
#
|
|
31
|
-
# `deliver` returns `nil` for a policy whose `where` did not hold —
|
|
32
|
-
# silently, the same as a policy `policies_for` never selected at all
|
|
33
|
-
# (an `event_qualifier` miss carries no reaction_log entry either) —
|
|
34
|
-
# so nothing is appended for it. A `for_each` policy answers an array
|
|
35
|
-
# (one record per matched row) rather than one record ; `Array(...)`
|
|
36
|
-
# is wrong here (it would explode a plain record Hash into its own
|
|
37
|
-
# key/value pairs), so the two shapes are told apart explicitly.
|
|
38
|
-
# `only:` — one `[policy, home_domain]` pair, the outbox relay's
|
|
39
|
-
# way of running exactly the consumer a row names (`Runtime::
|
|
40
|
-
# Outbox::Relay#run_consumer`) instead of every policy that
|
|
41
|
-
# matches the event. Selection is otherwise identical.
|
|
26
|
+
# the registry's reaction log. A policy whose `where` does not hold logs nothing.
|
|
42
27
|
#
|
|
43
28
|
# @param event [Runtime::Event] the just-emitted event to react to
|
|
44
29
|
# @param domain [String, Symbol] the domain `event`'s own aggregate belongs
|
|
45
30
|
# to, the emitting domain's policies fire first
|
|
46
31
|
# @param only [Array(Bluebook::Policy, String), nil] one `[policy, home_domain]`
|
|
47
|
-
# pair to run exactly, instead of scanning every
|
|
32
|
+
# pair to run exactly (the outbox relay's consumer), instead of scanning every
|
|
33
|
+
# loaded bluebook for candidates
|
|
34
|
+
# @param event_uid [String, nil] the outbox uid every consumer of this event shares, when the
|
|
35
|
+
# event was rebuilt from an outbox row; otherwise the event object itself is the identity
|
|
48
36
|
# @return [void]
|
|
49
|
-
def react(event, domain, only: nil)
|
|
37
|
+
def react(event, domain, only: nil, event_uid: nil)
|
|
50
38
|
selected = only ? [only] : policies_for(event, domain)
|
|
51
39
|
selected.each do |policy, home_domain|
|
|
52
40
|
result = deliver(policy, event, home_domain)
|
|
53
41
|
next if result.nil?
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
# A for_each policy answers an array; Array(...) would explode a record Hash.
|
|
44
|
+
identity = event_uid || event.object_id
|
|
45
|
+
(result.is_a?(Array) ? result : [result]).each { |record| @registry.log_reaction(record, event: identity) }
|
|
56
46
|
end
|
|
57
47
|
end
|
|
58
48
|
|
|
59
49
|
private
|
|
60
50
|
|
|
61
|
-
# Scans every loaded bluebook,
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
# ConceiveOnAbsorption reacts `on "DomainAbsorbed"`, an event
|
|
66
|
-
# `body/organs/bluebook/gut.bluebook`'s Gut.Absorb emits — two
|
|
67
|
-
# different bluebooks, joined only by the event's name). Restricting
|
|
68
|
-
# the scan to the emitting domain's own bluebook (the previous
|
|
69
|
-
# shape) silently drops every cross-domain reaction : the policy is
|
|
70
|
-
# never even a candidate, no refusal, no log entry, nothing —
|
|
71
|
-
# confirmed against the corpus's own .behaviors fixtures, several of
|
|
72
|
-
# which encode this exact cross-bluebook cascade as their contract.
|
|
73
|
-
#
|
|
74
|
-
# Returns [policy, home_domain] pairs rather than bare policies —
|
|
75
|
-
# `deliver`/`deliver_for_each` fall back to the reacting policy's
|
|
76
|
-
# own domain (not the emitting one) when a trigger or for_each route
|
|
77
|
-
# is bare, and that fallback has to travel with each match now that
|
|
78
|
-
# a single event can surface policies from several different homes.
|
|
79
|
-
#
|
|
80
|
-
# The emitting domain's own policies first, in declaration order,
|
|
81
|
-
# then other bluebooks' in load order (C10.2) — the same order the
|
|
82
|
-
# outbox lays its rows in (`Outbox::Fanout.policies`) and the Rust
|
|
83
|
-
# kernel runs (`react_policies`: its own table, then cross-domain).
|
|
51
|
+
# Scans every loaded bluebook, since a policy commonly lives in a different
|
|
52
|
+
# domain than the event it reacts to. Returns [policy, home_domain] pairs: the
|
|
53
|
+
# home domain is the fallback for a bare trigger or for_each route. Order is the
|
|
54
|
+
# emitting domain first, then load order, matching Outbox::Fanout and the Rust kernel.
|
|
84
55
|
def policies_for(event, domain)
|
|
85
56
|
emitting = Naming.demodulise(event.aggregate)
|
|
86
57
|
|
|
@@ -93,17 +64,9 @@ module Hecks
|
|
|
93
64
|
end
|
|
94
65
|
end
|
|
95
66
|
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
# from `attrs` (Expression::Resolver#fetch checks `attrs` before
|
|
100
|
-
# `state`, so this is exactly the shape `enforce_givens` already
|
|
101
|
-
# gives a command's own given, minus the settled-record half a
|
|
102
|
-
# policy simply has none of). Called from inside `deliver`'s own
|
|
103
|
-
# rescue-guarded body (both callers, below) — never guarded here —
|
|
104
|
-
# so an EvaluationError (an unresolvable field, a bad comparison) is
|
|
105
|
-
# caught the same way any other reaction defect is, not swallowed as
|
|
106
|
-
# though the policy had merely declined to fire.
|
|
67
|
+
# Evaluated against the event payload alone (a policy has no aggregate state).
|
|
68
|
+
# Not rescued here: an EvaluationError must reach `deliver`'s defect rescue, not
|
|
69
|
+
# read as a policy that declined to fire.
|
|
107
70
|
def where_holds?(policy, event)
|
|
108
71
|
return true if policy.where.to_s.empty?
|
|
109
72
|
|
|
@@ -111,11 +74,7 @@ module Hecks
|
|
|
111
74
|
end
|
|
112
75
|
|
|
113
76
|
def deliver(policy, event, domain)
|
|
114
|
-
# `record`
|
|
115
|
-
# `deliver_for_each`'s own header gives : both rescue clauses below
|
|
116
|
-
# call `.merge` on it, and a defect raised before it existed would
|
|
117
|
-
# be caught here only to raise a second, different NoMethodError
|
|
118
|
-
# trying to record the first one.
|
|
77
|
+
# `record` must exist before anything can raise: both rescues call `.merge` on it.
|
|
119
78
|
target = "#{policy.target_domain || domain}::#{policy.trigger_command}"
|
|
120
79
|
record = { policy: policy.name, on: event.name, trigger: target }
|
|
121
80
|
|
|
@@ -131,66 +90,26 @@ module Hecks
|
|
|
131
90
|
@door.reenter(target, **reaction_invocation(target, args, policy, event))
|
|
132
91
|
record.merge(delivered: true)
|
|
133
92
|
rescue *DOMAIN_REFUSALS => e
|
|
134
|
-
# The target refused — a fact about the domain, recorded and not
|
|
135
|
-
# fatal to the command that emitted the event.
|
|
136
93
|
record.merge(delivered: false, reason: e.message)
|
|
137
94
|
rescue StandardError => e
|
|
138
|
-
# A defect, not a refusal
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
# (errors.rb, see the comment above that constant) deliberately
|
|
142
|
-
# excludes, and for the reason that comment gives at length —
|
|
143
|
-
# folding a crash into the same `delivered: false` shape as an
|
|
144
|
-
# ordinary refusal makes a broken runtime read as normal operation
|
|
145
|
-
# in the log. This clause does not reopen that hole: it is a
|
|
146
|
-
# second, narrower rescue, tried only once the first one above has
|
|
147
|
-
# already declined to match, so a legitimate refusal still takes
|
|
148
|
-
# the branch above and a defect always takes this one.
|
|
149
|
-
#
|
|
150
|
-
# Catching it here is safe for a fact this method's caller cannot
|
|
151
|
-
# see from where it sits: by the time `react` runs, the command
|
|
152
|
-
# that emitted `event` has already succeeded and persisted —
|
|
153
|
-
# `Dispatcher#dispatch` calls `@policies.react` only after its own
|
|
154
|
-
# `announced` events are already in hand. Letting this exception
|
|
155
|
-
# keep propagating would not undo that command (nothing here is
|
|
156
|
-
# transactional across aggregates) — it would only blow up the
|
|
157
|
-
# original caller's `dispatch` call for a failure that happened in
|
|
158
|
-
# a different command, one the caller never asked to run and has no
|
|
159
|
-
# way to compensate for. So the defect is recorded, distinguishably
|
|
160
|
-
# (`defect: true`, plus the error's own class — nothing here is
|
|
161
|
-
# allowed to read like an ordinary refusal), warned to STDERR so it
|
|
162
|
-
# is never silent, and left exactly where it happened for a human
|
|
163
|
-
# to find — never re-raised, and never swallowed either.
|
|
95
|
+
# A defect, not a refusal: recorded with `defect: true` and warned, never
|
|
96
|
+
# re-raised. The emitting command has already persisted, so propagating would
|
|
97
|
+
# only fail an unrelated caller. See DOMAIN_REFUSALS for why the two stay apart.
|
|
164
98
|
warn "[hecks] defect in reaction — policy #{policy.name} on #{event.name} " \
|
|
165
99
|
"firing #{target}: #{e.class}: #{e.message}"
|
|
166
100
|
record.merge(delivered: false, reason: e.message, defect: true, error_class: e.class.name)
|
|
167
101
|
end
|
|
168
102
|
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
# forwarded payload under whichever key the target command itself
|
|
174
|
-
# expects to be addressed by (`Behaviour::Command#addressing_key_for`
|
|
175
|
-
# — never a guessed, one-size mint: `Account.Freeze`, addressed by
|
|
176
|
-
# `account` because it is declared on Account and self-references
|
|
177
|
-
# it, refused every dispatch for as long as this hardcoded
|
|
178
|
-
# `<aggregate>_id` instead — a real bug, found wiring `for_each`
|
|
179
|
-
# into a real domain for the first time, not a hypothetical). A
|
|
180
|
-
# refusal is recorded per row and the fan-out continues ; a crash
|
|
181
|
-
# resolving the query itself, or the target command's own inability
|
|
182
|
-
# to address this aggregate at all (`addressing_key_for` answering
|
|
183
|
-
# `nil` — a domain-authoring mistake, not a data problem), is a
|
|
184
|
-
# single top-level defect for the policy, the same shape `deliver`'s
|
|
185
|
-
# own outer rescue already gives every other reaction.
|
|
103
|
+
# Runs the `for_each` query against the event payload and fires the trigger once
|
|
104
|
+
# per row, addressing each row by `addressing_key_for`. A refusal is recorded per
|
|
105
|
+
# row and the fan-out continues; a crash resolving the query or an unaddressable
|
|
106
|
+
# target is one top-level defect for the policy.
|
|
186
107
|
def deliver_for_each(policy, event, domain, target, record)
|
|
187
108
|
return nil unless where_holds?(policy, event)
|
|
188
109
|
|
|
189
110
|
query_domain, aggregate_name, query_name = policy.for_each_route(domain)
|
|
190
111
|
aggregate = resolve_query_aggregate(query_domain, aggregate_name, policy.for_each)
|
|
191
|
-
# The query reads the event, never the
|
|
192
|
-
# what the trigger is given, and the fan-out's query is asking a
|
|
193
|
-
# different question (which rows) in the event's own vocabulary.
|
|
112
|
+
# The query reads the event, never the `with:` projection: it asks which rows.
|
|
194
113
|
query_args = for_each_query_args(aggregate.query(query_name), event)
|
|
195
114
|
rows = QueryInterpreter.new(@registry).call(query_domain, aggregate, query_name, query_args)
|
|
196
115
|
reference_key = addressing_key_for(target, aggregate_name)
|
|
@@ -206,24 +125,9 @@ module Hecks
|
|
|
206
125
|
record.merge(delivered: false, reason: e.message, defect: true, error_class: e.class.name)
|
|
207
126
|
end
|
|
208
127
|
|
|
209
|
-
# The event's own identity is
|
|
210
|
-
#
|
|
211
|
-
#
|
|
212
|
-
# very customer who was just suspended) — a fact routing keeps
|
|
213
|
-
# separate from payload (`to:`/`with:`, what the facade's own
|
|
214
|
-
# bang-methods always use), so `event.payload` alone does not carry
|
|
215
|
-
# it. Without this, the query would silently see neither the field
|
|
216
|
-
# it needs nor any error saying why — an empty result read as
|
|
217
|
-
# "nothing to freeze" instead of "the customer" the whole reaction
|
|
218
|
-
# exists to catch.
|
|
219
|
-
#
|
|
220
|
-
# Merged in only when the query declares an argument by that exact
|
|
221
|
-
# name and the emitting aggregate's own identity is genuinely what
|
|
222
|
-
# that name means (`construct.identity_heads`) — the same guard
|
|
223
|
-
# `SagaInterpreter::Correlation#self_identified?` uses for the
|
|
224
|
-
# identical shape one call away, so an unrelated aggregate sharing
|
|
225
|
-
# an argument name by coincidence never gets misread as this one.
|
|
226
|
-
# Never overrides a value the payload already supplied.
|
|
128
|
+
# The event's own identity is not in its payload, so a query argument named
|
|
129
|
+
# after an identity head of the emitting aggregate is filled from `event.id`.
|
|
130
|
+
# Without it the query silently sees nothing. Never overrides a payload value.
|
|
227
131
|
def for_each_query_args(query, event)
|
|
228
132
|
args = event.payload.transform_keys(&:to_sym)
|
|
229
133
|
return args unless query
|
|
@@ -242,26 +146,10 @@ module Hecks
|
|
|
242
146
|
args
|
|
243
147
|
end
|
|
244
148
|
|
|
245
|
-
#
|
|
246
|
-
#
|
|
247
|
-
#
|
|
248
|
-
#
|
|
249
|
-
#
|
|
250
|
-
# Declared, it is the same reading a saga's own `dispatch ...,
|
|
251
|
-
# with:` gets (`SagaInterpreter#dispatch_args`): a Symbol names a
|
|
252
|
-
# field on the source below, anything else is a literal the policy
|
|
253
|
-
# supplies itself. A saga additionally resolves against its own
|
|
254
|
-
# memory and correlation key; a policy has neither — it holds
|
|
255
|
-
# nothing between events — so the source is the event, plus:
|
|
256
|
-
#
|
|
257
|
-
# `extra` is a fan-out's row key, merged into the source before the
|
|
258
|
-
# projection rather than after it. That is what lets a `for_each`
|
|
259
|
-
# policy name the row it is acting on — `with: { account: :account }`
|
|
260
|
-
# — and therefore what lets one send the row and nothing else. A
|
|
261
|
-
# trigger needing only which record to act on is the ordinary case
|
|
262
|
-
# for a fan-out, and before this it could not be written: the whole
|
|
263
|
-
# event rode along, and the target had to declare every field of it
|
|
264
|
-
# whether it read them or not.
|
|
149
|
+
# What the trigger is given: the whole event payload verbatim when no `with:` is
|
|
150
|
+
# declared, otherwise the projection (a Symbol names a payload field, anything else
|
|
151
|
+
# is a literal). `extra` is a fan-out's row key, merged into the source before the
|
|
152
|
+
# projection so a `with:` can name the row it acts on.
|
|
265
153
|
def trigger_args(policy, event, extra = {})
|
|
266
154
|
payload = event.payload.transform_keys(&:to_sym).merge(extra)
|
|
267
155
|
return payload unless ReactionInvocation.projection_declared?(policy)
|
|
@@ -274,44 +162,16 @@ module Hecks
|
|
|
274
162
|
label: "#{policy.name}'s trigger"
|
|
275
163
|
)
|
|
276
164
|
|
|
277
|
-
#
|
|
278
|
-
# Ruby-only shape SagaInterpreter#deliver_saga_dispatch's own
|
|
279
|
-
# saga_dispatch_log gets, for Properties.dispatch_binding_
|
|
280
|
-
# fidelity's own independent re-derivation of Policy#with_spec's
|
|
281
|
-
# 2-branch resolution (Symbol → payload lookup, anything else →
|
|
282
|
-
# literal — a policy holds no correlation and no memory, so
|
|
283
|
-
# `payload` — the merged event-payload-plus-fan-out-row source —
|
|
284
|
-
# is the whole source, unlike a saga's own 4-branch one).
|
|
165
|
+
# Raw inputs kept for Properties.dispatch_binding_fidelity's re-derivation.
|
|
285
166
|
@registry.policy_dispatch_log << { policy: policy.name, on: event.name, payload: payload,
|
|
286
167
|
with_spec: policy.with_spec, args: args }
|
|
287
168
|
args
|
|
288
169
|
end
|
|
289
170
|
|
|
290
|
-
# The emitting record's
|
|
291
|
-
#
|
|
292
|
-
#
|
|
293
|
-
#
|
|
294
|
-
# the emitting aggregate's identity in the payload, which is right
|
|
295
|
-
# for the event (a KnightCaptured is a fact about a knight, not a
|
|
296
|
-
# re-statement of which game) but left a cross-aggregate reaction
|
|
297
|
-
# with no way to say which record to address: chess's Graveyard is
|
|
298
|
-
# one-per-game, fed by policy from every piece's own Captured
|
|
299
|
-
# event, and its burials had no way to name the game — the
|
|
300
|
-
# dispatcher fell through to the captured piece's `id` as the
|
|
301
|
-
# graveyard's identity and refused every one ("no Graveyard with
|
|
302
|
-
# label.value \"bb\""). Same-aggregate targets were already covered
|
|
303
|
-
# (`ReactionInvocation.source_receiver_for` lifts Event.id), so
|
|
304
|
-
# this is the other aggregate's half of that.
|
|
305
|
-
#
|
|
306
|
-
# Offered under the emitting aggregate's own identity heads, only
|
|
307
|
-
# to an explicit projection (a legacy wholesale forward keeps its
|
|
308
|
-
# exact old payload), and never over a value the payload itself
|
|
309
|
-
# carries. `event.id` is the scalar the identity resolves to, so a
|
|
310
|
-
# projection naming it as the target's own identity head routes it
|
|
311
|
-
# as the receiver (`Identity.of` coerces a scalar against a
|
|
312
|
-
# single-field VO head), and one naming it as a declared attribute
|
|
313
|
-
# carries it as a fact. The build-time validator admits the same
|
|
314
|
-
# names (`BluebookBuilder.check_with_spec!`).
|
|
171
|
+
# The emitting record's identity, offered to an explicit `with:` projection under
|
|
172
|
+
# the emitting aggregate's identity heads (never over a payload value). Without it
|
|
173
|
+
# a cross-aggregate reaction cannot say which record to address. The build-time
|
|
174
|
+
# validator admits the same names (`BluebookBuilder.check_with_spec!`).
|
|
315
175
|
def emitter_identity(event)
|
|
316
176
|
return {} if event.id.nil? || event.id.to_s.empty?
|
|
317
177
|
|
|
@@ -322,18 +182,9 @@ module Hecks
|
|
|
322
182
|
construct.identity_heads.to_h { |head| [head.to_sym, event.id] }
|
|
323
183
|
end
|
|
324
184
|
|
|
325
|
-
# Resolves `target`
|
|
326
|
-
# `
|
|
327
|
-
#
|
|
328
|
-
# `aggregate_name` — see `Behaviour::Command#addressing_key_for`'s
|
|
329
|
-
# own comment for the two shapes that answers. Raises (caught by
|
|
330
|
-
# `deliver_for_each`'s own outer `rescue StandardError`, the same
|
|
331
|
-
# "a defect, not a refusal" treatment `resolve_query_aggregate`'s
|
|
332
|
-
# own `UnknownVerb` already gets one level up) rather than
|
|
333
|
-
# silently falling back on a guess when the target command cannot
|
|
334
|
-
# be resolved, or genuinely cannot be addressed by this aggregate
|
|
335
|
-
# at all — either is a domain-authoring mistake worth surfacing
|
|
336
|
-
# loudly, not a row this fan-out simply skips.
|
|
185
|
+
# Resolves `target` back to its declared command and asks it how a row of
|
|
186
|
+
# `aggregate_name` addresses it. Raises rather than guessing when the command is
|
|
187
|
+
# unresolvable or cannot be addressed: a domain-authoring mistake to surface.
|
|
337
188
|
def addressing_key_for(target, aggregate_name)
|
|
338
189
|
target_domain, target_aggregate_name, target_command_name = Naming.split_verb(target)
|
|
339
190
|
command = @registry.bluebook(target_domain)&.aggregate(target_aggregate_name)&.command(target_command_name)
|
|
@@ -355,9 +206,7 @@ module Hecks
|
|
|
355
206
|
reason: "reaction depth #{@door.max_reaction_depth} reached")
|
|
356
207
|
end
|
|
357
208
|
|
|
358
|
-
#
|
|
359
|
-
# source a `with:` projection reads from, not bolted onto its
|
|
360
|
-
# result, or a projection could never name the row it acts on.
|
|
209
|
+
# The row key is already merged by `trigger_args`, so a projection can name it.
|
|
361
210
|
@door.reenter(target, **reaction_invocation(target, args, policy, event))
|
|
362
211
|
row_record.merge(delivered: true)
|
|
363
212
|
rescue *DOMAIN_REFUSALS => e
|
|
@@ -374,14 +223,6 @@ module Hecks
|
|
|
374
223
|
)
|
|
375
224
|
end
|
|
376
225
|
|
|
377
|
-
# `for_each`'s own query route moved onto the Policy itself
|
|
378
|
-
# (Behaviour::Policy#for_each_route) — one reading the interpreter
|
|
379
|
-
# and the fuzzer's fan-out property both call, rather than the
|
|
380
|
-
# same split spelled twice. The reference-key the dispatch itself
|
|
381
|
-
# uses is `addressing_key_for`, above — a property of the target
|
|
382
|
-
# command, not of the policy, so it lives on `Behaviour::Command`
|
|
383
|
-
# instead.
|
|
384
|
-
|
|
385
226
|
def resolve_query_aggregate(domain, aggregate_name, verb)
|
|
386
227
|
bluebook = @registry.bluebook(domain) ||
|
|
387
228
|
raise(UnknownVerb, RefusalWording.render_site("UnknownVerb", "no_domain", domain: domain, verb: verb))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require_relative "adapter_lookup"
|
|
1
2
|
require_relative "interpreting"
|
|
2
3
|
require_relative "command_interpreter/argument_gate"
|
|
3
4
|
require_relative "event"
|
|
@@ -6,15 +7,8 @@ require_relative "../naming"
|
|
|
6
7
|
|
|
7
8
|
module Hecks
|
|
8
9
|
module Runtime
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# a trimmed CommandInterpreter: the same payload gate and coercion
|
|
12
|
-
# (ArgumentGate, Interpreting#normalize_args), but no `given`, no
|
|
13
|
-
# `mutations`, no lifecycle, no save. A port operation does not act on an
|
|
14
|
-
# aggregate instance — it translates an external call into an event in
|
|
15
|
-
# this domain's own vocabulary, and whatever mutation follows happens
|
|
16
|
-
# wherever a `policy` reacts to that event, exactly as it would for any
|
|
17
|
-
# command-emitted one.
|
|
10
|
+
# Dispatch pipeline for a port operation, called by an adapter outside the bluebook.
|
|
11
|
+
# A trimmed CommandInterpreter: argument gate and coercion, but no `given`, mutations or save.
|
|
18
12
|
class PortOperationInterpreter
|
|
19
13
|
include Interpreting
|
|
20
14
|
include CommandInterpreter::ArgumentGate
|
|
@@ -34,24 +28,17 @@ module Hecks
|
|
|
34
28
|
@rules = rules
|
|
35
29
|
end
|
|
36
30
|
|
|
37
|
-
# `
|
|
38
|
-
# `ctx.args` is its `to_args`, `ctx.route` its `target`.
|
|
39
|
-
#
|
|
31
|
+
# `ctx.args` is the invocation's `to_args`, `ctx.route` its `target`.
|
|
40
32
|
# @param domain [String] the domain the aggregate belongs to
|
|
41
33
|
# @param aggregate [Bluebook::Aggregate] the aggregate the port operation belongs to
|
|
42
34
|
# @param operation [Bluebook::PortOperation] the port operation to dispatch
|
|
43
35
|
# @param invocation [Runtime::Invocation] the invocation `Dispatcher` built for this call
|
|
44
|
-
# @return [Array<Runtime::Event>]
|
|
45
|
-
# an
|
|
46
|
-
#
|
|
47
|
-
# @raise [Runtime::
|
|
48
|
-
#
|
|
49
|
-
# @raise [Runtime::
|
|
50
|
-
# argument
|
|
51
|
-
# @raise [Runtime::TypeMismatch] if an offered argument does not coerce to its declared
|
|
52
|
-
# type
|
|
53
|
-
# @raise [Runtime::NotFound] if an offered reference or the operation's own receiving
|
|
54
|
-
# record cannot be found
|
|
36
|
+
# @return [Array<Runtime::Event>] `emits` (inbound), or one `answers`/`refuses`
|
|
37
|
+
# event (outbound; an adapter failure is recorded as `refuses`, not raised)
|
|
38
|
+
# @raise [Runtime::UnknownArgument] if `invocation` offers an undeclared argument
|
|
39
|
+
# @raise [Runtime::AbsentArgument] if `invocation` omits a non-optional declared argument
|
|
40
|
+
# @raise [Runtime::TypeMismatch] if an offered argument does not coerce to its declared type
|
|
41
|
+
# @raise [Runtime::NotFound] if an offered reference or the receiving record is missing
|
|
55
42
|
def call(domain, aggregate, operation, invocation)
|
|
56
43
|
ctx = Context.new(domain, aggregate, operation, invocation.to_args)
|
|
57
44
|
ctx.invocation = invocation
|
|
@@ -89,37 +76,13 @@ module Hecks
|
|
|
89
76
|
ctx.result = step(:emit) { ctx.operation.outbound? ? ask(ctx) : emit(ctx) }
|
|
90
77
|
end
|
|
91
78
|
|
|
92
|
-
# The domain calling out,
|
|
93
|
-
#
|
|
94
|
-
# The adapter is found
|
|
95
|
-
# across whatever adapters this boot loaded — so an `asks` is bound by
|
|
96
|
-
# an adapter declaring `port "IssueTracker"` and nothing new to learn.
|
|
97
|
-
#
|
|
98
|
-
# Every failure is an answer. A raise from the far side of a boundary is
|
|
99
|
-
# not an exception in this domain's terms, it is the outside saying no,
|
|
100
|
-
# and the chapter already named the word for that. So the rescue is
|
|
101
|
-
# deliberately wide: a timeout, a bad credential, an adapter that does
|
|
102
|
-
# not exist, a nil where a number was wanted — all of them become the
|
|
103
|
-
# `refuses` event, carrying what was said. A policy reacts to it, a
|
|
104
|
-
# retry counter reads it, and nothing has to catch anything.
|
|
105
|
-
#
|
|
106
|
-
# An ask is handed the record it is about.
|
|
107
|
-
#
|
|
108
|
-
# An inbound operation deliberately cannot read state — it is the
|
|
109
|
-
# anti-corruption boundary, translating a fact from outside, and letting
|
|
110
|
-
# it read the aggregate would make it a second place rules live. That
|
|
111
|
-
# rule was written for that direction and does not survive the crossing.
|
|
79
|
+
# The domain calling out. Any failure, however wide (timeout, bad credential, missing
|
|
80
|
+
# adapter), becomes the `refuses` event rather than a raise, so a policy can react to it.
|
|
81
|
+
# The adapter is found by port name across the adapters this boot loaded.
|
|
112
82
|
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
# triggered this cannot supply because a command's event payload is its
|
|
117
|
-
# arguments, not its state. Without this, every ask would have to have
|
|
118
|
-
# its data re-passed through the command that fired it, so the same text
|
|
119
|
-
# would live in two places and could differ.
|
|
120
|
-
#
|
|
121
|
-
# Arguments win over state, because an argument is what this call said
|
|
122
|
-
# and state is what the record happens to hold.
|
|
83
|
+
# Unlike an inbound operation, an ask is handed the record's held state: the adapter
|
|
84
|
+
# needs data that lives on the record, and an event payload carries only arguments.
|
|
85
|
+
# Arguments win over state.
|
|
123
86
|
def ask(ctx)
|
|
124
87
|
payload = held_state(ctx).merge(materialise(ctx.args))
|
|
125
88
|
answer = adapter_for(ctx).public_send(Naming.snake(ctx.operation.hecks_name), **payload)
|
|
@@ -128,21 +91,10 @@ module Hecks
|
|
|
128
91
|
announce(ctx, ctx.operation.refuses, ctx.args.merge(refusal: { value: "#{e.class}: #{e.message}" }))
|
|
129
92
|
end
|
|
130
93
|
|
|
131
|
-
# The answer is spread, not nested
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# should record the issue number never gets one.
|
|
136
|
-
#
|
|
137
|
-
# Spread, the adapter's own keys are the arguments of whatever command
|
|
138
|
-
# reacts to the answering event. Which is a real contract on the adapter
|
|
139
|
-
# — it must return what that command takes, in the shape the runtime
|
|
140
|
-
# coerces (`{ number: { value: 43 } }`, not `43`) — and naming it here
|
|
141
|
-
# is cheaper than a mapping layer nobody could see into.
|
|
142
|
-
#
|
|
143
|
-
# A non-Hash answer keeps the old shape: a port that returns a URL
|
|
144
|
-
# string has nothing to spread, and `answered:` is the honest word for
|
|
145
|
-
# a single unnamed value.
|
|
94
|
+
# The answer is spread, not nested: a policy re-enters its target with the event
|
|
95
|
+
# payload verbatim and cannot reach inside a key. The adapter's keys are therefore the
|
|
96
|
+
# arguments of the reacting command, in the shape the runtime coerces
|
|
97
|
+
# (`{ number: { value: 43 } }`, not `43`). A non-Hash answer is kept under `answered:`.
|
|
146
98
|
def spread(answer)
|
|
147
99
|
return { answered: answer } unless answer.is_a?(Hash)
|
|
148
100
|
|
|
@@ -157,21 +109,16 @@ module Hecks
|
|
|
157
109
|
end
|
|
158
110
|
end
|
|
159
111
|
|
|
160
|
-
# The record, if there is one. A record
|
|
161
|
-
#
|
|
162
|
-
# whatever the adapter makes of that is its own business. Refusing
|
|
163
|
-
# would put a second existence check behind the one `resolve_references`
|
|
164
|
-
# already performed.
|
|
112
|
+
# The record, if there is one. A missing record is not an error here: the ask still
|
|
113
|
+
# goes with only its arguments, since `resolve_references` already checked existence.
|
|
165
114
|
def held_state(ctx)
|
|
166
115
|
ctx.instance ? Value.materialize(ctx.instance.state) : {}
|
|
167
116
|
rescue StandardError
|
|
168
117
|
{}
|
|
169
118
|
end
|
|
170
119
|
|
|
171
|
-
# The port this operation belongs to, found
|
|
172
|
-
#
|
|
173
|
-
# resolved it once to get here, and a second parameter carried purely so
|
|
174
|
-
# this method can read it would be a parameter every other step ignores.
|
|
120
|
+
# The port this operation belongs to, found through the aggregate rather than
|
|
121
|
+
# threaded through the call.
|
|
175
122
|
def port_name_for(ctx)
|
|
176
123
|
owning = ctx.aggregate.ports.find { |port| port.operations.any? { |op| op.equal?(ctx.operation) } }
|
|
177
124
|
owning&.name or raise WiringError,
|
|
@@ -179,21 +126,10 @@ module Hecks
|
|
|
179
126
|
end
|
|
180
127
|
|
|
181
128
|
def adapter_for(ctx)
|
|
182
|
-
|
|
183
|
-
implementations = @registry.adapters.values.select { |adapter| adapter.port == name }
|
|
184
|
-
|
|
185
|
-
case implementations.size
|
|
186
|
-
when 1 then Adapters.const_get(implementations.first.name).new
|
|
187
|
-
when 0 then raise WiringError, "no adapter implements the #{name} port — nothing can answer #{ctx.operation.hecks_name}"
|
|
188
|
-
else raise WiringError,
|
|
189
|
-
"#{implementations.size} adapters implement the #{name} port " \
|
|
190
|
-
"(#{implementations.map(&:name).sort.join(', ')}) — the runtime will not choose for you"
|
|
191
|
-
end
|
|
129
|
+
AdapterLookup.call(@registry, port_name_for(ctx), asked: ctx.operation.hecks_name)
|
|
192
130
|
end
|
|
193
131
|
|
|
194
|
-
#
|
|
195
|
-
# code and should be handed plain data, the same reasoning `JsonDoor`
|
|
196
|
-
# gives for materialising before it hands anything to an HTTP caller.
|
|
132
|
+
# Adapters are handed plain data, never a Value.
|
|
197
133
|
def materialise(args) = Value.materialize(args)
|
|
198
134
|
|
|
199
135
|
def announce(ctx, event_name, payload)
|
|
@@ -208,13 +144,8 @@ module Hecks
|
|
|
208
144
|
[event]
|
|
209
145
|
end
|
|
210
146
|
|
|
211
|
-
#
|
|
212
|
-
#
|
|
213
|
-
# saved. The record this event is about is named by whichever attribute
|
|
214
|
-
# is a reference to the owning aggregate (PortOperationBuilder#build
|
|
215
|
-
# already refused to build an operation with none), so its coerced
|
|
216
|
-
# value — already a plain id, never an object, per
|
|
217
|
-
# Value::Coercion#refuse_object_reference — is what stamps the event.
|
|
147
|
+
# Unlike CommandRules::Emission there is no mutated instance to read an id off; the
|
|
148
|
+
# event is stamped with the coerced reference to the owning aggregate (already a plain id).
|
|
218
149
|
def emit(ctx)
|
|
219
150
|
ctx.operation.emits.map do |event_name|
|
|
220
151
|
event = Event.new(
|