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
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require_relative "errors"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Runtime
|
|
5
|
+
# Finds the one adapter this boot loaded for a port name.
|
|
6
|
+
#
|
|
7
|
+
# Shared by the port-operation interpreter (an aggregate asking out) and the query interpreter
|
|
8
|
+
# (a query answered by a port), so both refuse the same way when nothing, or too much,
|
|
9
|
+
# implements the port.
|
|
10
|
+
module AdapterLookup
|
|
11
|
+
@stand_in = nil
|
|
12
|
+
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# Modules whose instance methods every object inherits; a method they own answers no query.
|
|
16
|
+
INHERITED_OWNERS = [Object, Kernel, BasicObject].freeze
|
|
17
|
+
|
|
18
|
+
# Answers every port with a stand-in instead of its adapter while the block runs, for a
|
|
19
|
+
# caller that must not reach what the adapters reach (the fuzzer replays a domain whose
|
|
20
|
+
# adapters run shells and write files). Boot still checks the real adapters' classes; only
|
|
21
|
+
# what `call` hands out changes.
|
|
22
|
+
#
|
|
23
|
+
# @param stand_in [#call] answers `(port_name, asked)` with the object to ask instead
|
|
24
|
+
# @yield the work to run with the stand-in in place
|
|
25
|
+
# @return [Object] what the block answers
|
|
26
|
+
def standing_in(stand_in)
|
|
27
|
+
previous = @stand_in
|
|
28
|
+
@stand_in = stand_in
|
|
29
|
+
yield
|
|
30
|
+
ensure
|
|
31
|
+
@stand_in = previous
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param registry [Runtime::Registry] the booted registry whose adapters are searched
|
|
35
|
+
# @param port_name [String] the port's name as an adapter declares it
|
|
36
|
+
# @param asked [String] what is being asked, worded into a refusal
|
|
37
|
+
# @return [Object] a new instance of the port's only adapter, or the stand-in for it
|
|
38
|
+
# @raise [Runtime::WiringError] if no adapter, or more than one, implements the port
|
|
39
|
+
def call(registry, port_name, asked:)
|
|
40
|
+
adapter_class(registry, port_name, asked: asked)
|
|
41
|
+
return @stand_in.call(port_name, asked) if @stand_in
|
|
42
|
+
|
|
43
|
+
adapter_class(registry, port_name, asked: asked).new
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Finds the class of the one adapter this boot loaded for a port name, without building it,
|
|
47
|
+
# so boot can check what the adapter answers before anything asks it.
|
|
48
|
+
#
|
|
49
|
+
# @param registry [Runtime::Registry] the booted registry whose adapters are searched
|
|
50
|
+
# @param port_name [String] the port's name as an adapter declares it
|
|
51
|
+
# @param asked [String] what is being asked, worded into a refusal
|
|
52
|
+
# @return [Class] the port's only adapter
|
|
53
|
+
# @raise [Runtime::WiringError] if no adapter, or more than one, implements the port
|
|
54
|
+
def adapter_class(registry, port_name, asked:)
|
|
55
|
+
implementations = registry.adapters.values.select { |adapter| adapter.port == port_name }
|
|
56
|
+
|
|
57
|
+
case implementations.size
|
|
58
|
+
when 1 then Adapters.const_get(implementations.first.name)
|
|
59
|
+
when 0 then raise WiringError, "no adapter implements the #{port_name} port — nothing can answer #{asked}"
|
|
60
|
+
else raise WiringError,
|
|
61
|
+
"#{implementations.size} adapters implement the #{port_name} port " \
|
|
62
|
+
"(#{implementations.map(&:name).sort.join(', ')}) — the runtime will not choose for you"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Checks that an adapter class can be built with a bare `.new` and answers a query: it
|
|
67
|
+
# defines the method itself (not inherited from Object or Kernel, so a query named `hash` or
|
|
68
|
+
# `display` is not answered by them) and takes exactly the query's arguments as keywords.
|
|
69
|
+
#
|
|
70
|
+
# @param klass [Class] the adapter class {adapter_class} found
|
|
71
|
+
# @param port_name [String] the port's name, worded into a refusal
|
|
72
|
+
# @param method [String] the snake-cased query name the adapter is asked by
|
|
73
|
+
# @param query [Bluebook::Query] the declared query whose arguments the method must take
|
|
74
|
+
# @param asked [String] what is being asked, worded into a refusal
|
|
75
|
+
# @return [void]
|
|
76
|
+
# @raise [Runtime::WiringError] if the constructor needs arguments, the method is missing or
|
|
77
|
+
# inherited, or its keywords do not match the query's arguments
|
|
78
|
+
def check_answers!(klass, port_name, method, query, asked:)
|
|
79
|
+
required = klass.instance_method(:initialize).parameters.filter_map { |kind, name| name if %i[req keyreq].include?(kind) }
|
|
80
|
+
unless required.empty?
|
|
81
|
+
raise WiringError, "#{klass} implements the #{port_name} port but its constructor requires " \
|
|
82
|
+
"#{required.join(', ')} — it is built with no arguments"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
unless klass.public_method_defined?(method) &&
|
|
86
|
+
!INHERITED_OWNERS.include?(klass.public_instance_method(method).owner)
|
|
87
|
+
raise WiringError, "#{klass} implements the #{port_name} port but not ##{method}, " \
|
|
88
|
+
"which answers #{asked}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
check_keywords!(klass, method, query, asked)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# @raise [Runtime::WiringError] if the method takes a positional argument, requires a keyword
|
|
95
|
+
# the query does not require, or accepts none of a declared argument
|
|
96
|
+
def check_keywords!(klass, method, query, asked)
|
|
97
|
+
parameters = klass.public_instance_method(method).parameters
|
|
98
|
+
wanted = query.attributes.map { |attribute| attribute.name.to_sym }
|
|
99
|
+
required = query.attributes.reject(&:optional?).map { |attribute| attribute.name.to_sym }
|
|
100
|
+
problems = keyword_problems(parameters, wanted, required)
|
|
101
|
+
return if problems.empty?
|
|
102
|
+
|
|
103
|
+
raise WiringError, "#{klass}##{method} answers #{asked} but #{problems.join(' and ')} — it is asked " \
|
|
104
|
+
"with keywords for the query's arguments (#{wanted.empty? ? 'none' : wanted.join(', ')})"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# @return [Array<String>] how `parameters` fails to take exactly the `wanted` keywords
|
|
108
|
+
def keyword_problems(parameters, wanted, required)
|
|
109
|
+
kinds = parameters.map(&:first)
|
|
110
|
+
taken = parameters.select { |kind, _| kind.to_s.start_with?("key") && kind != :keyrest }.map(&:last)
|
|
111
|
+
missing = kinds.include?(:keyrest) ? [] : wanted - taken
|
|
112
|
+
extra = parameters.select { |kind, name| kind == :keyreq && !required.include?(name) }.map(&:last)
|
|
113
|
+
[("takes positional arguments" if kinds.intersect?(%i[req opt rest])),
|
|
114
|
+
keyword_problem("does not take", missing),
|
|
115
|
+
keyword_problem("requires", extra, ", which the query does not")].compact
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @return [String, nil] a phrase naming `names` as keywords, or nil when there are none
|
|
119
|
+
def keyword_problem(verb, names, suffix = "")
|
|
120
|
+
"#{verb} #{names.map { |name| "#{name}:" }.join(', ')}#{suffix}" unless names.empty?
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -1,29 +1,10 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Runtime
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# `:optimistic_concurrency` (Heki, Memory today; see
|
|
6
|
-
# `CommandInterpreter#call`/`EntityInterpreter#call`, which choose
|
|
7
|
-
# between this and Postgres's CAS+retry purely off
|
|
8
|
-
# `repository.capabilities`).
|
|
3
|
+
# A process-wide, striped mutex registry, keyed by `[domain, aggregate, id]`.
|
|
4
|
+
# Serializes hydrate-through-save for adapters without `:optimistic_concurrency`.
|
|
9
5
|
#
|
|
10
|
-
#
|
|
11
|
-
# process
|
|
12
|
-
# states the confirmed fact this relies on — two `Runtime.boot` calls
|
|
13
|
-
# get two entirely separate adapter instances; there is never a second
|
|
14
|
-
# process writing the same Heki file or the same Memory Hash, only
|
|
15
|
-
# possibly other threads within this one process. A `Mutex` held for
|
|
16
|
-
# the full hydrate-through-save critical section closes the identical
|
|
17
|
-
# lost-update gap CAS closes for Postgres, with no schema, no version
|
|
18
|
-
# column, and no retry loop — the second thread simply doesn't start
|
|
19
|
-
# its own hydrate until the first thread's save has landed.
|
|
20
|
-
#
|
|
21
|
-
# **Striped, not one global lock**: keyed by `[domain, aggregate.hecks_name,
|
|
22
|
-
# id]`, so two dispatches against two different records never block
|
|
23
|
-
# each other. The registry Hash itself is guarded by its own top-level
|
|
24
|
-
# Mutex only for the moment a new per-key Mutex is created — two
|
|
25
|
-
# threads locking different keys for the first time never wait on one
|
|
26
|
-
# another beyond that brief creation window.
|
|
6
|
+
# A lock suffices because those adapters (Heki, Memory) hold process-local data:
|
|
7
|
+
# only threads of this process can write the same record.
|
|
27
8
|
module AggregateLock
|
|
28
9
|
@registry_lock = Mutex.new
|
|
29
10
|
@locks = {}
|
|
@@ -31,19 +12,13 @@ module Hecks
|
|
|
31
12
|
class << self
|
|
32
13
|
# Returns the Mutex striped to one record, creating it on first use.
|
|
33
14
|
#
|
|
34
|
-
#
|
|
35
|
-
# `id: nil` — identity could not be resolved yet (see
|
|
36
|
-
# `Identity.best_effort`) — locks by aggregate type alone, coarser
|
|
37
|
-
# (every record of this aggregate serializes against every other)
|
|
38
|
-
# but still correct: it can only ever make dispatch more
|
|
39
|
-
# conservative than a resolved id would.
|
|
15
|
+
# AggregateLock.for(domain, aggregate, id).synchronize { ... }
|
|
40
16
|
#
|
|
41
17
|
# @param domain [String] the domain the aggregate belongs to
|
|
42
18
|
# @param aggregate [Bluebook::Aggregate] the aggregate being dispatched
|
|
43
|
-
# @param id [String, nil] the
|
|
44
|
-
#
|
|
45
|
-
# @return [Mutex] the mutex for this `[domain, aggregate, id]` key
|
|
46
|
-
# hydrate-through-save critical section
|
|
19
|
+
# @param id [String, nil] the record id; nil locks by aggregate type alone, which
|
|
20
|
+
# is coarser but still correct
|
|
21
|
+
# @return [Mutex] the mutex for this `[domain, aggregate, id]` key
|
|
47
22
|
def for(domain, aggregate, id = nil)
|
|
48
23
|
key = id.nil? ? [domain.to_s, aggregate.hecks_name] : [domain.to_s, aggregate.hecks_name, id.to_s]
|
|
49
24
|
@registry_lock.synchronize { @locks[key] ||= Mutex.new }
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Runtime
|
|
3
|
-
# A boot's own
|
|
4
|
-
#
|
|
5
|
-
# call, never a module-level singleton: a process that boots more than
|
|
6
|
-
# one registry in its lifetime (every spec suite does) must never let
|
|
7
|
-
# one boot's capability profile leak into the next boot's gate list.
|
|
3
|
+
# A boot's own set of phase-tagged, conditionally-present gates (ADR 0031).
|
|
4
|
+
# A gate is anything responding to `.call(registry, directory)`; run in registration order.
|
|
8
5
|
#
|
|
9
|
-
#
|
|
10
|
-
# module method handed over as a `Method` object (`EraCheck.method
|
|
11
|
-
# (:check_lineage!)`) needs no wrapper; a bare block does. Phases run
|
|
12
|
-
# in the order `run!` is called, gates within a phase in registration
|
|
13
|
-
# order — today exactly one gate per phase, so ordering among
|
|
14
|
-
# same-phase gates has never been exercised.
|
|
15
|
-
#
|
|
16
|
-
# This is deliberately not the same registry `Hecks::Projector` uses
|
|
17
|
-
# (ADR 0027) — that one is a process-wide, static IR-in/artifact-out
|
|
18
|
-
# registry with no bindings and no live-state mutation; this one is
|
|
19
|
-
# per-boot and gates real I/O (a Postgres mint, a saga-store read).
|
|
20
|
-
# Sharing a primitive between them is deferred until a third consumer
|
|
21
|
-
# actually wants it (0031's own Rejected Alternatives).
|
|
6
|
+
# Instance-scoped, one per `Loader.boot`, so one boot's gates never leak into the next.
|
|
22
7
|
class BootGates
|
|
23
8
|
# @return [void]
|
|
24
9
|
def initialize
|
data/lib/hecks/runtime/caller.rb
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Runtime
|
|
3
|
-
# Who is dispatching, bound for the duration of a block
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# time (single-threaded by construction), this happens at dispatch
|
|
7
|
-
# time, which a future per-request caller (docs/rails-integration.md's
|
|
8
|
-
# still-unbuilt `WebDoor`) needs to bind safely under concurrency.
|
|
9
|
-
#
|
|
10
|
-
# A child `Thread.new` spawned mid-block does not inherit this — plain
|
|
11
|
-
# Ruby thread-local semantics — but nothing in this codebase spawns a
|
|
12
|
-
# worker thread mid-dispatch today, so this is a fact worth naming
|
|
13
|
-
# rather than a gap worth solving.
|
|
3
|
+
# Who is dispatching, bound for the duration of a block.
|
|
4
|
+
# `Thread.current`-backed, so per-request callers bind safely under concurrency;
|
|
5
|
+
# a child thread spawned mid-block does not inherit it.
|
|
14
6
|
module Caller
|
|
15
|
-
#
|
|
16
|
-
# here — a caller that states only a role (every caller before this)
|
|
17
|
-
# is checked the way it always was, string equality against the
|
|
18
|
-
# command's own `role`. A caller that also names who it is lets
|
|
19
|
-
# `CommandRules::Authorization` check a real Governance
|
|
20
|
-
# `RoleAssignment` instead, once the command's domain has Governance
|
|
21
|
-
# attached — see that module's own header for the full split.
|
|
7
|
+
# The bound caller: a role, plus optional `actor_id`, `as_of` and `scope`.
|
|
22
8
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# inside the interpreter (see `Ports::Clock`'s own header), so
|
|
27
|
-
# there is no other place to source it from. `scope` stays here
|
|
28
|
-
# rather than becoming a command-level DSL construct on purpose —
|
|
29
|
-
# a scope check that lived in the bluebook would put an
|
|
30
|
-
# authorization concern inside the domain declaration itself; this
|
|
31
|
-
# keeps it an application-boundary fact instead, the same shape
|
|
32
|
-
# `role`/`actor_id` already are. The tradeoff: a caller states what
|
|
33
|
-
# scope it is acting in, and `holds_role?` verifies a live grant
|
|
34
|
-
# exists for that scope — it does not independently confirm the
|
|
35
|
-
# scope matches whatever the command's own target data belongs to.
|
|
9
|
+
# All but `role` are self-asserted by the caller, not derived from the command;
|
|
10
|
+
# `scope` is deliberately not a DSL construct, and `holds_role?` checks only that a grant
|
|
11
|
+
# exists for it, not that it matches the command's target data.
|
|
36
12
|
Current = Struct.new(:role, :actor_id, :as_of, :scope, keyword_init: true)
|
|
37
13
|
|
|
38
14
|
module_function
|
|
@@ -43,27 +19,17 @@ module Hecks
|
|
|
43
19
|
# block is on the stack for this thread
|
|
44
20
|
def current = Thread.current[:hecks_caller]
|
|
45
21
|
|
|
46
|
-
# Binds the ambient caller for the duration of the block, restoring
|
|
47
|
-
#
|
|
22
|
+
# Binds the ambient caller for the duration of the block, restoring the previous
|
|
23
|
+
# one even if the block raises.
|
|
48
24
|
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
# @param
|
|
55
|
-
#
|
|
56
|
-
# @
|
|
57
|
-
# `CommandRules::Authorization` check a real Governance `RoleAssignment`
|
|
58
|
-
# instead of the bare role-string comparison
|
|
59
|
-
# @param as_of [Integer, nil] Unix epoch seconds the caller asserts as "now",
|
|
60
|
-
# filled at the door from `Ports::Clock.now`; nil leaves a `RoleAssignment`'s
|
|
61
|
-
# `starts_at` unchecked
|
|
62
|
-
# @param scope [String, nil] the scope the caller states it is acting in,
|
|
63
|
-
# checked against the matching `RoleAssignment`'s own `scope`; nil skips
|
|
64
|
-
# that check
|
|
65
|
-
# @yield the code that should see `role`/`actor_id`/`as_of`/`scope` as the
|
|
66
|
-
# ambient caller
|
|
25
|
+
# @param role [String] the role the caller holds, checked against the command's `role`
|
|
26
|
+
# @param actor_id [String, nil] who the caller is; when given, `CommandRules::Authorization`
|
|
27
|
+
# checks a real Governance `RoleAssignment`
|
|
28
|
+
# @param as_of [Integer, nil] Unix epoch seconds taken as "now"; nil leaves a
|
|
29
|
+
# `RoleAssignment`'s `starts_at` unchecked
|
|
30
|
+
# @param scope [String, nil] the scope acted in, checked against the `RoleAssignment`'s
|
|
31
|
+
# `scope`; nil skips that check
|
|
32
|
+
# @yield the code that sees these values as the ambient caller
|
|
67
33
|
# @return [Object] the block's result
|
|
68
34
|
def as(role:, actor_id: nil, as_of: nil, scope: nil)
|
|
69
35
|
previous = Thread.current[:hecks_caller]
|
|
@@ -75,14 +41,8 @@ module Hecks
|
|
|
75
41
|
Thread.current[:hecks_caller] = previous
|
|
76
42
|
end
|
|
77
43
|
|
|
78
|
-
# Clears the ambient caller for the duration of the block, restoring
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
# A reaction is the system acting, not the caller who happened to be
|
|
82
|
-
# on the stack when the triggering command ran — `Dispatcher#reenter`
|
|
83
|
-
# clears the ambient caller around a reaction's own dispatch so a
|
|
84
|
-
# triggering caller's role can neither satisfy nor block a reaction
|
|
85
|
-
# command it has nothing to do with.
|
|
44
|
+
# Clears the ambient caller for the duration of the block, restoring the previous one.
|
|
45
|
+
# A reaction is the system acting, so `Dispatcher#reenter` clears the caller around it.
|
|
86
46
|
#
|
|
87
47
|
# @yield the code that should see no ambient caller bound
|
|
88
48
|
# @return [Object] the block's result
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Runtime
|
|
3
|
-
# Which ports a boot can
|
|
4
|
-
#
|
|
5
|
-
# on ; `registry.adapters` names every adapter wired to implement one — the
|
|
6
|
-
# same `adapter.port == port.name` match `Ports::Extraction` and
|
|
7
|
-
# `Ports::IdentityGeneration` already make for themselves, one at a time,
|
|
8
|
-
# each time they resolve. This is that same question asked once, for
|
|
9
|
-
# every port at once, so a gap in the wiring is something a caller can ask
|
|
10
|
-
# about rather than something a live dispatch discovers by refusing.
|
|
11
|
-
#
|
|
12
|
-
# `cycles` answers `[]`, always, and honestly: nothing in this port model
|
|
13
|
-
# lets one port depend on another — a port names a verb and a signal, an
|
|
14
|
-
# adapter names the port it implements, and neither can point at a third
|
|
15
|
-
# port. There is no edge for a cycle to be made of.
|
|
3
|
+
# Which ports a boot can fulfill: each declared port matched to the adapters wired to it,
|
|
4
|
+
# so a wiring gap can be asked about before a dispatch refuses.
|
|
16
5
|
class CapabilityGraph
|
|
17
6
|
# @param registry [Runtime::Registry] the booted registry to read ports and adapters from
|
|
18
7
|
# @return [void]
|
|
@@ -20,9 +9,7 @@ module Hecks
|
|
|
20
9
|
@registry = registry
|
|
21
10
|
end
|
|
22
11
|
|
|
23
|
-
#
|
|
24
|
-
# declares — including the ports nothing implements, so a caller can
|
|
25
|
-
# tell "declared, unfulfilled" from "never declared at all".
|
|
12
|
+
# Maps each declared port's name to the names of its adapters, unfulfilled ports included.
|
|
26
13
|
#
|
|
27
14
|
# @return [Hash{String => Array<String>}] each declared port's name mapped to the names
|
|
28
15
|
# of every adapter bound to it (empty when none are)
|
|
@@ -30,17 +17,14 @@ module Hecks
|
|
|
30
17
|
@fulfillments ||= @registry.ports.each_key.to_h { |name| [name, adapters_for(name)] }
|
|
31
18
|
end
|
|
32
19
|
|
|
33
|
-
# The ports with zero adapters bound
|
|
34
|
-
# would otherwise only surface at the moment something tries to dispatch
|
|
35
|
-
# through one.
|
|
20
|
+
# The ports with zero adapters bound.
|
|
36
21
|
#
|
|
37
22
|
# @return [Array<String>] the names of every declared port with no adapter bound to it
|
|
38
23
|
def unfulfilled
|
|
39
24
|
fulfillments.select { |_, adapters| adapters.empty? }.keys
|
|
40
25
|
end
|
|
41
26
|
|
|
42
|
-
# Reports the port-dependency cycles
|
|
43
|
-
# header for why no port model here can express one.
|
|
27
|
+
# Reports the port-dependency cycles; always none, as a port cannot depend on another port.
|
|
44
28
|
#
|
|
45
29
|
# @return [Array] always empty
|
|
46
30
|
def cycles = []
|
|
@@ -5,37 +5,21 @@ require_relative "../refusal_wording"
|
|
|
5
5
|
module Hecks
|
|
6
6
|
module Runtime
|
|
7
7
|
class CommandInterpreter
|
|
8
|
-
# The payload gate: a command takes the arguments it declares
|
|
9
|
-
# them, and no others.
|
|
8
|
+
# The payload gate: a command takes the arguments it declares, all of them and no others.
|
|
10
9
|
module ArgumentGate
|
|
11
10
|
private
|
|
12
11
|
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# misspelled argument would do nothing, in silence.
|
|
12
|
+
# Refuses any argument the command does not declare.
|
|
13
|
+
# Addressing keys (`id`, the aggregate's identity heads, the reference key)
|
|
14
|
+
# and saga correlation keys are allowed through.
|
|
17
15
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# identified by, and the reference key of the root a command reaches
|
|
21
|
-
# through. Refusing those would refuse every dispatch there is.
|
|
22
|
-
#
|
|
23
|
-
# `extra_identity_heads:` — EntityInterpreter's own callers only. An
|
|
24
|
-
# entity dispatch addresses not just the root aggregate but every
|
|
25
|
-
# entity along the chain it walks to reach the piece the command
|
|
26
|
-
# actually belongs to (`Handler.Dispatch.Bind` is two hops), and each
|
|
27
|
-
# hop's own `identity_heads` is addressing the same way the root's
|
|
28
|
-
# are — `element_of` (entity_element.rb) reads them straight out of
|
|
29
|
-
# `args` to find the element, never as a fact the command itself
|
|
30
|
-
# declares. `[]` for a plain aggregate/port-operation dispatch, which
|
|
31
|
-
# has no chain to add.
|
|
16
|
+
# `extra_identity_heads:` carries the identity heads of each entity hop an entity
|
|
17
|
+
# dispatch walks; `[]` for a plain aggregate or port-operation dispatch.
|
|
32
18
|
def refuse_unknown_arguments(domain, aggregate, command, args, extra_identity_heads: [])
|
|
33
19
|
addressing = [:id, *aggregate.identity_heads, *extra_identity_heads, reference_key(command)] +
|
|
34
20
|
correlation_keys(domain)
|
|
35
21
|
known = (command.attributes.map(&:name) + addressing).compact.map(&:to_sym)
|
|
36
|
-
# Sorted
|
|
37
|
-
# refusal wording is contract — pinned byte-for-byte by the corpus, so
|
|
38
|
-
# it cannot depend on hash iteration order.
|
|
22
|
+
# Sorted: refusal wording is pinned byte-for-byte, so it cannot follow payload order.
|
|
39
23
|
unknown = (args.keys.map(&:to_sym) - known).sort
|
|
40
24
|
return if unknown.empty?
|
|
41
25
|
|
|
@@ -45,46 +29,18 @@ module Hecks
|
|
|
45
29
|
declared: declared_names(command))
|
|
46
30
|
end
|
|
47
31
|
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# Refusing `Customer.Register` for a missing `name` needs to be
|
|
53
|
-
# deliberate, not an accident with a lie for a message. Without this
|
|
54
|
-
# check, `then_set :name, to: :name` finds nothing to resolve, passes
|
|
55
|
-
# the literal symbol on, and coercion reports `name is a PersonName —
|
|
56
|
-
# pass its fields as an object`, which describes a mistake the caller
|
|
57
|
-
# did not make. The real mistake — an argument simply missing — is
|
|
58
|
-
# never the one named unless this refuses it on purpose.
|
|
59
|
-
#
|
|
60
|
-
# No command attribute anywhere in the corpus carries a default — checked,
|
|
61
|
-
# all eight chapters, zero — so there is no optional argument for this to
|
|
62
|
-
# step on. Every declared attribute is a fact the command needs.
|
|
32
|
+
# Refuses a declared, non-optional argument that is missing. Without it a missing
|
|
33
|
+
# argument surfaces later as a misleading coercion error about a mistake the caller
|
|
34
|
+
# did not make.
|
|
63
35
|
#
|
|
64
|
-
# `aggregate:`
|
|
65
|
-
#
|
|
66
|
-
# (`CommandBuilder#reference_to`'s bare self-reference mints no
|
|
67
|
-
# attribute to be absent) — but `PortOperationBuilder#reference_to`
|
|
68
|
-
# always mints one (this file's own header on `PortOperation`: "no
|
|
69
|
-
# creates?/acts_on distinction to protect"), because an operation had
|
|
70
|
-
# no other way to say which record it addressed before `to:` existed.
|
|
71
|
-
# `to:` is that way now (`Dispatcher#port_invocation` promotes the
|
|
72
|
-
# identity attribute's own value out of the payload and into
|
|
73
|
-
# routing) — which leaves the attribute still declared, still
|
|
74
|
-
# non-optional, and never present in `args` at all: without this
|
|
75
|
-
# exemption, every operation with an identity attribute would refuse
|
|
76
|
-
# its own well-formed calls, dispatched exactly the way `to:`
|
|
77
|
-
# intends. Exempted here on the same terms an aggregate command's
|
|
78
|
-
# self-address always was — an address, not a fact the operation
|
|
79
|
-
# still needs handed back.
|
|
36
|
+
# `aggregate:` is set only for a port operation, whose identity attribute is
|
|
37
|
+
# promoted into routing by `to:` and so never appears in `args`; it is exempted.
|
|
80
38
|
def refuse_absent_arguments(command, args, aggregate: nil)
|
|
81
39
|
given = args.keys.map(&:to_sym)
|
|
82
40
|
exempt = aggregate && command.respond_to?(:identity_attribute) &&
|
|
83
41
|
command.identity_attribute(aggregate.hecks_name)&.name
|
|
84
42
|
required = command.attributes.reject(&:optional?).map { |attribute| attribute.name.to_sym } - [exempt]
|
|
85
|
-
# Sorted, for the same reason the unknown list
|
|
86
|
-
# contract, and a pinned wording cannot depend on the order a set
|
|
87
|
-
# difference happens to be computed in.
|
|
43
|
+
# Sorted, for the same reason as the unknown list.
|
|
88
44
|
absent = (required - given).sort
|
|
89
45
|
return if absent.empty?
|
|
90
46
|
|
|
@@ -94,29 +50,11 @@ module Hecks
|
|
|
94
50
|
declared: declared_names(command))
|
|
95
51
|
end
|
|
96
52
|
|
|
97
|
-
#
|
|
98
|
-
# .Freeze` is `reference_to Account` and no attributes at all, so
|
|
99
|
-
# `{declared}` rendered empty and the sentence trailed off mid-
|
|
100
|
-
# clause : "Freeze does not declare standing — it takes ". Read
|
|
101
|
-
# against a real refusal that shape is worse than unhelpful — it
|
|
102
|
-
# looks like the message itself is broken, right where a caller
|
|
103
|
-
# is already trying to work out what went wrong.
|
|
104
|
-
#
|
|
105
|
-
# Only the empty case changes. Every command that declares even
|
|
106
|
-
# one attribute renders exactly as it did before, because refusal
|
|
107
|
-
# wording is contract and pinned byte-for-byte by the corpus (see
|
|
108
|
-
# `refuse_unknown_arguments`' own note on sorting for why).
|
|
53
|
+
# An empty list must still read as a sentence; only the empty case is worded differently.
|
|
109
54
|
def declared_names(command) = command.attributes.map(&:name)
|
|
110
55
|
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
# each leg emits carries it and the next step can be correlated — so the key
|
|
114
|
-
# arrives on commands that never declare it, and legitimately.
|
|
115
|
-
#
|
|
116
|
-
# This is the weakest part of the gate. Correlation is the saga's business,
|
|
117
|
-
# and the better shape is for the saga to stamp its own key onto the event
|
|
118
|
-
# it caused rather than smuggle it through the command's payload. Until it
|
|
119
|
-
# does, refusing the key here would break every saga in the corpus.
|
|
56
|
+
# A saga threads its correlation key through every leg's payload, so the key arrives on
|
|
57
|
+
# commands that never declare it. Refusing it would break every saga.
|
|
120
58
|
def correlation_keys(domain)
|
|
121
59
|
Array(@registry.bluebook(domain)&.process_managers)
|
|
122
60
|
.filter_map { |saga| saga.correlates_by && saga.correlation_head }
|