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
|
@@ -11,42 +11,13 @@ require_relative "../../runtime/errors"
|
|
|
11
11
|
require_relative "../../runtime/event"
|
|
12
12
|
require_relative "postgres/outbox"
|
|
13
13
|
require_relative "postgres/reconnect"
|
|
14
|
+
require_relative "postgres/shared_connection"
|
|
14
15
|
require_relative "../../runtime/instance"
|
|
15
16
|
|
|
16
17
|
module Hecks
|
|
17
18
|
module Adapters
|
|
18
|
-
# The plain Postgres store
|
|
19
|
-
#
|
|
20
|
-
# exactly the shape `Sqlite` already made for its own table. Sibling
|
|
21
|
-
# to `PostgresEra` (postgres_era.rb), which is the same database with
|
|
22
|
-
# full lineage/era machinery on top — pick this one unless a domain
|
|
23
|
-
# actually needs to survive a live shape change. See
|
|
24
|
-
# docs/implemented/postgres-era-adapter-split-plan.md for why the two are split.
|
|
25
|
-
#
|
|
26
|
-
# ## What it is not
|
|
27
|
-
#
|
|
28
|
-
# No `hecks_eras`, no lineage, no advisory-lock-per-write for era
|
|
29
|
-
# tracking, no `lineage_capable?`/`era_check!` — this class simply
|
|
30
|
-
# doesn't define those methods at all, and the capability idiom
|
|
31
|
-
# elsewhere already treats their absence as "not lineage-capable".
|
|
32
|
-
#
|
|
33
|
-
# ## Storage shape
|
|
34
|
-
#
|
|
35
|
-
# See postgres/schema_builder.rb for the DDL, postgres/codec.rb for the
|
|
36
|
-
# encode/decode.
|
|
37
|
-
#
|
|
38
|
-
# - One real column per attribute, typed for a scalar
|
|
39
|
-
# (`SQL_TYPES`, `text` default), `jsonb` for a nested (value-object)
|
|
40
|
-
# or list-typed attribute — never JSON-in-text the way `Sqlite` has
|
|
41
|
-
# to, since Postgres has a native jsonb type.
|
|
42
|
-
# - `append` and `project` are two real Postgres statements — `save`/
|
|
43
|
-
# `delete` wrap them in one transaction, same "the journal insert
|
|
44
|
-
# and the snapshot stay atomic" reasoning `PostgresEra#append`'s own
|
|
45
|
-
# comment gives: a crash between the two must never leave a
|
|
46
|
-
# half-written state. `append`/`project` stay plain, individually-
|
|
47
|
-
# callable methods (never wrapping their own transaction) so
|
|
48
|
-
# `AppendOnly#recover!`'s replay — `project` alone, no `append` —
|
|
49
|
-
# keeps working the same way it does on every other adapter.
|
|
19
|
+
# The plain Postgres store: one table per aggregate, real typed columns
|
|
20
|
+
# for scalars, jsonb for nested/list attributes. See `PostgresEra` for lineage/era support.
|
|
50
21
|
class Postgres
|
|
51
22
|
include SqlQueryBuilder
|
|
52
23
|
include SchemaBuilder
|
|
@@ -94,11 +65,8 @@ module Hecks
|
|
|
94
65
|
PG.connect(dbname: declared)
|
|
95
66
|
end
|
|
96
67
|
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
# with other domains, so every unqualified reference this
|
|
100
|
-
# adapter constructs resolves through search_path. A domain with
|
|
101
|
-
# no `schema` setting keeps Postgres's own default (public).
|
|
68
|
+
# A domain with `schema` set shares this Postgres instance, so every
|
|
69
|
+
# unqualified reference resolves through search_path.
|
|
102
70
|
schema = settings.key?(:schema) ? settings[:schema] : settings["schema"]
|
|
103
71
|
connection.exec("SET search_path TO #{connection.quote_ident(schema)}") if schema.to_s != ""
|
|
104
72
|
|
|
@@ -112,7 +80,8 @@ module Hecks
|
|
|
112
80
|
"cannot bind Postgres at #{declared} for #{name}: #{e.message.strip}"
|
|
113
81
|
end
|
|
114
82
|
|
|
115
|
-
#
|
|
83
|
+
# Joins the process's shared connection for the declared database and schema, then
|
|
84
|
+
# creates the aggregate, journal, event, saga and outbox tables if absent.
|
|
116
85
|
#
|
|
117
86
|
# @param aggregate [Bluebook::Aggregate] the aggregate whose table this adapter owns
|
|
118
87
|
# @param settings [Hash{Symbol, String => Object}] world settings for the binding:
|
|
@@ -126,11 +95,9 @@ module Hecks
|
|
|
126
95
|
def initialize(aggregate:, settings: {}, root: nil)
|
|
127
96
|
@aggregate = aggregate
|
|
128
97
|
@settings = settings
|
|
129
|
-
@db =
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
# directly-instantiated adapter (specs), same fallback shape
|
|
133
|
-
# Sqlite's own @domain already uses.
|
|
98
|
+
@db = PostgresSharedConnection.for(aggregate.name, settings, connector: self.class)
|
|
99
|
+
# Scopes saga rows; falls back to the aggregate's storage name when
|
|
100
|
+
# settings gives no domain (e.g. a directly-instantiated adapter).
|
|
134
101
|
@domain = (
|
|
135
102
|
if settings.key?(:domain)
|
|
136
103
|
settings[:domain]
|
|
@@ -146,6 +113,7 @@ module Hecks
|
|
|
146
113
|
create_event_table!
|
|
147
114
|
create_saga_table!
|
|
148
115
|
create_outbox_table!
|
|
116
|
+
create_checkpoint_table!
|
|
149
117
|
end
|
|
150
118
|
|
|
151
119
|
# Names the aggregate's table; the journal table and outbox rows are keyed off it.
|
|
@@ -169,9 +137,7 @@ module Hecks
|
|
|
169
137
|
|
|
170
138
|
# Lists every stored record, ordered by id unless an ordering attribute is given.
|
|
171
139
|
#
|
|
172
|
-
# order_by is a runtime value
|
|
173
|
-
# whitelisted the identical way before it ever reaches
|
|
174
|
-
# order_expression.
|
|
140
|
+
# order_by is a runtime value, whitelisted the same way Sqlite#all does.
|
|
175
141
|
#
|
|
176
142
|
# @param order_by [String, Symbol, nil] attribute (or dotted value-object path) to sort
|
|
177
143
|
# by, with id as the tie-break; nil orders by id alone
|
|
@@ -205,54 +171,39 @@ module Hecks
|
|
|
205
171
|
|
|
206
172
|
# Inserts one journal row, outside any transaction of its own.
|
|
207
173
|
#
|
|
174
|
+
# Stamps the row's assigned `sequence` onto `entry` in place, so a `project` call right
|
|
175
|
+
# after (same object, same transaction) can advance the checkpoint with no extra query.
|
|
176
|
+
#
|
|
208
177
|
# @param entry [Ports::Persistence::Entry] the save or delete to journal; `state` is
|
|
209
178
|
# encoded through the state codec and `mirrors` stored as JSON, or NULL when nil
|
|
210
|
-
# @return [Ports::Persistence::Entry] the same `entry`
|
|
179
|
+
# @return [Ports::Persistence::Entry] the same `entry`, `sequence` now set
|
|
211
180
|
# @raise [PG::Error] if the insert fails
|
|
212
181
|
def append(entry)
|
|
213
|
-
pg_exec_params(
|
|
214
|
-
"INSERT INTO #{quoted_entry_table} (aggregate_id, operation, state, mirrors) VALUES ($1, $2, $3, $4)"
|
|
215
|
-
|
|
216
|
-
# mirrors hash must bind
|
|
217
|
-
#
|
|
218
|
-
# check against it would never match. Same guard `sqlite.rb`/
|
|
219
|
-
# `d1.rb`/`postgres_era.rb` already use for their own journal's
|
|
220
|
-
# `mirrors` column.
|
|
182
|
+
result = pg_exec_params(
|
|
183
|
+
"INSERT INTO #{quoted_entry_table} (aggregate_id, operation, state, mirrors) VALUES ($1, $2, $3, $4) " \
|
|
184
|
+
"RETURNING sequence",
|
|
185
|
+
# `mirrors` is nullable; an absent hash must bind SQL NULL, not the
|
|
186
|
+
# string "null", or a future IS NULL check would never match.
|
|
221
187
|
[entry.id, entry.operation, state_json(entry.state), entry.mirrors && JSON.generate(entry.mirrors)]
|
|
222
188
|
)
|
|
189
|
+
entry.sequence = result[0]["sequence"].to_i
|
|
223
190
|
entry
|
|
224
191
|
end
|
|
225
192
|
|
|
226
193
|
# Upserts or deletes the aggregate's row for one journal entry, bumping its version.
|
|
227
194
|
#
|
|
228
|
-
# `expected_version
|
|
229
|
-
# `persistence_capabilities`/`Ports::Persistence::AppendOnly#save`).
|
|
230
|
-
# `hecks_version` is adapter bookkeeping — never in `persisted_fields`
|
|
231
|
-
# (Codec), so it never reaches `decode`'s domain-state hash. It goes
|
|
232
|
-
# in the INSERT column list at `1` (a genuinely new row) and bumps by
|
|
233
|
-
# one in the `ON CONFLICT DO UPDATE` branch; when `expected_version`
|
|
234
|
-
# is given, that update branch additionally requires
|
|
235
|
-
# `hecks_version = expected_version` to apply at all — Postgres's own
|
|
236
|
-
# `INSERT ... ON CONFLICT DO UPDATE ... WHERE`, which gates only
|
|
237
|
-
# whether the conflict branch's update applies. A genuinely new row
|
|
238
|
-
# never reaches that branch at all, so it always inserts regardless
|
|
239
|
-
# of this where. `RETURNING hecks_version` plus `ntuples.zero?` is
|
|
240
|
-
# how a real version mismatch is told apart from an ordinary write:
|
|
241
|
-
# zero rows back means the conflict branch's where excluded the row
|
|
242
|
-
# entirely — the version had already moved — so `nil` is returned
|
|
243
|
-
# for the caller (`AppendOnly#save`) to treat as "stale, no-op".
|
|
195
|
+
# `expected_version` requests optimistic-concurrency CAS; nil back means it didn't match.
|
|
244
196
|
#
|
|
245
197
|
# @param entry [Ports::Persistence::Entry] the save or delete to materialize
|
|
246
198
|
# @param expected_version [Integer, nil] the `hecks_version` the row must still hold for
|
|
247
199
|
# an update to apply; nil writes unconditionally. Ignored for a delete
|
|
248
|
-
# @return [Runtime::Instance, PG::Result, nil]
|
|
249
|
-
#
|
|
250
|
-
# `expected_version` did not match and nothing was written; for a delete, the
|
|
251
|
-
# `DELETE` statement's `PG::Result`
|
|
200
|
+
# @return [Runtime::Instance, PG::Result, nil] a new instance with `version` set, nil on
|
|
201
|
+
# CAS mismatch, or the `DELETE` statement's `PG::Result`
|
|
252
202
|
# @raise [PG::Error] if the statement fails
|
|
253
203
|
# rubocop:disable Metrics/AbcSize -- the CAS/plain upsert split is one
|
|
254
204
|
# protocol; splitting it would hide the version handshake.
|
|
255
205
|
def project(entry, expected_version: nil)
|
|
206
|
+
advance_checkpoint!(entry.sequence) if entry.sequence
|
|
256
207
|
return pg_exec_params("DELETE FROM #{quoted_table} WHERE id = $1", [entry.id]) if entry.delete?
|
|
257
208
|
|
|
258
209
|
instance = Runtime::Instance.new(aggregate: @aggregate, id: entry.id, state: entry.state)
|
|
@@ -286,15 +237,66 @@ module Hecks
|
|
|
286
237
|
# @raise [PG::Error] if the statement fails
|
|
287
238
|
# @raise [JSON::ParserError] if a stored `state` or `mirrors` value is not valid JSON
|
|
288
239
|
def entries
|
|
289
|
-
|
|
290
|
-
state
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
240
|
+
entries_matching(
|
|
241
|
+
"SELECT aggregate_id, operation, state, mirrors, sequence FROM #{quoted_entry_table} ORDER BY sequence"
|
|
242
|
+
)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Reads only the journal rows past a given `sequence`, for `AppendOnly#recover!` to replay
|
|
246
|
+
# after a checkpoint instead of the whole journal.
|
|
247
|
+
#
|
|
248
|
+
# @param sequence [Integer] the highest `sequence` already projected; rows at or below it
|
|
249
|
+
# are skipped
|
|
250
|
+
# @return [Array<Ports::Persistence::Entry>] the journalled entries past `sequence`, in
|
|
251
|
+
# append order, decoded exactly as `entries` decodes them; `[]` when none are newer
|
|
252
|
+
# @raise [PG::Error] if the statement fails
|
|
253
|
+
# @raise [JSON::ParserError] if a stored `state` or `mirrors` value is not valid JSON
|
|
254
|
+
def entries_since(sequence)
|
|
255
|
+
entries_matching(
|
|
256
|
+
"SELECT aggregate_id, operation, state, mirrors, sequence FROM #{quoted_entry_table} " \
|
|
257
|
+
"WHERE sequence > $1 ORDER BY sequence",
|
|
258
|
+
[sequence]
|
|
259
|
+
)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Reads the highest journal `sequence` this table has already had projected into it.
|
|
263
|
+
#
|
|
264
|
+
# @return [Integer] `0` when the table has never been checkpointed (a fresh table, or one
|
|
265
|
+
# from before this bookkeeping existed) — `entries_since(0)` then reads the whole journal,
|
|
266
|
+
# matching `entries`' own full replay
|
|
267
|
+
# @raise [PG::Error] if the statement fails
|
|
268
|
+
def checkpoint
|
|
269
|
+
result = pg_exec_params("SELECT last_sequence FROM hecks_checkpoints WHERE aggregate_table = $1", [table])
|
|
270
|
+
result.ntuples.zero? ? 0 : result[0]["last_sequence"].to_i
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Reads the highest journal `sequence` compaction has already deleted from this table.
|
|
274
|
+
#
|
|
275
|
+
# @return [Integer] `0` when nothing has ever been compacted
|
|
276
|
+
# @raise [PG::Error] if the statement fails
|
|
277
|
+
def compacted_through
|
|
278
|
+
result = pg_exec_params("SELECT compacted_through FROM hecks_checkpoints WHERE aggregate_table = $1", [table])
|
|
279
|
+
result.ntuples.zero? ? 0 : result[0]["compacted_through"].to_i
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Deletes every journal row at or before `through` and records it, so a `:strict`
|
|
283
|
+
# projection catch-up can tell whether it still has the history it needs.
|
|
284
|
+
#
|
|
285
|
+
# Never moves `compacted_through` backwards, and never touches the aggregate's own
|
|
286
|
+
# table — only the journal, which a `:refresh` projection rebuild never needs.
|
|
287
|
+
#
|
|
288
|
+
# @param through [Integer] the highest `sequence` to delete
|
|
289
|
+
# @return [Integer] the number of journal rows deleted
|
|
290
|
+
# @raise [PG::Error] if a statement fails
|
|
291
|
+
def compact_entries!(through:)
|
|
292
|
+
removed = pg_exec_params("DELETE FROM #{quoted_entry_table} WHERE sequence <= $1", [through]).cmd_tuples
|
|
293
|
+
pg_exec_params(
|
|
294
|
+
"INSERT INTO hecks_checkpoints (aggregate_table, compacted_through) VALUES ($1, $2) " \
|
|
295
|
+
"ON CONFLICT (aggregate_table) DO UPDATE SET " \
|
|
296
|
+
"compacted_through = GREATEST(hecks_checkpoints.compacted_through, excluded.compacted_through)",
|
|
297
|
+
[table, through]
|
|
298
|
+
)
|
|
299
|
+
removed
|
|
298
300
|
end
|
|
299
301
|
|
|
300
302
|
# Deletes every row of the aggregate's table and its journal; events, saga rows and
|
|
@@ -310,13 +312,8 @@ module Hecks
|
|
|
310
312
|
|
|
311
313
|
# Journals and upserts an instance's current state atomically.
|
|
312
314
|
#
|
|
313
|
-
# One transaction,
|
|
314
|
-
#
|
|
315
|
-
# real Postgres ACID atomicity is sitting right there, so a crash
|
|
316
|
-
# between the journal insert and the table upsert must not leave
|
|
317
|
-
# the two disagreeing. `append`/`project` themselves stay plain,
|
|
318
|
-
# transaction-free methods (see the class comment above) — the
|
|
319
|
-
# transaction lives here, the one caller that runs both together.
|
|
315
|
+
# One transaction, so a crash between the journal insert and the row upsert
|
|
316
|
+
# can never leave the two disagreeing.
|
|
320
317
|
#
|
|
321
318
|
# @param instance [Runtime::Instance] the instance to store
|
|
322
319
|
# @return [Runtime::Instance] a new instance over the saved state, `version` set to the
|
|
@@ -405,13 +402,32 @@ module Hecks
|
|
|
405
402
|
end
|
|
406
403
|
end
|
|
407
404
|
|
|
405
|
+
# Reads back one record's recorded events, oldest first — pushed down as a `WHERE`
|
|
406
|
+
# clause (`hecks_events_aggregate_id_idx`) instead of filtering `#events`'s whole-table
|
|
407
|
+
# read, since a `corrects` command's history lookup only ever needs this one record.
|
|
408
|
+
#
|
|
409
|
+
# @param aggregate [String] the `"domain::AggregateName"` key events are stored under
|
|
410
|
+
# @param id [String, Object] the record's identity, matched as `id.to_s`
|
|
411
|
+
# @return [Array<Runtime::Event>] the record's stored events; `[]` when it has none
|
|
412
|
+
# @raise [PG::Error] if the statement fails
|
|
413
|
+
def events_for(aggregate:, id:)
|
|
414
|
+
pg_exec_params(
|
|
415
|
+
"SELECT * FROM events WHERE aggregate = $1 AND aggregate_id = $2 ORDER BY id",
|
|
416
|
+
[aggregate, id.to_s]
|
|
417
|
+
).map do |row|
|
|
418
|
+
Runtime::Event.new(
|
|
419
|
+
name: row["name"],
|
|
420
|
+
aggregate: row["aggregate"],
|
|
421
|
+
id: row["aggregate_id"],
|
|
422
|
+
payload: JSON.parse(row["payload"], symbolize_names: true),
|
|
423
|
+
occurred_at: row["occurred_at"]
|
|
424
|
+
)
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
|
|
408
428
|
# Upserts one saga instance's checkpoint, keyed by domain, process manager and
|
|
409
429
|
# correlation.
|
|
410
430
|
#
|
|
411
|
-
# ── the optional saga-persistence capability (§2) — same DDL and
|
|
412
|
-
# shape as PostgresEra's own (postgres_era.rb), not lineage-
|
|
413
|
-
# specific, copied verbatim.
|
|
414
|
-
#
|
|
415
431
|
# @param process_manager [String, Symbol] the process manager's name
|
|
416
432
|
# @param correlation [String, Object] the instance's correlation value, stored as
|
|
417
433
|
# `correlation.to_s`
|
|
@@ -475,8 +491,6 @@ module Hecks
|
|
|
475
491
|
|
|
476
492
|
private
|
|
477
493
|
|
|
478
|
-
# ── SqlQueryBuilder's dialect hooks ─────────────────────────────
|
|
479
|
-
|
|
480
494
|
def select_list = "*"
|
|
481
495
|
def from_relation = quoted_table
|
|
482
496
|
def dialect_name = "Postgres"
|
|
@@ -491,11 +505,8 @@ module Hecks
|
|
|
491
505
|
"position(#{placeholder} in #{expression}) > 0"
|
|
492
506
|
end
|
|
493
507
|
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
# own version does, since every attribute there shares one `state`
|
|
497
|
-
# column). Here, `column` names a real column of its own, already
|
|
498
|
-
# jsonb, already the array.
|
|
508
|
+
# `column` is already a real jsonb column and already the array — no shared
|
|
509
|
+
# `state` blob to walk into first, unlike PostgresEra's own version.
|
|
499
510
|
def list_contains_clause(column, member, placeholder)
|
|
500
511
|
target = member.empty? ? "elem #>> '{}'" : "elem ->> #{text_literal(member)}"
|
|
501
512
|
elements = "jsonb_array_elements(#{quote_ident(column)}) AS elem"
|
|
@@ -504,28 +515,15 @@ module Hecks
|
|
|
504
515
|
|
|
505
516
|
def plain_column(name) = quote_ident(name)
|
|
506
517
|
|
|
507
|
-
#
|
|
508
|
-
# shared `state`
|
|
509
|
-
# there. Here the attribute name is the column: the path into it
|
|
510
|
-
# is whatever is left after the column, never the column name
|
|
511
|
-
# repeated inside its own path.
|
|
518
|
+
# The attribute name is the column itself here, not part of the path (unlike
|
|
519
|
+
# PostgresEra's shared `state` blob) — the path is whatever follows the column.
|
|
512
520
|
def nested_expression(name, path, member)
|
|
513
521
|
segments = path.empty? ? [(member || "value").to_s] : path
|
|
514
522
|
jsonb_path(name, segments)
|
|
515
523
|
end
|
|
516
524
|
|
|
517
|
-
#
|
|
518
|
-
#
|
|
519
|
-
# no cast at all, unlike PostgresEra's shared jsonb `state` blob,
|
|
520
|
-
# where even a top-level scalar only ever comes out of `#>>` as
|
|
521
|
-
# text. A jsonb-extracted value (a value-object member reached
|
|
522
|
-
# through `nested_expression`/`jsonb_path` above) still comes out
|
|
523
|
-
# of `#>>` as text the exact same way PostgresEra's own does, and
|
|
524
|
-
# still needs the same `::numeric` cast to compare/sort
|
|
525
|
-
# numerically rather than lexicographically. `jsonb_extraction?`
|
|
526
|
-
# tells the two apart by inspecting the expression `query_expression`
|
|
527
|
-
# already built — never a second, hand-rolled field walk that
|
|
528
|
-
# could disagree with the one the SQL actually uses.
|
|
525
|
+
# A jsonb-extracted value still comes out as text; cast it to compare/sort
|
|
526
|
+
# numerically instead of lexicographically.
|
|
529
527
|
def comparable_expression(expression, value)
|
|
530
528
|
value.is_a?(Numeric) && jsonb_extraction?(expression) ? "(#{expression})::numeric" : expression
|
|
531
529
|
end
|
|
@@ -534,19 +532,14 @@ module Hecks
|
|
|
534
532
|
pg_exec_params(sql, binds).map { |row| instance_from_row(row) }
|
|
535
533
|
end
|
|
536
534
|
|
|
537
|
-
# Stamps `.version`
|
|
538
|
-
#
|
|
539
|
-
# every Instance this adapter builds from a real stored row, so a
|
|
540
|
-
# later `save`'s optimistic-concurrency CAS has something to check
|
|
541
|
-
# against.
|
|
535
|
+
# Stamps `.version` from `hecks_version` so a later CAS save has something
|
|
536
|
+
# to check against.
|
|
542
537
|
def instance_from_row(row)
|
|
543
538
|
instance = Runtime::Instance.new(aggregate: @aggregate, id: row["id"], state: decode(row))
|
|
544
539
|
instance.version = row["hecks_version"].to_i
|
|
545
540
|
instance
|
|
546
541
|
end
|
|
547
542
|
|
|
548
|
-
# ── the rest of the dialect ─────────────────────────────────────
|
|
549
|
-
|
|
550
543
|
def quote_ident(name) = PG::Connection.quote_ident(name.to_s)
|
|
551
544
|
def quoted_table = quote_ident(table)
|
|
552
545
|
def entry_table = "#{table}_entries"
|
|
@@ -559,11 +552,8 @@ module Hecks
|
|
|
559
552
|
jsonb_extraction?(expression) && numeric_field?(field) ? "(#{expression})::numeric" : expression
|
|
560
553
|
end
|
|
561
554
|
|
|
562
|
-
# Postgres
|
|
563
|
-
#
|
|
564
|
-
# answers identically no matter which adapter serves it (the
|
|
565
|
-
# port's in-memory semantics, which Sqlite's own default happens
|
|
566
|
-
# to match, put null rows FIRST ascending and LAST descending).
|
|
555
|
+
# Overrides Postgres's default NULLS LAST on ASC so every adapter answers
|
|
556
|
+
# a declared query's null ordering identically.
|
|
567
557
|
def order_clause(order_by, policy)
|
|
568
558
|
direction = order_by.direction.to_s.downcase == "desc" ? "DESC" : "ASC"
|
|
569
559
|
nulls = case policy&.mode.to_s
|
|
@@ -584,15 +574,38 @@ module Hecks
|
|
|
584
574
|
end
|
|
585
575
|
end
|
|
586
576
|
|
|
587
|
-
# Array[...]
|
|
588
|
-
#
|
|
589
|
-
# hand-rolled '{a,b,c}' array literal has no escaping at all, and
|
|
590
|
-
# a segment is a field or value-object member name this method has
|
|
591
|
-
# no way to know is always schema-declared.
|
|
577
|
+
# Builds an escaped Array[...] literal rather than a hand-rolled '{a,b,c}'
|
|
578
|
+
# string, since a segment name isn't guaranteed schema-declared.
|
|
592
579
|
def jsonb_path(column, segments)
|
|
593
580
|
"#{quote_ident(column)} #>> ARRAY[#{segments.map { |segment| text_literal(segment) }.join(', ')}]::text[]"
|
|
594
581
|
end
|
|
595
582
|
|
|
583
|
+
# Shared decode step for `entries`/`entries_since` — runs a query already selecting
|
|
584
|
+
# `aggregate_id, operation, state, mirrors, sequence` and builds one Entry per row.
|
|
585
|
+
def entries_matching(sql, binds = [])
|
|
586
|
+
pg_exec_params(sql, binds).map do |row|
|
|
587
|
+
state = JSON.parse(row["state"])
|
|
588
|
+
Ports::Persistence::Entry.new(
|
|
589
|
+
operation: row["operation"] || "save",
|
|
590
|
+
id: row["aggregate_id"],
|
|
591
|
+
state: Ports::Persistence::StateCodec.decode(@aggregate, state),
|
|
592
|
+
mirrors: row["mirrors"] && JSON.parse(row["mirrors"]),
|
|
593
|
+
sequence: row["sequence"].to_i
|
|
594
|
+
)
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
# Advances this table's checkpoint to `sequence`, never backwards — two overlapping
|
|
599
|
+
# `project` calls for out-of-order entries must not let an older sequence win.
|
|
600
|
+
def advance_checkpoint!(sequence)
|
|
601
|
+
pg_exec_params(
|
|
602
|
+
"INSERT INTO hecks_checkpoints (aggregate_table, last_sequence) VALUES ($1, $2) " \
|
|
603
|
+
"ON CONFLICT (aggregate_table) DO UPDATE SET " \
|
|
604
|
+
"last_sequence = GREATEST(hecks_checkpoints.last_sequence, EXCLUDED.last_sequence)",
|
|
605
|
+
[table, sequence]
|
|
606
|
+
)
|
|
607
|
+
end
|
|
608
|
+
|
|
596
609
|
def text_literal(text) = "'#{text.to_s.gsub("'", "''")}'"
|
|
597
610
|
end
|
|
598
611
|
end
|
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# declaration stays here, unmoved. `Adapters::Folder#load_library` globs
|
|
4
|
-
# `.adapter` files by DIRECTORY, not by require path, on every boot,
|
|
5
|
-
# regardless of which adapters a given domain actually binds — the same
|
|
6
|
-
# reason every other adapter's own `.adapter` file lives beside this one.
|
|
7
|
-
# Pure metadata (which port, which fields) — no era-specific code, and
|
|
8
|
-
# harmless for a domain that never binds `persisted_by "PostgresEra"`.
|
|
9
|
-
# `registry.adapter_class("PostgresEra")` is only ever resolved for a
|
|
10
|
-
# domain that actually binds to it, at which point the plugin must
|
|
11
|
-
# already be `require`d for the class to exist.
|
|
1
|
+
# Declares the PostgresEra adapter's port and fields; the class lives in the era plugin.
|
|
2
|
+
# This file is loaded on every boot, so it stays metadata only.
|
|
12
3
|
Hecks.adapter "PostgresEra" do
|
|
13
4
|
port "persistence"
|
|
14
5
|
field :database
|
|
15
6
|
field :role
|
|
16
7
|
field :schema
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# BYPASSRLS, which the era write-fence (row-level security) cannot
|
|
20
|
-
# bite. Refused by default; see `Lineage#check_fence_applies!` (BUG#24).
|
|
8
|
+
# Opt-in to boot over a superuser or BYPASSRLS role, which the era write fence cannot
|
|
9
|
+
# bite. Refused by default; see `Lineage#check_fence_applies!`.
|
|
21
10
|
field :allow_superuser
|
|
22
11
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "monitor"
|
|
1
2
|
require "prism"
|
|
2
3
|
require_relative "../../bluebook/expression/canonical_form"
|
|
3
4
|
|
|
@@ -5,13 +6,8 @@ module Hecks
|
|
|
5
6
|
module Adapters
|
|
6
7
|
class NotExtractable < StandardError; end
|
|
7
8
|
|
|
8
|
-
# Extracts a `given`/`ensures`/invariant block's own source text
|
|
9
|
-
#
|
|
10
|
-
# parses it with the `prism` gem, and canonicalises it — how a rule's
|
|
11
|
-
# predicate becomes readable, comparable text (era diffing, docs) rather
|
|
12
|
-
# than an opaque compiled Proc. Per-process `TREES` cache keyed by file
|
|
13
|
-
# path; `forget`/`forget_all` exist for a caller that reloads an edited
|
|
14
|
-
# file in-process (see their own comment).
|
|
9
|
+
# Extracts a `given`/`ensures`/invariant block's own source text via
|
|
10
|
+
# `prism`, canonicalised into readable, comparable text (era diffing, docs).
|
|
15
11
|
module Prism
|
|
16
12
|
# Not frozen — a real cache, keyed by file path and mutated by
|
|
17
13
|
# #tree_for below (`TREES[file] ||= ...`) and #forget/#forget_all.
|
|
@@ -19,6 +15,16 @@ module Hecks
|
|
|
19
15
|
# rubocop:disable-next Style/MutableConstant
|
|
20
16
|
TREES = {}
|
|
21
17
|
|
|
18
|
+
# The first block node starting on each line, per parsed tree (by identity), built by one
|
|
19
|
+
# walk of the tree the first time a block in its file is looked up. Dropped with its tree
|
|
20
|
+
# by #forget/#forget_all.
|
|
21
|
+
BLOCKS_BY_LINE = {}.compare_by_identity
|
|
22
|
+
|
|
23
|
+
# Guards `TREES` and `BLOCKS_BY_LINE` together, so a parse or an index build never
|
|
24
|
+
# interleaves with a `forget` that drops the same tree. Reentrant: `block_node_at`
|
|
25
|
+
# calls `tree_for` under it.
|
|
26
|
+
LOCK = Monitor.new
|
|
27
|
+
|
|
22
28
|
module_function
|
|
23
29
|
|
|
24
30
|
# Recovers a block's body as canonical source text.
|
|
@@ -52,14 +58,25 @@ module Hecks
|
|
|
52
58
|
# @return [Prism::BlockNode, nil] the first block node found starting on `line`, or nil
|
|
53
59
|
# if none does
|
|
54
60
|
def block_node_at(file, line)
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
LOCK.synchronize do
|
|
62
|
+
tree = tree_for(file)
|
|
63
|
+
BLOCKS_BY_LINE[tree] ||= blocks_by_line(tree)
|
|
64
|
+
BLOCKS_BY_LINE[tree][line]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Indexes a tree's block nodes by the line they start on, keeping the first in walk order.
|
|
69
|
+
#
|
|
70
|
+
# @param tree [Prism::ProgramNode] a parsed file's root node
|
|
71
|
+
# @return [Hash{Integer => Prism::BlockNode}] block node by 1-based start line
|
|
72
|
+
def blocks_by_line(tree)
|
|
73
|
+
index = {}
|
|
74
|
+
walk(tree) do |node|
|
|
57
75
|
next unless node.is_a?(::Prism::BlockNode)
|
|
58
|
-
next unless node.location.start_line == line
|
|
59
76
|
|
|
60
|
-
|
|
77
|
+
index[node.location.start_line] ||= node
|
|
61
78
|
end
|
|
62
|
-
|
|
79
|
+
index
|
|
63
80
|
end
|
|
64
81
|
|
|
65
82
|
# Parses a file with `prism`, caching the result for the life of the process.
|
|
@@ -67,42 +84,35 @@ module Hecks
|
|
|
67
84
|
# @param file [String] the file path to parse and cache under
|
|
68
85
|
# @return [Prism::ProgramNode] the parsed syntax tree's root node
|
|
69
86
|
def tree_for(file)
|
|
70
|
-
# ::Prism.parse_file
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
# which presses a hecks-based app into a single executable —
|
|
75
|
-
# see domain/README.md's "Deploying" section in a client site's domain for
|
|
76
|
-
# why that matters). ::Prism.parse(File.read(file)) parses the
|
|
77
|
-
# exact same bytes, just read through Ruby's File.read first,
|
|
78
|
-
# which those tools do intercept.
|
|
79
|
-
TREES[file] ||= ::Prism.parse(File.read(file)).value
|
|
87
|
+
# ::Prism.parse_file reads the file at the C-extension level, bypassing
|
|
88
|
+
# Ruby's File/IO layer — invisible to tools that virtualize the filesystem
|
|
89
|
+
# there (e.g. tebako's memfs). Read through File.read first so they intercept it.
|
|
90
|
+
LOCK.synchronize { TREES[file] ||= ::Prism.parse(File.read(file)).value }
|
|
80
91
|
end
|
|
81
92
|
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# loads once per process: one `bin/ir` run, one rspec worker,
|
|
85
|
-
# never edited out from under it), but wrong for anything that
|
|
86
|
-
# legitimately reloads an edited file in-process: a stale cached
|
|
87
|
-
# tree reports a `given`/`ensures` block at its old line number,
|
|
88
|
-
# which does not match the freshly re-executed file's own
|
|
89
|
-
# `block.source_location` — surfacing as "did not survive
|
|
90
|
-
# extraction" on a perfectly valid file. Built for real building
|
|
91
|
-
# `Hecks::Codemod` (lib/hecks/codemod.rb), which needs exactly this
|
|
92
|
-
# invalidation rather than reaching into `TREES.clear` directly — a
|
|
93
|
-
# private implementation detail poked from outside. `forget`/
|
|
94
|
-
# `forget_all` are the real API so nothing else that reloads an
|
|
95
|
-
# edited file in-process has to know `TREES` exists at all.
|
|
93
|
+
# Drops one file from the process-wide parse cache, for a caller (`Hecks::Codemod`)
|
|
94
|
+
# that reloads an edited file in-process and needs the stale tree invalidated.
|
|
96
95
|
#
|
|
97
96
|
# @param file [String] the file path to drop from the cache
|
|
98
97
|
# @return [Prism::ProgramNode, nil] the cached tree that was removed, or nil if
|
|
99
98
|
# nothing was cached for `file`
|
|
100
|
-
def forget(file)
|
|
99
|
+
def forget(file)
|
|
100
|
+
LOCK.synchronize do
|
|
101
|
+
tree = TREES.delete(file)
|
|
102
|
+
BLOCKS_BY_LINE.delete(tree)
|
|
103
|
+
tree
|
|
104
|
+
end
|
|
105
|
+
end
|
|
101
106
|
|
|
102
107
|
# Drops every cached parse tree.
|
|
103
108
|
#
|
|
104
109
|
# @return [Hash] the now-empty cache
|
|
105
|
-
def forget_all
|
|
110
|
+
def forget_all
|
|
111
|
+
LOCK.synchronize do
|
|
112
|
+
BLOCKS_BY_LINE.clear
|
|
113
|
+
TREES.clear
|
|
114
|
+
end
|
|
115
|
+
end
|
|
106
116
|
|
|
107
117
|
# Visits `node` and every descendant depth-first, calling `visit` on each.
|
|
108
118
|
#
|