hecks 3.5.0 → 3.6.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/examples/pizzas/bluebook/hecksagon/mock_stripe_payment_adapter.rb +1 -1
- data/lib/hecks/adapters/driven/claude_code.rb +11 -7
- data/lib/hecks/adapters/driven/d1/connection.rb +90 -0
- data/lib/hecks/adapters/driven/d1.rb +48 -314
- data/lib/hecks/adapters/driven/folder.rb +20 -10
- data/lib/hecks/adapters/driven/google_authentication.rb +18 -4
- data/lib/hecks/adapters/driven/governance_authorization.rb +2 -2
- data/lib/hecks/adapters/driven/heki/journal.rb +11 -10
- data/lib/hecks/adapters/driven/heki/saga_store.rb +4 -6
- data/lib/hecks/adapters/driven/heki/sagas.rb +55 -0
- data/lib/hecks/adapters/driven/heki.rb +21 -66
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +37 -12
- data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +1 -8
- data/lib/hecks/adapters/driven/memory/outbox_rows.rb +76 -0
- data/lib/hecks/adapters/driven/memory/shared_elements/values.rb +117 -0
- data/lib/hecks/adapters/driven/memory/shared_elements.rb +10 -97
- data/lib/hecks/adapters/driven/memory.rb +3 -65
- data/lib/hecks/adapters/driven/postgres/codec.rb +29 -26
- data/lib/hecks/adapters/driven/postgres/ddl.rb +50 -0
- data/lib/hecks/adapters/driven/postgres/dialect.rb +93 -0
- data/lib/hecks/adapters/driven/postgres/events.rb +57 -0
- data/lib/hecks/adapters/driven/postgres/journal.rb +127 -0
- data/lib/hecks/adapters/driven/postgres/outbox.rb +39 -31
- data/lib/hecks/adapters/driven/postgres/repository.rb +190 -0
- data/lib/hecks/adapters/driven/postgres/sagas.rb +72 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +13 -41
- data/lib/hecks/adapters/driven/postgres.rb +61 -528
- data/lib/hecks/adapters/driven/prism.rb +1 -1
- data/lib/hecks/adapters/driven/sql_query_builder.rb +45 -53
- data/lib/hecks/adapters/driven/sql_value_members.rb +57 -0
- data/lib/hecks/adapters/driven/sqlite/codec.rb +32 -29
- data/lib/hecks/adapters/driven/sqlite/ddl.rb +68 -0
- data/lib/hecks/adapters/driven/sqlite/dialect.rb +55 -0
- data/lib/hecks/adapters/driven/sqlite/events.rb +61 -0
- data/lib/hecks/adapters/driven/sqlite/journal.rb +125 -0
- data/lib/hecks/adapters/driven/sqlite/outbox.rb +98 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +82 -63
- data/lib/hecks/adapters/driven/sqlite/repository.rb +146 -0
- data/lib/hecks/adapters/driven/sqlite/sagas.rb +69 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +8 -55
- data/lib/hecks/adapters/driven/sqlite.rb +36 -513
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +13 -7
- data/lib/hecks/adapters/driving/github_webhook.rb +11 -8
- data/lib/hecks/behaviors/dsl.rb +17 -12
- data/lib/hecks/behaviors/expectations/boot.rb +81 -0
- data/lib/hecks/behaviors/expectations/checks.rb +178 -0
- data/lib/hecks/behaviors/expectations/dispatching.rb +93 -0
- data/lib/hecks/behaviors/expectations/qualify.rb +81 -0
- data/lib/hecks/behaviors/expectations.rb +39 -355
- data/lib/hecks/behaviors/rspec.rb +12 -12
- data/lib/hecks/behaviors/runner.rb +20 -11
- data/lib/hecks/bench/cli.rb +16 -13
- data/lib/hecks/bench/environment.rb +1 -1
- data/lib/hecks/bench/report.rb +11 -7
- data/lib/hecks/bench/ruby_runner.rb +13 -8
- data/lib/hecks/bench/rust_runner.rb +19 -11
- data/lib/hecks/bench/suite.rb +48 -20
- data/lib/hecks/bench/workload.rb +42 -31
- data/lib/hecks/bluebook/aggregate.rb +15 -21
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +18 -21
- data/lib/hecks/bluebook/assembly/build.rb +12 -7
- data/lib/hecks/bluebook/assembly/contracts/read_models.rb +70 -0
- data/lib/hecks/bluebook/assembly/contracts/rules.rb +84 -0
- data/lib/hecks/bluebook/assembly/contracts/sagas.rb +109 -0
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +91 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +9 -319
- data/lib/hecks/bluebook/assembly/marks.rb +9 -8
- data/lib/hecks/bluebook/attribute.rb +13 -10
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -3
- data/lib/hecks/bluebook/behaviour/read_model.rb +26 -13
- data/lib/hecks/bluebook/chapter.rb +22 -14
- data/lib/hecks/bluebook/command.rb +14 -18
- data/lib/hecks/bluebook/domain_port.rb +11 -8
- data/lib/hecks/bluebook/dsl/aggregate_builder/correction_sealing.rb +78 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/draining.rb +74 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/query_field_sealing.rb +105 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/query_sealing.rb +121 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +128 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/rules.rb +84 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +61 -249
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +51 -285
- data/lib/hecks/bluebook/dsl/attribute_collector/identity_resolution.rb +113 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +58 -117
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +24 -19
- data/lib/hecks/bluebook/dsl/bluebook_builder/pending_givens.rb +109 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +105 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/event_shapes.rb +126 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/hop_tails.rb +79 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +76 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +65 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/query_hops.rb +123 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/references.rb +112 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +126 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +34 -595
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +18 -107
- data/lib/hecks/bluebook/dsl/command_builder/implicit_attributes.rb +132 -0
- data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +190 -0
- data/lib/hecks/bluebook/dsl/command_builder/owner.rb +22 -0
- data/lib/hecks/bluebook/dsl/command_builder/rules.rb +57 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +60 -360
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +19 -13
- data/lib/hecks/bluebook/dsl/entity_builder/rules.rb +96 -0
- data/lib/hecks/bluebook/dsl/entity_builder/scope.rb +25 -0
- data/lib/hecks/bluebook/dsl/entity_builder/sealing.rb +94 -0
- data/lib/hecks/bluebook/dsl/entity_builder.rb +35 -169
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +53 -24
- data/lib/hecks/bluebook/dsl/hecksagon_builder/chapter_scope.rb +133 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +3 -97
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +73 -73
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +7 -3
- data/lib/hecks/bluebook/dsl/need_word.rb +1 -1
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +34 -29
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +57 -41
- data/lib/hecks/bluebook/dsl/query_builder.rb +12 -15
- data/lib/hecks/bluebook/dsl/read_model_builder/sealing.rb +116 -0
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +25 -102
- data/lib/hecks/bluebook/dsl/rule_reference.rb +26 -12
- data/lib/hecks/bluebook/dsl/translation_builder.rb +24 -14
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +29 -19
- data/lib/hecks/bluebook/dsl/word_gate.rb +34 -27
- data/lib/hecks/bluebook/entity.rb +13 -17
- data/lib/hecks/bluebook/expression/ast_json/emitters.rb +93 -0
- data/lib/hecks/bluebook/expression/ast_json/emitters.rb-e +88 -0
- data/lib/hecks/bluebook/expression/ast_json.rb +49 -76
- data/lib/hecks/bluebook/expression/ast_reader.rb +95 -28
- data/lib/hecks/bluebook/expression/canonical_form.rb +6 -26
- data/lib/hecks/bluebook/expression/evaluator/parser.rb +62 -0
- data/lib/hecks/bluebook/expression/evaluator/scanning.rb +122 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +11 -111
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +28 -44
- data/lib/hecks/bluebook/expression/resolver/lookups.rb +77 -0
- data/lib/hecks/bluebook/expression/resolver/operations.rb +78 -0
- data/lib/hecks/bluebook/expression/resolver/parsing.rb +110 -0
- data/lib/hecks/bluebook/expression/resolver/scanning.rb +139 -0
- data/lib/hecks/bluebook/expression/resolver/values.rb +115 -0
- data/lib/hecks/bluebook/expression/resolver.rb +16 -414
- data/lib/hecks/bluebook/{hexagon.rb → hecksagon.rb} +22 -14
- data/lib/hecks/bluebook/keyword_fields.rb +42 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +7 -6
- data/lib/hecks/bluebook/meta_validator/judge/cells.rb +99 -0
- data/lib/hecks/bluebook/meta_validator/judge/dispatching.rb +111 -0
- data/lib/hecks/bluebook/meta_validator/judge/identity.rb +108 -0
- data/lib/hecks/bluebook/meta_validator/judge/walking.rb +141 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +31 -376
- data/lib/hecks/bluebook/meta_validator/modes.rb +137 -0
- data/lib/hecks/bluebook/meta_validator/plan/category.rb +44 -0
- data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +73 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +38 -122
- data/lib/hecks/bluebook/meta_validator/readings/fields.rb +100 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +10 -95
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +89 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +96 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -151
- data/lib/hecks/bluebook/meta_validator/shapes/helpers.rb +83 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +8 -75
- data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +77 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +31 -95
- data/lib/hecks/bluebook/meta_validator/translation_judge/rules.rb +74 -0
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +15 -65
- data/lib/hecks/bluebook/meta_validator/verdict_cache/tagging.rb +63 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +22 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +8 -4
- data/lib/hecks/bluebook/meta_validator.rb +59 -175
- data/lib/hecks/bluebook/model_check/lifecycle_checks.rb +122 -0
- data/lib/hecks/bluebook/model_check/policy_checks.rb +129 -0
- data/lib/hecks/bluebook/model_check/saga_checks.rb +134 -0
- data/lib/hecks/bluebook/model_check/verbs.rb +69 -0
- data/lib/hecks/bluebook/model_check.rb +73 -413
- data/lib/hecks/bluebook/pattern_subset/refusals.rb +54 -0
- data/lib/hecks/bluebook/pattern_subset/scan.rb +58 -0
- data/lib/hecks/bluebook/pattern_subset.rb +93 -134
- data/lib/hecks/bluebook/process_manager.rb +10 -9
- data/lib/hecks/bluebook/project_discovery.rb +10 -7
- data/lib/hecks/bluebook/project_register.rb +42 -41
- data/lib/hecks/bluebook/query.rb +19 -12
- data/lib/hecks/bluebook/read_model.rb +41 -39
- data/lib/hecks/bluebook/smoke_test.rb +51 -36
- data/lib/hecks/bluebook/synthesizer.rb +13 -5
- data/lib/hecks/bluebook/translation.rb +12 -12
- data/lib/hecks/bluebook.rb +1 -1
- data/lib/hecks/chapters.rb +32 -16
- data/lib/hecks/cli/behaviors.rb +22 -15
- data/lib/hecks/cli/check_era.rb +2 -2
- data/lib/hecks/cli/command_table.rb +72 -0
- data/lib/hecks/cli/console.rb +10 -7
- data/lib/hecks/cli/deploy_template_diff.rb +22 -9
- data/lib/hecks/cli/document.rb +14 -10
- data/lib/hecks/cli/domain_stub.rb +1 -1
- data/lib/hecks/cli/domain_writer.rb +1 -1
- data/lib/hecks/cli/expression_projection.rb +8 -6
- data/lib/hecks/cli/follow.rb +10 -4
- data/lib/hecks/cli/interview_aggregate.rb +132 -0
- data/lib/hecks/cli/interview_draft.rb +16 -200
- data/lib/hecks/cli/interview_record.rb +130 -0
- data/lib/hecks/cli/interview_run.rb +19 -8
- data/lib/hecks/cli/interview_session/agent_state.rb +70 -0
- data/lib/hecks/cli/interview_session/catalog.rb +76 -0
- data/lib/hecks/cli/interview_session/manual_findings.rb +48 -0
- data/lib/hecks/cli/interview_session/proposals.rb +90 -0
- data/lib/hecks/cli/interview_session.rb +8 -205
- data/lib/hecks/cli/interview_shape.rb +13 -6
- data/lib/hecks/cli/ir.rb +8 -11
- data/lib/hecks/cli/launcher_words.rb +168 -0
- data/lib/hecks/cli/model_check/examination.rb +93 -0
- data/lib/hecks/cli/model_check/sources.rb +57 -0
- data/lib/hecks/cli/model_check.rb +28 -134
- data/lib/hecks/cli/project_cli/launcher_source.rb +177 -0
- data/lib/hecks/cli/project_cli/templates.rb +106 -0
- data/lib/hecks/cli/project_cli.rb +57 -236
- data/lib/hecks/cli/project_diagrams.rb +26 -4
- data/lib/hecks/cli/project_glossary.rb +19 -9
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +29 -13
- data/lib/hecks/cli/release.rb +29 -22
- data/lib/hecks/cli/release_gem.rb +12 -6
- data/lib/hecks/cli/rspec_io_parallel_files.rb +87 -30
- data/lib/hecks/cli/rspec_shard_files.rb +24 -9
- data/lib/hecks/cli/run.rb +25 -44
- data/lib/hecks/cli/run_expectations.rb +63 -0
- data/lib/hecks/cli/seed_semantics_corpus.rb +37 -17
- data/lib/hecks/cli/smoke_http/checks.rb +66 -0
- data/lib/hecks/cli/smoke_http/settings.rb +63 -0
- data/lib/hecks/cli/smoke_http/transport.rb +45 -0
- data/lib/hecks/cli/smoke_http.rb +8 -142
- data/lib/hecks/cli/smoke_test.rb +18 -4
- data/lib/hecks/cli/stores.rb +7 -4
- data/lib/hecks/cli/stress_concurrency_specs/reporting.rb +44 -0
- data/lib/hecks/cli/stress_concurrency_specs/usage.rb +28 -0
- data/lib/hecks/cli/stress_concurrency_specs.rb +82 -80
- data/lib/hecks/cli.rb +32 -208
- data/lib/hecks/codemod/runner.rb +92 -0
- data/lib/hecks/codemod/sweep.rb +94 -0
- data/lib/hecks/codemod.rb +22 -165
- data/lib/hecks/corpus/routes.rb +34 -0
- data/lib/hecks/corpus/rust.rb +193 -0
- data/lib/hecks/corpus/sources.rb +46 -0
- data/lib/hecks/corpus.rb +28 -265
- data/lib/hecks/doc/reference/coverage.rb +70 -0
- data/lib/hecks/doc/reference/harvester.rb +55 -0
- data/lib/hecks/doc/reference/readme.rb +89 -0
- data/lib/hecks/doc/reference/rendering.rb +149 -0
- data/lib/hecks/doc/reference.rb +14 -273
- data/lib/hecks/doors/cli_door/nesting.rb +34 -0
- data/lib/hecks/doors/cli_door/shorthand.rb +85 -0
- data/lib/hecks/doors/cli_door.rb +23 -95
- data/lib/hecks/doors/cli_runner/answers.rb +138 -0
- data/lib/hecks/doors/cli_runner/resolution.rb +146 -0
- data/lib/hecks/doors/cli_runner/settling.rb +115 -0
- data/lib/hecks/doors/cli_runner/streaming.rb +90 -0
- data/lib/hecks/doors/cli_runner/suggestions.rb +43 -0
- data/lib/hecks/doors/cli_runner.rb +12 -336
- data/lib/hecks/doors/command_request.rb +42 -31
- data/lib/hecks/doors/handle.rb +32 -30
- data/lib/hecks/doors/launcher_options.rb +62 -7
- data/lib/hecks/doors/mcp_door/properties.rb +47 -0
- data/lib/hecks/doors/mcp_door/tool_calls.rb +113 -0
- data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +51 -0
- data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +69 -0
- data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +97 -0
- data/lib/hecks/doors/mcp_door/tool_definitions.rb +15 -0
- data/lib/hecks/doors/mcp_door.rb +55 -301
- data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +92 -0
- data/lib/hecks/doors/mcp_door_scope/env_problems.rb +55 -0
- data/lib/hecks/doors/mcp_door_scope/presenter.rb +78 -0
- data/lib/hecks/doors/mcp_door_scope.rb +16 -172
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +1 -1
- data/lib/hecks/doors/ruby_door/chapter.rb +33 -16
- data/lib/hecks/doors/ruby_door.rb +14 -11
- data/lib/hecks/doors/usage_cache.rb +14 -8
- data/lib/hecks/doors.rb +10 -4
- data/lib/hecks/embryonaut_bluebook/manifest.rb +11 -3
- data/lib/hecks/embryonaut_bluebook/registry/changelog.rb +26 -0
- data/lib/hecks/embryonaut_bluebook/registry/versions.rb +27 -0
- data/lib/hecks/embryonaut_bluebook/registry.rb +27 -37
- data/lib/hecks/embryonaut_bluebook/vendor/acceptance.rb +37 -0
- data/lib/hecks/embryonaut_bluebook/vendor.rb +22 -36
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +9 -6
- data/lib/hecks/embryonaut_bluebook.rb +16 -11
- data/lib/hecks/engine_agreement.rb +24 -17
- data/lib/hecks/forms/app/commands.rb +98 -0
- data/lib/hecks/forms/app/queries.rb +62 -0
- data/lib/hecks/forms/app/records.rb +67 -0
- data/lib/hecks/forms/app/responses.rb +46 -0
- data/lib/hecks/forms/app.rb +33 -221
- data/lib/hecks/forms/banking_presentation.rb +5 -0
- data/lib/hecks/forms/command_form_renderer.rb +55 -14
- data/lib/hecks/forms/field_controls.rb +95 -0
- data/lib/hecks/forms/field_renderer.rb +34 -88
- data/lib/hecks/forms/field_shape.rb +9 -34
- data/lib/hecks/forms/html.rb +1 -1
- data/lib/hecks/forms/index_renderer.rb +14 -9
- data/lib/hecks/forms/page.rb +2 -106
- data/lib/hecks/forms/page_assets.rb +88 -0
- data/lib/hecks/forms/page_script.rb +28 -0
- data/lib/hecks/forms/params.rb +17 -8
- data/lib/hecks/forms/query_form_renderer.rb +11 -7
- data/lib/hecks/forms/record_renderer.rb +28 -19
- data/lib/hecks/forms/reference_options.rb +1 -1
- data/lib/hecks/forms/text_shape.rb +40 -0
- data/lib/hecks/fqn.rb +64 -32
- data/lib/hecks/framework.rb +10 -3
- data/lib/hecks/freezer.rb +10 -1
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions/fragments.rb +61 -0
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions/productions.rb +217 -0
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +5 -194
- data/lib/hecks/fuzzing/combination_miner.rb +23 -12
- data/lib/hecks/fuzzing/concurrent_dispatch/racing.rb +64 -0
- data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +66 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +31 -107
- data/lib/hecks/fuzzing/coverage_campaign.rb +7 -7
- data/lib/hecks/fuzzing/differential/wire_comparison.rb +74 -0
- data/lib/hecks/fuzzing/differential.rb +59 -84
- data/lib/hecks/fuzzing/domain_generator/block_rendering.rb +70 -0
- data/lib/hecks/fuzzing/domain_generator/builder/attribute_shapes.rb +105 -0
- data/lib/hecks/fuzzing/domain_generator/builder/shapes.rb +97 -0
- data/lib/hecks/fuzzing/domain_generator/builder/wiring.rb +128 -0
- data/lib/hecks/fuzzing/domain_generator/builder.rb +105 -0
- data/lib/hecks/fuzzing/domain_generator/pruning.rb +90 -0
- data/lib/hecks/fuzzing/domain_generator/removals.rb +62 -0
- data/lib/hecks/fuzzing/domain_generator/rendering.rb +94 -0
- data/lib/hecks/fuzzing/domain_generator/tokens.rb +38 -0
- data/lib/hecks/fuzzing/domain_generator.rb +7 -555
- data/lib/hecks/fuzzing/era_boundary.rb +34 -24
- data/lib/hecks/fuzzing/form_census.rb +18 -8
- data/lib/hecks/fuzzing/generated_domain_check.rb +23 -11
- data/lib/hecks/fuzzing/isolated_boot/copying.rb +62 -0
- data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +133 -0
- data/lib/hecks/fuzzing/isolated_boot/worlds.rb +102 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +25 -252
- data/lib/hecks/fuzzing/persistence_parity.rb +5 -5
- data/lib/hecks/fuzzing/properties/aggregation_recompute.rb +121 -0
- data/lib/hecks/fuzzing/properties/catalog.rb +138 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +23 -20
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +64 -185
- data/lib/hecks/fuzzing/properties/group_by_recompute.rb +69 -0
- data/lib/hecks/fuzzing/properties/guards.rb +76 -108
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +66 -227
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +46 -35
- data/lib/hecks/fuzzing/properties/mutation_recompute.rb +162 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +41 -24
- data/lib/hecks/fuzzing/properties/piece_invariants.rb +61 -0
- data/lib/hecks/fuzzing/properties/policy_wiring.rb +140 -0
- data/lib/hecks/fuzzing/properties/query_rows.rb +67 -0
- data/lib/hecks/fuzzing/properties/querying.rb +69 -90
- data/lib/hecks/fuzzing/properties/references.rb +100 -0
- data/lib/hecks/fuzzing/properties/tenant_scope.rb +84 -0
- data/lib/hecks/fuzzing/properties.rb +6 -119
- data/lib/hecks/fuzzing/qa_settings.rb +23 -17
- data/lib/hecks/fuzzing/replay/fan_out.rb +78 -0
- data/lib/hecks/fuzzing/replay/filters.rb +72 -0
- data/lib/hecks/fuzzing/replay/guard_check.rb +88 -0
- data/lib/hecks/fuzzing/replay/mutation_trace.rb +117 -0
- data/lib/hecks/fuzzing/replay/observation.rb +60 -0
- data/lib/hecks/fuzzing/replay/read_only_steps.rb +84 -0
- data/lib/hecks/fuzzing/replay/session.rb +151 -0
- data/lib/hecks/fuzzing/replay.rb +35 -442
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +3 -4
- data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +133 -0
- data/lib/hecks/fuzzing/self_consistency/sagas.rb +93 -0
- data/lib/hecks/fuzzing/self_consistency/value_objects.rb +87 -0
- data/lib/hecks/fuzzing/self_consistency.rb +8 -213
- data/lib/hecks/fuzzing/sequence_generator/adversary/argument_mutations.rb +116 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary/caller_draw.rb +68 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary/identity_mutations.rb +62 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary/precedence_mutations.rb +126 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +23 -283
- data/lib/hecks/fuzzing/sequence_generator/argument_drawing.rb +78 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +69 -53
- data/lib/hecks/fuzzing/sequence_generator/identity_shaping.rb +85 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +20 -16
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +12 -6
- data/lib/hecks/fuzzing/sequence_generator/prefixing.rb +45 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +19 -8
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +43 -144
- data/lib/hecks/fuzzing/sequence_generator.rb +65 -63
- data/lib/hecks/fuzzing/shrinker.rb +33 -29
- data/lib/hecks/fuzzing/target_capabilities.rb +10 -4
- data/lib/hecks/fuzzing/value_generator.rb +27 -17
- data/lib/hecks/gate/stages.yml +10 -0
- data/lib/hecks/grammar/evolve/arguments.rb +90 -0
- data/lib/hecks/grammar/evolve/keywords.rb +81 -0
- data/lib/hecks/grammar/evolve/seeds.rb +172 -0
- data/lib/hecks/grammar/evolve.rb +22 -263
- data/lib/hecks/grammar/operators.rb +111 -0
- data/lib/hecks/grammar.rb +53 -126
- data/lib/hecks/hecks/adapters/bluebook_report.rb +6 -6
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +23 -9
- data/lib/hecks/hecks/adapters/codebase/language/edits.rb +75 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +30 -72
- data/lib/hecks/hecks/adapters/codebase/promotion/candidates.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/gate.rb +50 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/move.rb +70 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/standing.rb +88 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/watch.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/promotion.rb +115 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +31 -12
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +43 -6
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +16 -5
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +9 -1
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/style.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +11 -5
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +27 -8
- data/lib/hecks/hecks/adapters/console_capture.rb +21 -17
- data/lib/hecks/hecks/adapters/cost_explorer.rb +11 -6
- data/lib/hecks/hecks/adapters/deploy_plans.rb +3 -3
- data/lib/hecks/hecks/adapters/deploy_toolchain/answers.rb +141 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/scripts.rb +95 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +74 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +21 -239
- data/lib/hecks/hecks/adapters/finding_github.rb +2 -2
- data/lib/hecks/hecks/adapters/first_admin.rb +22 -8
- data/lib/hecks/hecks/adapters/git.rb +18 -5
- data/lib/hecks/hecks/adapters/git_refs.rb +144 -0
- data/lib/hecks/hecks/adapters/github_rulesets.rb +126 -0
- data/lib/hecks/hecks/adapters/host_http.rb +16 -6
- data/lib/hecks/hecks/adapters/in_process_boot.rb +9 -5
- data/lib/hecks/hecks/adapters/in_process_operations/tailing.rb +61 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +33 -35
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +21 -15
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +29 -12
- data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +52 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +52 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +5 -62
- data/lib/hecks/hecks/adapters/local_files.rb +27 -10
- data/lib/hecks/hecks/adapters/pg_admin/ownership.rb +115 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +14 -87
- data/lib/hecks/hecks/adapters/process_pool.rb +54 -22
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +12 -4
- data/lib/hecks/hecks/adapters/site_toolchain.rb +16 -7
- data/lib/hecks/hecks/adapters/terminal.rb +13 -9
- data/lib/hecks/hecks/codebase.bluebook +322 -5
- data/lib/hecks/hecks/hecks.hecksagon +16 -0
- data/lib/hecks/hecks/hecks.world +10 -2
- data/lib/hecks/kernel_capabilities/templates.rb +92 -0
- data/lib/hecks/kernel_capabilities.rb +18 -85
- data/lib/hecks/language/bluebook/vocabulary.bluebook +43 -1
- data/lib/hecks/literal/item_splitter.rb +50 -0
- data/lib/hecks/literal.rb +29 -38
- data/lib/hecks/mcp_stdio_guard.rb +8 -8
- data/lib/hecks/naming.rb +9 -3
- data/lib/hecks/persistence_legacy_fixture/postgres_stores.rb +81 -0
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +26 -66
- data/lib/hecks/persistence_legacy_fixture.rb +13 -10
- data/lib/hecks/ports/access_control.rb +13 -10
- data/lib/hecks/ports/agent/answers.rb +2 -2
- data/lib/hecks/ports/agent.rb +13 -10
- data/lib/hecks/ports/authentication.rb +13 -10
- data/lib/hecks/ports/authorization.rb +13 -10
- data/lib/hecks/ports/clock.rb +13 -10
- data/lib/hecks/ports/extraction.rb +13 -12
- data/lib/hecks/ports/identity_assignment.rb +13 -10
- data/lib/hecks/ports/identity_generation.rb +13 -10
- data/lib/hecks/ports/identity_resolution.rb +13 -10
- data/lib/hecks/ports/key_vault.rb +13 -10
- data/lib/hecks/ports/persistence/append_only.rb +5 -5
- data/lib/hecks/ports/persistence/binding_policy.rb +33 -9
- data/lib/hecks/ports/persistence/codec_boundary.rb +22 -11
- data/lib/hecks/ports/persistence/constants.rb +10 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +18 -16
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +27 -18
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +52 -23
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +14 -8
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +17 -6
- data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +58 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +130 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +25 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +20 -180
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +41 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/class_methods.rb +105 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/dialect.rb +137 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +25 -28
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/head_writes.rb +62 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/journal.rb +128 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/chain_sql.rb +169 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +91 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_integrity.rb +99 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +0 -73
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +55 -39
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +51 -222
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/merge_writes.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +85 -60
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +97 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +19 -19
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/sql_templates.rb +88 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +77 -118
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +3 -117
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_sql.rb +116 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +3 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/context.rb +38 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +43 -25
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +62 -38
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +21 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +66 -86
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +75 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +27 -9
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/query_phases.rb +63 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/sagas.rb +78 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +28 -482
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +40 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +22 -15
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +39 -19
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -16
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +48 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +60 -99
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/path_diff.rb +57 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +21 -11
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +13 -4
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +4 -2
- data/lib/hecks/ports/persistence/postgres_dump.rb +13 -7
- data/lib/hecks/ports/persistence/repository_factory.rb +35 -11
- data/lib/hecks/ports/persistence/state_codec.rb +10 -0
- data/lib/hecks/ports/persistence.rb +1 -10
- data/lib/hecks/ports/projection.rb +34 -21
- data/lib/hecks/ports/query/in_memory.rb +16 -8
- data/lib/hecks/projection_files/expression_tables.rb +64 -0
- data/lib/hecks/projection_files/texts.rb +67 -0
- data/lib/hecks/projection_files.rb +19 -103
- data/lib/hecks/projections/bootstrap_table.rb +43 -29
- data/lib/hecks/projections/deploy/bastion_lines.rb +32 -0
- data/lib/hecks/projections/deploy/box/access.rb +73 -0
- data/lib/hecks/projections/deploy/box/caddy.rb +87 -0
- data/lib/hecks/projections/deploy/box/compose.rb +70 -0
- data/lib/hecks/projections/deploy/box/hosting.rb +4 -105
- data/lib/hecks/projections/deploy/box/hosting_parts.rb +97 -0
- data/lib/hecks/projections/deploy/box/hosting_settings.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_scripts.rb +135 -0
- data/lib/hecks/projections/deploy/box/settings/checks.rb +38 -0
- data/lib/hecks/projections/deploy/box/settings/containers.rb +123 -0
- data/lib/hecks/projections/deploy/box/settings/origin.rb +56 -0
- data/lib/hecks/projections/deploy/box/settings/patterns.rb +43 -0
- data/lib/hecks/projections/deploy/box/settings/types.rb +72 -0
- data/lib/hecks/projections/deploy/box/settings.rb +58 -263
- data/lib/hecks/projections/deploy/box/stack_yaml.rb +107 -0
- data/lib/hecks/projections/deploy/box/templates/MIGRATION.md.tmpl +39 -0
- data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +24 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +41 -1
- data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +2 -1
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +2 -1
- data/lib/hecks/projections/deploy/box/templates/deploy-usage-services.tmpl +4 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-usage-taskdef.tmpl +5 -0
- data/lib/hecks/projections/deploy/box/templates/ecr-repository.yaml.tmpl +9 -0
- data/lib/hecks/projections/deploy/box/templates/mode-summary-services.tmpl +2 -0
- data/lib/hecks/projections/deploy/box/templates/mode-summary-taskdef.tmpl +4 -0
- data/lib/hecks/projections/deploy/box/templates/services-block.tmpl +9 -0
- data/lib/hecks/projections/deploy/box/templates/tunnel-egress.yaml.tmpl +11 -0
- data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
- data/lib/hecks/projections/deploy/box.rb +33 -493
- data/lib/hecks/projections/deploy/fargate/assembly.rb +13 -142
- data/lib/hecks/projections/deploy/fargate/cdn/behaviors.rb +76 -0
- data/lib/hecks/projections/deploy/fargate/cdn/lines.rb +112 -0
- data/lib/hecks/projections/deploy/fargate/cdn/options.rb +85 -0
- data/lib/hecks/projections/deploy/fargate/cdn.rb +23 -215
- data/lib/hecks/projections/deploy/fargate/check.rb +16 -6
- data/lib/hecks/projections/deploy/fargate/containers/definition_lines.rb +61 -0
- data/lib/hecks/projections/deploy/fargate/containers/reading.rb +86 -0
- data/lib/hecks/projections/deploy/fargate/containers/rendering.rb +132 -0
- data/lib/hecks/projections/deploy/fargate/containers/routing.rb +93 -0
- data/lib/hecks/projections/deploy/fargate/containers.rb +10 -286
- data/lib/hecks/projections/deploy/fargate/extras/reading.rb +90 -0
- data/lib/hecks/projections/deploy/fargate/extras/rendering.rb +81 -0
- data/lib/hecks/projections/deploy/fargate/extras.rb +9 -158
- data/lib/hecks/projections/deploy/fargate/monitoring/alarms.rb +115 -0
- data/lib/hecks/projections/deploy/fargate/monitoring/reading.rb +84 -0
- data/lib/hecks/projections/deploy/fargate/monitoring/topic.rb +59 -0
- data/lib/hecks/projections/deploy/fargate/monitoring/warmer.rb +90 -0
- data/lib/hecks/projections/deploy/fargate/monitoring/warmer_roles.rb +76 -0
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +14 -348
- data/lib/hecks/projections/deploy/fargate/sections.rb +115 -0
- data/lib/hecks/projections/deploy/fargate/settings/ids.rb +55 -0
- data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +77 -0
- data/lib/hecks/projections/deploy/fargate/settings.rb +17 -104
- data/lib/hecks/projections/deploy/fargate/stack/blocks.rb +91 -0
- data/lib/hecks/projections/deploy/fargate/stack/readers.rb +87 -0
- data/lib/hecks/projections/deploy/fargate/stack/recipes.rb +106 -0
- data/lib/hecks/projections/deploy/fargate/stack.rb +146 -0
- data/lib/hecks/projections/deploy/fargate/task_sections.rb +56 -0
- data/lib/hecks/projections/deploy/fargate/yaml.rb +1 -1
- data/lib/hecks/projections/deploy/fargate.rb +51 -756
- data/lib/hecks/projections/deploy/lambda/pii.rb +49 -0
- data/lib/hecks/projections/deploy/lambda/stack/blocks.rb +118 -0
- data/lib/hecks/projections/deploy/lambda/stack/checks.rb +64 -0
- data/lib/hecks/projections/deploy/lambda/stack/deploy_chain.rb +119 -0
- data/lib/hecks/projections/deploy/lambda/stack/readers.rb +62 -0
- data/lib/hecks/projections/deploy/lambda/stack/reading.rb +170 -0
- data/lib/hecks/projections/deploy/lambda/stack/reading_web.rb +53 -0
- data/lib/hecks/projections/deploy/lambda/stack/recipes.rb +112 -0
- data/lib/hecks/projections/deploy/lambda/stack/web.rb +57 -0
- data/lib/hecks/projections/deploy/lambda/stack.rb +54 -0
- data/lib/hecks/projections/deploy/lambda.rb +77 -1885
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +8 -74
- data/lib/hecks/projections/deploy/preview/containers.rb +18 -7
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +15 -87
- data/lib/hecks/projections/deploy/preview/settings.rb +7 -4
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +42 -106
- data/lib/hecks/projections/deploy/preview/template.rb +11 -106
- data/lib/hecks/projections/deploy/preview/yaml_text.rb +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/settings.rb +14 -6
- data/lib/hecks/projections/deploy/scripts.rb +11 -9
- data/lib/hecks/projections/deploy/shared/rows.rb +48 -0
- data/lib/hecks/projections/deploy/shared.rb +89 -449
- data/lib/hecks/projections/deploy/smoke.rb +15 -10
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +21 -147
- data/lib/hecks/projections/deploy/template_diff/normalizer.rb +60 -0
- data/lib/hecks/projections/deploy/template_diff/value_diff.rb +136 -0
- data/lib/hecks/projections/deploy/template_diff.rb +8 -3
- data/lib/hecks/projections/deploy/templates/fargate/Dockerfile.tmpl +28 -0
- data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +63 -0
- data/lib/hecks/projections/deploy/templates/fargate/always_params.tmpl +4 -0
- data/lib/hecks/projections/deploy/templates/fargate/deploy_plain.tmpl +1 -0
- data/lib/hecks/projections/deploy/templates/fargate/deploy_shared.tmpl +11 -0
- data/lib/hecks/projections/deploy/templates/fargate/mint_era_own.tmpl +44 -0
- data/lib/hecks/projections/deploy/templates/fargate/mint_era_shared.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/fargate/missing_owner.tmpl +9 -0
- data/lib/hecks/projections/deploy/templates/fargate/oauth_params.tmpl +7 -0
- data/lib/hecks/projections/deploy/templates/fargate/oauth_task_env.tmpl +4 -0
- data/lib/hecks/projections/deploy/templates/fargate/oauth_task_policy.tmpl +7 -0
- data/lib/hecks/projections/deploy/templates/fargate/owning_params.tmpl +33 -0
- data/lib/hecks/projections/deploy/templates/fargate/template.yaml.tmpl +281 -0
- data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +218 -0
- data/lib/hecks/projections/deploy/templates/lambda/aurora_depends.tmpl +18 -0
- data/lib/hecks/projections/deploy/templates/lambda/build_dispatch_none.tmpl +10 -0
- data/lib/hecks/projections/deploy/templates/lambda/build_pg.tmpl +15 -0
- data/lib/hecks/projections/deploy/templates/lambda/build_plain.tmpl +2 -0
- data/lib/hecks/projections/deploy/templates/lambda/build_web.tmpl +11 -0
- data/lib/hecks/projections/deploy/templates/lambda/env_blind_guard.tmpl +4 -0
- data/lib/hecks/projections/deploy/templates/lambda/mint_era_own.tmpl +122 -0
- data/lib/hecks/projections/deploy/templates/lambda/mint_era_shared.tmpl +47 -0
- data/lib/hecks/projections/deploy/templates/lambda/missing_owner.tmpl +9 -0
- data/lib/hecks/projections/deploy/templates/lambda/nat_comment_oauth.tmpl +14 -0
- data/lib/hecks/projections/deploy/templates/lambda/nat_comment_plain.tmpl +3 -0
- data/lib/hecks/projections/deploy/templates/lambda/oauth_note.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/lambda/params_oauth.tmpl +13 -0
- data/lib/hecks/projections/deploy/templates/lambda/params_shared.tmpl +33 -0
- data/lib/hecks/projections/deploy/templates/lambda/pg_native.tmpl +71 -0
- data/lib/hecks/projections/deploy/templates/lambda/pii_oac.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/lambda/pii_permission.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/lambda/pii_resources.tmpl +116 -0
- data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge.tmpl +30 -0
- data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_oauth.tmpl +12 -0
- data/lib/hecks/projections/deploy/templates/lambda/predeploy_bridge_plain.tmpl +7 -0
- data/lib/hecks/projections/deploy/templates/lambda/rename_schema_own.tmpl +93 -0
- data/lib/hecks/projections/deploy/templates/lambda/rename_schema_shared.tmpl +7 -0
- data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_env.tmpl +17 -0
- data/lib/hecks/projections/deploy/templates/lambda/rust_oauth_policy.tmpl +16 -0
- data/lib/hecks/projections/deploy/templates/lambda/rust_session_secret.tmpl +13 -0
- data/lib/hecks/projections/deploy/templates/lambda/samconfig.toml.tmpl +12 -0
- data/lib/hecks/projections/deploy/templates/lambda/shared_note.tmpl +6 -0
- data/lib/hecks/projections/deploy/templates/lambda/sync_oauth.tmpl +23 -0
- data/lib/hecks/projections/deploy/templates/lambda/template.yaml.tmpl +187 -0
- data/lib/hecks/projections/deploy/templates/lambda/translation_own.tmpl +46 -0
- data/lib/hecks/projections/deploy/templates/lambda/translation_shared.tmpl +2 -0
- data/lib/hecks/projections/deploy/templates/lambda/web_function.tmpl +207 -0
- data/lib/hecks/projections/deploy/templates/lambda/web_google_oauth_env.tmpl +12 -0
- data/lib/hecks/projections/deploy/templates/lambda/web_no_oauth_env.tmpl +7 -0
- data/lib/hecks/projections/deploy/templates/lambda/web_oauth_policy.tmpl +4 -0
- data/lib/hecks/projections/deploy/templates/lambda/webhook_secret_resource.tmpl +20 -0
- data/lib/hecks/projections/deploy/templates/preview/alb.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/preview/alb_security_group.tmpl +11 -0
- data/lib/hecks/projections/deploy/templates/preview/assume_role.tmpl +6 -0
- data/lib/hecks/projections/deploy/templates/preview/base_parameters.tmpl +24 -0
- data/lib/hecks/projections/deploy/templates/preview/cluster.tmpl +4 -0
- data/lib/hecks/projections/deploy/templates/preview/container_secret.tmpl +9 -0
- data/lib/hecks/projections/deploy/templates/preview/db_init_script.sh.tmpl +23 -0
- data/lib/hecks/projections/deploy/templates/preview/db_init_secrets.tmpl +5 -0
- data/lib/hecks/projections/deploy/templates/preview/db_init_task.tmpl +39 -0
- data/lib/hecks/projections/deploy/templates/preview/desired_count.tmpl +5 -0
- data/lib/hecks/projections/deploy/templates/preview/distribution.tmpl +24 -0
- data/lib/hecks/projections/deploy/templates/preview/execution_role.tmpl +16 -0
- data/lib/hecks/projections/deploy/templates/preview/header.tmpl +16 -0
- data/lib/hecks/projections/deploy/templates/preview/ingress.tmpl +8 -0
- data/lib/hecks/projections/deploy/templates/preview/listener.tmpl +9 -0
- data/lib/hecks/projections/deploy/templates/preview/listener_rule.tmpl +11 -0
- data/lib/hecks/projections/deploy/templates/preview/log_group.tmpl +5 -0
- data/lib/hecks/projections/deploy/templates/preview/log_options.tmpl +5 -0
- data/lib/hecks/projections/deploy/templates/preview/outputs.tmpl +14 -0
- data/lib/hecks/projections/deploy/templates/preview/service.tmpl +17 -0
- data/lib/hecks/projections/deploy/templates/preview/session_secret.tmpl +11 -0
- data/lib/hecks/projections/deploy/templates/preview/target_group.tmpl +9 -0
- data/lib/hecks/projections/deploy/templates/preview/task_definition.tmpl +15 -0
- data/lib/hecks/projections/deploy/templates/preview/task_role.tmpl +22 -0
- data/lib/hecks/projections/deploy/templates/shared/aurora_db.tmpl +52 -0
- data/lib/hecks/projections/deploy/templates/shared/bastion.tmpl +74 -0
- data/lib/hecks/projections/deploy/templates/shared/bastion_own_public.tmpl +41 -0
- data/lib/hecks/projections/deploy/templates/shared/bastion_reuse_public.tmpl +10 -0
- data/lib/hecks/projections/deploy/templates/shared/nat_gateway.tmpl +102 -0
- data/lib/hecks/projections/deploy/templates/shared/oauth_egress.tmpl +17 -0
- data/lib/hecks/projections/deploy/templates/shared/plain_db.tmpl +16 -0
- data/lib/hecks/projections/deploy/templates/shared/vpc_and_database.tmpl +67 -0
- data/lib/hecks/projections/deploy/text_template.rb +35 -0
- data/lib/hecks/projections/diagrams/dispatch.rb +114 -0
- data/lib/hecks/projections/diagrams/statecharts.rb +59 -0
- data/lib/hecks/projections/diagrams/structure.rb +114 -0
- data/lib/hecks/projections/diagrams.rb +33 -256
- data/lib/hecks/projections/glossary/entries.rb +140 -0
- data/lib/hecks/projections/glossary/html/page.rb +96 -0
- data/lib/hecks/projections/glossary/html/parser.rb +66 -0
- data/lib/hecks/projections/glossary/html/sections.rb +78 -0
- data/lib/hecks/projections/glossary/html.rb +7 -179
- data/lib/hecks/projections/glossary/index.rb +45 -0
- data/lib/hecks/projections/glossary/markdown.rb +22 -11
- data/lib/hecks/projections/glossary/mermaid.rb +44 -31
- data/lib/hecks/projections/glossary/sensitivity.rb +7 -4
- data/lib/hecks/projections/glossary/sentences/value_objects.rb +77 -0
- data/lib/hecks/projections/glossary/sentences.rb +42 -81
- data/lib/hecks/projections/glossary/slugs.rb +33 -0
- data/lib/hecks/projections/glossary.rb +22 -190
- data/lib/hecks/projections/model.rb +20 -14
- data/lib/hecks/projections/rust_vocabulary/arguments/support.rb +33 -0
- data/lib/hecks/projections/rust_vocabulary/arguments.rb +171 -0
- data/lib/hecks/projections/rust_vocabulary/enum_body.rb +114 -0
- data/lib/hecks/projections/rust_vocabulary/tests.rb +144 -0
- data/lib/hecks/projections/rust_vocabulary.rb +24 -293
- data/lib/hecks/projections/site/admin.rb +15 -9
- data/lib/hecks/projections/site/admin_cms/templates/membership.rb +115 -0
- data/lib/hecks/projections/site/admin_cms/templates/session_strategy.rb +90 -0
- data/lib/hecks/projections/site/admin_cms/templates/sso.rb +101 -0
- data/lib/hecks/projections/site/admin_cms/templates/sso_tail.rb +54 -0
- data/lib/hecks/projections/site/admin_cms/templates/users.rb +83 -0
- data/lib/hecks/projections/site/admin_cms/templates.rb +14 -369
- data/lib/hecks/projections/site/admin_cms.rb +15 -9
- data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
- data/lib/hecks/projections/site/edge/checks.rb +30 -80
- data/lib/hecks/projections/site/edge/findings.rb +28 -0
- data/lib/hecks/projections/site/edge/route_checks.rb +110 -0
- data/lib/hecks/projections/site/edge/row_reader.rb +52 -0
- data/lib/hecks/projections/site/edge/rules.rb +28 -26
- data/lib/hecks/projections/site/edge.rb +20 -31
- data/lib/hecks/projections/site/live_edge.rb +9 -7
- data/lib/hecks/projections/site/payload/fields/definitions.rb +90 -0
- data/lib/hecks/projections/site/payload/fields/readers.rb +69 -0
- data/lib/hecks/projections/site/payload/fields.rb +14 -111
- data/lib/hecks/projections/site/payload/lifecycle/text.rb +84 -0
- data/lib/hecks/projections/site/payload/lifecycle/text_tail.rb +106 -0
- data/lib/hecks/projections/site/payload/lifecycle.rb +8 -166
- data/lib/hecks/projections/site/payload/model.rb +22 -22
- data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
- data/lib/hecks/projections/site/payload/specs.rb +24 -68
- data/lib/hecks/projections/site/payload_driver.rb +19 -17
- data/lib/hecks/projections/site/root_rows.rb +12 -4
- data/lib/hecks/projections/site/routes_ts/helpers.rb +79 -0
- data/lib/hecks/projections/site/routes_ts/listings.rb +75 -0
- data/lib/hecks/projections/site/routes_ts/navigation.rb +79 -0
- data/lib/hecks/projections/site/routes_ts.rb +27 -175
- data/lib/hecks/projections/site/site_admin/access.rb +104 -0
- data/lib/hecks/projections/site/site_admin/session.rb +127 -0
- data/lib/hecks/projections/site/site_admin.rb +12 -219
- data/lib/hecks/projections/site/site_cdn.rb +12 -7
- data/lib/hecks/projections/site/site_host/dockerfile.rb +75 -0
- data/lib/hecks/projections/site/site_host/templates.rb +7 -63
- data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
- data/lib/hecks/projections/site/site_root.rb +3 -54
- data/lib/hecks/projections/site/table/checks.rb +28 -57
- data/lib/hecks/projections/site/table/link_builder.rb +14 -5
- data/lib/hecks/projections/site/table/navigation_checks.rb +75 -0
- data/lib/hecks/projections/site/table/row_builder.rb +31 -53
- data/lib/hecks/projections/site/table/row_defaults.rb +65 -0
- data/lib/hecks/projections/site/table.rb +9 -5
- data/lib/hecks/projections/vocabulary.rb +34 -31
- data/lib/hecks/projector/cli_audience.rb +42 -0
- data/lib/hecks/projector/cli_projector/claims.rb +149 -0
- data/lib/hecks/projector/cli_projector/command_help.rb +65 -0
- data/lib/hecks/projector/cli_projector/command_specs.rb +133 -0
- data/lib/hecks/projector/cli_projector/listing.rb +100 -0
- data/lib/hecks/projector/cli_projector/option_specs.rb +116 -0
- data/lib/hecks/projector/cli_projector/query_specs.rb +67 -0
- data/lib/hecks/projector/cli_projector/usage.rb +101 -0
- data/lib/hecks/projector/cli_projector.rb +15 -532
- data/lib/hecks/projector/docs_projector/attributes.rb +78 -0
- data/lib/hecks/projector/docs_projector/behaviour.rb +127 -0
- data/lib/hecks/projector/docs_projector/closing.rb +40 -0
- data/lib/hecks/projector/docs_projector.rb +58 -192
- data/lib/hecks/projector/exporter/bindings.rb +174 -0
- data/lib/hecks/projector/exporter/translations.rb +127 -0
- data/lib/hecks/projector/exporter.rb +8 -279
- data/lib/hecks/projector/narrate_projector/commands.rb +108 -0
- data/lib/hecks/projector/narrate_projector/reactions.rb +33 -0
- data/lib/hecks/projector/narrate_projector.rb +60 -160
- data/lib/hecks/projector.rb +22 -13
- data/lib/hecks/quality_control/adapters/agent_profile.rb +25 -16
- data/lib/hecks/quality_control/adapters/github_checks.rb +42 -6
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +1 -1
- data/lib/hecks/quality_control/adapters/github_issues.rb +22 -10
- data/lib/hecks/quality_control/cli/qa_discover_external_domains/parsing.rb +54 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains/reporting.rb +44 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +119 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +28 -155
- data/lib/hecks/quality_control/cli/qa_domain_novelty/verdict.rb +76 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +33 -66
- data/lib/hecks/quality_control/cli/qa_generated_domains/arguments.rb +62 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/blueprints.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +107 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +107 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/reporting.rb +97 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/shrinking.rb +70 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +43 -327
- data/lib/hecks/quality_control/cli/qa_log_bug/arguments.rb +55 -0
- data/lib/hecks/quality_control/cli/qa_log_bug/proof.rb +65 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +18 -81
- data/lib/hecks/quality_control/cli/qa_mine_combinations/arguments.rb +54 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations/booting.rb +96 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +45 -109
- data/lib/hecks/quality_control/cli/qa_open_pr/arguments.rb +55 -0
- data/lib/hecks/quality_control/cli/qa_open_pr/recording.rb +79 -0
- data/lib/hecks/quality_control/cli/qa_open_pr/rules.rb +122 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +41 -200
- data/lib/hecks/quality_control/cli/qa_postgres_migrate/copying.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate/reporting.rb +33 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +37 -63
- data/lib/hecks/quality_control/cli/qa_postgres_role/ownership.rb +57 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +66 -71
- data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +118 -0
- data/lib/hecks/quality_control/cli/qa_pr_check/reporting.rb +54 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +28 -145
- data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +80 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +13 -86
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode/children.rb +80 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode/report.rb +125 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +63 -193
- data/lib/hecks/quality_control/cli/qa_sweep/checks/boundary.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks/engines.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks/seeds.rb +86 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +10 -248
- data/lib/hecks/quality_control/cli/qa_sweep/conclusion.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep/depth.rb +61 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +26 -13
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report/shrunk.rb +42 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +40 -41
- data/lib/hecks/quality_control/cli/qa_sweep/parsing/validation.rb +70 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +35 -65
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +41 -22
- data/lib/hecks/quality_control/cli/qa_sweep/scratch.rb +67 -0
- data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +94 -0
- data/lib/hecks/quality_control/cli/qa_sweep/seed_loop.rb +149 -0
- data/lib/hecks/quality_control/cli/qa_sweep/target_setup.rb +115 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +22 -445
- data/lib/hecks/quality_control/cli/qa_tick/output.rb +107 -0
- data/lib/hecks/quality_control/cli/qa_tick/preflight.rb +95 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +42 -175
- data/lib/hecks/query_ir/formatting.rb +86 -0
- data/lib/hecks/query_ir/rules.rb +132 -0
- data/lib/hecks/query_ir/touchpoints.rb +104 -0
- data/lib/hecks/query_ir.rb +33 -281
- data/lib/hecks/query_ir_mcp/tools.rb +68 -0
- data/lib/hecks/query_ir_mcp.rb +27 -71
- data/lib/hecks/query_specification/common/comparison.rb +25 -5
- data/lib/hecks/query_specification/common/dsl.rb +1 -1
- data/lib/hecks/query_specification/common/null_policy.rb +9 -6
- data/lib/hecks/query_specification/common/options.rb +21 -14
- data/lib/hecks/query_specification/field_path.rb +5 -2
- data/lib/hecks/query_specification/hop_path.rb +15 -18
- data/lib/hecks/release/lane.rb +22 -0
- data/lib/hecks/release/runner/clean_tree.rb +2 -2
- data/lib/hecks/release/runner/commands.rb +1 -1
- data/lib/hecks/release/runner/options.rb +82 -0
- data/lib/hecks/release/runner/preflight.rb +12 -7
- data/lib/hecks/release/runner/publishing.rb +86 -0
- data/lib/hecks/release/runner/tagger.rb +8 -3
- data/lib/hecks/release/runner.rb +40 -156
- data/lib/hecks/rendering.rb +13 -9
- data/lib/hecks/router/door.rb +37 -0
- data/lib/hecks/router/namespace_installer.rb +45 -83
- data/lib/hecks/router/options_proxy.rb +44 -0
- data/lib/hecks/runtime/adapter_lookup.rb +45 -24
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -8
- data/lib/hecks/runtime/command_interpreter/delegation.rb +116 -0
- data/lib/hecks/runtime/command_interpreter/enforcement.rb +38 -0
- data/lib/hecks/runtime/command_interpreter/hydration.rb +139 -0
- data/lib/hecks/runtime/command_interpreter/list_mutations.rb +98 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +67 -114
- data/lib/hecks/runtime/command_interpreter/persisting.rb +96 -0
- data/lib/hecks/runtime/command_interpreter.rb +57 -352
- data/lib/hecks/runtime/command_rules/admissibility.rb +64 -147
- data/lib/hecks/runtime/command_rules/arithmetic.rb +13 -72
- data/lib/hecks/runtime/command_rules/authorization.rb +9 -9
- data/lib/hecks/runtime/command_rules/emission.rb +13 -14
- data/lib/hecks/runtime/command_rules/guard_state.rb +49 -0
- data/lib/hecks/runtime/command_rules/invariants.rb +84 -0
- data/lib/hecks/runtime/command_rules/operands.rb +88 -0
- data/lib/hecks/runtime/command_rules/references.rb +59 -57
- data/lib/hecks/runtime/command_rules/tenant_boundary.rb +69 -0
- data/lib/hecks/runtime/dependency_planning/analyzer.rb +90 -0
- data/lib/hecks/runtime/dependency_planning/expression_reads.rb +73 -0
- data/lib/hecks/runtime/dependency_planning/mutation_analysis.rb +89 -0
- data/lib/hecks/runtime/dependency_planning/rule_analysis.rb +82 -0
- data/lib/hecks/runtime/dependency_planning.rb +3 -250
- data/lib/hecks/runtime/dispatcher/queries.rb +62 -0
- data/lib/hecks/runtime/dispatcher/result.rb +55 -0
- data/lib/hecks/runtime/dispatcher/routing.rb +107 -0
- data/lib/hecks/runtime/dispatcher.rb +64 -209
- data/lib/hecks/runtime/entity_element/location.rb +124 -0
- data/lib/hecks/runtime/entity_element/mutations.rb +150 -0
- data/lib/hecks/runtime/entity_element.rb +5 -177
- data/lib/hecks/runtime/entity_interpreter/enforcement.rb +51 -0
- data/lib/hecks/runtime/entity_interpreter/locating.rb +62 -0
- data/lib/hecks/runtime/entity_interpreter/resolution.rb +42 -0
- data/lib/hecks/runtime/entity_interpreter/saving.rb +49 -0
- data/lib/hecks/runtime/entity_interpreter.rb +45 -164
- data/lib/hecks/runtime/identity.rb +15 -9
- data/lib/hecks/runtime/instance.rb +11 -7
- data/lib/hecks/runtime/interpreting.rb +16 -8
- data/lib/hecks/runtime/invocation.rb +3 -155
- data/lib/hecks/runtime/invocation_builder.rb +132 -0
- data/lib/hecks/runtime/invocation_facts.rb +87 -0
- data/lib/hecks/runtime/loader/boot_steps.rb +96 -0
- data/lib/hecks/runtime/loader/described.rb +27 -0
- data/lib/hecks/runtime/loader.rb +27 -114
- data/lib/hecks/runtime/outbox/consumer_runner.rb +40 -0
- data/lib/hecks/runtime/outbox/fanout.rb +82 -0
- data/lib/hecks/runtime/outbox/relay.rb +149 -0
- data/lib/hecks/runtime/outbox.rb +3 -214
- data/lib/hecks/runtime/policy_interpreter/arguments.rb +67 -0
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +96 -0
- data/lib/hecks/runtime/policy_interpreter.rb +22 -137
- data/lib/hecks/runtime/port_operation_interpreter.rb +18 -17
- data/lib/hecks/runtime/query_interpreter/arguments.rb +51 -0
- data/lib/hecks/runtime/query_interpreter/entity_rows.rb +82 -0
- data/lib/hecks/runtime/query_interpreter/outside_answer.rb +89 -0
- data/lib/hecks/runtime/query_interpreter.rb +43 -191
- data/lib/hecks/runtime/reaction_invocation/identities.rb +92 -0
- data/lib/hecks/runtime/reaction_invocation/target_resolution.rb +88 -0
- data/lib/hecks/runtime/reaction_invocation.rb +66 -183
- data/lib/hecks/runtime/reaction_outcome.rb +7 -3
- data/lib/hecks/runtime/read_model_interpreter/head_ordering.rb +49 -0
- data/lib/hecks/runtime/read_model_interpreter/reductions.rb +123 -0
- data/lib/hecks/runtime/read_model_interpreter/shaping.rb +100 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +71 -214
- data/lib/hecks/runtime/reference_hop.rb +11 -11
- data/lib/hecks/runtime/refusal_wording.rb +11 -8
- data/lib/hecks/runtime/registry/chapter_verification.rb +84 -0
- data/lib/hecks/runtime/registry/declarations.rb +17 -0
- data/lib/hecks/runtime/registry/durability_warnings.rb +71 -0
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +124 -0
- data/lib/hecks/runtime/registry/merging.rb +49 -0
- data/lib/hecks/runtime/registry/providers.rb +139 -0
- data/lib/hecks/runtime/registry/query_verification.rb +144 -0
- data/lib/hecks/runtime/registry/read_repository.rb +61 -0
- data/lib/hecks/runtime/registry/runtime_state.rb +27 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +12 -8
- data/lib/hecks/runtime/registry/verification.rb +45 -389
- data/lib/hecks/runtime/registry/world_defaults.rb +3 -3
- data/lib/hecks/runtime/registry.rb +58 -296
- data/lib/hecks/runtime/remote_dispatcher.rb +47 -31
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +90 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +19 -10
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +147 -0
- data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +63 -0
- data/lib/hecks/runtime/saga_interpreter/transitions.rb +112 -0
- data/lib/hecks/runtime/saga_interpreter.rb +41 -320
- data/lib/hecks/runtime/tenant_check.rb +14 -9
- data/lib/hecks/runtime/value/admission.rb +28 -19
- data/lib/hecks/runtime/value/coercion.rb +55 -404
- data/lib/hecks/runtime/value/entity_list_coercion.rb +27 -29
- data/lib/hecks/runtime/value/field_checks.rb +57 -100
- data/lib/hecks/runtime/value/flags.rb +65 -0
- data/lib/hecks/runtime/value/identifiers.rb +64 -0
- data/lib/hecks/runtime/value/references.rb +195 -0
- data/lib/hecks/runtime/value/shape_checks.rb +61 -0
- data/lib/hecks/runtime/value/validation.rb +125 -0
- data/lib/hecks/runtime/value.rb +18 -6
- data/lib/hecks/rust_build/conformance/surface.rb +75 -0
- data/lib/hecks/rust_build/conformance.rb +27 -59
- data/lib/hecks/rust_build/conformance_fuzz.rb +26 -15
- data/lib/hecks/rust_build/coverage.rb +32 -104
- data/lib/hecks/rust_build/coverage_parts/expected.rb +68 -0
- data/lib/hecks/rust_build/coverage_parts/printer.rb +75 -0
- data/lib/hecks/rust_build/host.rb +23 -13
- data/lib/hecks/rust_build/kernel_input.rb +19 -12
- data/lib/hecks/rust_build/native_build.rb +19 -15
- data/lib/hecks/rust_build/project_rust/domain_loader.rb +75 -0
- data/lib/hecks/rust_build/project_rust/root_mod/notes.rb +66 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +22 -55
- data/lib/hecks/rust_build/project_rust/target_ir.rb +74 -0
- data/lib/hecks/rust_build/project_rust.rb +21 -89
- data/lib/hecks/rust_build/wasm.rb +11 -4
- data/lib/hecks/rust_build/wasm_browser.rb +7 -7
- data/lib/hecks/rust_build/write_if_changed.rb +3 -6
- data/lib/hecks/rust_build.rb +7 -3
- data/lib/hecks/storehouse/audit.rb +106 -0
- data/lib/hecks/storehouse/callers.rb +73 -0
- data/lib/hecks/storehouse/dispatching.rb +149 -0
- data/lib/hecks/storehouse/introspection.rb +145 -0
- data/lib/hecks/storehouse/querying.rb +78 -0
- data/lib/hecks/storehouse.rb +43 -451
- data/lib/hecks/tickets/bluebook/tickets.bluebook +29 -0
- data/lib/hecks/tools/argument_gate_matrix/dispatching.rb +69 -0
- data/lib/hecks/tools/argument_gate_matrix/rows.rb +121 -0
- data/lib/hecks/tools/argument_gate_matrix/violations.rb +108 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +43 -212
- data/lib/hecks/tools/ci_gate_decision.rb +21 -14
- data/lib/hecks/tools/ci_gates.rb +40 -26
- data/lib/hecks/tools/comment_style/baseline.rb +41 -0
- data/lib/hecks/tools/comment_style/caps_words.rb +104 -0
- data/lib/hecks/tools/comment_style/cli.rb +121 -0
- data/lib/hecks/tools/comment_style/dictionary.rb +60 -0
- data/lib/hecks/tools/comment_style/fixing.rb +119 -0
- data/lib/hecks/tools/comment_style/long_blocks.rb +51 -0
- data/lib/hecks/tools/comment_style/masking.rb +94 -0
- data/lib/hecks/tools/comment_style/patterns.rb +61 -0
- data/lib/hecks/tools/comment_style/run.rb +161 -0
- data/lib/hecks/tools/comment_style/signature.rb +59 -0
- data/lib/hecks/tools/comment_style/source_file.rb +105 -0
- data/lib/hecks/tools/comment_style/structure_checks.rb +113 -0
- data/lib/hecks/tools/comment_style/text_checks.rb +67 -0
- data/lib/hecks/tools/comment_style/vocabulary.rb +55 -0
- data/lib/hecks/tools/comment_style/walker.rb +136 -0
- data/lib/hecks/tools/comment_style.rb +17 -1000
- data/lib/hecks/tools/corpus_report.rb +26 -16
- data/lib/hecks/tools/deploy_recipe/targets.rb +61 -0
- data/lib/hecks/tools/deploy_recipe/worlds.rb +114 -0
- data/lib/hecks/tools/deploy_recipe.rb +60 -174
- data/lib/hecks/tools/deploy_recipe_lint/checks.rb +78 -0
- data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +88 -0
- data/lib/hecks/tools/deploy_recipe_lint/makefile.rb +84 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +29 -192
- data/lib/hecks/tools/drop_implicit_append_fields.rb +20 -12
- data/lib/hecks/tools/era_projection_backfill.rb +50 -33
- data/lib/hecks/tools/era_reattest/reporting.rb +55 -0
- data/lib/hecks/tools/era_reattest.rb +32 -43
- data/lib/hecks/tools/evolve_run/arguments.rb +49 -0
- data/lib/hecks/tools/evolve_run/words.rb +60 -0
- data/lib/hecks/tools/evolve_run.rb +43 -90
- data/lib/hecks/tools/fuzz_sweep/findings.rb +106 -0
- data/lib/hecks/tools/fuzz_sweep/options.rb +69 -0
- data/lib/hecks/tools/fuzz_sweep/pool.rb +74 -0
- data/lib/hecks/tools/fuzz_sweep/reporting.rb +88 -0
- data/lib/hecks/tools/fuzz_sweep.rb +75 -273
- data/lib/hecks/tools/gate.rb +31 -16
- data/lib/hecks/tools/heki_compaction.rb +63 -42
- data/lib/hecks/tools/hoist_local_givens/rewriting.rb +119 -0
- data/lib/hecks/tools/hoist_local_givens.rb +89 -157
- data/lib/hecks/tools/journal_compaction.rb +40 -31
- data/lib/hecks/tools/lanes/files.rb +82 -0
- data/lib/hecks/tools/lanes/live.rb +41 -0
- data/lib/hecks/tools/lanes/rows.rb +45 -0
- data/lib/hecks/tools/lanes/ruleset.rb +44 -0
- data/lib/hecks/tools/lanes/watch_workflow.rb +82 -0
- data/lib/hecks/tools/lanes/workflow.rb +79 -0
- data/lib/hecks/tools/lanes.rb +71 -0
- data/lib/hecks/tools/oidc_manifests.rb +10 -9
- data/lib/hecks/tools/query_ir_run.rb +7 -3
- data/lib/hecks/tools/regeneration_run.rb +40 -26
- data/lib/hecks/tools/rust_comment_style/caps_words.rb +98 -0
- data/lib/hecks/tools/rust_comment_style/fixing.rb +102 -0
- data/lib/hecks/tools/rust_comment_style/masking.rb +85 -0
- data/lib/hecks/tools/rust_comment_style/run.rb +94 -0
- data/lib/hecks/tools/rust_comment_style/source_file.rb +71 -0
- data/lib/hecks/tools/rust_comment_style/structure.rb +79 -0
- data/lib/hecks/tools/rust_comment_style/text_checks.rb +63 -0
- data/lib/hecks/tools/rust_comment_style/tokenizer.rb +102 -0
- data/lib/hecks/tools/rust_comment_style.rb +38 -535
- data/lib/hecks/tools/sequence_script.rb +20 -14
- data/lib/hecks/tools/site_routes/cli.rb +70 -0
- data/lib/hecks/tools/site_routes/root_files.rb +59 -0
- data/lib/hecks/tools/site_routes/templates.rb +77 -0
- data/lib/hecks/tools/site_routes.rb +84 -160
- data/lib/hecks/tools/tail_merge.rb +45 -37
- data/lib/hecks/tools/tenant_provisioning.rb +45 -31
- data/lib/hecks/tools/tools_doc.rb +42 -19
- data/lib/hecks/tools/translation_audit/domain_loading.rb +71 -0
- data/lib/hecks/tools/translation_audit/edges.rb +71 -0
- data/lib/hecks/tools/translation_audit/verdicts.rb +107 -0
- data/lib/hecks/tools/translation_audit.rb +30 -161
- data/lib/hecks/tools/translation_scaffold/reporting.rb +40 -0
- data/lib/hecks/tools/translation_scaffold.rb +77 -60
- data/lib/hecks/tools.rb +1 -0
- data/lib/hecks/vendoring.rb +37 -11
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +16 -1
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +7 -9
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +8 -6
- data/rust/.cargo/mutants.toml +8 -0
- data/rust/host/Cargo.toml +5 -0
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/src/auth.rs +32 -0
- data/rust/host/src/web.rs +2 -3
- data/rust/src/kernel/dispatch.rs +4 -0
- data/rust/src/kernel/dispatch_guard_tests.rs +506 -0
- data/rust/src/kernel/orchestrate.rs +4 -0
- data/rust/src/kernel/orchestrate_guard_tests.rs +708 -0
- metadata +591 -3
- /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require_relative "
|
|
2
|
-
require_relative "
|
|
1
|
+
require_relative "chain_sql"
|
|
2
|
+
require_relative "sql_templates"
|
|
3
3
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module Adapters
|
|
@@ -8,31 +8,14 @@ module Hecks
|
|
|
8
8
|
# The read side of lineage: builds and maintains the head-snapshot
|
|
9
9
|
# table and the compiled view/matview a query actually reads.
|
|
10
10
|
module HeadCompiler
|
|
11
|
+
include ChainSql
|
|
12
|
+
include SqlTemplates
|
|
13
|
+
|
|
11
14
|
# Backfill runs unconditionally after create: an existing journal
|
|
12
15
|
# must never look empty just because its snapshot table is new.
|
|
13
16
|
def ensure_head_snapshot!(storage_name, era)
|
|
14
17
|
name = head_snapshot(storage_name, era)
|
|
15
|
-
unless table_exists?(name)
|
|
16
|
-
# Locked, not a bare CREATE, so two first-time boots can't race;
|
|
17
|
-
# nested_transaction lets this run standalone or inside mint's
|
|
18
|
-
# own already-open transaction without ending it early.
|
|
19
|
-
nested_transaction("hecks_head_snapshot") do
|
|
20
|
-
@db.exec_params("SELECT pg_advisory_xact_lock(hashtext('hecks_head_snapshot:' || $1))", [name])
|
|
21
|
-
next if table_exists?(name)
|
|
22
|
-
|
|
23
|
-
# A delete upserts a tombstone (operation = 'delete', state
|
|
24
|
-
# NULL) instead of removing the row, so it still outranks a
|
|
25
|
-
# stale ancestor `save` row by ordinal under DISTINCT ON.
|
|
26
|
-
@db.exec(<<~SQL)
|
|
27
|
-
CREATE TABLE #{quote(name)} (
|
|
28
|
-
id text PRIMARY KEY,
|
|
29
|
-
ordinal bigint NOT NULL,
|
|
30
|
-
operation text NOT NULL DEFAULT 'save',
|
|
31
|
-
state jsonb
|
|
32
|
-
)
|
|
33
|
-
SQL
|
|
34
|
-
end
|
|
35
|
-
end
|
|
18
|
+
create_head_snapshot_table!(name) unless table_exists?(name)
|
|
36
19
|
# Self-healing for a table created before this column existed;
|
|
37
20
|
# a no-op once it and the relaxed constraint are already there.
|
|
38
21
|
@db.exec("ALTER TABLE #{quote(name)} ADD COLUMN IF NOT EXISTS operation text NOT NULL DEFAULT 'save'")
|
|
@@ -46,29 +29,8 @@ module Hecks
|
|
|
46
29
|
def backfill_head_snapshot!(name, storage_name, era)
|
|
47
30
|
chunked_backfill!(
|
|
48
31
|
name,
|
|
49
|
-
source_sql:
|
|
50
|
-
|
|
51
|
-
SELECT id, ordinal, state FROM (
|
|
52
|
-
SELECT DISTINCT ON (aggregate_id) aggregate_id AS id, ordinal, operation, state
|
|
53
|
-
FROM #{quoted_journal}
|
|
54
|
-
WHERE era = #{era.to_i} AND aggregate = #{text_literal(storage_name)}
|
|
55
|
-
#{"AND aggregate_id > #{text_literal(cursor)}" if cursor}
|
|
56
|
-
ORDER BY aggregate_id, ordinal DESC
|
|
57
|
-
) latest WHERE operation = 'save' ORDER BY id LIMIT #{ResumableBackfill::CHUNK_SIZE}
|
|
58
|
-
SQL
|
|
59
|
-
end,
|
|
60
|
-
upsert: lambda do |rows|
|
|
61
|
-
rows.each do |row|
|
|
62
|
-
# Always 'save' — source_sql above already filtered to
|
|
63
|
-
# operation = 'save' rows only.
|
|
64
|
-
@db.exec_params(
|
|
65
|
-
"INSERT INTO #{quote(name)} (id, ordinal, operation, state) VALUES ($1, $2, 'save', $3) " \
|
|
66
|
-
"ON CONFLICT (id) DO UPDATE SET ordinal = EXCLUDED.ordinal, operation = EXCLUDED.operation, " \
|
|
67
|
-
"state = EXCLUDED.state WHERE #{quote(name)}.ordinal < EXCLUDED.ordinal",
|
|
68
|
-
[row["id"], row["ordinal"], row["state"]]
|
|
69
|
-
)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
32
|
+
source_sql: ->(cursor) { head_backfill_page_sql(cursor, storage_name, era) },
|
|
33
|
+
upsert: ->(rows) { upsert_head_snapshot_rows!(name, rows) }
|
|
72
34
|
)
|
|
73
35
|
end
|
|
74
36
|
|
|
@@ -100,136 +62,8 @@ module Hecks
|
|
|
100
62
|
# tail to reduce.
|
|
101
63
|
def ensure_first_head!(storage_name)
|
|
102
64
|
ensure_head_snapshot!(storage_name, 1)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# of resolving to a nil state.
|
|
106
|
-
@db.exec(<<~SQL)
|
|
107
|
-
CREATE OR REPLACE VIEW #{quote(head_view(storage_name))} AS
|
|
108
|
-
SELECT id, state FROM #{quote(head_snapshot(storage_name, 1))} WHERE operation = 'save'
|
|
109
|
-
SQL
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Reduces the tail before chaining edges over it, not after: every
|
|
113
|
-
# reader already reduces to latest-per-id, so translating a
|
|
114
|
-
# superseded entry would be wasted work. `era` survives the
|
|
115
|
-
# reduction because each edge's case still needs it.
|
|
116
|
-
def latest_per_id(tail)
|
|
117
|
-
return tail if tail.to_s.empty?
|
|
118
|
-
|
|
119
|
-
"SELECT DISTINCT ON (aggregate_id) ordinal, era, aggregate, aggregate_id, operation, state " \
|
|
120
|
-
"FROM (#{tail}) tail_entries ORDER BY aggregate_id, ordinal DESC"
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# Builds era N by layering its own last edge onto era N-1's existing
|
|
124
|
-
# matview, instead of re-deriving from raw history; returns nil
|
|
125
|
-
# (falling back to chain_sql) whenever that shortcut can't honestly
|
|
126
|
-
# apply. `edges.size != era - 1` guards names_by_era's own
|
|
127
|
-
# assumption that `edges` is the full chain reaching `era` — a
|
|
128
|
-
# shorter chain here would index names[:storage] out of bounds
|
|
129
|
-
# rather than safely falling back.
|
|
130
|
-
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
131
|
-
# rubocop:disable-next Metrics/PerceivedComplexity
|
|
132
|
-
def layered_chain_sql(aggregate, era, edges)
|
|
133
|
-
return nil if era < 3 || edges.size < 2 || edges.size != era - 1
|
|
134
|
-
|
|
135
|
-
held = eras
|
|
136
|
-
prior = held.find { |candidate| candidate[:ordinal] == era - 1 }
|
|
137
|
-
return nil unless prior && prior[:label]
|
|
138
|
-
|
|
139
|
-
prior_view = matview(aggregate.storage_name, era - 1, prior[:label])
|
|
140
|
-
return nil unless view_exists?(prior_view)
|
|
141
|
-
|
|
142
|
-
names = names_by_era(aggregate, edges)
|
|
143
|
-
cut = held.find { |candidate| candidate[:ordinal] == era }&.dig(:watermark)
|
|
144
|
-
declared = edges.last[:translation].for_aggregate(names[:current][edges.size])
|
|
145
|
-
expression = declared ? Translation::RuleCompiler.compile_rules(declared) : "state"
|
|
146
|
-
id_column = if Translation::RuleCompiler.rekeyed?(declared)
|
|
147
|
-
Translation::RuleCompiler.id_case("operation = 'save'",
|
|
148
|
-
declared)
|
|
149
|
-
else
|
|
150
|
-
"aggregate_id"
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
<<~SQL
|
|
154
|
-
WITH layered AS (
|
|
155
|
-
SELECT DISTINCT ON (aggregate_id) ordinal, aggregate_id, operation, state FROM (
|
|
156
|
-
SELECT ordinal, aggregate_id, operation, state FROM #{quote(prior_view)}
|
|
157
|
-
UNION ALL
|
|
158
|
-
SELECT ordinal, aggregate_id, operation, state FROM #{quoted_journal}
|
|
159
|
-
WHERE era = #{era - 1} AND aggregate = #{text_literal(names[:storage][era - 2])}#{" AND ordinal <= #{cut}" if cut}
|
|
160
|
-
) layers ORDER BY aggregate_id, ordinal DESC
|
|
161
|
-
)
|
|
162
|
-
SELECT ordinal, #{id_column}, operation,
|
|
163
|
-
CASE WHEN operation = 'save' THEN #{expression} ELSE state END AS state
|
|
164
|
-
FROM layered
|
|
165
|
-
SQL
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Chains the original edges in mint order rather than flattening them
|
|
169
|
-
# into one rule set: edge 1 renaming A→B then edge 2 renaming C→A
|
|
170
|
-
# has no single phase order that applies both correctly.
|
|
171
|
-
def chain_sql(aggregate, era, edges)
|
|
172
|
-
names = names_by_era(aggregate, edges)
|
|
173
|
-
tail = latest_per_id(ancestor_tail_sql(names, era))
|
|
174
|
-
chain = edges.each_with_index.map do |edge, index|
|
|
175
|
-
declared = edge[:translation].for_aggregate(names[:current][index + 1])
|
|
176
|
-
expression = declared ? Translation::RuleCompiler.compile_rules(declared) : "state"
|
|
177
|
-
guard = "era <= #{index + 1} AND operation = 'save'"
|
|
178
|
-
id_column = if Translation::RuleCompiler.rekeyed?(declared)
|
|
179
|
-
Translation::RuleCompiler.id_case(guard,
|
|
180
|
-
declared)
|
|
181
|
-
else
|
|
182
|
-
"aggregate_id"
|
|
183
|
-
end
|
|
184
|
-
"edge_#{index + 1} AS (SELECT ordinal, era, #{id_column}, operation, " \
|
|
185
|
-
"CASE WHEN #{guard} THEN #{expression} ELSE state END AS state " \
|
|
186
|
-
"FROM #{index.zero? ? 'tail' : "edge_#{index}"})"
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
<<~SQL
|
|
190
|
-
WITH tail AS (#{tail}),
|
|
191
|
-
#{chain.join(",\n")}
|
|
192
|
-
SELECT ordinal, aggregate_id, operation, state FROM edge_#{edges.size}
|
|
193
|
-
SQL
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
# Reads through head_body_sql — the same layered-or-full choice
|
|
197
|
-
# compile_head! makes at mint time — so a preview can't silently
|
|
198
|
-
# drift from what a real mint will materialize.
|
|
199
|
-
def translated_latest(aggregate, era, edges)
|
|
200
|
-
latest_of(head_body_sql(aggregate, era, edges))
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# The untranslated ancestor tail, latest entry per id — the "before"
|
|
204
|
-
# side of a per-rule preservation check.
|
|
205
|
-
def ancestor_latest(aggregate, era, edges)
|
|
206
|
-
names = names_by_era(aggregate, edges)
|
|
207
|
-
tail = ancestor_tail_sql(names, era)
|
|
208
|
-
return {} if tail.empty?
|
|
209
|
-
|
|
210
|
-
latest_of("SELECT ordinal, era, aggregate_id, operation, state FROM (#{tail}) tail_rows")
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# Reduces to newest entry per aggregate id, dropping any id whose
|
|
214
|
-
# newest entry is a delete rather than returning it with a nil state.
|
|
215
|
-
def latest_of(sql)
|
|
216
|
-
rows = @db.exec(<<~SQL)
|
|
217
|
-
SELECT aggregate_id, state FROM (
|
|
218
|
-
SELECT DISTINCT ON (aggregate_id) aggregate_id, operation, state
|
|
219
|
-
FROM (#{sql}) chained ORDER BY aggregate_id, ordinal DESC
|
|
220
|
-
) latest WHERE operation = 'save'
|
|
221
|
-
SQL
|
|
222
|
-
rows.to_h { |row| [row["aggregate_id"], JSON.parse(row["state"])] }
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# The one place that picks layered vs full, so a preview
|
|
226
|
-
# (translated_latest) can never approve a branch the real mint
|
|
227
|
-
# doesn't take. `full:` mirrors compile_head!'s own default;
|
|
228
|
-
# tail_merge is the one caller that forces it true.
|
|
229
|
-
def head_body_sql(aggregate, era, edges, full: false)
|
|
230
|
-
return chain_sql(aggregate, era, edges) if full
|
|
231
|
-
|
|
232
|
-
layered_chain_sql(aggregate, era, edges) || chain_sql(aggregate, era, edges)
|
|
65
|
+
tokens = { head_view: quote(head_view(storage_name)), snapshot: quote(head_snapshot(storage_name, 1)) }
|
|
66
|
+
@db.exec(format(FIRST_HEAD_VIEW_SQL, tokens))
|
|
233
67
|
end
|
|
234
68
|
|
|
235
69
|
# The matview bakes each ancestor's watermark in as a literal;
|
|
@@ -240,55 +74,11 @@ module Hecks
|
|
|
240
74
|
storage_name = aggregate.storage_name
|
|
241
75
|
view = matview(storage_name, era, label)
|
|
242
76
|
body = head_body_sql(aggregate, era, edges, full: full)
|
|
243
|
-
@db.exec(
|
|
244
|
-
CREATE MATERIALIZED VIEW #{quote(view)} AS
|
|
245
|
-
#{body}
|
|
246
|
-
SQL
|
|
77
|
+
@db.exec("CREATE MATERIALIZED VIEW #{quote(view)} AS\n#{body}\n")
|
|
247
78
|
@db.exec("CREATE INDEX IF NOT EXISTS #{quote("#{view}_reduce_idx")} ON #{quote(view)} (aggregate_id, ordinal DESC)")
|
|
248
79
|
|
|
249
80
|
ensure_head_snapshot!(storage_name, era)
|
|
250
|
-
|
|
251
|
-
# Reads the snapshot's own operation column rather than hardcoding
|
|
252
|
-
# 'save', so a tombstone here outranks a stale ancestor save row
|
|
253
|
-
# by ordinal instead of letting it resurrect a deleted record.
|
|
254
|
-
@db.exec(<<~SQL)
|
|
255
|
-
CREATE VIEW #{quote(head_view(storage_name))} AS
|
|
256
|
-
SELECT id, state FROM (
|
|
257
|
-
SELECT DISTINCT ON (aggregate_id) aggregate_id AS id, operation, state FROM (
|
|
258
|
-
SELECT ordinal, aggregate_id, operation, state FROM #{quote(view)}
|
|
259
|
-
UNION ALL
|
|
260
|
-
SELECT ordinal, id AS aggregate_id, operation, state
|
|
261
|
-
FROM #{quote(head_snapshot(storage_name, era))}
|
|
262
|
-
) merged ORDER BY aggregate_id, ordinal DESC
|
|
263
|
-
) latest WHERE operation = 'save'
|
|
264
|
-
SQL
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
# Walks `was:` chains backward from the current name, so each
|
|
268
|
-
# ancestor era's rows can be found under the name of their time.
|
|
269
|
-
# names[:storage][e - 1] is the storage name for era e (1-based).
|
|
270
|
-
def names_by_era(aggregate, edges)
|
|
271
|
-
current = Array.new(edges.size + 1)
|
|
272
|
-
current[edges.size] = aggregate.name
|
|
273
|
-
(edges.size - 1).downto(0) do |index|
|
|
274
|
-
declared = edges[index][:translation].for_aggregate(current[index + 1])
|
|
275
|
-
current[index] = declared&.was || current[index + 1]
|
|
276
|
-
end
|
|
277
|
-
storage = current.map { |name| Naming.snake(name) }
|
|
278
|
-
{ current: current, storage: storage }
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
# Cuts each ancestor era's rows at the watermark recorded when its
|
|
282
|
-
# successor was minted, so later writes to the old world don't leak in.
|
|
283
|
-
def ancestor_tail_sql(names, era)
|
|
284
|
-
watermarks = eras.to_h { |held| [held[:ordinal], held[:watermark]] }
|
|
285
|
-
selects = (1...era).map do |ancestor|
|
|
286
|
-
cut = watermarks[ancestor + 1]
|
|
287
|
-
"SELECT ordinal, era, aggregate, aggregate_id, operation, state FROM #{quoted_journal} " \
|
|
288
|
-
"WHERE era = #{ancestor} AND aggregate = #{text_literal(names[:storage][ancestor - 1])}" \
|
|
289
|
-
"#{" AND ordinal <= #{cut}" if cut}"
|
|
290
|
-
end
|
|
291
|
-
selects.join(" UNION ALL ")
|
|
81
|
+
replace_head_view!(storage_name, era, view)
|
|
292
82
|
end
|
|
293
83
|
|
|
294
84
|
# The rule-compiling helpers live in Translation::RuleCompiler instead,
|
|
@@ -307,6 +97,45 @@ module Hecks
|
|
|
307
97
|
[name]
|
|
308
98
|
).ntuples.positive?
|
|
309
99
|
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
# Locked, not a bare CREATE, so two first-time boots can't race;
|
|
104
|
+
# nested_transaction lets this run standalone or inside mint's
|
|
105
|
+
# own already-open transaction without ending it early.
|
|
106
|
+
def create_head_snapshot_table!(name)
|
|
107
|
+
nested_transaction("hecks_head_snapshot") do
|
|
108
|
+
@db.exec_params("SELECT pg_advisory_xact_lock(hashtext('hecks_head_snapshot:' || $1))", [name])
|
|
109
|
+
next if table_exists?(name)
|
|
110
|
+
|
|
111
|
+
@db.exec(format(HEAD_SNAPSHOT_SQL, table: quote(name)))
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def head_backfill_page_sql(cursor, storage_name, era)
|
|
116
|
+
after_cursor = ("AND aggregate_id > #{text_literal(cursor)}" if cursor)
|
|
117
|
+
format(HEAD_BACKFILL_SQL, journal: quoted_journal, era: era.to_i, aggregate: text_literal(storage_name),
|
|
118
|
+
after_cursor: after_cursor, chunk_size: ResumableBackfill::CHUNK_SIZE)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def upsert_head_snapshot_rows!(name, rows)
|
|
122
|
+
rows.each do |row|
|
|
123
|
+
# Always 'save' — the source SQL filtered to operation = 'save' rows only.
|
|
124
|
+
@db.exec_params(
|
|
125
|
+
"INSERT INTO #{quote(name)} (id, ordinal, operation, state) VALUES ($1, $2, 'save', $3) " \
|
|
126
|
+
"ON CONFLICT (id) DO UPDATE SET ordinal = EXCLUDED.ordinal, operation = EXCLUDED.operation, " \
|
|
127
|
+
"state = EXCLUDED.state WHERE #{quote(name)}.ordinal < EXCLUDED.ordinal",
|
|
128
|
+
[row["id"], row["ordinal"], row["state"]]
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def replace_head_view!(storage_name, era, view)
|
|
134
|
+
@db.exec("DROP VIEW IF EXISTS #{quote(head_view(storage_name))}")
|
|
135
|
+
tokens = { head_view: quote(head_view(storage_name)), view: quote(view),
|
|
136
|
+
snapshot: quote(head_snapshot(storage_name, era)) }
|
|
137
|
+
@db.exec(format(HEAD_VIEW_SQL, tokens))
|
|
138
|
+
end
|
|
310
139
|
end
|
|
311
140
|
end
|
|
312
141
|
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
class PostgresEra
|
|
4
|
+
class Lineage
|
|
5
|
+
# The row-level steps of a tail merge: finding the ids both worlds touched, capturing the
|
|
6
|
+
# new world's head states, rebuilding the heads, and writing each winner back.
|
|
7
|
+
module MergeWrites
|
|
8
|
+
# The ids written by both worlds since the cut.
|
|
9
|
+
CONFLICT_SQL = <<~SQL.freeze
|
|
10
|
+
SELECT aggregate_id FROM %<journal>s
|
|
11
|
+
WHERE era < %<era>s AND aggregate IN (%<olds>s) AND ordinal > %<cut>s
|
|
12
|
+
INTERSECT
|
|
13
|
+
SELECT aggregate_id FROM %<journal>s
|
|
14
|
+
WHERE era = %<era>s AND aggregate = %<current>s
|
|
15
|
+
SQL
|
|
16
|
+
|
|
17
|
+
# Ids written by both worlds since the cut, as `[storage_name, aggregate_id]` pairs.
|
|
18
|
+
#
|
|
19
|
+
# Compares raw ids: a rekeyed record's pre- and post-rekey rows never intersect and
|
|
20
|
+
# survive as two separate heads (a duplicate, not corruption); resolve by hand.
|
|
21
|
+
def conflict_ids(aggregate, edges, era, cut)
|
|
22
|
+
names = names_by_era(aggregate, edges)
|
|
23
|
+
rows = @db.exec(conflict_sql(names, era, cut))
|
|
24
|
+
rows.map { |row| [aggregate.storage_name, row["aggregate_id"]] }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def conflict_sql(names, era, cut)
|
|
30
|
+
olds = (1...era).map { |ancestor| text_literal(names[:storage][ancestor - 1]) }.join(", ")
|
|
31
|
+
format(CONFLICT_SQL, journal: quoted_journal, era: era.to_i, olds: olds, cut: cut.to_i,
|
|
32
|
+
current: text_literal(names[:storage][era - 1]))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The new world's pre-merge head states, captured before the
|
|
36
|
+
# rebuild lets the tail interleave.
|
|
37
|
+
def pre_merge_states(merge)
|
|
38
|
+
new_ids = merge.winners.select { |_, side| side == "new" }.keys
|
|
39
|
+
merge.aggregates.each_with_object({}) do |aggregate, states|
|
|
40
|
+
new_ids.each do |id|
|
|
41
|
+
state = head_state(aggregate, id)
|
|
42
|
+
states[id] = [aggregate.storage_name, state] if state
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The record's state in the aggregate's current head, or nil when it is not there.
|
|
48
|
+
def head_state(aggregate, id)
|
|
49
|
+
row = @db.exec_params("SELECT state FROM #{quote(head_view(aggregate.storage_name))} WHERE id = $1", [id])
|
|
50
|
+
row[0]["state"] if row.ntuples.positive?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def recompile_heads!(merge)
|
|
54
|
+
@db.exec_params("UPDATE hecks_eras SET watermark = $2 WHERE domain = $1 AND ordinal > 1", [@domain, merge.tip])
|
|
55
|
+
merge.aggregates.each do |aggregate|
|
|
56
|
+
drop_head!(aggregate, merge)
|
|
57
|
+
# full: the watermarks just moved — every ancestor matview's
|
|
58
|
+
# cut is stale, so there is nothing safe to layer on.
|
|
59
|
+
compile_head!(aggregate, merge.era, merge.label, merge.edges, full: true)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def drop_head!(aggregate, merge)
|
|
64
|
+
@db.exec("DROP VIEW IF EXISTS #{quote(head_view(aggregate.storage_name))}")
|
|
65
|
+
@db.exec("DROP MATERIALIZED VIEW IF EXISTS #{quote(matview(aggregate.storage_name, merge.era, merge.label))}")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def reinsert_winners!(merge, new_states)
|
|
69
|
+
merge.winners.each do |id, side|
|
|
70
|
+
merge.aggregates.each do |aggregate|
|
|
71
|
+
state = winner_state(merge, aggregate, id, side, new_states)
|
|
72
|
+
write_winner!(merge, aggregate, id, state) if state
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# The winning state of one record: the old world's from the rebuilt matview, the new
|
|
78
|
+
# world's from the states captured before the rebuild; nil when this aggregate has none.
|
|
79
|
+
def winner_state(merge, aggregate, id, side, new_states)
|
|
80
|
+
return new_winner_state(aggregate, id, new_states) unless side == "old"
|
|
81
|
+
|
|
82
|
+
row = @db.exec_params(
|
|
83
|
+
"SELECT state FROM #{quote(matview(aggregate.storage_name, merge.era, merge.label))} " \
|
|
84
|
+
"WHERE aggregate_id = $1 AND operation = 'save' ORDER BY ordinal DESC LIMIT 1",
|
|
85
|
+
[id]
|
|
86
|
+
)
|
|
87
|
+
row.ntuples.positive? ? row[0]["state"] : nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def new_winner_state(aggregate, id, new_states)
|
|
91
|
+
new_states[id]&.first == aggregate.storage_name ? new_states[id][1] : nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Journal first, snapshot second, as a live write does: this INSERT bypasses
|
|
95
|
+
# PostgresEra#append, and head_view reads live rows from the snapshot table.
|
|
96
|
+
def write_winner!(merge, aggregate, id, state)
|
|
97
|
+
ordinal = @db.exec_params(
|
|
98
|
+
"INSERT INTO #{quoted_journal} (era, aggregate, aggregate_id, operation, state) " \
|
|
99
|
+
"VALUES ($1, $2, $3, 'save', $4) RETURNING ordinal",
|
|
100
|
+
[merge.era, aggregate.storage_name, id, state]
|
|
101
|
+
)[0]["ordinal"]
|
|
102
|
+
upsert_winner_snapshot!(snapshot: quote(head_snapshot(aggregate.storage_name, merge.era)),
|
|
103
|
+
id: id, ordinal: ordinal, state: state)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Always 'save': winners come from save-only sources, never a delete.
|
|
107
|
+
def upsert_winner_snapshot!(snapshot:, id:, ordinal:, state:)
|
|
108
|
+
@db.exec_params(
|
|
109
|
+
"INSERT INTO #{snapshot} (id, ordinal, operation, state) " \
|
|
110
|
+
"VALUES ($1, $2, 'save', $3) " \
|
|
111
|
+
"ON CONFLICT (id) DO UPDATE SET ordinal = EXCLUDED.ordinal, operation = EXCLUDED.operation, " \
|
|
112
|
+
"state = EXCLUDED.state WHERE #{snapshot}.ordinal < EXCLUDED.ordinal",
|
|
113
|
+
[id, ordinal, state]
|
|
114
|
+
)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -8,67 +8,36 @@ module Hecks
|
|
|
8
8
|
# `mint_era!`: writes a new era in one transaction and advances the current-era
|
|
9
9
|
# RLS fence (`advance_era!`) just before commit.
|
|
10
10
|
module MintTransaction
|
|
11
|
+
# The era a mint writes: its name, frozen text, the aggregates to recompile and the
|
|
12
|
+
# edge chain that derives their heads.
|
|
13
|
+
Mint = Data.define(:ordinal, :shape_hash, :label, :held_text, :aggregates, :edges, :role, :projection) do
|
|
14
|
+
def initialize(role: nil, projection: nil, **rest) = super
|
|
15
|
+
end
|
|
16
|
+
|
|
11
17
|
# Makes a new era real in one locked transaction, or reports a concurrent minter won.
|
|
12
18
|
#
|
|
13
|
-
# @param ordinal [Integer] ordinal of the era to mint, one past the newest held era
|
|
14
19
|
# @param hash [String] the era's shape hash, SHA-256 hex
|
|
15
|
-
# @param
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
20
|
+
# @param fields [Hash] the keywords of `Mint`: `ordinal:` (one past the newest held era),
|
|
21
|
+
# `label:` (a prefix of `hash`),
|
|
22
|
+
# `held_text:` (the bluebook source to freeze as this era), `aggregates:` (whose heads
|
|
23
|
+
# are recompiled), `edges:` (the full edge chain in mint order, one per step), and
|
|
24
|
+
# optionally `role:` (app role to grant privileges to; nil grants nothing) and
|
|
25
|
+
# `projection:` (the storage-shape projection, or nil)
|
|
21
26
|
# @return [Boolean] true once committed; false, rolled back, if `ordinal` is held
|
|
22
27
|
# @raise [Runtime::WiringError] on a lock wait over 10s or a Postgres error
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@db.exec("SELECT pg_advisory_xact_lock(hashtext('hecks_eras:' || #{text_literal(@domain)}))")
|
|
28
|
-
if eras.any? { |era| era[:ordinal] == ordinal }
|
|
29
|
-
@db.exec("ROLLBACK")
|
|
30
|
-
return false
|
|
31
|
-
end
|
|
28
|
+
# @raise [ArgumentError] on a missing or unknown keyword
|
|
29
|
+
def mint_era!(hash:, **fields)
|
|
30
|
+
mint = Mint.new(shape_hash: hash, **fields)
|
|
31
|
+
return false if stand_down?(mint)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
@db.exec_params(
|
|
35
|
-
"INSERT INTO hecks_eras (domain, ordinal, hash, label, held_text, watermark, held_digest, " \
|
|
36
|
-
"held_projection, canon_form) " \
|
|
37
|
-
"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
|
38
|
-
[@domain, ordinal, hash, label, held_text, watermark, Digest::SHA256.hexdigest(held_text),
|
|
39
|
-
projection && JSON.generate(projection), Runtime::StorageShape::FORM_VERSION]
|
|
40
|
-
)
|
|
41
|
-
archive_text!(ordinal, held_text)
|
|
42
|
-
ensure_partition!(ordinal)
|
|
43
|
-
# grant_role! must follow compile_head!, which creates the per-era snapshot
|
|
44
|
-
# tables that it grants on.
|
|
45
|
-
aggregates.each { |aggregate| compile_head!(aggregate, ordinal, label, edges) }
|
|
46
|
-
grant_role!(role, aggregates: aggregates, era: ordinal) if role
|
|
47
|
-
# Must stay last, right before `COMMIT`: DROP/CREATE POLICY takes an
|
|
48
|
-
# AccessExclusiveLock held to commit, so placing it before compile_head!
|
|
49
|
-
# would block every writer for the whole matview build.
|
|
50
|
-
#
|
|
51
|
-
# Unconditional, even with no role configured: the cutoff is a fact about the
|
|
52
|
-
# era, and a role granted by an earlier boot must lose old-era writes on commit.
|
|
53
|
-
advance_era!(ordinal)
|
|
54
|
-
@db.exec("COMMIT")
|
|
33
|
+
write_era!(mint)
|
|
55
34
|
true
|
|
56
35
|
rescue PG::LockNotAvailable
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
rescue StandardError
|
|
60
|
-
nil
|
|
61
|
-
end
|
|
62
|
-
raise Runtime::WiringError,
|
|
63
|
-
"cannot mint era #{ordinal} of #{@domain}: another mint holds the domain lock — " \
|
|
64
|
-
"waited 10s; try again shortly"
|
|
36
|
+
rollback_quietly
|
|
37
|
+
raise Runtime::WiringError, lock_refusal(mint)
|
|
65
38
|
rescue PG::Error => e
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
rescue StandardError
|
|
69
|
-
nil
|
|
70
|
-
end
|
|
71
|
-
raise Runtime::WiringError, "cannot mint era #{ordinal} of #{@domain}: #{e.message.strip}"
|
|
39
|
+
rollback_quietly
|
|
40
|
+
raise Runtime::WiringError, "cannot mint era #{mint.ordinal} of #{@domain}: #{e.message.strip}"
|
|
72
41
|
end
|
|
73
42
|
|
|
74
43
|
# Grants an app role what it needs to append to the journal and read and write heads.
|
|
@@ -91,14 +60,7 @@ module Hecks
|
|
|
91
60
|
@db.exec("GRANT USAGE ON SEQUENCE #{quote(sequence)} TO #{quoted_role}")
|
|
92
61
|
return unless era
|
|
93
62
|
|
|
94
|
-
aggregates.each
|
|
95
|
-
storage_name = aggregate.storage_name
|
|
96
|
-
@db.exec("GRANT SELECT, INSERT, UPDATE, DELETE ON #{quote(head_snapshot(storage_name, era))} TO #{quoted_role}")
|
|
97
|
-
if view_exists?(head_view(storage_name))
|
|
98
|
-
@db.exec("GRANT SELECT ON #{quote(head_view(storage_name))} " \
|
|
99
|
-
"TO #{quoted_role}")
|
|
100
|
-
end
|
|
101
|
-
end
|
|
63
|
+
aggregates.each { |aggregate| grant_head!(aggregate.storage_name, era, quoted_role) }
|
|
102
64
|
end
|
|
103
65
|
|
|
104
66
|
# Replaces the journal's row policies: one era accepts INSERTs, every row stays readable.
|
|
@@ -121,6 +83,69 @@ module Hecks
|
|
|
121
83
|
@db.exec("DROP POLICY IF EXISTS hecks_read_all ON #{quoted_journal}")
|
|
122
84
|
@db.exec("CREATE POLICY hecks_read_all ON #{quoted_journal} FOR SELECT TO PUBLIC USING (true)")
|
|
123
85
|
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# Opens the mint transaction and takes the domain's mint lock. When a concurrent minter
|
|
90
|
+
# already holds this ordinal, rolls back and answers true.
|
|
91
|
+
def stand_down?(mint)
|
|
92
|
+
@db.exec("BEGIN")
|
|
93
|
+
# Mint is non-interactive, so a concurrent minter fails fast with a name, not a hang.
|
|
94
|
+
@db.exec("SET LOCAL lock_timeout = '10s'")
|
|
95
|
+
@db.exec("SELECT pg_advisory_xact_lock(hashtext('hecks_eras:' || #{text_literal(@domain)}))")
|
|
96
|
+
held = eras.any? { |era| era[:ordinal] == mint.ordinal }
|
|
97
|
+
@db.exec("ROLLBACK") if held
|
|
98
|
+
held
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def write_era!(mint)
|
|
102
|
+
insert_era!(mint)
|
|
103
|
+
materialize_era!(mint)
|
|
104
|
+
@db.exec("COMMIT")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def lock_refusal(mint)
|
|
108
|
+
"cannot mint era #{mint.ordinal} of #{@domain}: another mint holds the domain lock — " \
|
|
109
|
+
"waited 10s; try again shortly"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def insert_era!(mint)
|
|
113
|
+
@db.exec_params(
|
|
114
|
+
"INSERT INTO hecks_eras (domain, ordinal, hash, label, held_text, watermark, held_digest, " \
|
|
115
|
+
"held_projection, canon_form) " \
|
|
116
|
+
"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
|
117
|
+
[@domain, mint.ordinal, mint.shape_hash, mint.label, mint.held_text, last_ordinal,
|
|
118
|
+
Digest::SHA256.hexdigest(mint.held_text), mint.projection && JSON.generate(mint.projection),
|
|
119
|
+
Runtime::StorageShape::FORM_VERSION]
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def materialize_era!(mint)
|
|
124
|
+
archive_text!(mint.ordinal, mint.held_text)
|
|
125
|
+
ensure_partition!(mint.ordinal)
|
|
126
|
+
compile_and_grant!(mint)
|
|
127
|
+
# Must stay last, right before `COMMIT`: DROP/CREATE POLICY takes an
|
|
128
|
+
# AccessExclusiveLock held to commit, so placing it before compile_head!
|
|
129
|
+
# would block every writer for the whole matview build.
|
|
130
|
+
#
|
|
131
|
+
# Unconditional, even with no role configured: the cutoff is a fact about the
|
|
132
|
+
# era, and a role granted by an earlier boot must lose old-era writes on commit.
|
|
133
|
+
advance_era!(mint.ordinal)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# grant_role! must follow compile_head!, which creates the per-era snapshot
|
|
137
|
+
# tables that it grants on.
|
|
138
|
+
def compile_and_grant!(mint)
|
|
139
|
+
mint.aggregates.each { |aggregate| compile_head!(aggregate, mint.ordinal, mint.label, mint.edges) }
|
|
140
|
+
grant_role!(mint.role, aggregates: mint.aggregates, era: mint.ordinal) if mint.role
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def grant_head!(storage_name, era, quoted_role)
|
|
144
|
+
@db.exec("GRANT SELECT, INSERT, UPDATE, DELETE ON #{quote(head_snapshot(storage_name, era))} TO #{quoted_role}")
|
|
145
|
+
return unless view_exists?(head_view(storage_name))
|
|
146
|
+
|
|
147
|
+
@db.exec("GRANT SELECT ON #{quote(head_view(storage_name))} TO #{quoted_role}")
|
|
148
|
+
end
|
|
124
149
|
end
|
|
125
150
|
end
|
|
126
151
|
end
|