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
|
@@ -3,30 +3,20 @@ require_relative "../../bluebook/hexagon"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Runtime
|
|
5
5
|
class Registry
|
|
6
|
-
# The wiring gate: every bind names a declared aggregate, every
|
|
7
|
-
#
|
|
8
|
-
# a field the adapter admits, and the default adapter is usable at
|
|
9
|
-
# all. Included into Registry — `verify!` is what a boot calls after
|
|
10
|
-
# loading, and the smaller checks are also called piecemeal by the
|
|
11
|
-
# repository factory.
|
|
6
|
+
# The wiring gate: every bind names a declared aggregate, every adapter satisfies its
|
|
7
|
+
# port's verb, and every world default is usable. `verify!` runs it all at boot.
|
|
12
8
|
module Verification
|
|
13
|
-
# Runs
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# @return [Runtime::Registry] self
|
|
17
|
-
# @raise [Runtime::WiringError] if a bind names an undeclared aggregate, an
|
|
18
|
-
# adapter cannot satisfy its port's verb or declared `answers`, a world
|
|
19
|
-
# setting names a field its adapter does not declare, the default adapter
|
|
20
|
-
# is unusable, a world's `default_adapter` is not a persistence adapter, a
|
|
21
|
-
# command declares a role with no authorization provider attached, or a
|
|
22
|
-
# membership chapter is loaded with no identity chapter
|
|
9
|
+
# Runs every wiring check against this registry's loaded bluebooks, hexagons, ports
|
|
10
|
+
# and adapters.
|
|
23
11
|
def verify!
|
|
24
12
|
verify_default_adapter!
|
|
25
13
|
verify_world_defaults!
|
|
26
14
|
verify_singleton_port_answers!
|
|
27
15
|
refuse_cross_package_bluebook_merge!
|
|
16
|
+
refuse_reserved_chapter_names!
|
|
28
17
|
refuse_membership_without_identity!
|
|
29
18
|
refuse_unresolved_port_operations!
|
|
19
|
+
refuse_unanswerable_queries!
|
|
30
20
|
|
|
31
21
|
@hecksagons.each_value do |hexagon|
|
|
32
22
|
refuse_ungoverned_roles!(hexagon)
|
|
@@ -35,19 +25,9 @@ module Hecks
|
|
|
35
25
|
refuse_bounded_without_acl!(hexagon)
|
|
36
26
|
|
|
37
27
|
hexagon.binds.each do |bind|
|
|
38
|
-
# A domain-level default (§0)
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# the bluebook for this row specifically. Still validate its
|
|
42
|
-
# own adapter/verb shape (the same reason
|
|
43
|
-
# `verify_default_adapter!` checks the framework-wide
|
|
44
|
-
# default the same way, aggregate-less). Coverage of real
|
|
45
|
-
# aggregates that only resolve through this default comes
|
|
46
|
-
# from their own dispatch-time `BindingPolicy.resolve` —
|
|
47
|
-
# deliberately not required to be exhaustive here, the same
|
|
48
|
-
# leniency this method already extended to any aggregate
|
|
49
|
-
# left out of an explicit bind list entirely (real test
|
|
50
|
-
# fixtures bind only the aggregates they exercise).
|
|
28
|
+
# A domain-level default (§0) names no aggregate of its own; still validate its
|
|
29
|
+
# adapter/verb shape. Real aggregates resolving through it are covered by their
|
|
30
|
+
# own dispatch-time `BindingPolicy.resolve`, not required to be exhaustive here.
|
|
51
31
|
if bind.aggregate.nil?
|
|
52
32
|
check_verb(bind)
|
|
53
33
|
next
|
|
@@ -67,13 +47,7 @@ module Hecks
|
|
|
67
47
|
self
|
|
68
48
|
end
|
|
69
49
|
|
|
70
|
-
# Checks that the framework-wide default persistence adapter
|
|
71
|
-
# aggregate left out of an explicit bind list) is itself wired correctly.
|
|
72
|
-
#
|
|
73
|
-
# @return [Runtime::Registry] self
|
|
74
|
-
# @raise [Runtime::WiringError] if the default adapter cannot satisfy the
|
|
75
|
-
# persistence port's verb, is missing a declared `answers` method, or has
|
|
76
|
-
# no Ruby implementation
|
|
50
|
+
# Checks that the framework-wide default persistence adapter is itself wired correctly.
|
|
77
51
|
def verify_default_adapter!
|
|
78
52
|
name = Ports::Persistence::DEFAULT_ADAPTER
|
|
79
53
|
|
|
@@ -92,14 +66,7 @@ module Hecks
|
|
|
92
66
|
"aggregate with no bind could not be given one: #{e.message}"
|
|
93
67
|
end
|
|
94
68
|
|
|
95
|
-
# Checks that `bind`'s adapter implements the port it names and satisfies
|
|
96
|
-
# the verb the bind declares.
|
|
97
|
-
#
|
|
98
|
-
# @param bind [Bluebook::Bind] the bind to check
|
|
99
|
-
# @return [void]
|
|
100
|
-
# @raise [Runtime::WiringError] if `bind`'s adapter is unknown, declares an
|
|
101
|
-
# unknown port, is missing a declared `answers` method, or cannot satisfy
|
|
102
|
-
# `bind`'s own verb
|
|
69
|
+
# Checks that `bind`'s adapter implements the port it names and satisfies its verb.
|
|
103
70
|
def check_verb(bind)
|
|
104
71
|
port = port_for(bind)
|
|
105
72
|
check_answers(port, bind.adapter)
|
|
@@ -110,20 +77,8 @@ module Hecks
|
|
|
110
77
|
"and cannot satisfy #{bind.verb}"
|
|
111
78
|
end
|
|
112
79
|
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
# verb, and admit every `.world` setting `check_settings` checks,
|
|
116
|
-
# and still be missing the one method a live dispatch will
|
|
117
|
-
# actually call. `answers` is optional per port (an empty list is
|
|
118
|
-
# today's pre-existing behavior, unchecked), so this only ever
|
|
119
|
-
# tightens a port that opted in.
|
|
120
|
-
#
|
|
121
|
-
# @param port [Bluebook::Port] the port whose declared `answers` methods
|
|
122
|
-
# `adapter_name` must respond to
|
|
123
|
-
# @param adapter_name [String] the adapter's declared name to check
|
|
124
|
-
# @return [void]
|
|
125
|
-
# @raise [Runtime::WiringError] if `adapter_name` has no Ruby implementation,
|
|
126
|
-
# or its implementation does not respond to one of `port.answers`
|
|
80
|
+
# `answers` is optional per port, so an adapter can satisfy a port's verb and still
|
|
81
|
+
# miss a method live dispatch will call; this only tightens ports that opt in.
|
|
127
82
|
def check_answers(port, adapter_name)
|
|
128
83
|
answers = Array(port.answers)
|
|
129
84
|
return if answers.empty?
|
|
@@ -138,27 +93,19 @@ module Hecks
|
|
|
138
93
|
"#{answers.map(&:inspect).join(', ')}"
|
|
139
94
|
end
|
|
140
95
|
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
# every real `bind` a hexagon declares; a singleton port
|
|
144
|
-
# (`clock`, `authorization`, …) is never bound to an aggregate at
|
|
145
|
-
# all, so nothing above ever resolves one and nothing above ever
|
|
146
|
-
# ran `check_answers` against it. Each one's own `Ports::*.adapter`
|
|
147
|
-
# already refuses zero or multiple implementations, live, at
|
|
148
|
-
# first dispatch — that stays exactly as-is here (0 or 2+ is
|
|
149
|
-
# ambiguity, not a method-contract question, and asserting every
|
|
150
|
-
# declared port must have exactly one adapter would wrongly
|
|
151
|
-
# refuse a boot that simply never wires a port it doesn't use).
|
|
152
|
-
# This only ever tightens the one case those checks don't cover:
|
|
153
|
-
# exactly one adapter, wired, missing a method `answers` names.
|
|
96
|
+
# persistence/projection/loading are per-aggregate bound and already checked via
|
|
97
|
+
# each bind above; a singleton port is never bound to an aggregate at all.
|
|
154
98
|
PER_AGGREGATE_PORTS = %w[persistence projection loading].freeze
|
|
155
99
|
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
#
|
|
161
|
-
|
|
100
|
+
# The directory holding the gem's own Hecks chapter, the only place a chapter named
|
|
101
|
+
# `Hecks` may be declared from.
|
|
102
|
+
GEM_CHAPTER_DIR = File.expand_path("../../hecks", __dir__).freeze
|
|
103
|
+
|
|
104
|
+
# The chapter names only the gem itself may declare (ADR 0080, section 9).
|
|
105
|
+
RESERVED_CHAPTER_NAMES = %w[Hecks].freeze
|
|
106
|
+
|
|
107
|
+
# Checks every singleton port with exactly one wired adapter against its own
|
|
108
|
+
# declared `answers` methods.
|
|
162
109
|
def verify_singleton_port_answers!
|
|
163
110
|
@ports.each_value do |port|
|
|
164
111
|
next if PER_AGGREGATE_PORTS.include?(port.name)
|
|
@@ -172,16 +119,8 @@ module Hecks
|
|
|
172
119
|
self
|
|
173
120
|
end
|
|
174
121
|
|
|
175
|
-
# Checks that every setting `settings` declares (besides `:adapter`) is a
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
# @param bind [Bluebook::Bind] the bind naming the adapter to check against;
|
|
179
|
-
# a no-op if its adapter is unknown
|
|
180
|
-
# @param settings [Hash{Symbol => Object}] the world's declared settings for
|
|
181
|
-
# this bind
|
|
182
|
-
# @return [void]
|
|
183
|
-
# @raise [Runtime::WiringError] if `settings` declares a field `bind`'s
|
|
184
|
-
# adapter does not declare
|
|
122
|
+
# Checks that every setting `settings` declares (besides `:adapter`) is a field
|
|
123
|
+
# `bind`'s adapter actually admits.
|
|
185
124
|
def check_settings(bind, settings)
|
|
186
125
|
adapter = @adapters[bind.adapter]
|
|
187
126
|
return unless adapter
|
|
@@ -196,12 +135,6 @@ module Hecks
|
|
|
196
135
|
"Add the field to the adapter, or remove it from the world."
|
|
197
136
|
end
|
|
198
137
|
|
|
199
|
-
# Finds the port `bind`'s adapter declares.
|
|
200
|
-
#
|
|
201
|
-
# @param bind [Bluebook::Bind] the bind naming the adapter to look up
|
|
202
|
-
# @return [Bluebook::Port] the port `bind`'s adapter declares
|
|
203
|
-
# @raise [Runtime::WiringError] if `bind` names an unknown adapter, or one
|
|
204
|
-
# declaring an unknown port
|
|
205
138
|
def port_for(bind)
|
|
206
139
|
adapter = @adapters[bind.adapter]
|
|
207
140
|
raise WiringError, "unknown adapter #{bind.adapter.inspect}" unless adapter
|
|
@@ -210,12 +143,6 @@ module Hecks
|
|
|
210
143
|
raise(WiringError, "adapter #{bind.adapter} declares unknown port #{adapter.port.inspect}")
|
|
211
144
|
end
|
|
212
145
|
|
|
213
|
-
# Finds the Ruby module implementing the adapter declared `name`.
|
|
214
|
-
#
|
|
215
|
-
# @param name [String] the adapter's declared name, such as `"PostgresEra"`
|
|
216
|
-
# @return [Module] the adapter module or class under `Hecks::Adapters`
|
|
217
|
-
# @raise [Runtime::WiringError] if no Ruby implementation named `name` exists
|
|
218
|
-
# under `Hecks::Adapters`
|
|
219
146
|
def adapter_class(name)
|
|
220
147
|
Adapters.const_get(name)
|
|
221
148
|
rescue NameError
|
|
@@ -225,33 +152,10 @@ module Hecks
|
|
|
225
152
|
|
|
226
153
|
private
|
|
227
154
|
|
|
228
|
-
#
|
|
229
|
-
#
|
|
230
|
-
#
|
|
231
|
-
#
|
|
232
|
-
# access control by exact string equality ... Governance ...
|
|
233
|
-
# connected to none of it"). Checked here, at `verify!` — recovered
|
|
234
|
-
# and moved, not new: running this per-block, at hecksagon
|
|
235
|
-
# build time (Bluebook::DSL::HecksagonBuilder#build), breaks
|
|
236
|
-
# the moment a domain is split across multiple hecksagon
|
|
237
|
-
# blocks (base + an `environments/<name>.hecksagon` overlay,
|
|
238
|
-
# Runtime::Loader.boot's `environment:` — see its own comment for
|
|
239
|
-
# the recovery provenance): every block but the one declaring
|
|
240
|
-
# `uses_framework "Governance"` would be refused there, even
|
|
241
|
-
# though `Registry#add_hecksagon` merges every block for a domain
|
|
242
|
-
# into one Hecksagon before anything ever dispatches against it.
|
|
243
|
-
# Checking the merged result once, here, after every file for
|
|
244
|
-
# this domain has loaded, is both more permissive (no need to
|
|
245
|
-
# repeat `uses_framework` in every file) and strictly more
|
|
246
|
-
# correct (a check against an incomplete, not-yet-merged
|
|
247
|
-
# hecksagon can never see the real final shape).
|
|
248
|
-
#
|
|
249
|
-
# A provider is recognised by its declaration, not its name —
|
|
250
|
-
# `authorization_provider_for` answers for the domain's own
|
|
251
|
-
# chapter too, so Governance (which declares `provides
|
|
252
|
-
# "authorization"`) passes here because of what it declares, and
|
|
253
|
-
# the same rule `CommandRules::Authorization#governance_attached?`
|
|
254
|
-
# applies at dispatch time.
|
|
155
|
+
# Checked once against the merged hecksagon so a domain split across multiple
|
|
156
|
+
# hecksagon files sees every uses_framework declaration first. A role is real
|
|
157
|
+
# access control only once an authorization provider exists to check it against
|
|
158
|
+
# (ADR 0025); a provider is recognized by declaring authorization, not by name.
|
|
255
159
|
def refuse_ungoverned_roles!(hexagon)
|
|
256
160
|
return if authorization_provider_for(hexagon.domain)
|
|
257
161
|
|
|
@@ -268,15 +172,9 @@ module Hecks
|
|
|
268
172
|
"without that it is silent decoration, the exact defect this refusal exists to catch"
|
|
269
173
|
end
|
|
270
174
|
|
|
271
|
-
#
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
# anti-corruption layer (`translates` field mapping) live on a named
|
|
275
|
-
# sibling hecksagon the consumer must declare. Without that hexagon
|
|
276
|
-
# the package has no wiring of its own, and cross-context field
|
|
277
|
-
# mapping has nowhere to be written. Breaking in 2.0: attaching a
|
|
278
|
-
# vendored chapter without `Hecks.hecksagon "PackageName"` refuses
|
|
279
|
-
# at boot rather than silently sharing the consumer's hexagon.
|
|
175
|
+
# `uses_embryonaut_bluebook` only loads a package's `.bluebook` files; persistence,
|
|
176
|
+
# Governance and the `translates` ACL live on a sibling hecksagon the consumer must
|
|
177
|
+
# declare, or cross-context field mapping has nowhere to be written.
|
|
280
178
|
def refuse_unwired_vendored_bluebooks!(hexagon)
|
|
281
179
|
Array(hexagon.vendored_bluebooks).each do |package|
|
|
282
180
|
chapter_name = Naming.pascal(package)
|
|
@@ -291,16 +189,14 @@ module Hecks
|
|
|
291
189
|
end
|
|
292
190
|
end
|
|
293
191
|
|
|
294
|
-
#
|
|
295
|
-
#
|
|
296
|
-
# is its ACL. Governance/Identity/Privacy already follow this in
|
|
297
|
-
# every real consumer; boot now refuses a silent miss.
|
|
192
|
+
# `uses_framework` and `attaches` load a bounded context; the consumer must declare the
|
|
193
|
+
# sibling hecksagon that is its ACL (Governance/Identity/Privacy already do).
|
|
298
194
|
def refuse_unwired_framework_members!(hexagon)
|
|
299
|
-
|
|
195
|
+
hexagon.member_chapters.each do |member|
|
|
300
196
|
next if hecksagon(member)
|
|
301
197
|
|
|
302
198
|
raise WiringError,
|
|
303
|
-
"#{hexagon.domain} attaches
|
|
199
|
+
"#{hexagon.domain} attaches #{member.inspect} " \
|
|
304
200
|
"(bounded context) but never declared Hecks.hecksagon " \
|
|
305
201
|
"#{member.inspect} — put that sibling (and any `translates` " \
|
|
306
202
|
"ACL) in context_map.hecksagon; same-name blocks merge, " \
|
|
@@ -308,19 +204,12 @@ module Hecks
|
|
|
308
204
|
end
|
|
309
205
|
end
|
|
310
206
|
|
|
311
|
-
# An explicit `bounded` mark on a consumer chapter always needs an
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
#
|
|
317
|
-
# rust/host Google sign-in reads `ir.json`'s `membership` and
|
|
318
|
-
# `identity` keys (Exporter.membership / Exporter.identity) —
|
|
319
|
-
# never a deploy-time env var. Membership without Identity is
|
|
320
|
-
# the exact gap that produced a live `google_unlinked` after a
|
|
321
|
-
# successful Google handshake: provision cannot Register/Link.
|
|
322
|
-
# Refuse at Ruby boot (and project_rust, which exports the same
|
|
323
|
-
# pair) so a missing sibling cannot ship.
|
|
207
|
+
# An explicit `bounded` mark on a consumer chapter always needs an ACL. `uses_framework`
|
|
208
|
+
# / `uses_embryonaut_bluebook` mark the attached chapter bounded and require the sibling
|
|
209
|
+
# hecksagon above; they don't require a `translates` on it unless the consumer also
|
|
210
|
+
# wrote `bounded`.
|
|
211
|
+
# rust/host Google sign-in reads ir.json's membership/identity keys, never a deploy-time
|
|
212
|
+
# env var; Membership without Identity means provision cannot Register/Link an identity.
|
|
324
213
|
def refuse_membership_without_identity!
|
|
325
214
|
return unless @bluebooks.values.any? { |chapter| chapter.provides?(Bluebook::Capabilities::MEMBERSHIP) }
|
|
326
215
|
return if @bluebooks.values.any? { |chapter| chapter.provides?(Bluebook::Capabilities::IDENTITY) }
|
|
@@ -333,11 +222,8 @@ module Hecks
|
|
|
333
222
|
"identity verbs are exported onto ir.json, not guessed at deploy."
|
|
334
223
|
end
|
|
335
224
|
|
|
336
|
-
# A
|
|
337
|
-
#
|
|
338
|
-
# attaches after the chapter is built, so this is the first point the
|
|
339
|
-
# operation can be checked. Without it, a host reading the declared
|
|
340
|
-
# verb would dispatch to an operation nothing declares.
|
|
225
|
+
# A hecksagon attaches after its chapter builds, so this is the first point a
|
|
226
|
+
# declared `:port_operation` capability can be checked against it.
|
|
341
227
|
def refuse_unresolved_port_operations!
|
|
342
228
|
@bluebooks.each_value do |chapter|
|
|
343
229
|
chapter.provides.each do |row|
|
|
@@ -352,12 +238,130 @@ module Hecks
|
|
|
352
238
|
end
|
|
353
239
|
end
|
|
354
240
|
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
241
|
+
# A query has exactly one answer path. It is derivable when the bluebook says which of the
|
|
242
|
+
# aggregate's own records it wants (a where, order_by, limit or offset, or no arguments at
|
|
243
|
+
# all: the plain list) and returns no value object of its own; it is bound when it
|
|
244
|
+
# `returns` a value object and the hecksagon names the port whose adapter answers it. None
|
|
245
|
+
# of the two is "no answer path"; both is "two answer paths". A bound query also needs an
|
|
246
|
+
# adapter behind its port that implements it, found here so it fails at boot rather than
|
|
247
|
+
# on the first ask.
|
|
248
|
+
def refuse_unanswerable_queries!
|
|
249
|
+
@bluebooks.each_value do |chapter|
|
|
250
|
+
chapter.aggregates.each do |aggregate|
|
|
251
|
+
refuse_misbound_queries!(chapter, aggregate)
|
|
252
|
+
|
|
253
|
+
aggregate.queries.each { |query| refuse_answer_paths!(chapter, aggregate, query) }
|
|
254
|
+
aggregate.entities.each do |entity|
|
|
255
|
+
entity.queries.each { |query| refuse_entity_answer_path!(chapter, aggregate, entity, query) }
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Counts the query's answer paths (the bindings, plus the derived answer when it exists)
|
|
262
|
+
# and refuses any count but one, then checks a bound query's shape and adapter.
|
|
263
|
+
def refuse_answer_paths!(chapter, aggregate, query)
|
|
264
|
+
where = "#{chapter.name}::#{aggregate.hecks_name}.#{query.hecks_name}"
|
|
265
|
+
ports = aggregate.query_bindings(query.hecks_name)
|
|
266
|
+
paths = ports.size + (derivable?(query) ? 1 : 0)
|
|
267
|
+
|
|
268
|
+
if paths > 1
|
|
269
|
+
raise WiringError, "#{where} has two answer paths: #{answer_path_names(query, ports)} — " \
|
|
270
|
+
"a query is answered from records or from outside, not both"
|
|
271
|
+
end
|
|
272
|
+
return check_bound_query!(chapter, aggregate, query, ports.first) if ports.any?
|
|
273
|
+
return if paths == 1
|
|
274
|
+
|
|
275
|
+
raise WiringError, no_answer_path_message(chapter, aggregate, query, where)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# A query that returns nothing and says something about which records it wants, or wants
|
|
279
|
+
# all of them. One that takes arguments but filters, orders and bounds nothing reads none
|
|
280
|
+
# of them, so it derives no answer.
|
|
281
|
+
def derivable?(query)
|
|
282
|
+
return false if query.returns
|
|
283
|
+
|
|
284
|
+
filters_records?(query) || query.attributes.empty?
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def answer_path_names(query, ports)
|
|
288
|
+
names = ports.map { |port| "the #{port.name} port" }
|
|
289
|
+
names.unshift("its records") if derivable?(query)
|
|
290
|
+
names.join(" and ")
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def no_answer_path_message(chapter, aggregate, query, where)
|
|
294
|
+
if query.returns
|
|
295
|
+
"#{where} has no answer path: it returns #{query.returns}, which only an adapter can " \
|
|
296
|
+
"answer, and no hecksagon port binds it. Bind it: `#{chapter.name}::#{aggregate.hecks_name}" \
|
|
297
|
+
".port \"Port\" do answers_query \"#{query.hecks_name}\" end`."
|
|
298
|
+
else
|
|
299
|
+
"#{where} has no answer path: it declares no where and returns nothing, and no hecksagon " \
|
|
300
|
+
"binds it — its arguments (#{query.attributes.map(&:name).join(', ')}) select nothing. " \
|
|
301
|
+
"Add a where, or declare what it returns and bind it in the hecksagon."
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Checks what a binding needs to be answerable: a returned value object the aggregate
|
|
306
|
+
# declares, and one adapter behind the port that implements the query's method.
|
|
307
|
+
def check_bound_query!(chapter, aggregate, query, port)
|
|
308
|
+
where = "#{chapter.name}::#{aggregate.hecks_name}.#{query.hecks_name}"
|
|
309
|
+
unless query.returns
|
|
310
|
+
raise WiringError, "#{where} is bound to the #{port.name} port but returns nothing — " \
|
|
311
|
+
"declare the value object its answer takes with `returns`"
|
|
312
|
+
end
|
|
313
|
+
if filters_records?(query)
|
|
314
|
+
raise WiringError, "#{where} has two answer paths: it is bound to the #{port.name} port but " \
|
|
315
|
+
"also declares where, order_by or limit over stored records"
|
|
316
|
+
end
|
|
317
|
+
if query.authorization
|
|
318
|
+
raise WiringError, "#{where} is bound to the #{port.name} port but declares authorize — " \
|
|
319
|
+
"an outside answer is never tenant-scoped or authorized, so drop the " \
|
|
320
|
+
"authorize or answer the query from records"
|
|
321
|
+
end
|
|
322
|
+
unless Value.value_object_for(aggregate, query.returns_name)
|
|
323
|
+
raise WiringError, "#{where} returns #{query.returns_name}, but #{aggregate.hecks_name} " \
|
|
324
|
+
"declares no such value object"
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
klass = AdapterLookup.adapter_class(self, port.name, asked: where)
|
|
328
|
+
AdapterLookup.check_answers!(klass, port.name, Naming.snake(query.hecks_name), query, asked: where)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# An entity's query reads the elements of its aggregate's list, and nothing outside can
|
|
332
|
+
# be bound to one, so declaring a value object to return leaves it no answer.
|
|
333
|
+
def refuse_entity_answer_path!(chapter, aggregate, entity, query)
|
|
334
|
+
where = "#{chapter.name}::#{aggregate.hecks_name}.#{entity.hecks_name}.#{query.hecks_name}"
|
|
335
|
+
if query.returns
|
|
336
|
+
raise WiringError, "#{where} has no answer path: it returns #{query.returns}, but " \
|
|
337
|
+
"only an aggregate's queries can be bound to a port"
|
|
338
|
+
end
|
|
339
|
+
return if derivable?(query)
|
|
340
|
+
|
|
341
|
+
raise WiringError, "#{where} has no answer path: it declares no where and returns nothing — its " \
|
|
342
|
+
"arguments (#{query.attributes.map(&:name).join(', ')}) select nothing"
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Refuses a binding that names a query its aggregate does not declare, or names one twice
|
|
346
|
+
# on a single port (the DSL already refuses that, so this guards a hand-built port).
|
|
347
|
+
def refuse_misbound_queries!(chapter, aggregate)
|
|
348
|
+
aggregate.ports.each do |port|
|
|
349
|
+
names = port.answered_queries.map(&:name)
|
|
350
|
+
names.each do |name|
|
|
351
|
+
where = "#{chapter.name}::#{aggregate.hecks_name}.#{name}"
|
|
352
|
+
unless aggregate.query(name)
|
|
353
|
+
raise WiringError, "the #{port.name} port binds #{where}, which the aggregate does not declare"
|
|
354
|
+
end
|
|
355
|
+
raise WiringError, "#{where} has two answer paths: the #{port.name} port twice" if names.count(name) > 1
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# A query that says anything about which stored records it wants.
|
|
361
|
+
def filters_records?(query)
|
|
362
|
+
!(query.wheres.empty? && query.order_by.nil? && query.limit.nil? && query.offset.nil?)
|
|
363
|
+
end
|
|
364
|
+
|
|
361
365
|
def port_operation_declared?(chapter, verb)
|
|
362
366
|
aggregate_name, port_name, operation_name = verb.split(".", 3)
|
|
363
367
|
ports = chapter.aggregate(aggregate_name)&.ports || []
|
|
@@ -377,8 +381,8 @@ module Hecks
|
|
|
377
381
|
"with: { ... } end` (any field) or drop `bounded`."
|
|
378
382
|
end
|
|
379
383
|
|
|
380
|
-
#
|
|
381
|
-
#
|
|
384
|
+
# Derived from whichever framework members actually declare `provides
|
|
385
|
+
# "authorization"` — never a hardcoded name.
|
|
382
386
|
def authorization_attachment_hint
|
|
383
387
|
providers = Framework.providers_of(Bluebook::Capabilities::AUTHORIZATION)
|
|
384
388
|
return "attaches a chapter that provides \"authorization\" (no framework member declares one)" if providers.empty?
|
|
@@ -386,30 +390,43 @@ module Hecks
|
|
|
386
390
|
providers.map { |name| "uses_framework #{name.inspect}" }.join(" or ")
|
|
387
391
|
end
|
|
388
392
|
|
|
389
|
-
# Every command this domain declares, an aggregate's own and every
|
|
390
|
-
#
|
|
391
|
-
# itself needs at dispatch time, just walked ahead of time here.
|
|
393
|
+
# Every command this domain declares, an aggregate's own and every entity nested
|
|
394
|
+
# inside one — the same reach dispatch-time role checking needs.
|
|
392
395
|
def commands_in(bluebook_ir)
|
|
393
396
|
bluebook_ir.aggregates.flat_map { |aggregate| aggregate.commands + aggregate.entities.flat_map(&:commands) }
|
|
394
397
|
end
|
|
395
398
|
|
|
396
|
-
#
|
|
397
|
-
#
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
399
|
+
# Refuses a chapter whose name is reserved unless every file that declared it sits under
|
|
400
|
+
# the gem's own chapter directory. A rename is the only fix, so the message says so.
|
|
401
|
+
#
|
|
402
|
+
# @raise [WiringError] naming the reserved word and the offending file(s)
|
|
403
|
+
def refuse_reserved_chapter_names!
|
|
404
|
+
RESERVED_CHAPTER_NAMES.each do |reserved|
|
|
405
|
+
next unless @bluebooks.key?(reserved)
|
|
406
|
+
|
|
407
|
+
sources = Array(@bluebook_sources[reserved]).compact
|
|
408
|
+
foreign = sources.reject { |path| gem_chapter_source?(path) }
|
|
409
|
+
next if foreign.empty? && !sources.empty?
|
|
410
|
+
|
|
411
|
+
where = foreign.empty? ? "" : " (declared in #{foreign.join(', ')})"
|
|
412
|
+
raise WiringError,
|
|
413
|
+
"a chapter named #{reserved.inspect} is refused: #{reserved.inspect} is a reserved " \
|
|
414
|
+
"word, the name of the gem's own chapter, and only the gem may declare it#{where}. " \
|
|
415
|
+
"Rename the chapter (for example to your app's name) in its " \
|
|
416
|
+
"`Hecks.bluebook #{reserved.inspect}` line and in its hecksagon."
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Whether `path` is a file of the gem's own chapter directory.
|
|
421
|
+
def gem_chapter_source?(path)
|
|
422
|
+
File.expand_path(path.to_s).start_with?("#{GEM_CHAPTER_DIR}/")
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
# Two packages can share a chapter name by coincidence (found live: a stale
|
|
426
|
+
# vendor/hecksagain fork of Governance/Identity/Deploy, still on 4 apps' load
|
|
427
|
+
# paths). Intentional accumulation (several files declaring the same chapter on
|
|
428
|
+
# purpose) is distinguished by package root, not file identity, and is left
|
|
429
|
+
# untouched here — checked once, after every file has loaded.
|
|
413
430
|
def refuse_cross_package_bluebook_merge!
|
|
414
431
|
@bluebook_sources.each do |name, paths|
|
|
415
432
|
roots = paths.map { |path| package_root_for(path) }.uniq
|
|
@@ -424,15 +441,9 @@ module Hecks
|
|
|
424
441
|
end
|
|
425
442
|
end
|
|
426
443
|
|
|
427
|
-
# The nearest boundary a path
|
|
428
|
-
#
|
|
429
|
-
#
|
|
430
|
-
# root regardless of what gemspec might sit above it: vendored
|
|
431
|
-
# code should never be considered "the same package" as whatever
|
|
432
|
-
# it's vendored into, even when nothing else marks the boundary.
|
|
433
|
-
# Neither found, the path's own directory is the root — two
|
|
434
|
-
# files with no closer marker only "belong together" if they are
|
|
435
|
-
# literally the same file.
|
|
444
|
+
# The nearest boundary a path belongs to: a real gemspec, or a bare `vendor/`
|
|
445
|
+
# component (vendored code is never "the same package" as what vendors it).
|
|
446
|
+
# Falls back to the path's own directory when neither is found.
|
|
436
447
|
def package_root_for(path)
|
|
437
448
|
return path.to_s if path.nil?
|
|
438
449
|
|
|
@@ -448,37 +459,10 @@ module Hecks
|
|
|
448
459
|
end
|
|
449
460
|
end
|
|
450
461
|
|
|
451
|
-
# A domain
|
|
452
|
-
# `
|
|
453
|
-
#
|
|
454
|
-
#
|
|
455
|
-
# see `SagaPersistence#resolve_saga_persistence`) gets sagas that
|
|
456
|
-
# advance correctly in-process and vanish on restart: no
|
|
457
|
-
# checkpoint written, nothing for `rehydrate_sagas!` to find, no
|
|
458
|
-
# compensation ever replayed. That is silent right up until the
|
|
459
|
-
# process actually dies mid-saga — the same "consistency/
|
|
460
|
-
# freshness defect applied to access control, failing open" ADR
|
|
461
|
-
# 0025 named for an unchecked `role`, here applied to saga
|
|
462
|
-
# durability instead.
|
|
463
|
-
#
|
|
464
|
-
# A warning, not a refusal — unlike `refuse_ungoverned_roles!`,
|
|
465
|
-
# running sagas on a store with no `save_saga` is legitimate on
|
|
466
|
-
# purpose in a fast in-memory test/dev boot (this project's own
|
|
467
|
-
# `saga_durability_spec.rb` boots a process manager on `Memory`
|
|
468
|
-
# specifically to exercise the saga_mutex without real I/O), so
|
|
469
|
-
# refusing the boot outright would break a choice an author made
|
|
470
|
-
# deliberately. What a deploy needs is for the gap to be loud and
|
|
471
|
-
# undeniable, not for local dev/test to become impossible.
|
|
472
|
-
# The outbox's twin of `warn_undurable_sagas!` — a domain that
|
|
473
|
-
# declares anything a commit could owe a reaction to (a policy
|
|
474
|
-
# listening to one of its events, or a process manager) but is
|
|
475
|
-
# bound to an adapter with no outbox (`AppendOnly#outbox?`) gets
|
|
476
|
-
# reactions the pre-outbox way: run inline, lost on a crash
|
|
477
|
-
# between commit and reaction. A warning, not a refusal, for the
|
|
478
|
-
# reason `warn_undurable_sagas!` gives — and Memory has an outbox
|
|
479
|
-
# (in-process, like everything else it holds), so a dev/test
|
|
480
|
-
# boot stays quiet; this speaks up for the file/remote adapters
|
|
481
|
-
# that persist state durably but hand reactions to nothing.
|
|
462
|
+
# A domain with policies/a process_manager but no outbox on its bound adapter
|
|
463
|
+
# (`AppendOnly#outbox?`) runs reactions inline — lost on a crash between a
|
|
464
|
+
# commit and its reaction. A warning, not a refusal: Memory has an in-process
|
|
465
|
+
# outbox, so dev/test stays quiet, but file/remote adapters need this to be loud.
|
|
482
466
|
def warn_undurable_outbox!(hexagon)
|
|
483
467
|
bluebook_ir = bluebook(hexagon.domain)
|
|
484
468
|
return unless bluebook_ir
|
|
@@ -505,6 +489,8 @@ module Hecks
|
|
|
505
489
|
@bluebooks.each_value.any? { |candidate| candidate.policies.any? { |policy| emitted.include?(policy.event_name.to_s) } }
|
|
506
490
|
end
|
|
507
491
|
|
|
492
|
+
# A warning, not a refusal: running sagas on a store with no `save_saga` is
|
|
493
|
+
# legitimate on purpose in a fast in-memory test/dev boot.
|
|
508
494
|
def warn_undurable_sagas!(hexagon)
|
|
509
495
|
bluebook_ir = bluebook(hexagon.domain)
|
|
510
496
|
return unless bluebook_ir
|