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
|
@@ -6,23 +6,8 @@ require_relative "../../../../runtime/registry"
|
|
|
6
6
|
|
|
7
7
|
module Hecks
|
|
8
8
|
module Runtime
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# `PostgresEra::LineageManager::CoverageCheck` calls `uncovered_
|
|
12
|
-
# attributes`/`unsafe_additions`/`refuse_uncovered!`/`refuse_unsafe_
|
|
13
|
-
# addition!`/`check_vanished_aggregates!` directly, per translation
|
|
14
|
-
# edge, over its own DB-held shapes; `Translation::Reattest` and
|
|
15
|
-
# `PostgresEra::LineageManager` call `shadow_parse` directly, to read
|
|
16
|
-
# historical bluebook text under old grammar defaults. Both are real,
|
|
17
|
-
# independent, currently-shipped consumers.
|
|
18
|
-
#
|
|
19
|
-
# There is deliberately no top-level `check!`/`check_bluebook!` here
|
|
20
|
-
# walking a registry and reading/writing a held snapshot under
|
|
21
|
-
# `data/eras/*.bluebook`: it would duplicate, on its own, the same
|
|
22
|
-
# per-aggregate walk `CoverageCheck` already performs against
|
|
23
|
-
# `PostgresEra`'s own DB-held shapes, and nothing in production would
|
|
24
|
-
# call it — an unwired driver is not kept, per ADR 0032. If one is
|
|
25
|
-
# wanted, it is built informed by `CoverageCheck`'s real orchestration.
|
|
9
|
+
# Shape-drift coverage primitives (ADR 0032). Not a driver: callers own
|
|
10
|
+
# walking a registry and reading/writing held snapshots; nothing here does either.
|
|
26
11
|
module EraGuard
|
|
27
12
|
extend ShapeDiff
|
|
28
13
|
|
|
@@ -30,20 +15,16 @@ module Hecks
|
|
|
30
15
|
|
|
31
16
|
# Refuses the boot when a held aggregate is gone and no translation says where it went.
|
|
32
17
|
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# against, and a plain per-aggregate diff would never see it: the
|
|
37
|
-
# current aggregate simply has no held counterpart to compare to.
|
|
18
|
+
# A held aggregate matching no current name has no counterpart for a
|
|
19
|
+
# plain per-aggregate diff to compare against; only a `was:` or
|
|
20
|
+
# `retired` translation can explain it.
|
|
38
21
|
#
|
|
39
|
-
# @param registry [Runtime::Registry] the registry
|
|
40
|
-
# searched for a `was:` or a `retired` entry naming the held aggregate
|
|
22
|
+
# @param registry [Runtime::Registry] the registry searched for a `was:`/`retired` entry
|
|
41
23
|
# @param bluebook [Bluebook::Chapter] the bluebook booting now
|
|
42
24
|
# @param held_bluebook [Bluebook::Chapter] the bluebook parsed from the held era's text
|
|
43
25
|
# @return [void]
|
|
44
|
-
# @raise [Runtime::WiringError] if a held aggregate matches no current aggregate
|
|
45
|
-
#
|
|
46
|
-
# for this domain retires it
|
|
26
|
+
# @raise [Runtime::WiringError] if a held aggregate matches no current aggregate, no
|
|
27
|
+
# `was:` declares it, and no translation retires it
|
|
47
28
|
def check_vanished_aggregates!(registry, bluebook, held_bluebook)
|
|
48
29
|
held_bluebook.aggregates.each do |held_aggregate|
|
|
49
30
|
claimed = bluebook.aggregates.any? do |aggregate|
|
|
@@ -125,65 +106,16 @@ module Hecks
|
|
|
125
106
|
end
|
|
126
107
|
end
|
|
127
108
|
|
|
128
|
-
# Parses held source into its own IR, in a
|
|
129
|
-
# era's text never touches the one actually booting.
|
|
109
|
+
# Parses held source into its own IR, in a throwaway registry.
|
|
130
110
|
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
# that has nothing to do with syntax the live grammar cannot
|
|
135
|
-
# read at all (`identified_by { }`, `belongs_to`, `has_one`,
|
|
136
|
-
# `has_many` — genuinely removed spellings, exactly what shadow-
|
|
137
|
-
# parsing exists to keep readable): `reference_to`'s own default
|
|
138
|
-
# mint name (`default_reference_name`, attribute_collector.rb)
|
|
139
|
-
# is bare under ADR 0025 and `_id`-suffixed under shadow mode, and
|
|
140
|
-
# that fork applies even to text using nothing but current, live
|
|
141
|
-
# syntax. Held text minted under the current grammar — every real
|
|
142
|
-
# era in this corpus today, since nothing has ever minted a second
|
|
143
|
-
# one — parses fine normally; under unconditional shadow mode only
|
|
144
|
-
# the reference-naming default differs, so it silently
|
|
145
|
-
# reconstructs a different shape (and hash) than a fresh parse of
|
|
146
|
-
# the identical text — the same text hashing two different ways
|
|
147
|
-
# depending on which code path read it, breaking `ensure_named!`'s
|
|
148
|
-
# own from/to edge lookup with a spurious "no translation edge
|
|
149
|
-
# covers it" refusal that has nothing to do with any real
|
|
150
|
-
# translation gap.
|
|
151
|
-
#
|
|
152
|
-
# A normal parse can only ever succeed on text the live grammar
|
|
153
|
-
# fully understands — there is no way for it to silently produce a
|
|
154
|
-
# wrong-but-plausible answer for genuinely legacy text, since every
|
|
155
|
-
# removed spelling refuses loudly (`Malformed`) rather than
|
|
156
|
-
# degrading. So: try normal first — if the ordinary grammar reads
|
|
157
|
-
# this text without complaint, that is the canonical, unambiguous
|
|
158
|
-
# interpretation, the same one `label_of`/`mint_hash` on the same
|
|
159
|
-
# source text always computes, whoever's asking. Only on a
|
|
160
|
-
# `Malformed` refusal — the one signal that actually means "this
|
|
161
|
-
# spelling is not in the live grammar" — fall back to the legacy
|
|
162
|
-
# grammar. Any other exception (a
|
|
163
|
-
# genuine syntax error, an unrelated validation refusal) propagates
|
|
164
|
-
# unchanged; swallowing it here to retry under shadow mode would
|
|
165
|
-
# risk masking a real defect in the held text behind a confusing
|
|
166
|
-
# second failure instead of the original, more specific one.
|
|
167
|
-
#
|
|
168
|
-
# `MetaValidator.while_shadow_parsing` (ADR 0025, docs/dsl-work-
|
|
169
|
-
# slices.md's S0a) is what makes the fallback a legacy grammar
|
|
170
|
-
# rather than just a second copy of today's: it stops
|
|
171
|
-
# `BluebookBuilder.build` from judging this text against the
|
|
172
|
-
# grammar as it stands now, which is the one thing that would make
|
|
173
|
-
# a removed spelling refuse history the day it is removed from
|
|
174
|
-
# live source. The scratch registry is throwaway either way —
|
|
175
|
-
# nothing here is dispatched against or exposed to the real one —
|
|
176
|
-
# so skipping the judge/assemble round-trip changes nothing this
|
|
177
|
-
# method reads: `shape`, `uncovered_attributes`, and friends only
|
|
178
|
-
# ever ask the built IR for its own structure.
|
|
111
|
+
# Tries the live grammar first, falling back to the shadow one only
|
|
112
|
+
# on `Malformed` — the one signal meaning "not in the live grammar"
|
|
113
|
+
# (ADR 0025); any other exception propagates unchanged.
|
|
179
114
|
#
|
|
180
115
|
# @param source [String] the held bluebook text to evaluate
|
|
181
|
-
# @param path [String] the file path
|
|
182
|
-
#
|
|
183
|
-
# @
|
|
184
|
-
# declares none
|
|
185
|
-
# @raise [Bluebook::DSL::Malformed] if the text parses under neither the live grammar
|
|
186
|
-
# nor the legacy one
|
|
116
|
+
# @param path [String] the file path reported as the text's origin
|
|
117
|
+
# @return [Bluebook::Chapter, nil] the first bluebook declared; nil when it declares none
|
|
118
|
+
# @raise [Bluebook::DSL::Malformed] if neither grammar accepts the text
|
|
187
119
|
# @raise [SyntaxError] if the text is not valid Ruby
|
|
188
120
|
def shadow_parse(source, path)
|
|
189
121
|
parse_bluebook(source, path, shadow: false)
|
|
@@ -196,7 +128,7 @@ module Hecks
|
|
|
196
128
|
# @param source [String] the bluebook text to evaluate
|
|
197
129
|
# @param path [String] the file path reported to `Kernel.eval` as the text's origin
|
|
198
130
|
# @param shadow [Boolean] true evaluates inside `MetaValidator.while_shadow_parsing`
|
|
199
|
-
# (the
|
|
131
|
+
# (the shadow grammar); false evaluates under the live grammar
|
|
200
132
|
# @return [Bluebook::Chapter, nil] the first bluebook the text registered in the scratch
|
|
201
133
|
# registry; nil when it declares none
|
|
202
134
|
# @raise [Bluebook::DSL::Malformed] if the chosen grammar refuses the text
|
|
@@ -207,7 +139,10 @@ module Hecks
|
|
|
207
139
|
run = lambda do
|
|
208
140
|
Hecks.with_registry(scratch) do
|
|
209
141
|
loading.load_library
|
|
210
|
-
|
|
142
|
+
# Held text of a chapter spread over files is several blocks in one string, each
|
|
143
|
+
# opening the same chapter: judge once after all of them, as a directory load does.
|
|
144
|
+
Hecks::Bluebook::MetaValidator.defer { Kernel.eval(source, TOPLEVEL_BINDING, path, 1) }
|
|
145
|
+
Hecks::Bluebook::MetaValidator.judge_deferred!(scratch)
|
|
211
146
|
end
|
|
212
147
|
end
|
|
213
148
|
shadow ? Hecks::Bluebook::MetaValidator.while_shadow_parsing(&run) : run.call
|
|
@@ -5,26 +5,11 @@ require_relative "storage_shape"
|
|
|
5
5
|
|
|
6
6
|
module Hecks
|
|
7
7
|
module Runtime
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# plain SHA256 comparison over raw bytes, unrelated to any of this);
|
|
11
|
-
# this only supplies the wording once that's already fired.
|
|
8
|
+
# Wording for the boot refusal when a held era's frozen text was
|
|
9
|
+
# edited after freezing (detected elsewhere via a digest mismatch).
|
|
12
10
|
#
|
|
13
|
-
# Lives here, not under `Ports::Persistence
|
|
14
|
-
# calls `
|
|
15
|
-
# (DSL-execution machinery), the "an adapter/port reaches into the
|
|
16
|
-
# runtime instead of being handed already-computed data" shape that
|
|
17
|
-
# has caused trouble here before. A capability this dependent on the
|
|
18
|
-
# runtime is a runtime-owned one that the Postgres adapter calls, not
|
|
19
|
-
# a ports-level module that happens to reach sideways into it.
|
|
20
|
-
#
|
|
21
|
-
# Every tamper refusal reaches the same generic wording, cosmetic edit
|
|
22
|
-
# or real shape change alike: telling the two apart by re-parsing the
|
|
23
|
-
# edited text is a pure quality-of-message nicety, not a safety
|
|
24
|
-
# property, and an edit that cannot be classified has to fall to the
|
|
25
|
-
# generic wording anyway. An operator judges "did this matter"
|
|
26
|
-
# themselves, reading the still-archived original — an anomalous
|
|
27
|
-
# recovery moment already, not a normal boot path.
|
|
11
|
+
# Lives here, not under `Ports::Persistence`, because `project` below
|
|
12
|
+
# calls runtime DSL-execution machinery (`EraGuard`, `StorageShape`) directly.
|
|
28
13
|
module EraTamper
|
|
29
14
|
module_function
|
|
30
15
|
|
|
@@ -40,12 +25,8 @@ module Hecks
|
|
|
40
25
|
|
|
41
26
|
# Parses a bluebook text and returns its storage-shape projection.
|
|
42
27
|
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# Always parsed through a fresh tempfile, never the held file's own
|
|
46
|
-
# path: the predicate extractor caches source by path, and a held
|
|
47
|
-
# path whose content has changed (the very situation this module
|
|
48
|
-
# exists for) would hand it stale lines.
|
|
28
|
+
# Always parsed from a fresh tempfile, never the held file's own path,
|
|
29
|
+
# since the predicate extractor caches source by path and would see stale lines there.
|
|
49
30
|
#
|
|
50
31
|
# @param text [String] the bluebook source to parse
|
|
51
32
|
# @param _source_path [String, nil] ignored; the text is always parsed from a tempfile
|
|
@@ -5,27 +5,8 @@ require "uri"
|
|
|
5
5
|
module Hecks
|
|
6
6
|
module Runtime
|
|
7
7
|
module EraCheck
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# it with an allow-list file of the eras that should be running.
|
|
11
|
-
#
|
|
12
|
-
# `EraCheck.check!` decides at boot, against the store, whether a host may
|
|
13
|
-
# run on an era. This answers the question after a roll, from outside:
|
|
14
|
-
# did the host that came up report an era the operator expects? The two
|
|
15
|
-
# never share state. The host's own `GET /version` document
|
|
16
|
-
# (`rust/host/src/server.rs`, `version_body`) is the only input, so a
|
|
17
|
-
# rollback to an older image, or a fork of the journal back onto an older
|
|
18
|
-
# era, shows up here as an era missing from the list.
|
|
19
|
-
#
|
|
20
|
-
# ## The allow-list file
|
|
21
|
-
#
|
|
22
|
-
# One era id per line. Blank lines and lines starting with `#` are
|
|
23
|
-
# ignored, and so is a trailing ` # comment`. A file that lists no era
|
|
24
|
-
# means "only check that the host reports one", so a first roll can be
|
|
25
|
-
# checked before any era id is known. The generated `expected-era` file
|
|
26
|
-
# (`Deploy::Scripts`) has this shape.
|
|
27
|
-
#
|
|
28
|
-
# `bin/check_era` is the command-line wrapper.
|
|
8
|
+
# Compares a running host's reported era (`GET /version`) against an
|
|
9
|
+
# allow-list file of eras that should be running, for use after a roll.
|
|
29
10
|
module ExpectedEra
|
|
30
11
|
# The host could not be reached, or did not answer with a `200`.
|
|
31
12
|
class Unreachable < StandardError; end
|
|
@@ -36,7 +17,7 @@ module Hecks
|
|
|
36
17
|
# What a comparison concluded.
|
|
37
18
|
#
|
|
38
19
|
# @!attribute [r] status
|
|
39
|
-
# @return [Symbol] `:match`, `:unlisted` (no era
|
|
20
|
+
# @return [Symbol] `:match`, `:unlisted` (no era listed) or `:mismatch`
|
|
40
21
|
# @!attribute [r] era
|
|
41
22
|
# @return [String] the era the host reported
|
|
42
23
|
# @!attribute [r] allowed
|
|
@@ -78,13 +59,26 @@ module Hecks
|
|
|
78
59
|
# @raise [Unreachable] if the request fails or the status is not `200`
|
|
79
60
|
# @raise [BadResponse] if the body is not JSON or its `era` is not a non-empty string
|
|
80
61
|
def fetch_era(url, timeout: 10)
|
|
62
|
+
fetch_version(url, timeout: timeout).fetch("era")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Asks a host for its `/version` document.
|
|
66
|
+
#
|
|
67
|
+
# @param url [String] the host's base URL, or its `/version` URL
|
|
68
|
+
# @param timeout [Numeric] seconds allowed for connecting and for reading
|
|
69
|
+
# @return [Hash{String => String}] `"era"` (never empty) and `"version"` (empty when the
|
|
70
|
+
# host reports none)
|
|
71
|
+
# @raise [Unreachable] if the request fails or the status is not `200`
|
|
72
|
+
# @raise [BadResponse] if the body is not JSON or its `era` is not a non-empty string
|
|
73
|
+
def fetch_version(url, timeout: 10)
|
|
81
74
|
response = get(version_url(url), timeout)
|
|
82
75
|
raise Unreachable, "#{version_url(url)} answered #{response.code}" unless response.code == "200"
|
|
83
76
|
|
|
84
|
-
|
|
77
|
+
document = JSON.parse(response.body)
|
|
78
|
+
era = document["era"]
|
|
85
79
|
raise BadResponse, "#{version_url(url)} carries no era" unless era.is_a?(String) && !era.empty?
|
|
86
80
|
|
|
87
|
-
era
|
|
81
|
+
{ "era" => era, "version" => document["version"].to_s }
|
|
88
82
|
rescue JSON::ParserError, TypeError
|
|
89
83
|
raise BadResponse, "#{version_url(url)} did not answer a JSON version document"
|
|
90
84
|
end
|
|
@@ -6,11 +6,7 @@ module Hecks
|
|
|
6
6
|
module Ports
|
|
7
7
|
module Persistence
|
|
8
8
|
# Translates a journal entry written under an old shape into the one
|
|
9
|
-
# the current bluebook declares
|
|
10
|
-
# aggregate, or a field crossing a value-object boundary. Applied
|
|
11
|
-
# wherever entries are read, so replay derives the current head from
|
|
12
|
-
# history that was never rewritten — the port owns the meaning,
|
|
13
|
-
# adapters stay oblivious.
|
|
9
|
+
# the current bluebook declares; replay derives the head from unrewritten history.
|
|
14
10
|
class Lineage
|
|
15
11
|
# `ancestor_name` is the declared name a rename came from (matches
|
|
16
12
|
# the held bluebook's own aggregate names); `ancestor_storage_name`
|
|
@@ -24,8 +20,8 @@ module Hecks
|
|
|
24
20
|
# searched, in declaration order
|
|
25
21
|
# @param domain [String, Symbol] name of the domain the aggregate belongs to
|
|
26
22
|
# @param aggregate [Bluebook::Aggregate] the aggregate as currently declared
|
|
27
|
-
# @return [Ports::Persistence::Lineage, nil] the
|
|
28
|
-
#
|
|
23
|
+
# @return [Ports::Persistence::Lineage, nil] the first translation for `domain` naming
|
|
24
|
+
# the aggregate; nil when none does
|
|
29
25
|
def self.for(registry, domain, aggregate)
|
|
30
26
|
translation = registry.translations.find do |candidate|
|
|
31
27
|
candidate.domain == domain.to_s && candidate.for_aggregate(aggregate.name)
|
|
@@ -37,9 +33,8 @@ module Hecks
|
|
|
37
33
|
|
|
38
34
|
# Builds the rules one declared translation edge carries for one aggregate.
|
|
39
35
|
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# edge in the registry mentioned the aggregate first.
|
|
36
|
+
# Unlike `for`, this uses one specific edge, not whichever edge in
|
|
37
|
+
# the registry mentions the aggregate first — what the mint path needs.
|
|
43
38
|
#
|
|
44
39
|
# @param declared [Bluebook::TranslationAggregate, nil] the edge's entry for the
|
|
45
40
|
# aggregate, as `Bluebook::Translation#for_aggregate` returns it; nil when the edge
|
|
@@ -60,24 +55,16 @@ module Hecks
|
|
|
60
55
|
ancestor_name: ancestor_name, ancestor_storage_name: ancestor_storage_name)
|
|
61
56
|
end
|
|
62
57
|
|
|
63
|
-
# @param renames [Hash{Symbol => Symbol}] old
|
|
64
|
-
# @param moves [Array<Bluebook::TranslationMove>]
|
|
65
|
-
#
|
|
66
|
-
# @param
|
|
67
|
-
#
|
|
68
|
-
# @param
|
|
69
|
-
# @param
|
|
70
|
-
#
|
|
71
|
-
# @param
|
|
72
|
-
#
|
|
73
|
-
# @param rekeys [Array<Bluebook::TranslationRekey>] SQL-only identity rewrites; only
|
|
74
|
-
# the first is read
|
|
75
|
-
# @param backfills [Array<Bluebook::TranslationBackfill>] defaults for new top-level
|
|
76
|
-
# attributes an old entry lacks
|
|
77
|
-
# @param ancestor_name [String, nil] the aggregate's declared name before the edge;
|
|
78
|
-
# nil unless the edge renames the aggregate itself
|
|
79
|
-
# @param ancestor_storage_name [String, nil] snake_case storage name of
|
|
80
|
-
# `ancestor_name`; nil unless the edge renames the aggregate itself
|
|
58
|
+
# @param renames [Hash{Symbol => Symbol}] old attribute name to new name
|
|
59
|
+
# @param moves [Array<Bluebook::TranslationMove>] from/to paths across a value object
|
|
60
|
+
# @param converts [Array<Bluebook::TranslationConvert>] moves mapped through a values table
|
|
61
|
+
# @param drops [Array<Symbol>] bare or dotted paths whose data is discarded
|
|
62
|
+
# @param retypes [Array<Bluebook::TranslationRetype>] type names meaning the same shape
|
|
63
|
+
# @param computes [Array<Bluebook::TranslationCompute>] SQL-only rules, never applied here
|
|
64
|
+
# @param rekeys [Array<Bluebook::TranslationRekey>] SQL rewrites; only the first is read
|
|
65
|
+
# @param backfills [Array<Bluebook::TranslationBackfill>] defaults for a new attribute
|
|
66
|
+
# @param ancestor_name [String, nil] the aggregate's name before the edge, if renamed
|
|
67
|
+
# @param ancestor_storage_name [String, nil] snake_case storage name of ancestor_name
|
|
81
68
|
def initialize(renames, moves = [], converts = [], drops = [], retypes: [], computes: [], rekeys: [],
|
|
82
69
|
backfills: [], ancestor_name: nil, ancestor_storage_name: nil)
|
|
83
70
|
@renames = renames
|
|
@@ -94,54 +81,39 @@ module Hecks
|
|
|
94
81
|
|
|
95
82
|
# Reports whether any rule in this edge is a compute.
|
|
96
83
|
#
|
|
97
|
-
# Compute
|
|
98
|
-
#
|
|
99
|
-
# Postgres, per-rule and by name, before the general drift
|
|
100
|
-
# machinery says anything vaguer.
|
|
84
|
+
# Compute has no in-process implementation; an aggregate carrying
|
|
85
|
+
# one refuses to boot anywhere but Postgres.
|
|
101
86
|
#
|
|
102
87
|
# @return [Boolean] true when the edge declares at least one compute rule
|
|
103
88
|
def computes? = !@computes.empty?
|
|
104
89
|
|
|
105
90
|
# Reports whether this edge rewrites the aggregate's identity.
|
|
106
91
|
#
|
|
107
|
-
# The single source of truth for
|
|
108
|
-
#
|
|
109
|
-
# minter.rb's approval gate, layer_two.rb's audit, head_compiler.rb's
|
|
110
|
-
# SQL compilation) asks this, never re-derives it from `declared`
|
|
111
|
-
# independently. One accessor to change if what a rekey rule means
|
|
112
|
-
# ever needs to change, not four call sites in four files.
|
|
92
|
+
# The single source of truth for this; other call sites ask here
|
|
93
|
+
# rather than re-deriving it from `declared` themselves.
|
|
113
94
|
#
|
|
114
95
|
# @return [Boolean] true when the edge declares at least one rekey rule
|
|
115
96
|
def rekey? = !@rekeys.empty?
|
|
116
97
|
|
|
117
98
|
# Returns the SQL expression the edge's first rekey rule declares.
|
|
118
99
|
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
# (an edge with more than one is a DSL-level decision, not
|
|
122
|
-
# something this reader arbitrates).
|
|
100
|
+
# Only the first rule is read, the same one-per-aggregate assumption
|
|
101
|
+
# `compute` makes; more than one is a DSL-level decision to arbitrate elsewhere.
|
|
123
102
|
#
|
|
124
103
|
# @return [String, nil] the first rekey rule's SQL; nil when the edge declares no rekey
|
|
125
104
|
def rekey_sql = @rekeys.first&.sql
|
|
126
105
|
|
|
127
106
|
# Rewrites one journal entry's state from the held shape into the current one.
|
|
128
107
|
#
|
|
129
|
-
# The reference semantics for
|
|
130
|
-
#
|
|
131
|
-
# `retype` moves nothing (stored state never carries a type name)
|
|
132
|
-
# and `compute` is deliberately not applied here: its SQL is its
|
|
133
|
-
# only implementation, so this transform neither imitates nor
|
|
134
|
-
# checks it — the source field passes through untouched, and the
|
|
135
|
-
# audit verifies compute output against the matview alone.
|
|
108
|
+
# The reference semantics for rename, move, convert, drop, and the aggregate-level `was:`.
|
|
109
|
+
# `compute` is not applied here — its SQL is the only implementation, audited separately.
|
|
136
110
|
#
|
|
137
|
-
# @param entry [Ports::Persistence::Entry] the entry as stored
|
|
138
|
-
# top-level keys and String keys
|
|
139
|
-
# @return [Ports::Persistence::Entry] a new entry with
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
# table, or a move or convert would nest under a destination already holding a
|
|
144
|
-
# non-Hash value
|
|
111
|
+
# @param entry [Ports::Persistence::Entry] the entry as stored, with Symbol
|
|
112
|
+
# top-level keys and String keys nested in a value-object Hash
|
|
113
|
+
# @return [Ports::Persistence::Entry] a new entry with translated state and the same
|
|
114
|
+
# `operation`, `id` and `mirrors`; `entry` itself when it is not a save or has no state
|
|
115
|
+
# @raise [Runtime::WiringError] if a convert value is missing from its `values` table, or a
|
|
116
|
+
# move/convert would nest under a destination already holding a non-Hash value
|
|
145
117
|
def translate(entry)
|
|
146
118
|
return entry unless entry.save? && entry.state
|
|
147
119
|
|
|
@@ -153,45 +125,18 @@ module Hecks
|
|
|
153
125
|
@moves.each { |move| apply_move(state, move) }
|
|
154
126
|
@converts.each { |convert| apply_convert(state, convert) }
|
|
155
127
|
@drops.each { |name| apply_drop(state, name) }
|
|
156
|
-
#
|
|
157
|
-
# fills the gap a rename/move/convert left untouched, never
|
|
158
|
-
# overwrites a value that already made it across. Dotted-path
|
|
159
|
-
# aware, same as `apply_drop` above (`apply_backfill`'s own
|
|
160
|
-
# header) — a bare name was the only shape this ever needed
|
|
161
|
-
# until a value object gained new required members with zero
|
|
162
|
-
# source data of their own (found live: a client site's Attendee
|
|
163
|
-
# redesign, commit 4326dcd).
|
|
128
|
+
# Only fills a gap nothing else already filled; dotted-path aware, like apply_drop.
|
|
164
129
|
@backfills.each { |backfill| apply_backfill(state, backfill) }
|
|
165
130
|
Entry.new(operation: entry.operation, id: entry.id, state: state, mirrors: entry.mirrors)
|
|
166
131
|
end
|
|
167
132
|
|
|
168
133
|
# Reports whether some rule accounts for a held path that vanished or changed type.
|
|
169
134
|
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
# member ("price.currency"); a rule covering the whole top-level
|
|
174
|
-
# attribute (a rename, a top-level move/convert/drop) also covers
|
|
175
|
-
# anything nested under it, since the whole value travels or goes
|
|
176
|
-
# away together. This is what catches a field — or a value object's
|
|
177
|
-
# own member — that vanished (or silently changed type) without
|
|
178
|
-
# anything explaining it, even when some other field is covered.
|
|
135
|
+
# A rule covering a whole top-level attribute also covers anything nested
|
|
136
|
+
# under it; `backfills` only matches a whole name, since a backfill adds an
|
|
137
|
+
# attribute that is new outright, never a path that existed and moved.
|
|
179
138
|
#
|
|
180
|
-
#
|
|
181
|
-
# prefix — a backfill names a top-level attribute that is new
|
|
182
|
-
# outright (nothing to be a prefix of on the held side), unlike
|
|
183
|
-
# every rule above it, which explains a path that existed and
|
|
184
|
-
# moved, converted, or vanished.
|
|
185
|
-
#
|
|
186
|
-
# One `||` chain over a closed, fixed set of rule kinds (renames,
|
|
187
|
-
# moves, converts, drops, computes, backfills) — the same six this
|
|
188
|
-
# file's other methods enumerate. Splitting each disjunct into its
|
|
189
|
-
# own predicate would scatter one question ("does any rule explain
|
|
190
|
-
# this path") across six same-shaped methods with nothing else to
|
|
191
|
-
# do.
|
|
192
|
-
#
|
|
193
|
-
# @param path [String, Symbol] a bare attribute name or a dotted value-object member
|
|
194
|
-
# path on the held side
|
|
139
|
+
# @param path [String, Symbol] a bare attribute name or a dotted value-object member path
|
|
195
140
|
# @return [Boolean] true when a rename, move, convert, drop or compute names the path or
|
|
196
141
|
# its top-level attribute as its source, or a backfill names the top-level attribute
|
|
197
142
|
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
@@ -210,32 +155,11 @@ module Hecks
|
|
|
210
155
|
|
|
211
156
|
# Reports whether some rule gives an existing record a value at a new attribute.
|
|
212
157
|
#
|
|
213
|
-
# The destination-side twin of `explains
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
# an existing record end up with a value here" — and a move or
|
|
217
|
-
# convert whose `to:` lands a old field inside a brand-new
|
|
218
|
-
# top-level attribute (`weight` becoming `contents.weight` when
|
|
219
|
-
# `Contents` did not exist before) fills that attribute for an
|
|
220
|
-
# existing record exactly as a `backfill` would, even though
|
|
221
|
-
# nothing named `contents` explains any vanished path. `compute`
|
|
222
|
-
# counts on the same terms `explains?` already grants it
|
|
223
|
-
# elsewhere in this file — Postgres-only and audited, not
|
|
224
|
-
# actually applied by this method, the same gap the vanish side
|
|
225
|
-
# already lives with.
|
|
158
|
+
# The destination-side twin of `explains?`, which checks a rule's source; this checks
|
|
159
|
+
# `@renames.value?` too, since a bare rename fills the destination unconditionally,
|
|
160
|
+
# the same way a backfill would.
|
|
226
161
|
#
|
|
227
|
-
#
|
|
228
|
-
# `rename :cost, to: :amount` is the plainest possible covering
|
|
229
|
-
# rule there is (`translate` above applies it unconditionally, no
|
|
230
|
-
# lookup table, no per-record ambiguity — simpler than a move or
|
|
231
|
-
# convert), and without it `unsafe_additions` reports the new name
|
|
232
|
-
# as an unexplained required addition on every rename-only edge,
|
|
233
|
-
# the single most common translation shape there is. `explains?`
|
|
234
|
-
# checks the source side (`@renames.key?`); this is the symmetric
|
|
235
|
-
# destination-side check.
|
|
236
|
-
#
|
|
237
|
-
# @param path [String, Symbol] the name of a top-level attribute new in the current
|
|
238
|
-
# shape
|
|
162
|
+
# @param path [String, Symbol] the name of a top-level attribute new in the current shape
|
|
239
163
|
# @return [Boolean] true when a rename, move, convert or compute lands a value in that
|
|
240
164
|
# attribute, or a backfill names it
|
|
241
165
|
def fills?(path)
|
|
@@ -250,15 +174,11 @@ module Hecks
|
|
|
250
174
|
|
|
251
175
|
# Reports whether a declared retype pairs two type names as the same shape.
|
|
252
176
|
#
|
|
253
|
-
#
|
|
254
|
-
#
|
|
255
|
-
# type name, so this never moves a value; it only satisfies the
|
|
256
|
-
# era diff's literal type-name comparison.
|
|
177
|
+
# Nothing in the stored data carries a type name, so this never moves a value;
|
|
178
|
+
# it only satisfies the era diff's literal type-name comparison.
|
|
257
179
|
#
|
|
258
|
-
# @param held_type [String, Bluebook::Reference] the type the held era declares
|
|
259
|
-
#
|
|
260
|
-
# @param current_type [String, Bluebook::Reference] the type declared now, compared by
|
|
261
|
-
# its `to_s`
|
|
180
|
+
# @param held_type [String, Bluebook::Reference] the type the held era declares
|
|
181
|
+
# @param current_type [String, Bluebook::Reference] the type declared now
|
|
262
182
|
# @return [Boolean] true when some retype rule runs from `held_type` to `current_type`
|
|
263
183
|
def retype?(held_type, current_type)
|
|
264
184
|
@retypes.any? { |retype| retype.from == held_type.to_s && retype.to == current_type.to_s }
|
|
@@ -274,30 +194,14 @@ module Hecks
|
|
|
274
194
|
end
|
|
275
195
|
end
|
|
276
196
|
|
|
277
|
-
#
|
|
278
|
-
#
|
|
279
|
-
#
|
|
280
|
-
# one rule at a time against the same hash it was reading from,
|
|
281
|
-
# loses data the instant one rule's destination is another
|
|
282
|
-
# rule's source. Applied sequentially, a swap (`rename :a, to: :b`
|
|
283
|
-
# alongside `rename :b, to: :a`) on `{a: 1, b: 2}` produces
|
|
284
|
-
# `{a: 1}` — the first rule writes `b: 1` over the real `b: 2`
|
|
285
|
-
# before the second rule ever gets a chance to read it, and the
|
|
286
|
-
# value the whole edge is supposed to preserve (2, moved to
|
|
287
|
-
# `:a`) is gone. The standard fix: snapshot every rule's old
|
|
288
|
-
# key and value from `state` first, then remove every old key
|
|
289
|
-
# and only then write every new key — a rename never reads a
|
|
290
|
-
# key this same pass has already written to, so a swap or a
|
|
291
|
-
# longer chain applies as one permutation, not a sequence of
|
|
292
|
-
# edits each stepping on the last.
|
|
197
|
+
# Snapshots every rename's old key/value before writing any new key, so a
|
|
198
|
+
# swap (:a<->:b) applies as one permutation instead of losing data when one
|
|
199
|
+
# rule's destination is another's source.
|
|
293
200
|
def apply_renames(state, renames)
|
|
294
201
|
snapshot = renames.filter_map { |old_name, new_name| [old_name, new_name, state[old_name]] if state.key?(old_name) }
|
|
295
202
|
snapshot.each { |old_name, _new_name, _value| state.delete(old_name) }
|
|
296
|
-
# Not combinable
|
|
297
|
-
#
|
|
298
|
-
# every delete done before any write, or the first rename's write
|
|
299
|
-
# becomes the second rename's delete target — see this method's
|
|
300
|
-
# own comment above.
|
|
203
|
+
# Not combinable: every delete must finish before any write, or a swap's
|
|
204
|
+
# first write becomes its second delete target.
|
|
301
205
|
snapshot.each { |_old_name, new_name, value| state[new_name] = value }
|
|
302
206
|
end
|
|
303
207
|
|
|
@@ -317,18 +221,7 @@ module Hecks
|
|
|
317
221
|
end
|
|
318
222
|
end
|
|
319
223
|
|
|
320
|
-
#
|
|
321
|
-
# mirror on the addition side. A bare name sets a plain top-level
|
|
322
|
-
# key, unchanged from before; a dotted name (`"attendee.
|
|
323
|
-
# first_name"`) reaches into an existing value-object member the
|
|
324
|
-
# same way `apply_drop`/`hecks_tr_insert` (rule_compiler.rb's own
|
|
325
|
-
# SQL-compiled twin, kept in step with this) already do — creating
|
|
326
|
-
# the container Hash if an old record somehow lacks it entirely,
|
|
327
|
-
# never overwriting a value already there at either level.
|
|
328
|
-
#
|
|
329
|
-
# @param state [Hash] the entry's own state Hash, mutated in place
|
|
330
|
-
# @param backfill [Bluebook::TranslationBackfill] the backfill rule to apply
|
|
331
|
-
# @return [void]
|
|
224
|
+
# Dotted-path aware; must stay in step with `hecks_tr_insert` in rule_compiler.rb.
|
|
332
225
|
def apply_backfill(state, backfill)
|
|
333
226
|
name = backfill.name.to_s
|
|
334
227
|
top, member = name.split(".", 2)
|
|
@@ -342,17 +235,8 @@ module Hecks
|
|
|
342
235
|
end
|
|
343
236
|
end
|
|
344
237
|
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
# key — the spelling a raw stored row carries. Translation runs on
|
|
348
|
-
# raw rows, before the state codec decodes anything (PR A3): its
|
|
349
|
-
# only caller (`Translation::Audit::LayerTwo`) feeds it
|
|
350
|
-
# head-snapshot rows straight out of `JSON.parse`, and the
|
|
351
|
-
# PostgresEra head applies the same rules in SQL before
|
|
352
|
-
# `PostgresEra#decode` ever sees the jsonb. Decode is always the
|
|
353
|
-
# last step, so an undeclared (retired) member this rule has to
|
|
354
|
-
# read is still exactly as it was written, and never something an
|
|
355
|
-
# adapter's `entries` — decoded, deep-symbol — would be fed here.
|
|
238
|
+
# Runs on raw rows, before the state codec decodes anything — decode is
|
|
239
|
+
# always the last step, so this never sees an adapter's deep-symbolized entry.
|
|
356
240
|
def apply_move(state, move)
|
|
357
241
|
old_top, old_member = move.from.split(".", 2)
|
|
358
242
|
new_top, new_member = move.to.split(".", 2)
|
|
@@ -364,9 +248,8 @@ module Hecks
|
|
|
364
248
|
insert(state, new_top.to_sym, new_member, value, rule: "move #{move.from} to: #{move.to}")
|
|
365
249
|
end
|
|
366
250
|
|
|
367
|
-
# A convert is a move whose value has nothing in common with its
|
|
368
|
-
#
|
|
369
|
-
# with no entry in the table refuses loudly rather than carry an
|
|
251
|
+
# A convert is a move whose value has nothing in common with its replacement.
|
|
252
|
+
# A value missing from the lookup table refuses loudly rather than carry an
|
|
370
253
|
# unrecognized value silently into the new era.
|
|
371
254
|
def apply_convert(state, convert)
|
|
372
255
|
old_top, old_member = convert.from.split(".", 2)
|
|
@@ -397,18 +280,9 @@ module Hecks
|
|
|
397
280
|
[value, true]
|
|
398
281
|
end
|
|
399
282
|
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
#
|
|
403
|
-
# dotted destination needs it (`state[top] ||= {}` alone only
|
|
404
|
-
# guards nil/false, so a truthy non-Hash sails straight through
|
|
405
|
-
# to `state[top][member] =`, i.e. `"team-1"["detail"] =`, which
|
|
406
|
-
# is String#[]= and raises an unrelated-looking IndexError).
|
|
407
|
-
# Whether it crashes or silently replaces the value, that is a
|
|
408
|
-
# `drop` that never declared itself — the one thing this language
|
|
409
|
-
# exists to make explicit (see apply_convert's own refusal above,
|
|
410
|
-
# the same shape). Refuse by name instead, on both sides: the SQL
|
|
411
|
-
# half (hecks_tr_insert) raises the identical wording.
|
|
283
|
+
# A destination already holding a non-Hash value (e.g. a bare reference id)
|
|
284
|
+
# must not be silently nested under — that would be an undeclared drop. The
|
|
285
|
+
# SQL half (`hecks_tr_insert`) refuses with identical wording.
|
|
412
286
|
def insert(state, top, member, value, rule:)
|
|
413
287
|
return state[top] = value unless member
|
|
414
288
|
|