hecks 3.4.2 → 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/deploy/bluebook/deploy.bluebook +1510 -3
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +57 -0
- data/lib/hecks/deploy/oidc.json +225 -0
- 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 +91 -0
- 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 +49 -0
- 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 +122 -59
- 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 +39 -37
- 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 +19 -10
- data/lib/hecks/hecks/adapters/terminal.rb +13 -9
- data/lib/hecks/hecks/codebase.bluebook +322 -5
- data/lib/hecks/hecks/custodian.bluebook +12 -2
- data/lib/hecks/hecks/hecks.hecksagon +73 -0
- data/lib/hecks/hecks/hecks.world +15 -3
- 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 +16 -108
- 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 +62 -0
- 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 +51 -4
- data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +4 -3
- data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +16 -4
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +8 -7
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef.part +1 -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/hosting.mk.tmpl +6 -3
- 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/restore-to-rds.sh.tmpl +8 -3
- 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/verify-copy.sh.tmpl +2 -2
- data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
- data/lib/hecks/projections/deploy/box.rb +37 -503
- 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 +146 -0
- 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 +33 -0
- data/lib/hecks/projections/site/admin_cms.rb +78 -0
- 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 +137 -0
- 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 +33 -0
- data/lib/hecks/projections/site/payload/model.rb +128 -0
- data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
- data/lib/hecks/projections/site/payload/specs.rb +135 -0
- data/lib/hecks/projections/site/payload_driver.rb +95 -0
- data/lib/hecks/projections/site/root_rows.rb +67 -0
- 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 +85 -0
- 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 +109 -0
- data/lib/hecks/projections/site/site_host.rb +58 -0
- data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
- data/lib/hecks/projections/site/site_root.rb +128 -0
- 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/site/bluebook/site.bluebook +7 -1
- 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 +102 -108
- 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 +607 -3
- /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
|
@@ -3,14 +3,25 @@ require "tmpdir"
|
|
|
3
3
|
require "securerandom"
|
|
4
4
|
require_relative "outside_world"
|
|
5
5
|
require_relative "../runtime/adapter_lookup"
|
|
6
|
+
require_relative "isolated_boot/copying"
|
|
7
|
+
require_relative "isolated_boot/worlds"
|
|
8
|
+
require_relative "isolated_boot/postgres_scratch"
|
|
6
9
|
|
|
7
10
|
module Hecks
|
|
8
11
|
module Fuzzing
|
|
9
12
|
# Rewrites a copied domain's persistence bindings before an ephemeral
|
|
10
13
|
# fuzz/replay boot; a directory copy alone does not isolate Postgres state.
|
|
11
14
|
module IsolatedBoot
|
|
12
|
-
#
|
|
13
|
-
|
|
15
|
+
# Postgres has no zero-config default (Postgres.connect_for refuses without a
|
|
16
|
+
# `database` setting), so every domain name gets a fresh `.world` written for it.
|
|
17
|
+
# One shared schema, dropped and recreated per boot, not a fresh name per call —
|
|
18
|
+
# safe only because callers run one ephemeral boot at a time.
|
|
19
|
+
FUZZ_POSTGRES_DATABASE = "hecks_fuzz".freeze
|
|
20
|
+
FUZZ_POSTGRES_SCHEMA = "hecks_fuzz".freeze
|
|
21
|
+
|
|
22
|
+
extend Copying
|
|
23
|
+
extend Worlds
|
|
24
|
+
extend PostgresScratch
|
|
14
25
|
|
|
15
26
|
module_function
|
|
16
27
|
|
|
@@ -25,59 +36,22 @@ module Hecks
|
|
|
25
36
|
copy = File.join(tmp, File.basename(domain_path))
|
|
26
37
|
copy_dereferencing(domain_path, copy)
|
|
27
38
|
FileUtils.rm_rf(File.join(copy, "data"))
|
|
28
|
-
|
|
29
|
-
when :memory then rebind_to_memory!(copy)
|
|
30
|
-
when :sqlite then rebind_to_sqlite!(copy)
|
|
31
|
-
when :postgres then rebind_to_postgres!(copy, **scratch)
|
|
32
|
-
when :postgres_era then rebind_to_postgres_era!(copy, database: database, schema: schema)
|
|
33
|
-
else raise ArgumentError,
|
|
34
|
-
"unknown fuzz adapter #{adapter.inspect} — :memory, :sqlite, :postgres, or :postgres_era"
|
|
35
|
-
end
|
|
39
|
+
rebind!(copy, adapter, database: database, schema: schema, scratch: scratch)
|
|
36
40
|
Runtime::AdapterLookup.standing_in(OutsideWorld) { yield copy }
|
|
37
41
|
end
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Dir.glob(File.join(source, "**", "*"), File::FNM_DOTMATCH).each do |path|
|
|
52
|
-
next if [".", ".."].include?(File.basename(path))
|
|
53
|
-
|
|
54
|
-
target = File.join(destination, path.delete_prefix("#{source}/"))
|
|
55
|
-
if File.directory?(path)
|
|
56
|
-
FileUtils.mkdir_p(target)
|
|
57
|
-
else
|
|
58
|
-
FileUtils.mkdir_p(File.dirname(target))
|
|
59
|
-
begin
|
|
60
|
-
FileUtils.cp(path, target)
|
|
61
|
-
rescue Errno::ENOENT
|
|
62
|
-
# A sibling can vanish between listing and copy under parallel workers;
|
|
63
|
-
# skip a file that's already gone.
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Copies vendored bluebook packages a copy's hecksagons name into the copy, since
|
|
70
|
-
# `Hecks.boot` only sees the domain directory itself, not `vendor/`.
|
|
71
|
-
def carry_vendored_bluebooks!(source, destination)
|
|
72
|
-
names = Dir.glob(File.join(destination, "**", "*.hecksagon")).flat_map do |path|
|
|
73
|
-
text = File.read(path)
|
|
74
|
-
text.scan(VENDORED_ATTACHED).flatten
|
|
75
|
-
end
|
|
76
|
-
names.uniq.each do |name|
|
|
77
|
-
package = File.join(File.dirname(source), "vendor", "embryonaut_bluebooks", name)
|
|
78
|
-
next unless File.directory?(package)
|
|
79
|
-
|
|
80
|
-
copy_files(package, File.join(File.dirname(destination), "vendor", "embryonaut_bluebooks", name))
|
|
44
|
+
# Rewrites the copy's bindings for `adapter`.
|
|
45
|
+
#
|
|
46
|
+
# @raise [ArgumentError] if `adapter` is not one of the fuzz adapters
|
|
47
|
+
def rebind!(copy, adapter, database:, schema:, scratch:)
|
|
48
|
+
case adapter
|
|
49
|
+
when :memory then rebind_to_memory!(copy)
|
|
50
|
+
when :sqlite then rebind_to_sqlite!(copy)
|
|
51
|
+
when :postgres then rebind_to_postgres!(copy, **scratch)
|
|
52
|
+
when :postgres_era then rebind_to_postgres_era!(copy, database: database, schema: schema)
|
|
53
|
+
else raise ArgumentError,
|
|
54
|
+
"unknown fuzz adapter #{adapter.inspect} — :memory, :sqlite, :postgres, or :postgres_era"
|
|
81
55
|
end
|
|
82
56
|
end
|
|
83
57
|
|
|
@@ -99,207 +73,6 @@ module Hecks
|
|
|
99
73
|
strip_translations!(copy)
|
|
100
74
|
write_default_worlds!(copy, "SqlitePersistence")
|
|
101
75
|
end
|
|
102
|
-
|
|
103
|
-
# Postgres has no zero-config default (Postgres.connect_for refuses without a
|
|
104
|
-
# `database` setting), so every domain name gets a fresh `.world` written for it.
|
|
105
|
-
# One shared schema, dropped and recreated per boot, not a fresh name per call —
|
|
106
|
-
# safe only because callers run one ephemeral boot at a time.
|
|
107
|
-
FUZZ_POSTGRES_DATABASE = "hecks_fuzz".freeze
|
|
108
|
-
FUZZ_POSTGRES_SCHEMA = "hecks_fuzz".freeze
|
|
109
|
-
|
|
110
|
-
# Rewrites every `.hecksagon` in the copy to bind through Postgres, against the
|
|
111
|
-
# shared scratch schema unless the caller names its own via `scratch:`.
|
|
112
|
-
def rebind_to_postgres!(copy, database: nil, schema: nil)
|
|
113
|
-
require "pg"
|
|
114
|
-
database ||= FUZZ_POSTGRES_DATABASE
|
|
115
|
-
schema ||= FUZZ_POSTGRES_SCHEMA
|
|
116
|
-
rewrite_bindings!(copy, "Postgres")
|
|
117
|
-
strip_translations!(copy)
|
|
118
|
-
ensure_fuzz_schema!(database, schema)
|
|
119
|
-
|
|
120
|
-
# One `.world` per directory a `.hecksagon` lives in, not one at the copy's
|
|
121
|
-
# root — `Folder#load_domain` globs `*.world` non-recursively.
|
|
122
|
-
write_worlds!(copy, "hecks_fuzz_postgres.world") do |name|
|
|
123
|
-
<<~WORLD
|
|
124
|
-
Hecks.world "#{name}" do
|
|
125
|
-
default_adapter "Postgres"
|
|
126
|
-
persisted_by("Postgres") do
|
|
127
|
-
database "#{database}"
|
|
128
|
-
schema "#{schema}"
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
WORLD
|
|
132
|
-
end
|
|
133
|
-
write_unbound_chapter_worlds!(copy)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Creates `database` once per process (memoized) and drops/recreates `schema`
|
|
137
|
-
# inside it on every call — that's what isolates one ephemeral boot from the next.
|
|
138
|
-
def ensure_fuzz_schema!(database = FUZZ_POSTGRES_DATABASE, schema = FUZZ_POSTGRES_SCHEMA)
|
|
139
|
-
# PG::Connection only closes its socket when GC finalizes it, and a tight fuzz
|
|
140
|
-
# loop opens connections faster than GC reclaims them — without this, a run
|
|
141
|
-
# exhausts Postgres's max_connections after a few dozen ephemeral boots.
|
|
142
|
-
GC.start
|
|
143
|
-
|
|
144
|
-
@fuzz_databases_ready ||= {}
|
|
145
|
-
unless @fuzz_databases_ready[database]
|
|
146
|
-
admin = PG.connect(dbname: "postgres")
|
|
147
|
-
exists = admin.exec_params(
|
|
148
|
-
"SELECT 1 FROM pg_database WHERE datname = $1", [database]
|
|
149
|
-
).ntuples.positive?
|
|
150
|
-
admin.exec(%(CREATE DATABASE "#{database}")) unless exists
|
|
151
|
-
admin.close
|
|
152
|
-
@fuzz_databases_ready[database] = true
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
db = PG.connect(dbname: database)
|
|
156
|
-
# Quiet on purpose: an ordinary DROP CASCADE NOTICEs per dropped object, which
|
|
157
|
-
# would bury hecks fuzz's own output on every boot after the first.
|
|
158
|
-
db.exec("SET client_min_messages = warning")
|
|
159
|
-
quoted = db.quote_ident(schema)
|
|
160
|
-
db.exec("DROP SCHEMA IF EXISTS #{quoted} CASCADE")
|
|
161
|
-
db.exec("CREATE SCHEMA #{quoted}")
|
|
162
|
-
db.close
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# `:postgres_era` is the only mode that exercises era/lineage-bound SQL; plain
|
|
166
|
-
# `:postgres` never touches that machinery. Unlike `:postgres`, there's no shared
|
|
167
|
-
# scratch constant here — `database:`/`schema:` are required keyword args because
|
|
168
|
-
# the caller (`hecks quality_control query sweep.run --persistence-parity`) owns that
|
|
169
|
-
# database's lifecycle.
|
|
170
|
-
def rebind_to_postgres_era!(copy, database:, schema:)
|
|
171
|
-
require "pg"
|
|
172
|
-
if database.to_s.empty? || schema.to_s.empty?
|
|
173
|
-
raise ArgumentError,
|
|
174
|
-
"adapter: :postgres_era requires both database: and schema: — a throwaway database/schema " \
|
|
175
|
-
"THIS CALLER creates and drops itself (see rebind_to_postgres_era!'s own header). " \
|
|
176
|
-
"There is no shared default, unlike :postgres, so the caller cannot forget to own the lifecycle."
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
rewrite_bindings!(copy, "PostgresEra")
|
|
180
|
-
ensure_postgres_era_schema!(database: database, schema: schema)
|
|
181
|
-
|
|
182
|
-
# `schema:` isolates one ephemeral boot from the next, the same job
|
|
183
|
-
# `FUZZ_POSTGRES_SCHEMA` does for `:postgres` (`connect_for` idempotently
|
|
184
|
-
# creates it; this method only needs to drop it first, in
|
|
185
|
-
# `ensure_postgres_era_schema!`).
|
|
186
|
-
#
|
|
187
|
-
# `allow_superuser true` is deliberate: PostgresEra normally refuses to boot as
|
|
188
|
-
# a superuser (its era write-fence is row-level security, which a superuser
|
|
189
|
-
# bypasses), to protect a real ledger from stale writes. This is a throwaway
|
|
190
|
-
# schema the caller creates and drops, comparing Memory against PostgresEra's
|
|
191
|
-
# SQL — the era fence isn't under test, so opting in here is safe.
|
|
192
|
-
write_worlds!(copy, "hecks_fuzz_postgres_era.world") do |name|
|
|
193
|
-
<<~WORLD
|
|
194
|
-
Hecks.world "#{name}" do
|
|
195
|
-
default_adapter "PostgresEra"
|
|
196
|
-
persisted_by("PostgresEra") do
|
|
197
|
-
database "#{database}"
|
|
198
|
-
schema "#{schema}"
|
|
199
|
-
allow_superuser true
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
WORLD
|
|
203
|
-
end
|
|
204
|
-
write_unbound_chapter_worlds!(copy)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
# Replaces every `.world` in the copy with one that declares only `default_adapter`,
|
|
208
|
-
# so an aggregate left unbound by its hecksagon still falls back to `adapter_name`.
|
|
209
|
-
def write_default_worlds!(copy, adapter_name)
|
|
210
|
-
write_worlds!(copy, "hecks_fuzz_default.world") do |name|
|
|
211
|
-
<<~WORLD
|
|
212
|
-
Hecks.world "#{name}" do
|
|
213
|
-
default_adapter "#{adapter_name}"
|
|
214
|
-
end
|
|
215
|
-
WORLD
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
# Gives every chapter with no hecksagon block (so no bind) a world of its own that
|
|
220
|
-
# falls back to Memory, since the worlds `write_worlds!` wrote require a database
|
|
221
|
-
# a chapter with no bind can't provide.
|
|
222
|
-
def write_unbound_chapter_worlds!(copy)
|
|
223
|
-
named = Dir.glob(File.join(copy, "**", "*.hecksagon")).flat_map do |path|
|
|
224
|
-
File.read(path).scan(/Hecks\.hecksagon\s+"([^"]+)"/).flatten
|
|
225
|
-
end
|
|
226
|
-
bluebooks = Dir.glob(File.join(copy, "**", "*.bluebook")).group_by { |path| File.dirname(path) }
|
|
227
|
-
bluebooks.each do |dir, files|
|
|
228
|
-
unbound = files.flat_map { |path| File.read(path).scan(/Hecks\.bluebook[\s(]+"([^"]+)"/).flatten }
|
|
229
|
-
.uniq - named
|
|
230
|
-
named.concat(unbound)
|
|
231
|
-
next if unbound.empty?
|
|
232
|
-
|
|
233
|
-
worlds = unbound.map { |name| %(Hecks.world "#{name}" do\n default_adapter "Memory"\nend\n) }
|
|
234
|
-
File.write(File.join(dir, "hecks_fuzz_unbound.world"), worlds.join("\n"))
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
# Writes one `.world` per directory holding a `.hecksagon`, naming every
|
|
239
|
-
# `Hecks.hecksagon` block found there, and deletes every other `.world` in the
|
|
240
|
-
# copy. One write per directory, not per file — a domain can split hecksagon
|
|
241
|
-
# blocks (e.g. `context_map.hecksagon` beside the main one) across sibling files
|
|
242
|
-
# in the same directory, and a second `File.write` to the same path would drop
|
|
243
|
-
# the first file's names.
|
|
244
|
-
def write_worlds!(copy, world_file, &world_for)
|
|
245
|
-
names_by_dir = Hash.new { |hash, dir| hash[dir] = [] }
|
|
246
|
-
Dir.glob(File.join(copy, "**", "*.hecksagon")).each do |hecksagon_path|
|
|
247
|
-
names = File.read(hecksagon_path).scan(/Hecks\.hecksagon\s+"([^"]+)"/).flatten
|
|
248
|
-
names_by_dir[File.dirname(hecksagon_path)].concat(names)
|
|
249
|
-
end
|
|
250
|
-
names_by_dir.each do |dir, names|
|
|
251
|
-
next if names.empty?
|
|
252
|
-
|
|
253
|
-
File.write(File.join(dir, world_file), names.uniq.map(&world_for).join("\n"))
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
Dir.glob(File.join(copy, "**", "*.world")).each do |path|
|
|
257
|
-
File.delete(path) unless File.basename(path) == world_file
|
|
258
|
-
end
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# Mirrors `ensure_fuzz_schema!`'s GC.start-before-connecting fix for the same
|
|
262
|
-
# max_connections exhaustion. Creates `database` if missing, but never drops
|
|
263
|
-
# it — that's the caller's job (see `rebind_to_postgres_era!`).
|
|
264
|
-
def ensure_postgres_era_schema!(database:, schema:)
|
|
265
|
-
GC.start
|
|
266
|
-
|
|
267
|
-
admin = PG.connect(dbname: "postgres")
|
|
268
|
-
exists = admin.exec_params(
|
|
269
|
-
"SELECT 1 FROM pg_database WHERE datname = $1", [database]
|
|
270
|
-
).ntuples.positive?
|
|
271
|
-
admin.exec(%(CREATE DATABASE "#{database}")) unless exists
|
|
272
|
-
admin.close
|
|
273
|
-
|
|
274
|
-
db = PG.connect(dbname: database)
|
|
275
|
-
db.exec("SET client_min_messages = warning")
|
|
276
|
-
quoted = db.quote_ident(schema)
|
|
277
|
-
db.exec("DROP SCHEMA IF EXISTS #{quoted} CASCADE")
|
|
278
|
-
db.close
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
# Deletes every `translations/*.bluebook` in the copy. A compute/rekey translation
|
|
282
|
-
# edge refuses to boot under any non-lineage-capable adapter (only `PostgresEra`
|
|
283
|
-
# answers `lineage_capable? == true`), so every other mode strips it here rather
|
|
284
|
-
# than tripping that refusal. Safe to drop: an ephemeral, zero-history boot never
|
|
285
|
-
# has a pre-existing era-1 row to translate — the edge only matters at mint time,
|
|
286
|
-
# against a real database, never here.
|
|
287
|
-
def strip_translations!(copy)
|
|
288
|
-
Dir.glob(File.join(copy, "**", "translations", "*.bluebook")).each { |path| File.delete(path) }
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# Rewrites every `persisted_by` bind — aggregate-scoped or bare at the hecksagon's
|
|
292
|
-
# own root, naming its adapter as a literal or through a local variable — to name
|
|
293
|
-
# `adapter_name`, and drops every `projected_by` bind outright (unread rather than
|
|
294
|
-
# broken, since `Registry#read_repository` falls back to the authoritative repo).
|
|
295
|
-
def rewrite_bindings!(copy, adapter_name)
|
|
296
|
-
Dir.glob(File.join(copy, "**", "*.hecksagon")).each do |path|
|
|
297
|
-
lines = File.readlines(path).grep_v(/\bprojected_by\s*\(?\s*"/)
|
|
298
|
-
# Horizontal space only: a newline ends the statement, and the next one must stay.
|
|
299
|
-
bind = /persisted_by[ \t]*\(?[ \t]*(?:"[^"]+"|[a-z_]\w*)[ \t]*\)?/
|
|
300
|
-
File.write(path, lines.join.gsub(bind, "persisted_by(\"#{adapter_name}\")"))
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
76
|
end
|
|
304
77
|
end
|
|
305
78
|
end
|
|
@@ -17,13 +17,13 @@ module Hecks
|
|
|
17
17
|
# @param left [Symbol] an `IsolatedBoot` adapter: `:memory`, `:sqlite`, `:postgres`,
|
|
18
18
|
# `:postgres_era`
|
|
19
19
|
# @param right [Symbol] the second adapter, same set as `left`
|
|
20
|
-
# @param
|
|
21
|
-
#
|
|
20
|
+
# @param storage [Hash] connection settings `Replay.call` takes, passed to both sides:
|
|
21
|
+
# `database:` and `schema:` (strings, required when either side is `:postgres_era`)
|
|
22
22
|
# @return [Array<Hash>] entries `{field: String, left => Object, right => Object}`,
|
|
23
23
|
# keyed by the adapter symbols; empty if both sides agree
|
|
24
|
-
def diff(domain_path, steps, left: :memory, right: :postgres_era,
|
|
25
|
-
left_result = Replay.call(domain_path, steps, adapter: left,
|
|
26
|
-
right_result = Replay.call(domain_path, steps, adapter: right,
|
|
24
|
+
def diff(domain_path, steps, left: :memory, right: :postgres_era, **storage)
|
|
25
|
+
left_result = Replay.call(domain_path, steps, adapter: left, **storage)
|
|
26
|
+
right_result = Replay.call(domain_path, steps, adapter: right, **storage)
|
|
27
27
|
|
|
28
28
|
divergences = []
|
|
29
29
|
divergences.concat(diff_instances(left_result, right_result, left, right))
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Fuzzing
|
|
3
|
+
module Properties
|
|
4
|
+
# Independent recomputations of read-model reductions and `group_by` nestings, for
|
|
5
|
+
# `InvariantsAndAggregation` to compare against what a query actually answered.
|
|
6
|
+
module AggregationRecompute
|
|
7
|
+
# The read model a recorded ask named, when it belongs to `bluebook`.
|
|
8
|
+
def asked_read_model(bluebook, asked)
|
|
9
|
+
domain, name = asked[:query].to_s.split(".", 2)
|
|
10
|
+
bluebook.read_model(name) if name && domain == bluebook.name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The head a read model reduces or groups: the one declared `many`.
|
|
14
|
+
def many_head(model) = model.aggregate_heads.find { |head| head[:many] }
|
|
15
|
+
|
|
16
|
+
# ADR 0078's siblings of `count`/`median`, each an independent fold over the same
|
|
17
|
+
# eligible rows — never reusing ReadModelInterpreter#reduce's own arithmetic, only the
|
|
18
|
+
# shared field-reading primitives `recompute_median` already relied on.
|
|
19
|
+
def recompute_reduction(model, rows)
|
|
20
|
+
return rows.length if model.count?
|
|
21
|
+
return recompute_median(rows, model.median_field) if model.median_field
|
|
22
|
+
return recompute_values(rows, model.sum_field).sum if model.sum_field
|
|
23
|
+
return recompute_avg(rows, model.avg_field) if model.avg_field
|
|
24
|
+
|
|
25
|
+
recompute_extremum_or_flag(model, rows)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The `min`, `max`, `percentile`, `any` and `all` folds of `recompute_reduction`.
|
|
29
|
+
def recompute_extremum_or_flag(model, rows)
|
|
30
|
+
return recompute_values(rows, model.min_field).min if model.min_field
|
|
31
|
+
return recompute_values(rows, model.max_field).max if model.max_field
|
|
32
|
+
|
|
33
|
+
recompute_percentile_or_flag(model, rows)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The `percentile`, `any` and `all` folds of `recompute_reduction`.
|
|
37
|
+
def recompute_percentile_or_flag(model, rows)
|
|
38
|
+
return recompute_percentile(rows, model.percentile_field, model.percentile_at) if model.percentile_field
|
|
39
|
+
return recompute_values(rows, model.any_field).any? if model.any_field
|
|
40
|
+
|
|
41
|
+
recompute_values(rows, model.all_field).all?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def recompute_values(rows, field)
|
|
45
|
+
rows.map { |state| comparable_field(state, field) }.compact
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# A field's value as the interpreter itself compares it.
|
|
49
|
+
def comparable_field(state, field)
|
|
50
|
+
Ports::Query::InMemory.comparable(QuerySpecification::FieldPath.dig(state, field))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def recompute_avg(rows, field)
|
|
54
|
+
values = recompute_values(rows, field)
|
|
55
|
+
values.empty? ? nil : values.sum.to_f / values.length
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Same linear-interpolation formula as `ReadModelInterpreter#percentile`, written
|
|
59
|
+
# independently here rather than called, for the same reason `recompute_median`
|
|
60
|
+
# already is: an oracle that calls the interpreter's own fold agrees with a bug in it
|
|
61
|
+
# by construction (ADR 0061's `nest_rows` lesson).
|
|
62
|
+
def recompute_percentile(rows, field, at)
|
|
63
|
+
values = recompute_values(rows, field).sort
|
|
64
|
+
return nil if values.empty?
|
|
65
|
+
|
|
66
|
+
interpolate(values, at * (values.length - 1))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def interpolate(values, position)
|
|
70
|
+
lower = position.floor
|
|
71
|
+
fraction = position - lower
|
|
72
|
+
fraction.zero? ? values[lower] : values[lower] + (fraction * (values[lower + 1] - values[lower]))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# ReadModelInterpreter#median's own definition, reproduced: the true
|
|
76
|
+
# middle for an odd count, the average of the two middles for an even
|
|
77
|
+
# count, `nil` for empty — never zero, so "nothing" isn't "zero."
|
|
78
|
+
def recompute_median(rows, field)
|
|
79
|
+
values = rows.map { |state| comparable_field(state, field) }.compact.sort
|
|
80
|
+
return nil if values.empty?
|
|
81
|
+
|
|
82
|
+
middle = values.length / 2
|
|
83
|
+
values.length.odd? ? values[middle] : (values[middle - 1] + values[middle]) / 2.0
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# The eligible rows a `count`/`median` head reduces: every instance of
|
|
87
|
+
# the reduced head's own aggregate, FK-matched against the report's root
|
|
88
|
+
# reference (if any), then narrowed by the report's own `where` clauses.
|
|
89
|
+
def eligible_rows(bluebook, instances, model, reduced_head, args)
|
|
90
|
+
prefix = "#{bluebook.name}::#{reduced_head[:aggregate]}#"
|
|
91
|
+
# `id:` merged in, the same shape every live head row carries —
|
|
92
|
+
# count/median never read it, but group_by's own nesting does.
|
|
93
|
+
rows = instances.filter_map { |key, state| state.merge(id: key.split("#").last) if key.start_with?(prefix) }
|
|
94
|
+
rows = rows_for_reference(rows, bluebook.aggregate(reduced_head[:aggregate]), model, args) if model.reference_target
|
|
95
|
+
|
|
96
|
+
rows.select { |state| satisfies_wheres?(model, state, args) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# The rows whose foreign key holds the root reference the ask named.
|
|
100
|
+
def rows_for_reference(rows, aggregate, model, args)
|
|
101
|
+
reference_id = args[model.reference_name].to_s
|
|
102
|
+
fk_fields = foreign_key_fields(aggregate, model)
|
|
103
|
+
rows.select { |state| fk_fields.any? { |field| state[field].to_s == reference_id } }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# The names of `aggregate`'s attributes referencing the read model's root.
|
|
107
|
+
def foreign_key_fields(aggregate, model)
|
|
108
|
+
aggregate.attributes.select do |attribute|
|
|
109
|
+
attribute.reference? && attribute.type.target_name == model.reference_target.to_s
|
|
110
|
+
end.map(&:name)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def satisfies_wheres?(model, state, args)
|
|
114
|
+
model.wheres.all? do |clause|
|
|
115
|
+
Ports::Query::InMemory.holds?(clause, comparable_field(state, clause.field), args)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Fuzzing
|
|
3
|
+
module Properties
|
|
4
|
+
# The standard battery, in the order `check` reports it.
|
|
5
|
+
PROPERTY_NAMES = [
|
|
6
|
+
:lifecycle_values_are_declared,
|
|
7
|
+
:saga_advances_follow_declared_handlers,
|
|
8
|
+
:query_answers_match_reference,
|
|
9
|
+
:guard_refusals_are_declared,
|
|
10
|
+
:sagas_rehydrate_cleanly,
|
|
11
|
+
:fanout_dispatches_once_per_matching_row,
|
|
12
|
+
:aggregation_matches_recompute,
|
|
13
|
+
:stored_records_satisfy_declared_invariants,
|
|
14
|
+
:group_by_matches_recompute,
|
|
15
|
+
:paging_offset_partitions_correctly,
|
|
16
|
+
:lifecycle_guard_and_given_violations_are_refused,
|
|
17
|
+
:authorize_scopes_or_refuses,
|
|
18
|
+
:commands_respect_tenant_scope,
|
|
19
|
+
:dispatch_binding_fidelity,
|
|
20
|
+
:mutations_match_recompute,
|
|
21
|
+
:dry_runs_leave_no_trace,
|
|
22
|
+
:corrections_reference_an_emitted_event,
|
|
23
|
+
:outbox_rows_match_reactions,
|
|
24
|
+
:policy_reactions_follow_declared_wiring,
|
|
25
|
+
:declared_undelivered_policies_stay_undelivered,
|
|
26
|
+
:references_resolve_to_earlier_records
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
# Which language feature each property is answerable for — exhaustive of
|
|
30
|
+
# what would go unchecked without it, not of everything its body touches.
|
|
31
|
+
FEATURE_COVERAGE = {
|
|
32
|
+
lifecycle_values_are_declared: %w[Aggregate#state_field Aggregate#state_start Aggregate#transitions
|
|
33
|
+
Entity#state_field Entity#state_start Entity#transitions],
|
|
34
|
+
saga_advances_follow_declared_handlers: %w[Handler#from_state Handler#to_state Handler#event_type],
|
|
35
|
+
query_answers_match_reference: %w[Query#wheres Query#order_field Query#order_way Query#limit],
|
|
36
|
+
paging_offset_partitions_correctly: %w[Query#options],
|
|
37
|
+
authorize_scopes_or_refuses: %w[Query#options],
|
|
38
|
+
guard_refusals_are_declared: %w[Command#givens Command#ensures Command#needs],
|
|
39
|
+
lifecycle_guard_and_given_violations_are_refused: %w[Command#from Aggregate#preconditions Entity#preconditions],
|
|
40
|
+
# Dispatch#command_name/with_spec aren't claimable feature names — the
|
|
41
|
+
# coverage walk only reaches one level of entity nesting and Dispatch
|
|
42
|
+
# sits two deep — but this property still checks the real behavior
|
|
43
|
+
# (dispatch_args) those names would have covered.
|
|
44
|
+
dispatch_binding_fidelity: %w[Handler#dispatches Policy#with_spec],
|
|
45
|
+
mutations_match_recompute: %w[Command#mutations],
|
|
46
|
+
sagas_rehydrate_cleanly: %w[ProcessManager#states ProcessManager#correlates_by
|
|
47
|
+
ProcessManager#starts_on ProcessManager#ends_on],
|
|
48
|
+
fanout_dispatches_once_per_matching_row: %w[Policy#for_each Policy#where],
|
|
49
|
+
aggregation_matches_recompute: %w[ReadModel#count ReadModel#median_field ReadModel#sum_field
|
|
50
|
+
ReadModel#avg_field ReadModel#min_field ReadModel#max_field
|
|
51
|
+
ReadModel#percentile_field ReadModel#percentile_at
|
|
52
|
+
ReadModel#any_field ReadModel#all_field],
|
|
53
|
+
stored_records_satisfy_declared_invariants: %w[Aggregate#invariants Entity#invariants],
|
|
54
|
+
group_by_matches_recompute: %w[ReadModel#group_by],
|
|
55
|
+
# A runtime door, not a grammar construct — `Dispatcher#dry_run?` is not
|
|
56
|
+
# a word a bluebook declares. Listed empty rather than omitted, so every
|
|
57
|
+
# property still names what it is answerable for.
|
|
58
|
+
dry_runs_leave_no_trace: [],
|
|
59
|
+
# Another runtime door, not a grammar construct — same reasoning as
|
|
60
|
+
# dry_runs_leave_no_trace above.
|
|
61
|
+
outbox_rows_match_reactions: [],
|
|
62
|
+
# Reads command.mutations for :corrects ops — the same list
|
|
63
|
+
# mutations_match_recompute reads, for a different question.
|
|
64
|
+
corrections_reference_an_emitted_event: %w[Command#mutations],
|
|
65
|
+
# Reads each logged reaction back against the policy that produced it: the event it
|
|
66
|
+
# answers, the trigger it builds, and the domain `across` sends it to.
|
|
67
|
+
policy_reactions_follow_declared_wiring: %w[Policy#on_event Policy#trigger_command Policy#target_domain],
|
|
68
|
+
# model_check holds the static half of `expect_undelivered`; this is the runtime half.
|
|
69
|
+
declared_undelivered_policies_stay_undelivered: %w[Policy#expect_undelivered],
|
|
70
|
+
# An accepted referencing command addressed a record an earlier event created.
|
|
71
|
+
references_resolve_to_earlier_records: %w[Command#references],
|
|
72
|
+
# No feature string exists for what this reads: an argument's own
|
|
73
|
+
# `relationship` (Argument is a value object, outside the meta-domain
|
|
74
|
+
# walk). Its declaration side, `Query#options`, is already claimed by
|
|
75
|
+
# authorize_scopes_or_refuses.
|
|
76
|
+
commands_respect_tenant_scope: []
|
|
77
|
+
}.freeze
|
|
78
|
+
|
|
79
|
+
# Features a replay could never observe violated, because construction
|
|
80
|
+
# makes the violation impossible to produce — not untested, but
|
|
81
|
+
# unfalsifiable. Each entry names the runtime path that guarantees it;
|
|
82
|
+
# add one only after reading and confirming that path (mirrors the
|
|
83
|
+
# discipline spec/fuzzing/meta_domain_coverage_spec.rb's KNOWN_GAPS demands
|
|
84
|
+
# in the other direction).
|
|
85
|
+
GUARANTEED_BY_CONSTRUCTION = {
|
|
86
|
+
"Aggregate#attributes" => "every field's pattern/closed-set/type passes through Value.build's one coercion " \
|
|
87
|
+
"door (value/coercion.rb#check_patterns, value/admission.rb) before it can exist " \
|
|
88
|
+
"— a stored value that violated its own declared shape was never producible to " \
|
|
89
|
+
"begin with",
|
|
90
|
+
"Aggregate#value_objects" => "the shape being coerced above — same door, same guarantee",
|
|
91
|
+
# S17, ADR 0026 — saga_advances_follow_declared_handlers already walks
|
|
92
|
+
# this list to find event_type/from_state/to_state; same door, same guarantee.
|
|
93
|
+
"ProcessManager#handlers" => "saga_advances_follow_declared_handlers already walks this list to find " \
|
|
94
|
+
"event_type/from_state/to_state — same door, same guarantee",
|
|
95
|
+
"Aggregate#identified_by" => "CommandInterpreter's data-driven dispatch order refuses AlreadyExists " \
|
|
96
|
+
"(command_interpreter.rb, command.creates?) for every creating command uniformly, " \
|
|
97
|
+
"before a duplicate id can ever be stored — collision is refused at the door, not " \
|
|
98
|
+
"produced and later caught",
|
|
99
|
+
"Entity#identified_by" => "EntityElement.check_entity_collision (runtime/entity_element.rb, moved there " \
|
|
100
|
+
"BUG#145 so both call sites share it) checks Array(current) against every part " \
|
|
101
|
+
"of the entity's own identity before an append can land — MutationApplier#" \
|
|
102
|
+
"entity_element's aggregate-owned call (Workspace.boards, on both branches " \
|
|
103
|
+
"identity arrives by: caller-supplied, or composite) AND EntityElement#" \
|
|
104
|
+
"appended_to_element's entity-owned, nested-one-hop-further call (Board.cards — " \
|
|
105
|
+
"unconditional, no auto-mint branch exists at that depth) — the same " \
|
|
106
|
+
"AlreadyExists refusal Aggregate#identified_by gets above, one or two levels " \
|
|
107
|
+
"down. Auto-minted (aggregate-owned) entities never reach the check " \
|
|
108
|
+
"(current.size + 1 can't repeat unless something remove:s from the list between " \
|
|
109
|
+
"mints, which no real domain does today — see the comment on #entity_element " \
|
|
110
|
+
"itself)",
|
|
111
|
+
"Command#attributes" => "command arguments are coerced through the SAME Value.build door as any other " \
|
|
112
|
+
"attribute — an accepted dispatch's own args already passed pattern/admits/invariant checks",
|
|
113
|
+
"Command#emits" => "CommandRules::Emission#emit iterates command.emits ITSELF to construct every " \
|
|
114
|
+
"announced Event (command_rules/emission.rb) — there is no other path to emit, so " \
|
|
115
|
+
"a command can never announce a name its own declaration doesn't list",
|
|
116
|
+
"Query#attributes" => "query arguments are coerced through the same Value.build door — same guarantee as " \
|
|
117
|
+
"Command#attributes",
|
|
118
|
+
"Query#returns" => "every row a port answers is built as the returned value object by Value.build " \
|
|
119
|
+
"(QueryInterpreter#shaped) before it enters the domain — an answer of any other " \
|
|
120
|
+
"shape is refused, so none can be accepted",
|
|
121
|
+
"Entity#attributes" => "same coercion door, one level in — an entity's own attributes are Value-typed exactly " \
|
|
122
|
+
"the way an aggregate's are",
|
|
123
|
+
"ValueObject#attributes" => "the shape Value.build enforces IS this declaration — the guarantee and the " \
|
|
124
|
+
"feature are the same fact seen from two sides",
|
|
125
|
+
"ValueObject#invariants" => "run inside the SAME coercion call (coercion.rb, before construction returns) " \
|
|
126
|
+
"that pattern-checks a VO's fields — a VO whose invariant did not hold could not " \
|
|
127
|
+
"finish being built",
|
|
128
|
+
"ValueObject#rows" => "closed-set membership is checked in value/admission.rb, the second half of the same " \
|
|
129
|
+
"one construction door",
|
|
130
|
+
# S17, ADR 0026 — Member is a genuine entity, so this reads Member#pairs,
|
|
131
|
+
# not Member#shape. ValueObject#members is the same fact ValueObject#rows
|
|
132
|
+
# counts, seen from the other side.
|
|
133
|
+
"ValueObject#members" => "the members list IS what ValueObject#rows counts — same door, same guarantee",
|
|
134
|
+
"Member#pairs" => "one level into ValueObject#rows — same door"
|
|
135
|
+
}.freeze
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -19,26 +19,25 @@ module Hecks
|
|
|
19
19
|
|
|
20
20
|
(history[:bluebooks] || {}).each do |domain, bluebook|
|
|
21
21
|
bluebook.aggregates.each do |aggregate|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
corrects_mutations = command.mutations.select { |mutation| mutation.op == :corrects }
|
|
26
|
-
next if corrects_mutations.empty?
|
|
22
|
+
violations.concat(aggregate_corrections(history[:events], "#{domain}::#{aggregate.hecks_name}", aggregate))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
violations.empty? || violations.uniq.join("; ")
|
|
27
|
+
end
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
# Every unmatched correction among the commands of `aggregate` and its entities.
|
|
30
|
+
def aggregate_corrections(events, aggregate_key, aggregate)
|
|
31
|
+
found = []
|
|
32
|
+
each_command_including_entities(aggregate) do |command|
|
|
33
|
+
command.mutations.select { |mutation| mutation.op == :corrects }.each do |mutation|
|
|
34
|
+
command.emits.each do |produced_event_name|
|
|
35
|
+
found.concat(unmatched_corrections(events, aggregate_key, produced_event_name.to_s,
|
|
36
|
+
mutation.target.to_s, command.hecks_name))
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
|
|
41
|
-
violations.empty? || violations.uniq.join("; ")
|
|
40
|
+
found
|
|
42
41
|
end
|
|
43
42
|
|
|
44
43
|
# Finds every occurrence of `produced_event_name`, on `aggregate_key`, with no
|
|
@@ -58,11 +57,7 @@ module Hecks
|
|
|
58
57
|
end
|
|
59
58
|
|
|
60
59
|
own_events.filter_map do |event, index|
|
|
61
|
-
|
|
62
|
-
next if preceding.any? do |earlier|
|
|
63
|
-
earlier[:name] == corrected_event && earlier[:aggregate] == aggregate_key &&
|
|
64
|
-
earlier[:id].to_s == event[:id].to_s
|
|
65
|
-
end
|
|
60
|
+
next if corrected_earlier?(events.first(index), aggregate_key, corrected_event, event)
|
|
66
61
|
|
|
67
62
|
"#{command_name} (#{aggregate_key}##{event[:id]}) emitted #{produced_event_name}, claiming to " \
|
|
68
63
|
"correct #{corrected_event}, but no #{corrected_event} for the same aggregate/id appears " \
|
|
@@ -70,6 +65,14 @@ module Hecks
|
|
|
70
65
|
end
|
|
71
66
|
end
|
|
72
67
|
|
|
68
|
+
# Whether `preceding` holds the corrected event for `event`'s aggregate and id.
|
|
69
|
+
def corrected_earlier?(preceding, aggregate_key, corrected_event, event)
|
|
70
|
+
preceding.any? do |earlier|
|
|
71
|
+
earlier[:name] == corrected_event && earlier[:aggregate] == aggregate_key &&
|
|
72
|
+
earlier[:id].to_s == event[:id].to_s
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
73
76
|
# Yields every command on `owner` and, recursively, on its entities (ADR 0026).
|
|
74
77
|
#
|
|
75
78
|
# @param owner [Bluebook::Aggregate, Bluebook::Entity] the aggregate or entity
|