hecks 2.8.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +50 -7
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +32 -100
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +149 -136
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +48 -38
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +16 -50
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +49 -67
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +39 -661
- data/lib/hecks/bluebook/hexagon.rb +18 -33
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +87 -352
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +122 -596
- data/lib/hecks/bluebook/pattern_subset.rb +49 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +27 -51
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +9 -99
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- data/lib/hecks/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +5 -23
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +4 -6
- data/lib/hecks/cli/mcp.rb +5 -6
- data/lib/hecks/cli/model_check.rb +24 -88
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +223 -64
- data/lib/hecks/cli/project_diagrams.rb +4 -10
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +15 -61
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +7 -19
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -6
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +216 -73
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +14 -34
- data/lib/hecks/doors/handle.rb +206 -0
- data/lib/hecks/doors/json_door.rb +132 -0
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
- data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
- data/lib/hecks/doors/ruby_door.rb +77 -0
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +5 -72
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +23 -51
- data/lib/hecks/forms/app.rb +21 -76
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +31 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +19 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +47 -108
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +12 -44
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +40 -207
- data/lib/hecks/projections/deploy/lambda.rb +191 -708
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +3 -59
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +48 -147
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +22 -584
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +16 -43
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +13 -32
- data/lib/hecks/projections/reference.rb +4 -18
- data/lib/hecks/projections/rust_vocabulary.rb +13 -251
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +154 -400
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +5 -8
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +15 -9
- data/lib/hecks/release/runner/npm_publisher.rb +9 -53
- data/lib/hecks/release/runner/preflight.rb +29 -20
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +31 -23
- data/lib/hecks/release/runner.rb +60 -38
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +15 -39
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +50 -104
- data/lib/hecks/runtime/dispatcher.rb +134 -243
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +14 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +109 -194
- data/lib/hecks/runtime/outbox.rb +39 -262
- data/lib/hecks/runtime/policy_interpreter.rb +43 -202
- data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
- data/lib/hecks/runtime/query_interpreter.rb +122 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +28 -87
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +213 -227
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +156 -247
- data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +162 -760
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +15 -84
- data/lib/hecks/runtime.rb +35 -69
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +155 -582
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +52 -90
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +478 -12
- data/lib/hecks/facade/cli_door.rb +0 -178
- data/lib/hecks/facade/cli_runner.rb +0 -271
- data/lib/hecks/facade/handle.rb +0 -293
- data/lib/hecks/facade/json_door.rb +0 -247
- data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
- data/lib/hecks/facade/surface/chapter.rb +0 -116
- data/lib/hecks/facade/surface.rb +0 -61
- data/lib/hecks/mcp_door_scope.rb +0 -176
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "digest"
|
|
4
|
+
require "json"
|
|
5
|
+
require_relative "held_domain"
|
|
6
|
+
require_relative "edge_audit"
|
|
7
|
+
require_relative "compaction"
|
|
8
|
+
|
|
9
|
+
module Hecks
|
|
10
|
+
module Adapters
|
|
11
|
+
class JournalStore
|
|
12
|
+
# The facts the journal store reports about a change before it is made, for the rules of
|
|
13
|
+
# Custodian's `Era.Permit` to hold against. Nothing here writes: an examination reads the
|
|
14
|
+
# domain and its journal and answers numbers and yes-or-no.
|
|
15
|
+
module Examination
|
|
16
|
+
# What every fact is until an examination finds otherwise.
|
|
17
|
+
NEUTRAL = {
|
|
18
|
+
capable: false, held: 0, forks: 0, contested: 0, edges: 0, bound: 0, candidates: 0,
|
|
19
|
+
audited: false, rehearsal_needed: false, rehearsal_recorded: false,
|
|
20
|
+
drifted: false, loadable: false, shape_kept: false
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
# Examines the domain a change was asked for.
|
|
24
|
+
#
|
|
25
|
+
# @param held [Hash] the `Era` record: `operation`, `domain`, and whichever of `winners`,
|
|
26
|
+
# `era`, `aggregates` and the rehearsal fields the request carried
|
|
27
|
+
# @return [Hash{Symbol => Hash}] every fact, as `{ value: x }`, and the request's own
|
|
28
|
+
# `operation`, which the reactions to the examination read
|
|
29
|
+
# @raise [Runtime::NotFound] if the domain cannot be loaded or has no such era
|
|
30
|
+
def examine(**held)
|
|
31
|
+
found = send(:"examine_#{plain(held[:operation])}", held)
|
|
32
|
+
NEUTRAL.merge(found).transform_values { |fact| { value: fact } }
|
|
33
|
+
.merge(operation: { value: plain(held[:operation]) })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def examine_hold_first(held)
|
|
39
|
+
domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
|
|
40
|
+
return {} unless domain.capable?
|
|
41
|
+
|
|
42
|
+
{ capable: true, held: domain.reading { |lineage| domain.held_eras(lineage).size } }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def examine_merge_tail(held)
|
|
46
|
+
domain = HeldDomain.open(plain(held[:domain]))
|
|
47
|
+
return {} unless domain.capable?
|
|
48
|
+
|
|
49
|
+
domain.reading do |lineage|
|
|
50
|
+
eras = domain.held_eras(lineage)
|
|
51
|
+
forks = forks_in(domain, eras)
|
|
52
|
+
unresolved = eras.size > 1 && forks.zero? ? unresolved_conflicts(domain, lineage, eras, winners(held)) : 0
|
|
53
|
+
{ capable: true, held: eras.size, forks: forks, contested: unresolved }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def examine_reattest(held)
|
|
58
|
+
domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
|
|
59
|
+
return {} unless domain.capable?
|
|
60
|
+
|
|
61
|
+
ordinal = plain(held[:era])
|
|
62
|
+
era = domain.reading { |lineage| raw_era(domain, lineage, ordinal) }
|
|
63
|
+
{ capable: true }.merge(text_facts(era))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Whether the held text drifted from its digest and, if so, whether it still loads and
|
|
67
|
+
# still projects to the shape the era froze with. A text that matches its digest has
|
|
68
|
+
# nothing to attest, so its shape is not examined.
|
|
69
|
+
def text_facts(era)
|
|
70
|
+
return {} if era[:held_digest] == Digest::SHA256.hexdigest(era[:held_text])
|
|
71
|
+
|
|
72
|
+
found = Translation::Reattest.verdict(
|
|
73
|
+
text: era[:held_text], stored_hash: era[:hash],
|
|
74
|
+
stored_projection: era[:held_projection] && JSON.parse(era[:held_projection])
|
|
75
|
+
)
|
|
76
|
+
{ drifted: true, loadable: found != :unloadable, shape_kept: %i[cosmetic unnamed].include?(found) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def examine_backfill_projections(held)
|
|
80
|
+
domain = HeldDomain.open(plain(held[:domain]), mode: :bare)
|
|
81
|
+
{ capable: domain.capable? }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def examine_compact(held) = examine_compaction(held, :entries)
|
|
85
|
+
|
|
86
|
+
def examine_compact_heki(held) = examine_compaction(held, :heki)
|
|
87
|
+
|
|
88
|
+
def examine_compaction(held, kind)
|
|
89
|
+
compaction = Compaction.new(plain(held[:domain]), aggregates: names(held[:aggregates]), kind: kind)
|
|
90
|
+
{ candidates: compaction.candidates.size, bound: compaction.bound.size }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def examine_approve_translation(held)
|
|
94
|
+
domain = HeldDomain.open(plain(held[:domain]))
|
|
95
|
+
return {} unless domain.capable?
|
|
96
|
+
|
|
97
|
+
domain.reading do |lineage|
|
|
98
|
+
eras = domain.held_eras(lineage)
|
|
99
|
+
finding = eras.empty? ? nil : EdgeAudit.call(domain, lineage, eras)
|
|
100
|
+
next { capable: true, held: eras.size } unless finding
|
|
101
|
+
|
|
102
|
+
{ capable: true, held: eras.size, edges: finding.leaving, audited: finding.ok }.merge(rehearsal_facts(finding, held))
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def rehearsal_facts(finding, held)
|
|
107
|
+
{
|
|
108
|
+
rehearsal_needed: Translation::ApprovalFile.needs_rehearsal?(finding.edge),
|
|
109
|
+
rehearsal_recorded: Translation::ApprovalFile.rehearsed?(rehearsal_block(held))
|
|
110
|
+
}
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# How many eras, before the latest, do not have exactly one edge leading to the next.
|
|
114
|
+
def forks_in(domain, eras)
|
|
115
|
+
eras.each_cons(2).count do |from, to|
|
|
116
|
+
leaving = domain.registry.translations.select do |edge|
|
|
117
|
+
edge.domain == domain.bluebook.name && edge.from == from[:label]
|
|
118
|
+
end
|
|
119
|
+
leaving.size != 1 || leaving.first.to != to[:label]
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Records both worlds wrote since the cut that no winner was named for.
|
|
124
|
+
def unresolved_conflicts(domain, lineage, eras, named)
|
|
125
|
+
latest = eras.last
|
|
126
|
+
chain = PostgresEra::LineageManager.edge_chain(domain.registry, domain.bluebook, eras[0..-2], latest[:label])
|
|
127
|
+
conflicts = domain.bluebook.aggregates.flat_map do |aggregate|
|
|
128
|
+
lineage.conflict_ids(aggregate, chain, latest[:ordinal], latest[:watermark].to_i)
|
|
129
|
+
end
|
|
130
|
+
conflicts.count { |_, id| !named.key?(id) }
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks"
|
|
4
|
+
require "hecks/ports/persistence/plugins/era"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
class JournalStore
|
|
9
|
+
# A domain directory loaded the way the era tools load it, with the journal store its first
|
|
10
|
+
# aggregate is bound to.
|
|
11
|
+
#
|
|
12
|
+
# `translated` loads the whole domain, translation edges included; `bare` loads the
|
|
13
|
+
# bluebooks, hecksagons and worlds only, so an edge that does not resolve cannot stop a
|
|
14
|
+
# text from being attested; `scaffold` loads everything but the edges, since an unresolved
|
|
15
|
+
# edge file refuses to load and writing it is the point.
|
|
16
|
+
class HeldDomain
|
|
17
|
+
MODES = %i[translated bare scaffold].freeze
|
|
18
|
+
|
|
19
|
+
attr_reader :registry, :bluebook, :directory, :adapter_name
|
|
20
|
+
|
|
21
|
+
# Loads a domain and finds where its eras would be held.
|
|
22
|
+
#
|
|
23
|
+
# @param path [String] the domain directory, or the project holding its `bluebook/`
|
|
24
|
+
# @param mode [Symbol] one of `MODES`
|
|
25
|
+
# @return [HeldDomain] the loaded domain
|
|
26
|
+
# @raise [Runtime::NotFound] if the directory does not exist, declares no bluebook, or
|
|
27
|
+
# does not load
|
|
28
|
+
def self.open(path, mode: :translated)
|
|
29
|
+
raise ArgumentError, "unknown mode #{mode.inspect}" unless MODES.include?(mode)
|
|
30
|
+
|
|
31
|
+
loading = Ports::Loading.bootstrap
|
|
32
|
+
directory = loading.bluebook_directory(path)
|
|
33
|
+
registry = Runtime::Registry.new(root: File.dirname(directory))
|
|
34
|
+
load_into(registry, loading, directory, mode)
|
|
35
|
+
new(registry, directory)
|
|
36
|
+
rescue Errno::ENOENT
|
|
37
|
+
raise Runtime::NotFound, "no such domain #{path.inspect}"
|
|
38
|
+
rescue Bluebook::DSL::Malformed => e
|
|
39
|
+
raise Runtime::NotFound, "REFUSED at load: #{e.message}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @api private
|
|
43
|
+
def self.load_into(registry, loading, directory, mode)
|
|
44
|
+
environment = ENV.fetch("HECKS_PROJECT_ENVIRONMENT", nil)
|
|
45
|
+
Hecks.with_registry(registry) do
|
|
46
|
+
loading.load_library
|
|
47
|
+
loading.load_project(loading.shared_root(nil, directory))
|
|
48
|
+
case mode
|
|
49
|
+
when :translated then loading.load_domain(directory, environment: environment)
|
|
50
|
+
when :bare then loading.load_each(directory, %w[*.port *.adapter *.bluebook *.hecksagon *.world])
|
|
51
|
+
else load_scaffold(loading, directory, environment)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @api private
|
|
57
|
+
def self.load_scaffold(loading, directory, environment)
|
|
58
|
+
loading.load_each(directory, %w[*.port *.adapter])
|
|
59
|
+
loading.load_bluebooks(directory)
|
|
60
|
+
loading.load_each(directory, %w[*.hecksagon *.world])
|
|
61
|
+
return unless environment
|
|
62
|
+
|
|
63
|
+
loading.load_each(directory, [File.join("environments", "#{environment}.hecksagon")])
|
|
64
|
+
loading.load_each(directory, [File.join("environments", "#{environment}.world")])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param registry [Runtime::Registry] the loaded registry
|
|
68
|
+
# @param directory [String] the domain's bluebook directory
|
|
69
|
+
# @raise [Runtime::NotFound] if the registry holds no bluebook, or a bluebook no aggregate
|
|
70
|
+
def initialize(registry, directory)
|
|
71
|
+
@registry = registry
|
|
72
|
+
@directory = directory
|
|
73
|
+
@bluebook = registry.bluebooks.values.first or raise Runtime::NotFound, "no bluebook in #{directory}"
|
|
74
|
+
first = @bluebook.aggregates.first or raise Runtime::NotFound, "#{@bluebook.name} declares no aggregates"
|
|
75
|
+
@adapter_name = Ports::Persistence::BindingPolicy.resolve(registry, @bluebook.name, first).adapter
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Whether the store the domain is bound to keeps eras (`EraCheck`'s own question).
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean] true when the adapter is lineage capable
|
|
81
|
+
def capable? = Runtime::EraCheck.lineage_capable?(registry, adapter_name)
|
|
82
|
+
|
|
83
|
+
# Explains, as a refusal, why a domain has no eras.
|
|
84
|
+
#
|
|
85
|
+
# @return [String] the sentence
|
|
86
|
+
def incapable_reason = "#{bluebook.name} is bound to #{adapter_name}, which holds no eras"
|
|
87
|
+
|
|
88
|
+
# The settings its journal store is connected with: the world's, and `HECKS_SCHEMA` for a
|
|
89
|
+
# domain on a shared database, whose schema production takes from the environment.
|
|
90
|
+
#
|
|
91
|
+
# @return [Hash] the settings
|
|
92
|
+
def settings
|
|
93
|
+
declared = registry.binding_settings(bluebook.name, Ports::Persistence::VERB, adapter_name)
|
|
94
|
+
ENV["HECKS_SCHEMA"] ? declared.merge(schema: ENV["HECKS_SCHEMA"]) : declared
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The text the era is frozen from: the bluebook source as it stands on disk.
|
|
98
|
+
#
|
|
99
|
+
# @return [String] the text
|
|
100
|
+
# @raise [Runtime::NotFound] if no file declares the bluebook
|
|
101
|
+
def source_text
|
|
102
|
+
Runtime::EraCheck.source_text_for(bluebook, directory) or
|
|
103
|
+
raise Runtime::NotFound, "no file under #{directory} declares #{bluebook.name}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# An era with the name it would be minted under, worked out in memory when none was stored.
|
|
107
|
+
# Naming an era is a write, so a read never does it.
|
|
108
|
+
#
|
|
109
|
+
# @param era [Hash] an era as `Lineage#eras` answers it
|
|
110
|
+
# @return [Hash] the era, with `hash` and `label` filled in
|
|
111
|
+
def named(era)
|
|
112
|
+
return era if era[:hash]
|
|
113
|
+
|
|
114
|
+
hash = Runtime::StorageShape.mint_hash(PostgresEra::LineageManager.shadow(era[:held_text]))
|
|
115
|
+
era.merge(hash: hash, label: hash[0, Runtime::StorageShape::LABEL_LENGTH])
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# The bluebook's storage shape as it stands.
|
|
119
|
+
#
|
|
120
|
+
# @return [Hash] the projection `StorageShape.project` answers
|
|
121
|
+
def shape = Runtime::StorageShape.project(bluebook)
|
|
122
|
+
|
|
123
|
+
# Connects to the journal store and yields a lineage over it. Nothing is provisioned, so a
|
|
124
|
+
# database that holds no eras is left as it is.
|
|
125
|
+
#
|
|
126
|
+
# @yield [Lineage] the domain's lineage
|
|
127
|
+
# @return [Object] the block's value
|
|
128
|
+
def reading
|
|
129
|
+
db = PostgresEra.connect_for(bluebook.name, settings)
|
|
130
|
+
yield PostgresEra::Lineage.new(db, bluebook.name)
|
|
131
|
+
ensure
|
|
132
|
+
db&.close
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Connects to the journal store, refuses a role that bypasses the write fence unless the
|
|
136
|
+
# world allows it, provisions the lineage tables, and yields a lineage over it.
|
|
137
|
+
#
|
|
138
|
+
# @yield [Lineage] the domain's lineage
|
|
139
|
+
# @return [Object] the block's value
|
|
140
|
+
# @raise [Runtime::WiringError] on a superuser connection the world has not allowed
|
|
141
|
+
def writing
|
|
142
|
+
db = PostgresEra.connect_for(bluebook.name, settings)
|
|
143
|
+
lineage = PostgresEra::Lineage.new(db, bluebook.name, formerly_known_as: bluebook.formerly_known_as)
|
|
144
|
+
lineage.check_fence_applies!(allow_superuser: PostgresEra.setting(settings, :allow_superuser, default: false))
|
|
145
|
+
lineage.ensure_base!
|
|
146
|
+
yield lineage
|
|
147
|
+
ensure
|
|
148
|
+
db&.close
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# The eras a lineage holds, without provisioning anything: none when the lineage tables do
|
|
152
|
+
# not exist yet.
|
|
153
|
+
#
|
|
154
|
+
# @param lineage [Lineage] the domain's lineage
|
|
155
|
+
# @return [Array<Hash>] `Lineage#eras`, verified against their digests; empty when none held
|
|
156
|
+
def held_eras(lineage)
|
|
157
|
+
present = lineage.db.exec("SELECT to_regclass('hecks_eras') AS present")[0]["present"]
|
|
158
|
+
present ? lineage.eras : []
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "digest"
|
|
5
|
+
require_relative "held_domain"
|
|
6
|
+
require_relative "edge_audit"
|
|
7
|
+
require_relative "compaction"
|
|
8
|
+
|
|
9
|
+
module Hecks
|
|
10
|
+
module Adapters
|
|
11
|
+
class JournalStore
|
|
12
|
+
# The queries the journal store answers: what would be scaffolded, how the audit reads, an
|
|
13
|
+
# era's held text, and what compacting would delete.
|
|
14
|
+
#
|
|
15
|
+
# A reading never writes. It provisions nothing, holds no era, names none and writes no file;
|
|
16
|
+
# a domain that holds no era answers that it holds none, and only `hold_first` holds one.
|
|
17
|
+
# What a reading refuses is a `Runtime::NotFound`, the refusal a launcher words as an answer.
|
|
18
|
+
module Readings
|
|
19
|
+
# Words the answer for a domain that holds no era.
|
|
20
|
+
#
|
|
21
|
+
# @param name [String] the domain's name
|
|
22
|
+
# @param path [String] the domain path, as the operator typed it
|
|
23
|
+
# @return [String] the sentence
|
|
24
|
+
def self.no_era(name, path)
|
|
25
|
+
"#{name} holds no era yet. `hecks hold_first #{path} --confirm` holds the first."
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The edge file that would lead the latest held era to the current shape, as its text.
|
|
29
|
+
#
|
|
30
|
+
# @param domain [Hash, String] the domain directory
|
|
31
|
+
# @return [Hash] `text:` the `.bluebook` text, under comments saying where to save it and
|
|
32
|
+
# what is left to decide
|
|
33
|
+
# @raise [Runtime::NotFound] if the domain holds no eras, or cannot be loaded
|
|
34
|
+
def scaffold_translation(domain:)
|
|
35
|
+
answering do
|
|
36
|
+
held = HeldDomain.open(plain(domain), mode: :scaffold)
|
|
37
|
+
refuse_incapable!(held)
|
|
38
|
+
held.reading { |lineage| scaffold(held, lineage, plain(domain)) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# The audit of the edge that leads the latest held era to the current shape.
|
|
43
|
+
#
|
|
44
|
+
# @param domain [Hash, String] the domain directory
|
|
45
|
+
# @return [Hash] `text:` the report, ending in what approving needs
|
|
46
|
+
# @raise [Runtime::NotFound] if the audit refuses, or no edge leads to the current shape
|
|
47
|
+
def audit_translation(domain:)
|
|
48
|
+
answering do
|
|
49
|
+
held = HeldDomain.open(plain(domain))
|
|
50
|
+
refuse_incapable!(held)
|
|
51
|
+
held.reading { |lineage| audit(held, lineage, plain(domain)) }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# An era's held text as it now stands, and whether it still matches its digest.
|
|
56
|
+
#
|
|
57
|
+
# @param domain [Hash, String] the domain directory
|
|
58
|
+
# @param era [Hash, Integer] the era's ordinal
|
|
59
|
+
# @return [Hash] `text:` the digests and the text a person reads before attesting to it
|
|
60
|
+
# @raise [Runtime::NotFound] if the domain holds no such era
|
|
61
|
+
def attestation(domain:, era:)
|
|
62
|
+
answering do
|
|
63
|
+
held = HeldDomain.open(plain(domain), mode: :bare)
|
|
64
|
+
refuse_incapable!(held)
|
|
65
|
+
held.reading { |lineage| attest(held, lineage, plain(era)) }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# What compacting the domain's journals would delete, without deleting anything.
|
|
70
|
+
#
|
|
71
|
+
# @param domain [Hash, String] the domain directory
|
|
72
|
+
# @param aggregates [Hash, String, nil] aggregate names, comma separated
|
|
73
|
+
# @return [Hash] `text:` one line per journal
|
|
74
|
+
# @raise [Runtime::NotFound] if the domain cannot be loaded
|
|
75
|
+
def compaction(domain:, aggregates: nil)
|
|
76
|
+
answering do
|
|
77
|
+
lines = %i[entries heki].flat_map do |kind|
|
|
78
|
+
Compaction.new(plain(domain), aggregates: names(aggregates), kind: kind).preview
|
|
79
|
+
end
|
|
80
|
+
lines.empty? ? "no journal of #{plain(domain)} can be compacted" : lines.join("\n")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Words a lower layer's refusal as the one a query is refused with. `pg` is loaded lazily,
|
|
87
|
+
# so its error is only named once something has connected.
|
|
88
|
+
def answering
|
|
89
|
+
{ text: yield }
|
|
90
|
+
rescue *lower_refusals => e
|
|
91
|
+
raise Runtime::NotFound, e.message.strip
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def lower_refusals
|
|
95
|
+
[Runtime::WiringError, Bluebook::DSL::Malformed, ArgumentError, *(PG::Error if defined?(PG))]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def refuse_incapable!(held)
|
|
99
|
+
raise Runtime::NotFound, held.incapable_reason unless held.capable?
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def scaffold(held, lineage, path)
|
|
103
|
+
eras = held.held_eras(lineage)
|
|
104
|
+
return Readings.no_era(held.bluebook.name, path) if eras.empty?
|
|
105
|
+
|
|
106
|
+
latest = held.named(eras.last)
|
|
107
|
+
shadow = PostgresEra::LineageManager.shadow(latest[:held_text])
|
|
108
|
+
if Runtime::StorageShape.project(shadow) == held.shape
|
|
109
|
+
return "#{held.bluebook.name} matches era #{latest[:ordinal]} — nothing to scaffold."
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
edge_text(held, latest, Translation::Scaffold.diff(shadow, held.bluebook))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def edge_text(held, latest, diffed)
|
|
116
|
+
label = Runtime::StorageShape.mint_hash(held.bluebook)[0, Runtime::StorageShape::LABEL_LENGTH]
|
|
117
|
+
edge = Translation::Scaffold::Edge.new(
|
|
118
|
+
domain: held.bluebook.name, from: latest[:label], to: label, ordinal: latest[:ordinal] + 1,
|
|
119
|
+
label: label, aggregates: diffed[:aggregates], retired: diffed[:retired]
|
|
120
|
+
)
|
|
121
|
+
text = Translation::Scaffold.render(edge)
|
|
122
|
+
[*scaffold_notes(edge, text, diffed[:unclaimed]), text].join("\n")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def scaffold_notes(edge, text, unclaimed)
|
|
126
|
+
unresolved = text.scan(/^\s*unresolved /).size
|
|
127
|
+
notes = ["# Save as translations/#{edge.ordinal}-#{edge.label}.bluebook."]
|
|
128
|
+
notes << "# #{unresolved} unresolved: decide what each became, then boot." if unresolved.positive?
|
|
129
|
+
unclaimed.each do |name|
|
|
130
|
+
notes << "# UNCLAIMED: #{name} existed and now doesn't, and its successor is ambiguous — add " \
|
|
131
|
+
"`aggregate \"NewName\", was: #{name.inspect}` (with its rules) or `retired #{name.inspect}`."
|
|
132
|
+
end
|
|
133
|
+
notes << "# 0 unresolved: this shape change costs one extra boot and no typing." if notes.size == 1
|
|
134
|
+
notes
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def audit(held, lineage, path)
|
|
138
|
+
eras = held.held_eras(lineage)
|
|
139
|
+
return Readings.no_era(held.bluebook.name, path) if eras.empty?
|
|
140
|
+
|
|
141
|
+
finding = EdgeAudit.call(held, lineage, eras)
|
|
142
|
+
return "#{held.bluebook.name} stands at era 1 — no edge to audit." unless finding
|
|
143
|
+
raise Runtime::NotFound, "#{finding.report}\nAUDIT REFUSED." unless finding.ok
|
|
144
|
+
|
|
145
|
+
[finding.report, audit_verdict(finding.edge, path)].join("\n")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def audit_verdict(edge, path)
|
|
149
|
+
if Translation::ApprovalFile.needs_rehearsal?(edge)
|
|
150
|
+
"AUDIT PASSED — this edge carries a compute or rekey rule, and the samples above are its ONLY " \
|
|
151
|
+
"verification. If they show what you intended, rehearse it against a snapshot and run " \
|
|
152
|
+
"`hecks approve_translation #{path} --confirm` with the rehearsal; the mint refuses until then."
|
|
153
|
+
else
|
|
154
|
+
"AUDIT PASSED — review the samples above; intent is yours to approve."
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def attest(held, lineage, ordinal)
|
|
159
|
+
era = raw_era(held, lineage, ordinal)
|
|
160
|
+
computed = Digest::SHA256.hexdigest(era[:held_text])
|
|
161
|
+
name = "#{held.bluebook.name} era #{ordinal}"
|
|
162
|
+
return "#{name}: the held text matches its digest — nothing to re-attest." if era[:held_digest] == computed
|
|
163
|
+
|
|
164
|
+
[
|
|
165
|
+
"#{name}: the held text does NOT match its recorded digest.",
|
|
166
|
+
" recorded: #{era[:held_digest] || '(none)'}", " computed: #{computed}", shape_line(held, era, ordinal),
|
|
167
|
+
"The held text AS IT NOW STANDS — the original is gone; this is what you would be attesting to:",
|
|
168
|
+
"─" * 72, era[:held_text], "─" * 72,
|
|
169
|
+
"Read it, then `hecks reattest #{held.bluebook.name} era=#{ordinal} --confirm` accepts it."
|
|
170
|
+
].join("\n")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def shape_line(held, era, ordinal)
|
|
174
|
+
verdict = Translation::Reattest.shape_guard!(
|
|
175
|
+
domain: held.bluebook.name, ordinal: ordinal, text: era[:held_text], stored_hash: era[:hash],
|
|
176
|
+
stored_projection: era[:held_projection] && JSON.parse(era[:held_projection])
|
|
177
|
+
)
|
|
178
|
+
if verdict == :cosmetic
|
|
179
|
+
" shape: unchanged — the edit is cosmetic (the text still projects to era #{ordinal}'s minted name)"
|
|
180
|
+
else
|
|
181
|
+
" shape: era #{ordinal} was never named, so no shape comparison is possible — read carefully"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
|
|
2
|
+
# and the implementation must load once, from `lib/`, not from the copy.
|
|
3
|
+
require "hecks/hecks/adapters/journal_store"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "JournalStore" do
|
|
6
|
+
port "JournalStore"
|
|
7
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "journal_store/examination"
|
|
4
|
+
require_relative "journal_store/changes"
|
|
5
|
+
require_relative "journal_store/readings"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Adapters
|
|
9
|
+
# The `JournalStore` port's adapter: reaches the era plugin and the persistence adapters on an
|
|
10
|
+
# operator's behalf, to examine a domain's journal, change it, or read how it stands.
|
|
11
|
+
#
|
|
12
|
+
# `examine` reports the facts Custodian's `Era.Permit` holds against the request, `apply` makes
|
|
13
|
+
# an admitted change, and the queries (`scaffold_translation`, `audit_translation`,
|
|
14
|
+
# `attestation`, `compaction`) answer without writing. Every method reuses the era plugin's
|
|
15
|
+
# own logic (`LineageManager`, `Lineage`, `Translation::*`); only the entry point moved.
|
|
16
|
+
#
|
|
17
|
+
# Arguments arrive materialized, so a value object is `{ value: x }`.
|
|
18
|
+
class JournalStore
|
|
19
|
+
include Examination
|
|
20
|
+
include Changes
|
|
21
|
+
include Readings
|
|
22
|
+
|
|
23
|
+
# Accepts the arguments every driven adapter is built with and keeps none of them.
|
|
24
|
+
#
|
|
25
|
+
# @param aggregate [Object, nil] unused
|
|
26
|
+
# @param settings [Hash] unused
|
|
27
|
+
# @param root [String, nil] unused
|
|
28
|
+
def initialize(aggregate: nil, settings: {}, root: nil); end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
|
|
33
|
+
|
|
34
|
+
# Aggregate names, from the comma-separated list a request carries.
|
|
35
|
+
def names(list) = plain(list).to_s.split(",").map(&:strip).reject(&:empty?)
|
|
36
|
+
|
|
37
|
+
# `id:old,id:new` as the map the tail merge takes; the side is what follows the last colon.
|
|
38
|
+
def winners(held)
|
|
39
|
+
plain(held[:winners]).to_s.split(",").to_h do |pair|
|
|
40
|
+
id, _, side = pair.rpartition(":")
|
|
41
|
+
[id, side]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The rehearsal a compute or rekey edge is approved on, as the block the file carries. A
|
|
46
|
+
# rehearsal that names no host version ran on this one, so it records this release.
|
|
47
|
+
def rehearsal_block(held)
|
|
48
|
+
block = { "snapshot" => plain(held[:snapshot]), "host_version" => plain(held[:host_version]),
|
|
49
|
+
"result" => plain(held[:rehearsal]), "at" => plain(held[:rehearsed_at]) }.compact
|
|
50
|
+
return nil if block.empty?
|
|
51
|
+
|
|
52
|
+
block["host_version"] ||= Hecks::VERSION
|
|
53
|
+
block
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The era as stored, digest unchecked: a text that drifted is what re-attesting is for.
|
|
57
|
+
def raw_era(domain, lineage, ordinal)
|
|
58
|
+
present = lineage.db.exec("SELECT to_regclass('hecks_eras') AS present")[0]["present"]
|
|
59
|
+
(present && lineage.raw_era(ordinal)) or
|
|
60
|
+
raise Runtime::NotFound, "#{domain.bluebook.name} holds no era #{ordinal}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
|
|
2
|
+
# and the implementation must load once, from `lib/`, not from the copy.
|
|
3
|
+
require "hecks/hecks/adapters/local_files"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "LocalFiles" do
|
|
6
|
+
port "Workspace"
|
|
7
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "console_capture"
|
|
4
|
+
require "hecks/cli/project_cli"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
# The `Workspace` port's adapter: writes files into the project the operator is standing in.
|
|
9
|
+
#
|
|
10
|
+
# Custodian commands whose whole effect is files on disk ask it, so the journal records that a
|
|
11
|
+
# write was requested and what came of it, and the writing happens here and nowhere else.
|
|
12
|
+
class LocalFiles
|
|
13
|
+
# Accepts the arguments every driven adapter is built with and keeps none of them.
|
|
14
|
+
#
|
|
15
|
+
# @param aggregate [Object, nil] unused
|
|
16
|
+
# @param settings [Hash] unused
|
|
17
|
+
# @param root [String, nil] unused
|
|
18
|
+
def initialize(aggregate: nil, settings: {}, root: nil); end
|
|
19
|
+
|
|
20
|
+
# Writes a command-line launcher beside each domain of the current directory, or beside the
|
|
21
|
+
# named ones, through `Hecks::CLI::ProjectCli`. A launcher is a generated file that only
|
|
22
|
+
# points at its domain, so an existing one is replaced and nothing else is touched.
|
|
23
|
+
#
|
|
24
|
+
# @param held [Hash] the `Door` record: `domains` (comma separated paths under the current
|
|
25
|
+
# directory; every domain found when absent)
|
|
26
|
+
# @return [Hash{Symbol => Hash}] `output:` one line per launcher written
|
|
27
|
+
# @raise [ConsoleCapture::Failure] when no launcher was written
|
|
28
|
+
def write(**held)
|
|
29
|
+
domains = plain(held[:domains]).to_s.split(",").map(&:strip).reject(&:empty?)
|
|
30
|
+
text = ConsoleCapture.answer do
|
|
31
|
+
CLI::ProjectCli.call(domains, program: "hecks project_cli", root: Dir.pwd, remove_stale_bin: false)
|
|
32
|
+
end
|
|
33
|
+
unless text.include?("->")
|
|
34
|
+
reason = text.strip.empty? ? "no domain found" : text.strip
|
|
35
|
+
raise ConsoleCapture::Failure, "no launcher written: #{reason}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
{ output: { value: text } }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def plain(argument) = argument.is_a?(Hash) ? argument[:value] : argument
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Required by name, not relative to this file: a fuzz or model check boots a copy of this directory,
|
|
2
|
+
# and the implementation must load once, from `lib/`, not from the copy.
|
|
3
|
+
require "hecks/hecks/adapters/pg_admin"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "PgAdmin" do
|
|
6
|
+
port "PgAdmin"
|
|
7
|
+
end
|