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
|
@@ -5,70 +5,73 @@ require_relative "../storage_shape"
|
|
|
5
5
|
|
|
6
6
|
module Hecks
|
|
7
7
|
module Translation
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# (comments, whitespace, behavior) re-freeze safely; a shape change
|
|
11
|
-
# would retroactively redefine what era N *meant* for data already
|
|
12
|
-
# written under it, and refuses hard — there is no --accept past
|
|
13
|
-
# this guard.
|
|
14
|
-
#
|
|
15
|
-
# This does not violate minted-once. That prohibition exists so
|
|
16
|
-
# boot-time recognition never depends on canonicalization stability;
|
|
17
|
-
# this is operator-initiated repair, where a false negative is a
|
|
18
|
-
# loud refusal, never a silent misread.
|
|
8
|
+
# Decides whether an edited era text changed the era's shape or only its text.
|
|
9
|
+
# A shape change refuses hard; no --accept flag gets past it.
|
|
19
10
|
module Reattest
|
|
20
11
|
module_function
|
|
21
12
|
|
|
22
|
-
#
|
|
23
|
-
#
|
|
13
|
+
# Says how an edited era text stands against the shape the era was frozen with, without
|
|
14
|
+
# refusing anything: the facts `Era.Permit`'s givens hold, and what `shape_guard!` raises on.
|
|
15
|
+
#
|
|
16
|
+
# @param text [String] the held era's bluebook source as it now stands
|
|
17
|
+
# @param stored_hash [String, nil] the era's minted shape hash (SHA-256 hex); nil if unnamed
|
|
18
|
+
# @param stored_projection [Hash{String => Object}, nil] the stored
|
|
19
|
+
# `Runtime::StorageShape.project` result as parsed JSON; nil when absent
|
|
20
|
+
# @return [Symbol] `:cosmetic` when the shape is unchanged, `:unnamed` when neither a
|
|
21
|
+
# projection nor a hash is stored, `:changed` when the text projects to another shape,
|
|
22
|
+
# `:unloadable` when the text does not load as a bluebook
|
|
23
|
+
def verdict(text:, stored_hash:, stored_projection: nil)
|
|
24
|
+
bluebook = shadow(text)
|
|
25
|
+
return :unloadable unless bluebook
|
|
26
|
+
|
|
27
|
+
# The stored projection is compared first: it is version-free, so a new canonical form
|
|
28
|
+
# cannot make a cosmetic edit look like a shape change. The hash is the fallback.
|
|
29
|
+
if stored_projection
|
|
30
|
+
edited = JSON.parse(JSON.generate(Runtime::StorageShape.project(bluebook)))
|
|
31
|
+
return edited == stored_projection ? :cosmetic : :changed
|
|
32
|
+
end
|
|
33
|
+
return :unnamed unless stored_hash
|
|
34
|
+
|
|
35
|
+
Runtime::StorageShape.mint_hash(bluebook) == stored_hash ? :cosmetic : :changed
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Refuses an edited era text that projects to another shape than the era froze with.
|
|
24
39
|
#
|
|
25
40
|
# @param domain [String] the domain's name, used in refusal messages
|
|
26
41
|
# @param ordinal [Integer] the era's ordinal, used in refusal messages
|
|
27
42
|
# @param text [String] the held era's bluebook source as it now stands
|
|
28
|
-
# @param stored_hash [String, nil] the era's minted shape hash (SHA-256 hex); nil
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# `Runtime::StorageShape.project` result as parsed JSON; nil for a store without one
|
|
43
|
+
# @param stored_hash [String, nil] the era's minted shape hash (SHA-256 hex); nil if unnamed
|
|
44
|
+
# @param stored_projection [Hash{String => Object}, nil] the stored
|
|
45
|
+
# `Runtime::StorageShape.project` result as parsed JSON; nil when absent
|
|
32
46
|
# @return [Symbol] `:cosmetic` when the shape is unchanged, `:unnamed` when neither a
|
|
33
|
-
# projection nor a hash is stored
|
|
34
|
-
# @raise [Runtime::WiringError] if `text` does not load
|
|
35
|
-
# a shape other than the stored one
|
|
47
|
+
# projection nor a hash is stored
|
|
48
|
+
# @raise [Runtime::WiringError] if `text` does not load, or projects to another shape
|
|
36
49
|
def shape_guard!(domain:, ordinal:, text:, stored_hash:, stored_projection: nil)
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
found = verdict(text: text, stored_hash: stored_hash, stored_projection: stored_projection)
|
|
51
|
+
return found if %i[cosmetic unnamed].include?(found)
|
|
52
|
+
|
|
53
|
+
if found == :unloadable
|
|
39
54
|
raise Runtime::WiringError,
|
|
40
55
|
"cannot re-attest era #{ordinal} of #{domain}: the edited text does not load as a " \
|
|
41
56
|
"bluebook — a held era text is bootable source; restore a loadable text"
|
|
42
57
|
end
|
|
58
|
+
raise Runtime::WiringError, changed_shape_message(domain, ordinal, text, stored_hash, stored_projection)
|
|
59
|
+
end
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
# The refusal for an edit that changed the era's shape.
|
|
62
|
+
#
|
|
63
|
+
# @return [String] names the minted label when the era was compared by hash
|
|
64
|
+
def changed_shape_message(domain, ordinal, text, stored_hash, stored_projection)
|
|
65
|
+
head = "cannot re-attest era #{ordinal} of #{domain}: the edit changed the era's SHAPE, not just "
|
|
66
|
+
tail = "Attesting would retroactively redefine what era #{ordinal} meant for data already written " \
|
|
67
|
+
"under it; restore a text with the original shape"
|
|
51
68
|
if stored_projection
|
|
52
|
-
|
|
53
|
-
return :cosmetic if edited == stored_projection
|
|
54
|
-
|
|
55
|
-
raise Runtime::WiringError,
|
|
56
|
-
"cannot re-attest era #{ordinal} of #{domain}: the edit changed the era's SHAPE, not just " \
|
|
57
|
-
"its text — the text no longer projects to the shape frozen for era #{ordinal}. " \
|
|
58
|
-
"Attesting would retroactively redefine what era #{ordinal} meant for data already written " \
|
|
59
|
-
"under it; restore a text with the original shape"
|
|
69
|
+
return "#{head}its text — the text no longer projects to the shape frozen for era #{ordinal}. #{tail}"
|
|
60
70
|
end
|
|
61
|
-
return :unnamed unless stored_hash
|
|
62
|
-
|
|
63
|
-
computed = Runtime::StorageShape.mint_hash(bluebook)
|
|
64
|
-
return :cosmetic if computed == stored_hash
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"a different shape (the text now projects to #{computed[0, Runtime::StorageShape::LABEL_LENGTH]}). " \
|
|
70
|
-
"Attesting would retroactively redefine what era #{ordinal} meant for data already written " \
|
|
71
|
-
"under it; restore a text with the original shape"
|
|
72
|
+
label = Runtime::StorageShape::LABEL_LENGTH
|
|
73
|
+
"#{head}its text — its name #{stored_hash[0, label]} was minted from a different shape (the text " \
|
|
74
|
+
"now projects to #{Runtime::StorageShape.mint_hash(shadow(text))[0, label]}). #{tail}"
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
# Parses bluebook source in a scratch registry, through a temporary file that is
|
|
@@ -2,37 +2,13 @@ require "json"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Translation
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# — the part that turns one TranslationAggregate's declared rules into
|
|
8
|
-
# a jsonb-transforming SQL expression. No database connection, no
|
|
9
|
-
# watermark, no era chain, no catalog lookup: those live in
|
|
10
|
-
# head_compiler.rb's own per-mint assembly, which calls into this
|
|
11
|
-
# module instead of defining these methods itself.
|
|
12
|
-
#
|
|
13
|
-
# A module of its own — not private methods on
|
|
14
|
-
# Adapters::PostgresEra::Lineage — so a second, adapter-agnostic
|
|
15
|
-
# caller (Exporter.translation_aggregate's build-time SQL export,
|
|
16
|
-
# feeding rust/host's own future boot-time mint) can call the exact
|
|
17
|
-
# same code Ruby's own mint path runs, not a hand-ported duplicate
|
|
18
|
-
# that could silently drift the way a hand-kept
|
|
19
|
-
# `Exporter.translation_hash` can drift from `hecks_eras`/
|
|
20
|
-
# `hecks_approvals`' real schema (leaving out rekeys and backfills).
|
|
5
|
+
# Compiles one TranslationAggregate's declared rules into a jsonb-transforming SQL
|
|
6
|
+
# expression, shared by Ruby's own mint path and any other SQL-emitting caller.
|
|
21
7
|
module RuleCompiler
|
|
22
8
|
module_function
|
|
23
9
|
|
|
24
|
-
#
|
|
25
|
-
# expression
|
|
26
|
-
# in the reference transform's phase order (renames, moves,
|
|
27
|
-
# converts, drops), computes last. `retype` compiles to nothing:
|
|
28
|
-
# stored state never carries a type name.
|
|
29
|
-
# Compiles a declared edge's rename/move/convert/drop/compute rules into one nested SQL
|
|
30
|
-
# expression over the `state` jsonb column.
|
|
31
|
-
#
|
|
32
|
-
# @param declared [Bluebook::TranslationAggregate] this edge's declared rules for one
|
|
33
|
-
# aggregate
|
|
34
|
-
# @return [String] a SQL expression, `"state"` unchanged when `declared` declares none
|
|
35
|
-
# of the five rule kinds
|
|
10
|
+
# Compiles one edge's rename/move/convert/drop/compute/backfill rules into a nested
|
|
11
|
+
# SQL expression over `state`, composed innermost-first in that phase order.
|
|
36
12
|
def compile_rules(declared)
|
|
37
13
|
expression = "state"
|
|
38
14
|
declared.renames.each do |old_name, new_name|
|
|
@@ -54,85 +30,33 @@ module Hecks
|
|
|
54
30
|
declared.computes.each do |compute|
|
|
55
31
|
expression = compile_compute(expression, compute)
|
|
56
32
|
end
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# already answered") — now compiled here too, closing the gap
|
|
60
|
-
# this rule kind otherwise leaves: `rust/host`'s boot-time mint
|
|
61
|
-
# audit reads this exact compiled expression, never
|
|
62
|
-
# `Lineage#translate`, so it cannot see a backfilled value unless
|
|
63
|
-
# backfills compile to SQL like every other rule kind here. A
|
|
64
|
-
# real, live gap for any new required value-object member with no
|
|
65
|
-
# source data at all — `compute` cannot fill it either, since its
|
|
66
|
-
# own guard requires a real, already-present field to consume
|
|
67
|
-
# (found live: a client site's Attendee redesign, commit 4326dcd,
|
|
68
|
-
# needed exactly this and had nothing that worked).
|
|
33
|
+
# Backfilled last, same order as `Lineage#translate`'s in-process pass, so the
|
|
34
|
+
# boot-time mint audit (which reads only this compiled SQL) sees the same result.
|
|
69
35
|
declared.backfills.each do |backfill|
|
|
70
36
|
expression = compile_backfill(expression, backfill)
|
|
71
37
|
end
|
|
72
38
|
expression
|
|
73
39
|
end
|
|
74
40
|
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
# every other rule kind is already read in `compile_rules`
|
|
78
|
-
# (`declared.computes`, `declared.moves`, ...), not through the
|
|
79
|
-
# `Ports::Persistence::Lineage` wrapper the app-level consumers
|
|
80
|
-
# (coverage_check.rb, minter.rb, layer_two.rb) go through — this
|
|
81
|
-
# module builds SQL straight off the IR either way.
|
|
82
|
-
# Reports whether an edge's declared rules for an aggregate include a rekey.
|
|
83
|
-
#
|
|
84
|
-
# @param declared [Bluebook::TranslationAggregate, nil] this edge's declared rules for
|
|
85
|
-
# one aggregate; nil for an aggregate the edge declares nothing about
|
|
86
|
-
# @return [Boolean] true when `declared` is present and its `rekeys` is non-empty
|
|
41
|
+
# Reports whether an edge's declared rules for an aggregate include a rekey, read
|
|
42
|
+
# directly off the raw IR like every other rule kind `compile_rules` checks.
|
|
87
43
|
def rekeyed?(declared) = declared && !declared.rekeys.empty?
|
|
88
44
|
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
# declared) stays the bare `aggregate_id` passthrough it always
|
|
92
|
-
# was — this case only appears in an edge that actually declares
|
|
93
|
-
# one.
|
|
94
|
-
#
|
|
95
|
-
# @param guard [String] a SQL boolean expression gating when the rekey applies, such as
|
|
96
|
-
# `"operation = 'save'"`
|
|
97
|
-
# @param declared [Bluebook::TranslationAggregate] this edge's declared rules; must
|
|
98
|
-
# declare a rekey (`rekeyed?(declared)` true)
|
|
99
|
-
# @return [String] a `"CASE WHEN ... END AS aggregate_id"` SQL expression
|
|
45
|
+
# Builds a `CASE WHEN ... END AS aggregate_id` expression that only overrides
|
|
46
|
+
# `aggregate_id` when `guard` matches, leaving the common no-rekey case untouched.
|
|
100
47
|
def id_case(guard, declared)
|
|
101
48
|
"CASE WHEN #{guard} THEN #{compile_id_expression(declared)} ELSE aggregate_id END AS aggregate_id"
|
|
102
49
|
end
|
|
103
50
|
|
|
104
|
-
#
|
|
105
|
-
# progressively-built
|
|
106
|
-
# from. A rekey doesn't consume or move any field the way a move
|
|
107
|
-
# or compute does, so there is no same-edge rename/move ordering
|
|
108
|
-
# it needs to see first — it reads the record's stored fields
|
|
109
|
-
# exactly as they already are, the same `__s` convention
|
|
110
|
-
# `compile_compute` exposes.
|
|
111
|
-
#
|
|
112
|
-
# @param declared [Bluebook::TranslationAggregate] this edge's declared rules; its
|
|
113
|
-
# first `rekeys` entry supplies the SQL
|
|
114
|
-
# @return [String] a SQL expression evaluating the rekey's own SQL against the record's
|
|
115
|
-
# current `state`
|
|
51
|
+
# Evaluates a rekey's own SQL against the record's current `state`, read directly
|
|
52
|
+
# rather than through `compile_rules`'s progressively-built expression chain.
|
|
116
53
|
def compile_id_expression(declared)
|
|
117
54
|
rekey = declared.rekeys.first
|
|
118
55
|
"(SELECT (#{rekey.sql}) FROM (SELECT (state) AS __s) __outer)"
|
|
119
56
|
end
|
|
120
57
|
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
# in-process. The source is read as a path through
|
|
124
|
-
# `hecks_tr_extract`, bare or a dotted value-object member alike,
|
|
125
|
-
# the same way the destination goes through `path_literal`. The
|
|
126
|
-
# source's value is exposed to the author's SQL as text under a
|
|
127
|
-
# column named by the source exactly as declared (`price_cents`,
|
|
128
|
-
# or `"price.cents"` for a dotted member), and the whole record
|
|
129
|
-
# stays readable as `__s`.
|
|
130
|
-
#
|
|
131
|
-
# @param expression [String] the SQL expression built so far by `compile_rules`, read as
|
|
132
|
-
# `__s` inside the compute's own SQL
|
|
133
|
-
# @param compute [Bluebook::TranslationCompute] the declared compute rule
|
|
134
|
-
# @return [String] `expression` wrapped so the compute's field lands at its declared
|
|
135
|
-
# destination when the source path is present, unchanged otherwise
|
|
58
|
+
# Wraps `expression` so a compute's SQL result lands at its declared destination
|
|
59
|
+
# when the source path is present; the whole record stays readable as `__s`.
|
|
136
60
|
def compile_compute(expression, compute)
|
|
137
61
|
from = compute.from.to_s
|
|
138
62
|
to = compute.to.to_s
|
|
@@ -145,23 +69,8 @@ module Hecks
|
|
|
145
69
|
"LATERAL (SELECT (__s #>> #{path_literal(from)}) AS #{quote(from)}) __fields)"
|
|
146
70
|
end
|
|
147
71
|
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
# no field to consume: `hecks_tr_extract`'s own `.present` flag
|
|
151
|
-
# (already installed for `hecks_tr_drop`/`hecks_tr_move`/
|
|
152
|
-
# `hecks_tr_convert` — no new database function needed) answers
|
|
153
|
-
# "is this path — bare or a dotted value-object member alike —
|
|
154
|
-
# already there," and `hecks_tr_insert` (already merge-safe: it
|
|
155
|
-
# creates a missing intermediate container without disturbing any
|
|
156
|
-
# sibling member already in it) fills it only when it is not, the
|
|
157
|
-
# exact "never overwrites a value already there" rule `Lineage#
|
|
158
|
-
# translate`'s own in-process backfill already holds itself to.
|
|
159
|
-
#
|
|
160
|
-
# @param expression [String] the SQL expression built so far by `compile_rules`, read as
|
|
161
|
-
# `__s` inside this backfill's own check
|
|
162
|
-
# @param backfill [Bluebook::TranslationBackfill] the declared backfill rule
|
|
163
|
-
# @return [String] `expression` wrapped so the backfill's default lands at its declared
|
|
164
|
-
# path when nothing is there yet, unchanged otherwise
|
|
72
|
+
# Wraps `expression` so a backfill's default lands at its declared path only when
|
|
73
|
+
# nothing is already there, the same rule `Lineage#translate`'s own pass holds to.
|
|
165
74
|
def compile_backfill(expression, backfill)
|
|
166
75
|
name = backfill.name.to_s
|
|
167
76
|
default_json = JSON.generate(backfill.default)
|
|
@@ -171,32 +80,17 @@ module Hecks
|
|
|
171
80
|
"FROM (SELECT (#{expression}) AS __s) __outer)"
|
|
172
81
|
end
|
|
173
82
|
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
# never wires PostgresEra should never need the gem" reasoning
|
|
177
|
-
# `PostgresEra.connect_for`'s own `require "pg"` already holds
|
|
178
|
-
# itself to, so a build tool that exports translations for a
|
|
179
|
-
# non-Postgres-bound domain (there are none today, but nothing
|
|
180
|
-
# here should assume there never will be) doesn't gain a hard
|
|
181
|
-
# dependency on `pg` just by loading this file.
|
|
182
|
-
#
|
|
183
|
-
# @param name [String, Symbol] the identifier to quote
|
|
184
|
-
# @return [String] `name` as a double-quoted Postgres identifier
|
|
83
|
+
# Quotes a Postgres identifier; requires "pg" lazily so a non-Postgres-bound
|
|
84
|
+
# domain never gains a hard dependency on the gem just by loading this file.
|
|
185
85
|
def quote(name)
|
|
186
86
|
require "pg"
|
|
187
87
|
PG::Connection.quote_ident(name.to_s)
|
|
188
88
|
end
|
|
189
89
|
|
|
190
90
|
# Renders a Ruby value as a single-quoted SQL text literal, escaping embedded quotes.
|
|
191
|
-
#
|
|
192
|
-
# @param text [String, Symbol, Object] the value to render; converted with `to_s`
|
|
193
|
-
# @return [String] a single-quoted SQL literal
|
|
194
91
|
def text_literal(text) = "'#{text.to_s.gsub("'", "''")}'"
|
|
195
92
|
|
|
196
93
|
# Renders a dotted path as a SQL `text[]` array literal, one element per segment.
|
|
197
|
-
#
|
|
198
|
-
# @param path [String, Symbol] a bare or dotted path, such as `"price.cents"`
|
|
199
|
-
# @return [String] a SQL `ARRAY[...]::text[]` expression
|
|
200
94
|
def path_literal(path)
|
|
201
95
|
segments = path.to_s.split(".").map { |segment| text_literal(segment) }
|
|
202
96
|
"ARRAY[#{segments.join(', ')}]::text[]"
|
|
@@ -3,18 +3,16 @@ require_relative "../../storage_shape"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Translation
|
|
5
5
|
module Scaffold
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# everything ambiguous left unresolved for a human.
|
|
6
|
+
# Diffs two eras' storage shapes into the edge's declarations; rules are written only
|
|
7
|
+
# for unique signature pairs, everything else is left unresolved.
|
|
9
8
|
module Differ
|
|
10
|
-
#
|
|
9
|
+
# Diffs two bluebook IRs into the edge's declarations.
|
|
11
10
|
#
|
|
12
11
|
# @param held_bluebook [Bluebook::Chapter] the era being translated from
|
|
13
12
|
# @param current_bluebook [Bluebook::Chapter] the era being translated to
|
|
14
|
-
# @return [Hash{Symbol => Object}] `:aggregates` (Array<Scaffold::ScaffoldedAggregate
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# aggregate names left ambiguous)
|
|
13
|
+
# @return [Hash{Symbol => Object}] `:aggregates` (Array<Scaffold::ScaffoldedAggregate>),
|
|
14
|
+
# `:retired` (Array<String>, vanished names with no successor), `:unclaimed`
|
|
15
|
+
# (Array<String>, vanished names left ambiguous)
|
|
18
16
|
def diff(held_bluebook, current_bluebook)
|
|
19
17
|
held_shapes = projections(held_bluebook)
|
|
20
18
|
current_shapes = projections(current_bluebook)
|
|
@@ -34,31 +32,19 @@ module Hecks
|
|
|
34
32
|
{ aggregates: aggregates, retired: matched[:retired], unclaimed: matched[:unclaimed] }
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
# Projects a bluebook's storage shape
|
|
38
|
-
#
|
|
39
|
-
# @param bluebook [Bluebook::Chapter] the bluebook to project
|
|
40
|
-
# @return [Hash{String => Hash}] the bluebook's storage-shape aggregates (see
|
|
41
|
-
# `Runtime::StorageShape.project`), keyed by aggregate name
|
|
35
|
+
# Projects a bluebook's storage shape, indexing its aggregates by name.
|
|
42
36
|
def projections(bluebook)
|
|
43
37
|
Runtime::StorageShape.project(bluebook)["aggregates"].to_h { |shape| [shape["name"], shape] }
|
|
44
38
|
end
|
|
45
39
|
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# beside an unmatched new one might be a rename-plus-reshape, and
|
|
50
|
-
# writing `retired` there would be a guess that strands data.
|
|
51
|
-
# Anything ambiguous stays unclaimed, and the coverage gate names
|
|
52
|
-
# it until a human decides.
|
|
40
|
+
# Pairs vanished aggregates with new ones whose full shape reappears under exactly one
|
|
41
|
+
# name. A vanished aggregate is `retired` only when no unmatched new one remains, since
|
|
42
|
+
# it could be a rename-plus-reshape and guessing would strand data.
|
|
53
43
|
#
|
|
54
|
-
# @param held_shapes [Hash{String => Hash}]
|
|
55
|
-
#
|
|
56
|
-
# @
|
|
57
|
-
#
|
|
58
|
-
# @return [Hash{Symbol => Object}] `:pairs` (Hash{String => String, nil}, each current
|
|
59
|
-
# name to its matched held name, or nil when unmatched), `:retired` (Array<String>,
|
|
60
|
-
# vanished names with no successor), `:unclaimed` (Array<String>, vanished names
|
|
61
|
-
# left ambiguous)
|
|
44
|
+
# @param held_shapes [Hash{String => Hash}] held aggregate shapes, keyed by name
|
|
45
|
+
# @param current_shapes [Hash{String => Hash}] current aggregate shapes, keyed by name
|
|
46
|
+
# @return [Hash{Symbol => Object}] `:pairs` (current name to held name, or nil),
|
|
47
|
+
# `:retired` (Array<String>), `:unclaimed` (Array<String>)
|
|
62
48
|
def match_aggregates(held_shapes, current_shapes)
|
|
63
49
|
pairs = {}
|
|
64
50
|
current_shapes.each_key { |name| pairs[name] = held_shapes.key?(name) ? name : nil }
|
|
@@ -81,20 +67,14 @@ module Hecks
|
|
|
81
67
|
{ pairs: pairs, retired: retired, unclaimed: retired.empty? ? unclaimed : [] }
|
|
82
68
|
end
|
|
83
69
|
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
# top-level) or a move (any dotted end). Same path, same members,
|
|
88
|
-
# new type name: a retype. Anything else: unresolved, carrying its
|
|
89
|
-
# type-compatible candidates (an empty list is the arrow toward
|
|
90
|
-
# compute, or drop).
|
|
70
|
+
# Resolves every changed path in one aggregate into rules by signature matching:
|
|
71
|
+
# a unique pair is a rename (both top-level) or a move (any dotted end), same members
|
|
72
|
+
# under a new type name is a retype, anything else is unresolved with its candidates.
|
|
91
73
|
#
|
|
92
|
-
# @param held_shape [Hash{String => Object}] the held era's aggregate shape
|
|
93
|
-
# `projections`)
|
|
74
|
+
# @param held_shape [Hash{String => Object}] the held era's aggregate shape
|
|
94
75
|
# @param current_shape [Hash{String => Object}] the current era's aggregate shape
|
|
95
|
-
# @return [Array<Hash{Symbol => Object}>] one rule
|
|
96
|
-
#
|
|
97
|
-
# `:unresolved` (see `Renderer#render_rule`); `[]` when nothing changed
|
|
76
|
+
# @return [Array<Hash{Symbol => Object}>] one rule per changed path (see
|
|
77
|
+
# `Renderer#render_rule`); `[]` when nothing changed
|
|
98
78
|
def attribute_rules(held_shape, current_shape)
|
|
99
79
|
rules = []
|
|
100
80
|
rules << identity_hint(held_shape, current_shape)
|
|
@@ -108,26 +88,13 @@ module Hecks
|
|
|
108
88
|
vanished = vanished_paths(held_attrs, current_attrs, retyped)
|
|
109
89
|
appeared = appeared_paths(held_attrs, current_attrs, retyped)
|
|
110
90
|
|
|
111
|
-
# Mutates `rules` in place
|
|
112
|
-
#
|
|
113
|
-
# `taken`, below, is recomputed from `rules` at the top of every
|
|
114
|
-
# iteration, so a target this same loop already claimed for an
|
|
115
|
-
# earlier vanished path is excluded from a later one. Passing a
|
|
116
|
-
# snapshot instead of the live array would let two vanished
|
|
117
|
-
# paths both match the same appeared target.
|
|
91
|
+
# Mutates `rules` in place: each iteration must see targets claimed by earlier ones,
|
|
92
|
+
# or two vanished paths could match the same appeared target.
|
|
118
93
|
resolve_vanished_rules!(rules, vanished, appeared)
|
|
119
94
|
rules
|
|
120
95
|
end
|
|
121
96
|
|
|
122
|
-
#
|
|
123
|
-
# type's own name changed
|
|
124
|
-
#
|
|
125
|
-
# @param held_attrs [Hash{String => Hash}] the held era's attributes, keyed by name
|
|
126
|
-
# @param current_attrs [Hash{String => Hash}] the current era's attributes, keyed by
|
|
127
|
-
# name
|
|
128
|
-
# @return [Array<Hash{Symbol => String}>] one `{kind: :retype, from:, to:}` rule per
|
|
129
|
-
# attribute whose members are unchanged but whose type name changed; `[]` when none
|
|
130
|
-
# match
|
|
97
|
+
# Retype rules for attributes whose members are unchanged but whose type name changed.
|
|
131
98
|
def retype_rules(held_attrs, current_attrs)
|
|
132
99
|
(held_attrs.keys & current_attrs.keys).filter_map do |name|
|
|
133
100
|
held = held_attrs[name]
|
|
@@ -140,16 +107,7 @@ module Hecks
|
|
|
140
107
|
end
|
|
141
108
|
end
|
|
142
109
|
|
|
143
|
-
# Resolves each vanished path into a rename, move or unresolved rule
|
|
144
|
-
# `rules` in place.
|
|
145
|
-
#
|
|
146
|
-
# @param rules [Array<Hash{Symbol => Object}>] the rule list to append to; also read
|
|
147
|
-
# for `:rename`/`:move` targets an earlier iteration already claimed
|
|
148
|
-
# @param vanished [Hash{String => Object}] vanished paths to type signature (see
|
|
149
|
-
# `vanished_paths`)
|
|
150
|
-
# @param appeared [Hash{String => Object}] appeared paths to type signature (see
|
|
151
|
-
# `appeared_paths`)
|
|
152
|
-
# @return [void]
|
|
110
|
+
# Resolves each vanished path into a rename, move or unresolved rule appended to `rules`.
|
|
153
111
|
def resolve_vanished_rules!(rules, vanished, appeared)
|
|
154
112
|
vanished.each do |path, signature|
|
|
155
113
|
matches = appeared.select { |_, candidate| candidate == signature }.keys
|
|
@@ -166,18 +124,9 @@ module Hecks
|
|
|
166
124
|
end
|
|
167
125
|
end
|
|
168
126
|
|
|
169
|
-
# Held paths that need explaining:
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
# for.
|
|
173
|
-
#
|
|
174
|
-
# @param held_attrs [Hash{String => Hash}] the held era's attributes, keyed by name
|
|
175
|
-
# @param current_attrs [Hash{String => Hash}] the current era's attributes, keyed by
|
|
176
|
-
# name
|
|
177
|
-
# @param retyped [Array<String>] type names already claimed by a `:retype` rule,
|
|
178
|
-
# excluded here
|
|
179
|
-
# @return [Hash{String => Object}] each vanished or changed path, dotted for a member,
|
|
180
|
-
# valued by that path's type signature
|
|
127
|
+
# Held paths that need explaining: vanished attributes, and members that vanished or
|
|
128
|
+
# changed type inside a kept attribute — the set EraGuard demands coverage for.
|
|
129
|
+
# Returns each path (dotted for a member) valued by its type signature.
|
|
181
130
|
def vanished_paths(held_attrs, current_attrs, retyped)
|
|
182
131
|
paths = {}
|
|
183
132
|
held_attrs.each do |name, held|
|
|
@@ -199,17 +148,7 @@ module Hecks
|
|
|
199
148
|
paths
|
|
200
149
|
end
|
|
201
150
|
|
|
202
|
-
# Current paths that need explaining
|
|
203
|
-
# that appeared (or changed type) inside a kept attribute — the mirror of
|
|
204
|
-
# `vanished_paths`.
|
|
205
|
-
#
|
|
206
|
-
# @param held_attrs [Hash{String => Hash}] the held era's attributes, keyed by name
|
|
207
|
-
# @param current_attrs [Hash{String => Hash}] the current era's attributes, keyed by
|
|
208
|
-
# name
|
|
209
|
-
# @param retyped [Array<String>] type names already claimed by a `:retype` rule,
|
|
210
|
-
# excluded here
|
|
211
|
-
# @return [Hash{String => Object}] each appeared or changed path, dotted for a
|
|
212
|
-
# member, valued by that path's type signature
|
|
151
|
+
# Current paths that need explaining; the mirror of `vanished_paths`.
|
|
213
152
|
def appeared_paths(held_attrs, current_attrs, retyped)
|
|
214
153
|
paths = {}
|
|
215
154
|
current_attrs.each do |name, current|
|
|
@@ -230,58 +169,30 @@ module Hecks
|
|
|
230
169
|
paths
|
|
231
170
|
end
|
|
232
171
|
|
|
233
|
-
#
|
|
234
|
-
#
|
|
235
|
-
# .project_aggregate`), it was simply never read here. An
|
|
236
|
-
# unresolved placeholder, not a guess: `coverage_check.rb`'s own
|
|
237
|
-
# `check_identity_unchanged!` is the real gate this only hints
|
|
238
|
-
# toward, the same "tool proactively guides you" pattern the
|
|
239
|
-
# generic unresolved message already gives unfed fields.
|
|
240
|
-
#
|
|
241
|
-
# @param held_shape [Hash{String => Object}] the held era's aggregate shape
|
|
242
|
-
# @param current_shape [Hash{String => Object}] the current era's aggregate shape
|
|
243
|
-
# @return [Hash{Symbol => Object}, nil] `{kind: :unresolved, from: :identity,
|
|
244
|
-
# candidates: []}` when the identity paths differ; nil when they match
|
|
172
|
+
# An unresolved placeholder when the identity paths differ; nil when they match.
|
|
173
|
+
# It only hints: `check_identity_unchanged!` in `coverage_check.rb` is the real gate.
|
|
245
174
|
def identity_hint(held_shape, current_shape)
|
|
246
175
|
return if held_shape["identity"] == current_shape["identity"]
|
|
247
176
|
|
|
248
177
|
{ kind: :unresolved, from: :identity, candidates: [] }
|
|
249
178
|
end
|
|
250
179
|
|
|
251
|
-
#
|
|
252
|
-
#
|
|
253
|
-
# @param appeared [Hash{String => Object}] appeared paths to type signature (see
|
|
254
|
-
# `appeared_paths`)
|
|
255
|
-
# @param signature [Object] the vanished path's own type signature to match against
|
|
256
|
-
# @return [Array<String>] appeared paths whose scalar signature (see `scalar_of`)
|
|
257
|
-
# matches `signature`'s
|
|
180
|
+
# Appeared paths type-compatible with a vanished path's signature.
|
|
258
181
|
def compatible_candidates(appeared, signature)
|
|
259
182
|
appeared.select { |_, candidate| scalar_of(candidate) == scalar_of(signature) }.keys
|
|
260
183
|
end
|
|
261
184
|
|
|
262
|
-
# Reduces a type signature to
|
|
263
|
-
#
|
|
264
|
-
# @param signature [Object, Hash] a path's type signature
|
|
265
|
-
# @return [Object] `signature["members"]` for a container Hash, else `signature`
|
|
266
|
-
# unchanged
|
|
185
|
+
# Reduces a type signature to what `compatible_candidates` compares: members or the scalar.
|
|
267
186
|
def scalar_of(signature) = signature.is_a?(Hash) ? signature["members"] : signature
|
|
268
187
|
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
# @param attribute [Hash{String => Object}] one path's type signature
|
|
272
|
-
# @return [Hash{String => Object}] each member's name to its type; `{}` when
|
|
273
|
-
# `attribute` is not a container
|
|
188
|
+
# A container attribute's members keyed by name; `{}` for a scalar.
|
|
274
189
|
def members_of(attribute)
|
|
275
190
|
return {} unless container?(attribute)
|
|
276
191
|
|
|
277
192
|
attribute["type"]["members"].to_h { |member| [member["name"], member["type"]] }
|
|
278
193
|
end
|
|
279
194
|
|
|
280
|
-
#
|
|
281
|
-
# scalar.
|
|
282
|
-
#
|
|
283
|
-
# @param attribute [Hash{String => Object}] one path's type signature
|
|
284
|
-
# @return [Boolean] true if `attribute["type"]` is a Hash, false for a scalar
|
|
195
|
+
# Whether the attribute's type is a container (value object or entity), not a scalar.
|
|
285
196
|
def container?(attribute) = attribute["type"].is_a?(Hash)
|
|
286
197
|
end
|
|
287
198
|
end
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Translation
|
|
3
3
|
module Scaffold
|
|
4
|
-
#
|
|
5
|
-
# ambiguities as parse-refusing `unresolved` constructs, never
|
|
4
|
+
# Renders an edge as .bluebook text. Ambiguities become `unresolved` constructs, not
|
|
6
5
|
# comments, so an unresolved file can only boot into a refusal.
|
|
7
6
|
module Renderer
|
|
8
7
|
# Renders a scaffolded edge as loadable `.bluebook` translation source.
|
|
9
8
|
#
|
|
10
9
|
# @param edge [Scaffold::Edge] the edge to render
|
|
11
|
-
# @return [String] the
|
|
10
|
+
# @return [String] the `.bluebook` text, ending in a newline
|
|
12
11
|
def render(edge)
|
|
13
12
|
lines = ["Hecks.data_translation #{edge.domain.inspect}, from: #{edge.from.inspect}, to: #{edge.to.inspect} do"]
|
|
14
13
|
edge.aggregates.each do |aggregate|
|
|
@@ -25,10 +24,8 @@ module Hecks
|
|
|
25
24
|
|
|
26
25
|
# Renders one scaffolded rule as a line of `.bluebook` source.
|
|
27
26
|
#
|
|
28
|
-
# @param rule [Hash{Symbol => Object}] a rule
|
|
29
|
-
#
|
|
30
|
-
# @return [String, nil] the rendered line; nil if `rule[:kind]` is none of `:rename`,
|
|
31
|
-
# `:move`, `:retype` or `:unresolved`
|
|
27
|
+
# @param rule [Hash{Symbol => Object}] a rule as `Differ#attribute_rules` builds it
|
|
28
|
+
# @return [String, nil] the rendered line; nil for an unknown `rule[:kind]`
|
|
32
29
|
def render_rule(rule)
|
|
33
30
|
case rule[:kind]
|
|
34
31
|
when :rename then "rename :#{rule[:from]}, to: :#{rule[:to]}"
|
|
@@ -40,11 +37,7 @@ module Hecks
|
|
|
40
37
|
end
|
|
41
38
|
end
|
|
42
39
|
|
|
43
|
-
# Renders a path as
|
|
44
|
-
# when dotted.
|
|
45
|
-
#
|
|
46
|
-
# @param path [String, Symbol] a bare or dotted path
|
|
47
|
-
# @return [String] `":name"` for a bare path, `path.inspect` for a dotted one
|
|
40
|
+
# Renders a bare path as a Symbol literal and a dotted path as a String literal.
|
|
48
41
|
def render_path(path) = path.to_s.include?(".") ? path.to_s.inspect : ":#{path}"
|
|
49
42
|
end
|
|
50
43
|
end
|
|
@@ -3,16 +3,10 @@ require "fileutils"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Translation
|
|
5
5
|
module Scaffold
|
|
6
|
-
#
|
|
7
|
-
# for the same shape pair already exists.
|
|
6
|
+
# Writes the rendered edge to disk, reusing the file for the same shape pair if present.
|
|
8
7
|
module Writer
|
|
9
|
-
# Renders an edge and writes it under `directory/translations
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# The edge file, regenerated in place when one for the same shape
|
|
13
|
-
# pair already exists (matched textually — an unresolved file
|
|
14
|
-
# cannot be loaded to ask, that being the whole point of
|
|
15
|
-
# unresolved).
|
|
8
|
+
# Renders an edge and writes it under `directory/translations`.
|
|
9
|
+
# An existing file is matched textually because an unresolved file cannot be loaded.
|
|
16
10
|
#
|
|
17
11
|
# @param directory [String] the domain's root directory
|
|
18
12
|
# @param edge [Scaffold::Edge] the edge to render and write
|