hecks 3.5.0 → 3.7.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 +102 -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/prebuilt.rb +44 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache/tagging.rb +63 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +25 -60
- 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/cache_dir.rb +10 -0
- 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 +109 -0
- data/lib/hecks/deploy/oidc.json +10 -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 +32 -16
- 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 +49 -24
- 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/failure_triage.rb +80 -0
- data/lib/hecks/fuzzing/form_census/chapter_forms.rb +38 -0
- data/lib/hecks/fuzzing/form_census/reference_forms.rb +49 -0
- data/lib/hecks/fuzzing/form_census.rb +44 -58
- 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 +148 -0
- data/lib/hecks/fuzzing/isolated_boot/scratch_schema.rb +27 -0
- data/lib/hecks/fuzzing/isolated_boot/worlds.rb +102 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +29 -252
- data/lib/hecks/fuzzing/mutation/checks.rb +76 -0
- data/lib/hecks/fuzzing/mutation/finders.rb +136 -0
- data/lib/hecks/fuzzing/mutation/judge.rb +94 -0
- data/lib/hecks/fuzzing/mutation/observation.rb +38 -0
- data/lib/hecks/fuzzing/mutation/operators.rb +52 -0
- data/lib/hecks/fuzzing/mutation/report.rb +78 -0
- data/lib/hecks/fuzzing/mutation/run.rb +99 -0
- data/lib/hecks/fuzzing/mutation/selection.rb +32 -0
- data/lib/hecks/fuzzing/mutation/site.rb +21 -0
- data/lib/hecks/fuzzing/mutation/source_map.rb +59 -0
- data/lib/hecks/fuzzing/mutation.rb +12 -0
- 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 +89 -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/guaranteed_by_construction.rb +63 -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/read_model_names.rb +50 -0
- data/lib/hecks/fuzzing/properties/read_models.rb +138 -0
- data/lib/hecks/fuzzing/properties/references.rb +100 -0
- data/lib/hecks/fuzzing/properties/role_checks.rb +50 -0
- data/lib/hecks/fuzzing/properties/tenant_scope.rb +84 -0
- data/lib/hecks/fuzzing/properties.rb +13 -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/role_check.rb +49 -0
- data/lib/hecks/fuzzing/replay/session.rb +167 -0
- data/lib/hecks/fuzzing/replay.rb +36 -442
- data/lib/hecks/fuzzing/runtime_coverage.rb +70 -0
- 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/value_simplification.rb +64 -0
- data/lib/hecks/fuzzing/shrinker.rb +36 -29
- data/lib/hecks/fuzzing/target_capabilities.rb +10 -4
- data/lib/hecks/fuzzing/value_generator.rb +27 -17
- data/lib/hecks/fuzzing.rb +3 -0
- data/lib/hecks/gate/stages.yml +11 -1
- data/lib/hecks/grammar/evolve/arguments.rb +90 -0
- data/lib/hecks/grammar/evolve/keywords.rb +81 -0
- data/lib/hecks/grammar/evolve/seeds.rb +172 -0
- data/lib/hecks/grammar/evolve.rb +22 -263
- data/lib/hecks/grammar/operators.rb +111 -0
- data/lib/hecks/grammar.rb +53 -126
- data/lib/hecks/hecks/adapters/bluebook_report.rb +6 -6
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +23 -9
- data/lib/hecks/hecks/adapters/codebase/language/edits.rb +75 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +30 -72
- data/lib/hecks/hecks/adapters/codebase/promotion/candidates.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/gate.rb +50 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/move.rb +70 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/standing.rb +88 -0
- data/lib/hecks/hecks/adapters/codebase/promotion/watch.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/promotion.rb +115 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +31 -12
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +43 -6
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +16 -5
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +9 -1
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/style.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +11 -5
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +27 -8
- data/lib/hecks/hecks/adapters/console_capture.rb +21 -17
- data/lib/hecks/hecks/adapters/cost_explorer.rb +11 -6
- data/lib/hecks/hecks/adapters/deploy_plans.rb +3 -3
- data/lib/hecks/hecks/adapters/deploy_toolchain/answers.rb +142 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/scripts.rb +95 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +74 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +21 -239
- data/lib/hecks/hecks/adapters/finding_github.rb +2 -2
- data/lib/hecks/hecks/adapters/first_admin.rb +22 -8
- data/lib/hecks/hecks/adapters/git.rb +18 -5
- data/lib/hecks/hecks/adapters/git_refs.rb +144 -0
- data/lib/hecks/hecks/adapters/github_rulesets.rb +128 -0
- data/lib/hecks/hecks/adapters/host_http.rb +16 -6
- data/lib/hecks/hecks/adapters/in_process_boot.rb +9 -5
- data/lib/hecks/hecks/adapters/in_process_operations/tailing.rb +61 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +33 -35
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +21 -15
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +29 -12
- data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +52 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +52 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +5 -62
- data/lib/hecks/hecks/adapters/local_files.rb +27 -10
- data/lib/hecks/hecks/adapters/pg_admin/ownership.rb +115 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +14 -87
- data/lib/hecks/hecks/adapters/process_pool.rb +75 -21
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +12 -4
- data/lib/hecks/hecks/adapters/site_toolchain.rb +16 -7
- data/lib/hecks/hecks/adapters/terminal.rb +13 -9
- data/lib/hecks/hecks/codebase.bluebook +322 -5
- data/lib/hecks/hecks/custodian.behaviors +6 -0
- data/lib/hecks/hecks/custodian.bluebook +37 -0
- data/lib/hecks/hecks/hecks.hecksagon +22 -0
- data/lib/hecks/hecks/hecks.world +10 -2
- data/lib/hecks/kernel_capabilities/templates.rb +92 -0
- data/lib/hecks/kernel_capabilities.rb +18 -85
- data/lib/hecks/language/bluebook/vocabulary.bluebook +46 -1
- data/lib/hecks/literal/item_splitter.rb +50 -0
- data/lib/hecks/literal.rb +29 -38
- data/lib/hecks/mcp_stdio_guard.rb +8 -8
- data/lib/hecks/naming.rb +9 -3
- data/lib/hecks/persistence_legacy_fixture/postgres_stores.rb +81 -0
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +26 -66
- data/lib/hecks/persistence_legacy_fixture.rb +13 -10
- data/lib/hecks/ports/access_control.rb +13 -10
- data/lib/hecks/ports/agent/answers.rb +2 -2
- data/lib/hecks/ports/agent.rb +13 -10
- data/lib/hecks/ports/authentication.rb +13 -10
- data/lib/hecks/ports/authorization.rb +13 -10
- data/lib/hecks/ports/clock.rb +13 -10
- data/lib/hecks/ports/extraction.rb +13 -12
- data/lib/hecks/ports/identity_assignment.rb +13 -10
- data/lib/hecks/ports/identity_generation.rb +13 -10
- data/lib/hecks/ports/identity_resolution.rb +13 -10
- data/lib/hecks/ports/key_vault.rb +13 -10
- data/lib/hecks/ports/persistence/append_only.rb +5 -5
- data/lib/hecks/ports/persistence/binding_policy.rb +33 -9
- data/lib/hecks/ports/persistence/codec_boundary.rb +22 -11
- data/lib/hecks/ports/persistence/constants.rb +10 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +18 -16
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +27 -18
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +52 -23
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +14 -8
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +17 -6
- data/lib/hecks/ports/persistence/plugins/era/lineage/coverage.rb +58 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage/rewrite.rb +130 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage/rules.rb +25 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +20 -180
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +41 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/class_methods.rb +105 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/dialect.rb +137 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +25 -28
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/head_writes.rb +62 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/journal.rb +128 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/base_sql.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/chain_sql.rb +169 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/domain_rename.rb +91 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_integrity.rb +99 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +0 -73
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +55 -39
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +51 -222
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/merge_writes.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +85 -60
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +97 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +19 -19
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/sql_templates.rb +88 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +77 -118
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +3 -117
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_sql.rb +116 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +3 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/context.rb +38 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +43 -25
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +62 -38
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +21 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +66 -86
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/refusals.rb +75 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +27 -9
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/query_phases.rb +63 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/sagas.rb +78 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +28 -482
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +40 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +22 -15
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +39 -19
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -16
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +48 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +60 -99
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/path_diff.rb +57 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +21 -11
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +13 -4
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +4 -2
- data/lib/hecks/ports/persistence/postgres_dump.rb +13 -7
- data/lib/hecks/ports/persistence/repository_factory.rb +35 -11
- data/lib/hecks/ports/persistence/state_codec.rb +10 -0
- data/lib/hecks/ports/persistence.rb +1 -10
- data/lib/hecks/ports/projection.rb +34 -21
- data/lib/hecks/ports/query/in_memory.rb +16 -8
- data/lib/hecks/projection_files/expression_tables.rb +64 -0
- data/lib/hecks/projection_files/texts.rb +67 -0
- data/lib/hecks/projection_files.rb +19 -103
- data/lib/hecks/projections/bootstrap_table.rb +43 -29
- data/lib/hecks/projections/deploy/bastion_lines.rb +32 -0
- data/lib/hecks/projections/deploy/box/access.rb +73 -0
- data/lib/hecks/projections/deploy/box/caddy.rb +87 -0
- data/lib/hecks/projections/deploy/box/compose.rb +70 -0
- data/lib/hecks/projections/deploy/box/hosting.rb +4 -105
- data/lib/hecks/projections/deploy/box/hosting_parts.rb +97 -0
- data/lib/hecks/projections/deploy/box/hosting_settings.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_scripts.rb +137 -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 +47 -0
- data/lib/hecks/projections/deploy/box/settings/types.rb +76 -0
- data/lib/hecks/projections/deploy/box/settings.rb +76 -263
- data/lib/hecks/projections/deploy/box/shared_database.rb +69 -0
- 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 +23 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +42 -2
- data/lib/hecks/projections/deploy/box/templates/deploy-service.services-roll.part +2 -1
- data/lib/hecks/projections/deploy/box/templates/deploy-service.taskdef-roll.part +2 -1
- data/lib/hecks/projections/deploy/box/templates/deploy-usage-services.tmpl +4 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-usage-taskdef.tmpl +5 -0
- data/lib/hecks/projections/deploy/box/templates/ecr-repository.yaml.tmpl +9 -0
- data/lib/hecks/projections/deploy/box/templates/mode-summary-services.tmpl +2 -0
- data/lib/hecks/projections/deploy/box/templates/mode-summary-taskdef.tmpl +4 -0
- data/lib/hecks/projections/deploy/box/templates/provision-database.sh.tmpl +97 -0
- data/lib/hecks/projections/deploy/box/templates/restore-to-rds.sh.tmpl +4 -2
- 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 -1
- data/lib/hecks/projections/deploy/box/templates/writable-secrets.yaml.tmpl +7 -0
- data/lib/hecks/projections/deploy/box.rb +43 -491
- 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/shared_database_instance/templates/Makefile.tmpl +11 -0
- data/lib/hecks/projections/deploy/shared_database_instance/templates/README.md.tmpl +25 -0
- data/lib/hecks/projections/deploy/shared_database_instance/templates/rds.yaml.tmpl +180 -0
- data/lib/hecks/projections/deploy/shared_database_instance.rb +106 -0
- 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/deploy/vercel/settings.rb +83 -0
- data/lib/hecks/projections/deploy/vercel.rb +134 -0
- data/lib/hecks/projections/diagrams/dispatch.rb +114 -0
- data/lib/hecks/projections/diagrams/statecharts.rb +59 -0
- data/lib/hecks/projections/diagrams/structure.rb +114 -0
- data/lib/hecks/projections/diagrams.rb +33 -256
- data/lib/hecks/projections/glossary/entries.rb +140 -0
- data/lib/hecks/projections/glossary/html/page.rb +96 -0
- data/lib/hecks/projections/glossary/html/parser.rb +66 -0
- data/lib/hecks/projections/glossary/html/sections.rb +78 -0
- data/lib/hecks/projections/glossary/html.rb +7 -179
- data/lib/hecks/projections/glossary/index.rb +45 -0
- data/lib/hecks/projections/glossary/markdown.rb +22 -11
- data/lib/hecks/projections/glossary/mermaid.rb +44 -31
- data/lib/hecks/projections/glossary/sensitivity.rb +7 -4
- data/lib/hecks/projections/glossary/sentences/value_objects.rb +77 -0
- data/lib/hecks/projections/glossary/sentences.rb +42 -81
- data/lib/hecks/projections/glossary/slugs.rb +33 -0
- data/lib/hecks/projections/glossary.rb +22 -190
- data/lib/hecks/projections/model.rb +20 -14
- data/lib/hecks/projections/rust_vocabulary/arguments/support.rb +33 -0
- data/lib/hecks/projections/rust_vocabulary/arguments.rb +171 -0
- data/lib/hecks/projections/rust_vocabulary/enum_body.rb +114 -0
- data/lib/hecks/projections/rust_vocabulary/tests.rb +144 -0
- data/lib/hecks/projections/rust_vocabulary.rb +24 -293
- data/lib/hecks/projections/site/admin.rb +15 -9
- data/lib/hecks/projections/site/admin_cms/templates/membership.rb +115 -0
- data/lib/hecks/projections/site/admin_cms/templates/session_strategy.rb +90 -0
- data/lib/hecks/projections/site/admin_cms/templates/sso.rb +101 -0
- data/lib/hecks/projections/site/admin_cms/templates/sso_tail.rb +54 -0
- data/lib/hecks/projections/site/admin_cms/templates/users.rb +83 -0
- data/lib/hecks/projections/site/admin_cms/templates.rb +14 -369
- data/lib/hecks/projections/site/admin_cms.rb +15 -9
- data/lib/hecks/projections/site/edge/behaviours.rb +10 -6
- data/lib/hecks/projections/site/edge/checks.rb +30 -80
- data/lib/hecks/projections/site/edge/findings.rb +28 -0
- data/lib/hecks/projections/site/edge/route_checks.rb +110 -0
- data/lib/hecks/projections/site/edge/row_reader.rb +52 -0
- data/lib/hecks/projections/site/edge/rules.rb +28 -26
- data/lib/hecks/projections/site/edge.rb +20 -31
- data/lib/hecks/projections/site/live_edge.rb +9 -7
- data/lib/hecks/projections/site/payload/fields/definitions.rb +90 -0
- data/lib/hecks/projections/site/payload/fields/readers.rb +69 -0
- data/lib/hecks/projections/site/payload/fields.rb +14 -111
- data/lib/hecks/projections/site/payload/lifecycle/text.rb +84 -0
- data/lib/hecks/projections/site/payload/lifecycle/text_tail.rb +106 -0
- data/lib/hecks/projections/site/payload/lifecycle.rb +8 -166
- data/lib/hecks/projections/site/payload/model.rb +22 -22
- data/lib/hecks/projections/site/payload/specs/wire.rb +69 -0
- data/lib/hecks/projections/site/payload/specs.rb +24 -68
- data/lib/hecks/projections/site/payload_driver.rb +19 -17
- data/lib/hecks/projections/site/root_rows.rb +12 -4
- data/lib/hecks/projections/site/routes_ts/helpers.rb +79 -0
- data/lib/hecks/projections/site/routes_ts/listings.rb +75 -0
- data/lib/hecks/projections/site/routes_ts/navigation.rb +79 -0
- data/lib/hecks/projections/site/routes_ts.rb +27 -175
- data/lib/hecks/projections/site/site_admin/access.rb +104 -0
- data/lib/hecks/projections/site/site_admin/session.rb +127 -0
- data/lib/hecks/projections/site/site_admin.rb +12 -219
- data/lib/hecks/projections/site/site_cdn.rb +12 -7
- data/lib/hecks/projections/site/site_host/dockerfile.rb +75 -0
- data/lib/hecks/projections/site/site_host/templates.rb +19 -67
- data/lib/hecks/projections/site/site_root/workflow.rb +65 -0
- data/lib/hecks/projections/site/site_root.rb +3 -54
- data/lib/hecks/projections/site/table/checks.rb +28 -57
- data/lib/hecks/projections/site/table/link_builder.rb +14 -5
- data/lib/hecks/projections/site/table/navigation_checks.rb +75 -0
- data/lib/hecks/projections/site/table/row_builder.rb +31 -53
- data/lib/hecks/projections/site/table/row_defaults.rb +65 -0
- data/lib/hecks/projections/site/table.rb +9 -5
- data/lib/hecks/projections/vocabulary.rb +34 -31
- data/lib/hecks/projections.rb +2 -0
- 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 +49 -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 +27 -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 +157 -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 +48 -16
- 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 +27 -7
- data/lib/hecks/rust_build/wasm_browser.rb +7 -7
- data/lib/hecks/rust_build/write_if_changed.rb +3 -6
- data/lib/hecks/rust_build.rb +7 -3
- data/lib/hecks/storehouse/audit.rb +106 -0
- data/lib/hecks/storehouse/callers.rb +73 -0
- data/lib/hecks/storehouse/dispatching.rb +149 -0
- data/lib/hecks/storehouse/introspection.rb +145 -0
- data/lib/hecks/storehouse/querying.rb +78 -0
- data/lib/hecks/storehouse.rb +43 -451
- data/lib/hecks/tickets/bluebook/tickets.bluebook +29 -0
- data/lib/hecks/tools/argument_gate_matrix/dispatching.rb +69 -0
- data/lib/hecks/tools/argument_gate_matrix/rows.rb +121 -0
- data/lib/hecks/tools/argument_gate_matrix/violations.rb +108 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +43 -212
- data/lib/hecks/tools/ci_gate_decision.rb +21 -14
- data/lib/hecks/tools/ci_gates.rb +40 -26
- data/lib/hecks/tools/comment_style/baseline.rb +41 -0
- data/lib/hecks/tools/comment_style/caps_words.rb +104 -0
- data/lib/hecks/tools/comment_style/cli.rb +121 -0
- data/lib/hecks/tools/comment_style/dictionary.rb +60 -0
- data/lib/hecks/tools/comment_style/fixing.rb +119 -0
- data/lib/hecks/tools/comment_style/long_blocks.rb +51 -0
- data/lib/hecks/tools/comment_style/masking.rb +94 -0
- data/lib/hecks/tools/comment_style/patterns.rb +61 -0
- data/lib/hecks/tools/comment_style/run.rb +161 -0
- data/lib/hecks/tools/comment_style/signature.rb +59 -0
- data/lib/hecks/tools/comment_style/source_file.rb +105 -0
- data/lib/hecks/tools/comment_style/structure_checks.rb +113 -0
- data/lib/hecks/tools/comment_style/text_checks.rb +67 -0
- data/lib/hecks/tools/comment_style/vocabulary.rb +55 -0
- data/lib/hecks/tools/comment_style/walker.rb +136 -0
- data/lib/hecks/tools/comment_style.rb +17 -1000
- data/lib/hecks/tools/corpus_report.rb +26 -16
- data/lib/hecks/tools/deploy_recipe/generation.rb +59 -0
- data/lib/hecks/tools/deploy_recipe/targets.rb +115 -0
- data/lib/hecks/tools/deploy_recipe/worlds.rb +115 -0
- data/lib/hecks/tools/deploy_recipe.rb +72 -176
- 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 +80 -0
- data/lib/hecks/tools/fuzz_sweep/pool.rb +74 -0
- data/lib/hecks/tools/fuzz_sweep/reporting.rb +110 -0
- data/lib/hecks/tools/fuzz_sweep.rb +91 -272
- 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 +80 -0
- data/lib/hecks/tools/lanes/live.rb +40 -0
- data/lib/hecks/tools/lanes/rows.rb +45 -0
- data/lib/hecks/tools/lanes/ruleset.rb +66 -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 +82 -0
- data/lib/hecks/tools/mutation_run.rb +73 -0
- data/lib/hecks/tools/oidc_manifests.rb +10 -9
- data/lib/hecks/tools/query_ir_run.rb +7 -3
- data/lib/hecks/tools/regeneration_run.rb +40 -26
- data/lib/hecks/tools/rust_comment_style/caps_words.rb +98 -0
- data/lib/hecks/tools/rust_comment_style/fixing.rb +102 -0
- data/lib/hecks/tools/rust_comment_style/masking.rb +85 -0
- data/lib/hecks/tools/rust_comment_style/run.rb +94 -0
- data/lib/hecks/tools/rust_comment_style/source_file.rb +71 -0
- data/lib/hecks/tools/rust_comment_style/structure.rb +79 -0
- data/lib/hecks/tools/rust_comment_style/text_checks.rb +63 -0
- data/lib/hecks/tools/rust_comment_style/tokenizer.rb +102 -0
- data/lib/hecks/tools/rust_comment_style.rb +38 -535
- data/lib/hecks/tools/sequence_script.rb +20 -14
- data/lib/hecks/tools/site_routes/cli.rb +70 -0
- data/lib/hecks/tools/site_routes/root_files.rb +59 -0
- data/lib/hecks/tools/site_routes/templates.rb +77 -0
- data/lib/hecks/tools/site_routes.rb +84 -160
- data/lib/hecks/tools/tail_merge.rb +45 -37
- data/lib/hecks/tools/tenant_provisioning.rb +45 -31
- data/lib/hecks/tools/tools_doc.rb +42 -19
- data/lib/hecks/tools/translation_audit/domain_loading.rb +71 -0
- data/lib/hecks/tools/translation_audit/edges.rb +71 -0
- data/lib/hecks/tools/translation_audit/verdicts.rb +107 -0
- data/lib/hecks/tools/translation_audit.rb +30 -161
- data/lib/hecks/tools/translation_scaffold/reporting.rb +40 -0
- data/lib/hecks/tools/translation_scaffold.rb +77 -60
- data/lib/hecks/tools.rb +2 -0
- data/lib/hecks/vendoring.rb +37 -11
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +18 -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/prebuilt/945481eefbdb584649d45f256307053558966a868b9c38dee7ee88f8169610f8.marshal +0 -0
- data/prebuilt/a0818e2de67364dc1ab22868b6cbf869c62da6f8d9b924c778fa5cce2e76ee94.marshal +0 -0
- data/prebuilt/verdicts-be73f0df9eee0abe2f4aadc968321c4b919d19d424a3ccfe1777a71dabf7d9e7.json +1 -0
- data/qa/settings.yml +1 -0
- 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/api.rs +28 -5
- data/rust/host/src/auth.rs +43 -1
- data/rust/host/src/boundary_fuzz/api.rs +260 -0
- data/rust/host/src/boundary_fuzz/auth.rs +119 -0
- data/rust/host/src/boundary_fuzz/expr_json.rs +158 -0
- data/rust/host/src/boundary_fuzz/ir.rs +78 -0
- data/rust/host/src/boundary_fuzz/server.rs +227 -0
- data/rust/host/src/boundary_fuzz/web.rs +125 -0
- data/rust/host/src/fuzz_support.rs +165 -0
- data/rust/host/src/ir.rs +4 -0
- data/rust/host/src/main.rs +9 -4
- data/rust/host/src/secrets.rs +44 -0
- data/rust/host/src/server.rs +6 -1
- data/rust/host/src/web.rs +14 -5
- data/rust/parser/fuzz/.gitignore +4 -0
- data/rust/parser/fuzz/Cargo.lock +89 -0
- data/rust/parser/fuzz/Cargo.toml +27 -0
- data/rust/parser/fuzz/README.md +19 -0
- data/rust/parser/fuzz/fuzz_targets/chapter.rs +50 -0
- data/rust/parser/fuzz/fuzz_targets/resolve.rs +35 -0
- data/rust/parser/src/parse/command.rs +14 -2
- data/rust/parser/src/parse/mod.rs +25 -0
- data/rust/parser/src/ruby_value.rs +95 -6
- data/rust/src/kernel/dispatch.rs +4 -0
- data/rust/src/kernel/dispatch_guard_tests.rs +506 -0
- data/rust/src/kernel/json.rs +34 -3
- data/rust/src/kernel/orchestrate.rs +4 -0
- data/rust/src/kernel/orchestrate_guard_tests.rs +708 -0
- metadata +640 -3
- /data/lib/hecks/bluebook/behaviour/{hexagon.rb → hecksagon.rb} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
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
|
+
:role_checks_agree_with_grants,
|
|
28
|
+
:read_model_names_resolve_uniquely,
|
|
29
|
+
:read_model_heads_compose_from_references
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
# Which language feature each property is answerable for — exhaustive of
|
|
33
|
+
# what would go unchecked without it, not of everything its body touches.
|
|
34
|
+
FEATURE_COVERAGE = {
|
|
35
|
+
lifecycle_values_are_declared: %w[Aggregate#state_field Aggregate#state_start Aggregate#transitions
|
|
36
|
+
Entity#state_field Entity#state_start Entity#transitions],
|
|
37
|
+
saga_advances_follow_declared_handlers: %w[Handler#from_state Handler#to_state Handler#event_type],
|
|
38
|
+
query_answers_match_reference: %w[Query#wheres Query#order_field Query#order_way Query#limit],
|
|
39
|
+
paging_offset_partitions_correctly: %w[Query#options],
|
|
40
|
+
authorize_scopes_or_refuses: %w[Query#options],
|
|
41
|
+
guard_refusals_are_declared: %w[Command#givens Command#ensures Command#needs],
|
|
42
|
+
lifecycle_guard_and_given_violations_are_refused: %w[Command#from Aggregate#preconditions Entity#preconditions],
|
|
43
|
+
# Dispatch#command_name/with_spec aren't claimable feature names — the
|
|
44
|
+
# coverage walk only reaches one level of entity nesting and Dispatch
|
|
45
|
+
# sits two deep — but this property still checks the real behavior
|
|
46
|
+
# (dispatch_args) those names would have covered.
|
|
47
|
+
dispatch_binding_fidelity: %w[Handler#dispatches Policy#with_spec],
|
|
48
|
+
mutations_match_recompute: %w[Command#mutations],
|
|
49
|
+
sagas_rehydrate_cleanly: %w[ProcessManager#states ProcessManager#correlates_by
|
|
50
|
+
ProcessManager#starts_on ProcessManager#ends_on],
|
|
51
|
+
fanout_dispatches_once_per_matching_row: %w[Policy#for_each Policy#where],
|
|
52
|
+
aggregation_matches_recompute: %w[ReadModel#count ReadModel#median_field ReadModel#sum_field
|
|
53
|
+
ReadModel#avg_field ReadModel#min_field ReadModel#max_field
|
|
54
|
+
ReadModel#percentile_field ReadModel#percentile_at
|
|
55
|
+
ReadModel#any_field ReadModel#all_field],
|
|
56
|
+
stored_records_satisfy_declared_invariants: %w[Aggregate#invariants Entity#invariants],
|
|
57
|
+
group_by_matches_recompute: %w[ReadModel#group_by],
|
|
58
|
+
# A runtime door, not a grammar construct — `Dispatcher#dry_run?` is not
|
|
59
|
+
# a word a bluebook declares. Listed empty rather than omitted, so every
|
|
60
|
+
# property still names what it is answerable for.
|
|
61
|
+
dry_runs_leave_no_trace: [],
|
|
62
|
+
# Another runtime door, not a grammar construct — same reasoning as
|
|
63
|
+
# dry_runs_leave_no_trace above.
|
|
64
|
+
outbox_rows_match_reactions: [],
|
|
65
|
+
# Reads command.mutations for :corrects ops — the same list
|
|
66
|
+
# mutations_match_recompute reads, for a different question.
|
|
67
|
+
corrections_reference_an_emitted_event: %w[Command#mutations],
|
|
68
|
+
# Reads each logged reaction back against the policy that produced it: the event it
|
|
69
|
+
# answers, the trigger it builds, and the domain `across` sends it to.
|
|
70
|
+
policy_reactions_follow_declared_wiring: %w[Policy#on_event Policy#trigger_command Policy#target_domain],
|
|
71
|
+
# model_check holds the static half of `expect_undelivered`; this is the runtime half.
|
|
72
|
+
declared_undelivered_policies_stay_undelivered: %w[Policy#expect_undelivered],
|
|
73
|
+
# An accepted referencing command addressed a record an earlier event created.
|
|
74
|
+
references_resolve_to_earlier_records: %w[Command#references],
|
|
75
|
+
# The grants read back through the verb the authorization provider declares in `provides`.
|
|
76
|
+
role_checks_agree_with_grants: %w[Bluebook#provides],
|
|
77
|
+
read_model_names_resolve_uniquely: %w[ReadModel#query_name],
|
|
78
|
+
# Each head's rows recomputed from the references; options apply to targeted heads only.
|
|
79
|
+
read_model_heads_compose_from_references: %w[ReadModel#reference_name ReadModel#reference_target
|
|
80
|
+
ReadModel#aggregate_heads ReadModel#options],
|
|
81
|
+
# No feature string exists for what this reads: an argument's own
|
|
82
|
+
# `relationship` (Argument is a value object, outside the meta-domain
|
|
83
|
+
# walk). Its declaration side, `Query#options`, is already claimed by
|
|
84
|
+
# authorize_scopes_or_refuses.
|
|
85
|
+
commands_respect_tenant_scope: []
|
|
86
|
+
}.freeze
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
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
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative "mutation_recompute"
|
|
2
|
+
|
|
1
3
|
module Hecks
|
|
2
4
|
module Fuzzing
|
|
3
5
|
module Properties
|
|
@@ -11,26 +13,36 @@ module Hecks
|
|
|
11
13
|
# @return [true, String] true if every dry-run trace shows no change; otherwise
|
|
12
14
|
# a semicolon-joined message naming each offending dry run
|
|
13
15
|
def dry_runs_leave_no_trace(history)
|
|
14
|
-
offenders = Array(history[:dry_run_traces]).filter_map
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
next unless before && after
|
|
16
|
+
offenders = Array(history[:dry_run_traces]).filter_map { |entry| dry_run_offender(entry) }
|
|
17
|
+
offenders.empty? || offenders.join("; ")
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
# The message for one dry run that left a trace, or nil.
|
|
21
|
+
def dry_run_offender(entry)
|
|
22
|
+
before = entry[:before]
|
|
23
|
+
after = entry[:after]
|
|
24
|
+
return unless before && after
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
traces = dry_run_changes(before, after)
|
|
27
|
+
return if traces.empty?
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
"dry run of #{entry[:verb]} (ok: #{entry[:ok]}) left a trace: #{traces.join(", ")}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# What differs between a dry run's before and after snapshots.
|
|
33
|
+
def dry_run_changes(before, after)
|
|
34
|
+
traces = []
|
|
35
|
+
traces << "events #{before[:events]} -> #{after[:events]}" unless before[:events] == after[:events]
|
|
36
|
+
traces << "instances changed" unless before[:instances] == after[:instances]
|
|
37
|
+
traces
|
|
28
38
|
end
|
|
29
39
|
end
|
|
30
40
|
|
|
31
41
|
# Properties: saga/policy dispatch args match their `with_spec`, and command
|
|
32
42
|
# mutations match an independent recomputation.
|
|
33
43
|
module DispatchAndMutations
|
|
44
|
+
include MutationRecompute
|
|
45
|
+
|
|
34
46
|
# Checks saga and policy dispatch args against an independent re-derivation of
|
|
35
47
|
# `with_spec`. Re-deriving, not calling the interpreter again, keeps the check
|
|
36
48
|
# from agreeing with itself. Args are compared as captured live, because a
|
|
@@ -41,7 +53,13 @@ module Hecks
|
|
|
41
53
|
# match an independent re-derivation of their `with_spec`; otherwise a
|
|
42
54
|
# semicolon-joined message naming each offending dispatch
|
|
43
55
|
def dispatch_binding_fidelity(history)
|
|
44
|
-
|
|
56
|
+
offenders = saga_binding_offenders(history) + policy_binding_offenders(history)
|
|
57
|
+
offenders.empty? || offenders.join("; ")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# One message per saga dispatch whose bound args differ from the re-derivation.
|
|
61
|
+
def saga_binding_offenders(history)
|
|
62
|
+
history.fetch(:saga_dispatches, []).filter_map do |entry|
|
|
45
63
|
expected = resolve_dispatch_binding(entry)
|
|
46
64
|
next if expected == entry[:args]
|
|
47
65
|
|
|
@@ -49,17 +67,17 @@ module Hecks
|
|
|
49
67
|
"bound #{entry[:args].inspect}, but independently re-deriving with_spec's own resolution gives " \
|
|
50
68
|
"#{expected.inspect}"
|
|
51
69
|
end
|
|
70
|
+
end
|
|
52
71
|
|
|
53
|
-
|
|
72
|
+
# One message per policy dispatch whose bound args differ from the re-derivation.
|
|
73
|
+
def policy_binding_offenders(history)
|
|
74
|
+
history.fetch(:policy_dispatches, []).filter_map do |entry|
|
|
54
75
|
expected = resolve_trigger_binding(entry)
|
|
55
76
|
next if expected == entry[:args]
|
|
56
77
|
|
|
57
78
|
"#{entry[:policy]} on #{entry[:on]} — bound #{entry[:args].inspect}, but independently re-deriving " \
|
|
58
79
|
"with_spec's own resolution gives #{expected.inspect}"
|
|
59
80
|
end
|
|
60
|
-
|
|
61
|
-
offenders = saga_offenders + policy_offenders
|
|
62
|
-
offenders.empty? || offenders.join("; ")
|
|
63
81
|
end
|
|
64
82
|
|
|
65
83
|
# Re-derives SagaInterpreter#dispatch_args: a literal, the correlation key,
|
|
@@ -106,33 +124,44 @@ module Hecks
|
|
|
106
124
|
# naming each offending mutation
|
|
107
125
|
def mutations_match_recompute(history)
|
|
108
126
|
bluebooks = history.fetch(:bluebooks)
|
|
127
|
+
offenders = history.fetch(:mutation_traces, []).flat_map { |entry| mutation_offenders(bluebooks, entry) }
|
|
128
|
+
offenders.empty? || offenders.join("; ")
|
|
129
|
+
end
|
|
109
130
|
|
|
110
|
-
|
|
111
|
-
|
|
131
|
+
# One message per recomputable mutation of `entry` whose real after-state differs.
|
|
132
|
+
def mutation_offenders(bluebooks, entry)
|
|
133
|
+
return [] unless entry[:after]
|
|
112
134
|
|
|
113
|
-
|
|
114
|
-
|
|
135
|
+
context = mutation_context(bluebooks, entry)
|
|
136
|
+
return [] unless context
|
|
115
137
|
|
|
116
|
-
|
|
117
|
-
|
|
138
|
+
recomputable = context.command.mutations.select { |m| RECOMPUTABLE_MUTATION_OPS.include?(m.op) }
|
|
139
|
+
recomputable.filter_map { |mutation| mutation_offender(mutation, entry, context) }
|
|
140
|
+
end
|
|
118
141
|
|
|
119
|
-
|
|
142
|
+
# What recomputing `entry` needs, or nil when its verb names no command or aggregate.
|
|
143
|
+
def mutation_context(bluebooks, entry)
|
|
144
|
+
command = command_for_verb(bluebooks, entry[:verb])
|
|
145
|
+
return unless command
|
|
120
146
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
expected = recompute_mutation(mutation, entry[:before][mutation.target], args, entry[:before],
|
|
124
|
-
aggregate, command, owner)
|
|
125
|
-
next if expected == :unrecomputable
|
|
147
|
+
aggregate = aggregate_for_verb(bluebooks, entry[:verb])
|
|
148
|
+
return unless aggregate
|
|
126
149
|
|
|
127
|
-
|
|
128
|
-
|
|
150
|
+
owner = owner_for_verb(bluebooks, entry[:verb]) || aggregate
|
|
151
|
+
MutationRecompute::Context.new(aggregate, command, owner, entry[:before],
|
|
152
|
+
with_declared_defaults(command, entry[:args]))
|
|
153
|
+
end
|
|
129
154
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
155
|
+
# The message for one mutation whose recomputation disagrees with the real dispatch.
|
|
156
|
+
def mutation_offender(mutation, entry, context)
|
|
157
|
+
expected = recompute_mutation(mutation, entry[:before][mutation.target], context)
|
|
158
|
+
return if expected == :unrecomputable
|
|
134
159
|
|
|
135
|
-
|
|
160
|
+
actual = entry[:after][mutation.target]
|
|
161
|
+
return if symbolize_deep(expected) == symbolize_deep(actual)
|
|
162
|
+
|
|
163
|
+
"#{entry[:verb]} — #{mutation.op} on #{mutation.target} — recomputing independently gives " \
|
|
164
|
+
"#{expected.inspect}, but the real dispatch left #{actual.inspect}"
|
|
136
165
|
end
|
|
137
166
|
|
|
138
167
|
# The arguments the command actually ran with: an argument the caller left out takes the
|
|
@@ -174,156 +203,6 @@ module Hecks
|
|
|
174
203
|
entity_name, = command_path.split(".", 2)
|
|
175
204
|
aggregate.entities.find { |candidate| candidate.hecks_name == entity_name }
|
|
176
205
|
end
|
|
177
|
-
|
|
178
|
-
# Dispatches to the recompute rule for `mutation.op`.
|
|
179
|
-
def recompute_mutation(mutation, current, args, before_scope, aggregate, command, owner = aggregate)
|
|
180
|
-
case mutation.op
|
|
181
|
-
when :append
|
|
182
|
-
recompute_append(current, mutation.source, before_scope, args, aggregate, command, owner, mutation.target)
|
|
183
|
-
when :remove then recompute_remove(current, mutation.source, args)
|
|
184
|
-
when :multiply then recompute_multiply(current, resolve_mutation_source(mutation.source, args))
|
|
185
|
-
when :clamp then recompute_clamp(current, mutation.source)
|
|
186
|
-
when :set then recompute_set(mutation.source, args, aggregate, owner, mutation.target)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Re-derives the `:set` branch of `EntityElement#apply_to_element`. The
|
|
191
|
-
# attribute comes from `owner`, not the root aggregate, which would leave a
|
|
192
|
-
# nested entity's value uncoerced and disagree with the real after-state.
|
|
193
|
-
# Any raise means the raw material was wrong, so the result is `:unrecomputable`.
|
|
194
|
-
def recompute_set(source, args, aggregate, owner, target)
|
|
195
|
-
raw = resolve_mutation_source(source, args)
|
|
196
|
-
attribute = owner&.attribute(target)
|
|
197
|
-
coerced = attribute ? Runtime::Value.for_attribute(aggregate, attribute, raw) : raw
|
|
198
|
-
Runtime::Value.materialize(coerced)
|
|
199
|
-
rescue StandardError
|
|
200
|
-
:unrecomputable
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# Re-derives `EntityElement#appended_to_element`: each field resolves from a
|
|
204
|
-
# caller arg (coerced as `Interpreting#coerce_declared_arguments` does) or from
|
|
205
|
-
# the entity's current field (already materialized), then the element is appended.
|
|
206
|
-
# A nested-entity element also gets its declared defaults.
|
|
207
|
-
def recompute_append(current, source_map, before_scope, args, aggregate, command, owner = aggregate, target = nil)
|
|
208
|
-
fields = source_map.transform_values do |source|
|
|
209
|
-
resolve_mutation_append_field(source, before_scope, args, aggregate, command)
|
|
210
|
-
end
|
|
211
|
-
fill_recompute_declared_defaults(aggregate, owner, target, fields)
|
|
212
|
-
Array(current) + [symbolize_deep(fields)]
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# Fills defaults for a nested-entity element via `Instance.default_for`, which is
|
|
216
|
-
# independently tested. No-op unless `target` names an entity under `owner`
|
|
217
|
-
# (`owner.entities`, not `aggregate.entities`).
|
|
218
|
-
#
|
|
219
|
-
# A value-object element type (the more common shape: `list_of` a plain composite,
|
|
220
|
-
# not a nested entity) defaults the other way real dispatch does — through
|
|
221
|
-
# `Runtime::Value.apply_defaults`, the exact primitive `EntityElement#appended_to_
|
|
222
|
-
# element`'s own `Value.build` call uses. Without this branch, a caller-omitted,
|
|
223
|
-
# VO-declared `default:` field is left out of the recomputed element entirely,
|
|
224
|
-
# disagreeing with real dispatch's fully-defaulted one.
|
|
225
|
-
def fill_recompute_declared_defaults(aggregate, owner, target, fields)
|
|
226
|
-
return fields unless target
|
|
227
|
-
|
|
228
|
-
element_type = owner&.attribute(target)&.type
|
|
229
|
-
return fields unless element_type
|
|
230
|
-
|
|
231
|
-
entity = owner.entities.find { |piece| piece.hecks_name == element_type.to_s }
|
|
232
|
-
if entity
|
|
233
|
-
entity.attributes.each do |attribute|
|
|
234
|
-
next if fields.key?(attribute.name)
|
|
235
|
-
|
|
236
|
-
fields[attribute.name] = attribute.list? ? [] : Runtime::Instance.default_for(aggregate, attribute)
|
|
237
|
-
end
|
|
238
|
-
return fields
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
value_object = aggregate.value_object(element_type)
|
|
242
|
-
return fields unless value_object
|
|
243
|
-
|
|
244
|
-
Runtime::Value.apply_defaults(value_object, fields)
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# Resolves one appended field's value from its declared source.
|
|
248
|
-
def resolve_mutation_append_field(source, before_scope, args, aggregate, command)
|
|
249
|
-
return source unless source.is_a?(Symbol)
|
|
250
|
-
return before_scope[source] unless args.key?(source)
|
|
251
|
-
|
|
252
|
-
coerce_recompute_append_arg(aggregate, command, source, args[source])
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
# Coerces a raw arg only when `source` is a declared attribute of the command,
|
|
256
|
-
# as a real dispatch does. Materialized so the comparison is plain data on both sides.
|
|
257
|
-
def coerce_recompute_append_arg(aggregate, command, source, raw)
|
|
258
|
-
attribute = command.attribute(source)
|
|
259
|
-
return raw unless attribute
|
|
260
|
-
|
|
261
|
-
Runtime::Value.materialize(Runtime::Value.for_attribute(aggregate, attribute, raw, argument: true))
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
# Re-derives `MutationApplier#removed`: removes every value-equal element.
|
|
265
|
-
# `Value.materialize` first: once `args` arrives normalized (replay.rb's
|
|
266
|
-
# `build_mutation_trace`), a composite `remove:` source is already a built
|
|
267
|
-
# `Runtime::Value` with its own declared defaults filled — comparing it
|
|
268
|
-
# unmaterialized against `current`'s plain Hashes would never match, wrongly
|
|
269
|
-
# keeping an element real dispatch correctly removed.
|
|
270
|
-
def recompute_remove(current, source, args)
|
|
271
|
-
target = symbolize_deep(Runtime::Value.materialize(resolve_mutation_source(source, args)))
|
|
272
|
-
Array(current).reject { |element| symbolize_deep(element) == target }
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
# Re-derives `CommandRules::Arithmetic#multiply` on plain data: a Hash with one
|
|
276
|
-
# numeric field scales that field, a bare Numeric scales itself. A nil
|
|
277
|
-
# `current` is treated as 0.
|
|
278
|
-
def recompute_multiply(current, amount)
|
|
279
|
-
return :unrecomputable unless amount.is_a?(Numeric)
|
|
280
|
-
|
|
281
|
-
current ||= 0
|
|
282
|
-
if current.is_a?(Hash)
|
|
283
|
-
field = current.keys.find { |f| current[f].is_a?(Numeric) }
|
|
284
|
-
return :unrecomputable unless field
|
|
285
|
-
|
|
286
|
-
current.merge(field => current[field] * amount)
|
|
287
|
-
elsif current.is_a?(Numeric)
|
|
288
|
-
current * amount
|
|
289
|
-
else
|
|
290
|
-
:unrecomputable
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# Re-derives `CommandRules::Arithmetic#clamp` like #recompute_multiply. The
|
|
295
|
-
# source is always a literal `[min, max]`, never an argument reference.
|
|
296
|
-
def recompute_clamp(current, bounds)
|
|
297
|
-
return :unrecomputable unless bounds.is_a?(Array) && bounds.size == 2
|
|
298
|
-
|
|
299
|
-
min, max = bounds
|
|
300
|
-
current ||= 0
|
|
301
|
-
if current.is_a?(Hash)
|
|
302
|
-
field = current.keys.find { |f| current[f].is_a?(Numeric) }
|
|
303
|
-
return :unrecomputable unless field
|
|
304
|
-
|
|
305
|
-
current.merge(field => current[field].clamp(min, max))
|
|
306
|
-
elsif current.is_a?(Numeric)
|
|
307
|
-
current.clamp(min, max)
|
|
308
|
-
else
|
|
309
|
-
:unrecomputable
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
# A mutation source is an argument name (Symbol) or a literal.
|
|
314
|
-
def resolve_mutation_source(source, args)
|
|
315
|
-
source.is_a?(Symbol) ? args[source] : source
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Symbolizes hash keys recursively. Generated args carry string keys while
|
|
319
|
-
# materialized trace state carries symbols, and `Hash#==` would otherwise differ.
|
|
320
|
-
def symbolize_deep(value)
|
|
321
|
-
case value
|
|
322
|
-
when Hash then value.to_h { |key, val| [key.to_sym, symbolize_deep(val)] }
|
|
323
|
-
when Array then value.map { |val| symbolize_deep(val) }
|
|
324
|
-
else value
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
206
|
end
|
|
328
207
|
end
|
|
329
208
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Fuzzing
|
|
3
|
+
module Properties
|
|
4
|
+
# Independent nestings of a `group_by` read model's rows, for
|
|
5
|
+
# `InvariantsAndAggregation#group_by_matches_recompute` to compare against the answer.
|
|
6
|
+
module GroupByRecompute
|
|
7
|
+
# Judges one `group_by` ask against the rows it was eligible to see:
|
|
8
|
+
# refused exactly when two of them share a checked key path, and
|
|
9
|
+
# otherwise nested exactly as `nest_rows` nests them.
|
|
10
|
+
def group_by_offense(bluebook, asked, model, grouped_head)
|
|
11
|
+
rows = eligible_rows(bluebook, asked.fetch(:instances_at), model, grouped_head, asked[:args] || {})
|
|
12
|
+
materialized = rows.map { |state| Runtime::Value.materialize_unwrapped(state) }
|
|
13
|
+
shared = shared_key_paths(materialized, model.group_by_fields)
|
|
14
|
+
return nesting_offense(asked, model, grouped_head, materialized) if shared.empty?
|
|
15
|
+
|
|
16
|
+
collision_offense(asked, model.group_by_fields, shared.length, checked_key_paths?(bluebook, model, grouped_head))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Whether the grouped key paths are checked, i.e. do not cover the head's identity.
|
|
20
|
+
def checked_key_paths?(bluebook, model, grouped_head)
|
|
21
|
+
!model.groups_by_identity?(bluebook.aggregate(grouped_head[:aggregate]))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Judges an ask with no shared key path: it must not have refused, and its grouping must
|
|
25
|
+
# equal the independent nesting.
|
|
26
|
+
def nesting_offense(asked, model, grouped_head, materialized)
|
|
27
|
+
return nil if asked[:error]
|
|
28
|
+
return nil if asked[:rows]&.first&.dig(grouped_head[:as]) == nest_rows(materialized, model.group_by_fields)
|
|
29
|
+
|
|
30
|
+
"#{asked[:query]} #{asked[:args].inspect} answered a #{grouped_head[:as]} grouping that disagrees " \
|
|
31
|
+
"with independently nesting group_by #{model.group_by_fields.inspect} over #{materialized.length} " \
|
|
32
|
+
"eligible row(s)"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Judges an ask whose eligible rows share at least one full key path:
|
|
36
|
+
# a checked key path must have refused, and an identity-covering one
|
|
37
|
+
# cannot be shared by rows that hold their identity.
|
|
38
|
+
def collision_offense(asked, fields, shared, checked)
|
|
39
|
+
return nil if checked && asked[:error]
|
|
40
|
+
|
|
41
|
+
"#{asked[:query]} #{asked[:args].inspect} #{checked ? "answered" : "reached"}, but #{shared} key " \
|
|
42
|
+
"path(s) of group_by #{fields.inspect} are shared by more than one eligible row, " \
|
|
43
|
+
"#{checked ? "so the ask must refuse" : "though they cover the identity"}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Every full `group_by` key path more than one row reaches, found by
|
|
47
|
+
# tallying each row's tuple of grouped values, with no nesting at all.
|
|
48
|
+
def shared_key_paths(rows, fields)
|
|
49
|
+
rows.map { |row| fields.map { |field| row[field] } }.tally.select { |_, count| count > 1 }.keys
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# One level of nesting per `group_by` field in declared order; the leaf
|
|
53
|
+
# is the row with every grouped field stripped. Called only when no key
|
|
54
|
+
# path is shared (`shared_key_paths` rules that out), so each leaf holds
|
|
55
|
+
# exactly one row; a second row raises rather than being picked over.
|
|
56
|
+
def nest_rows(rows, fields)
|
|
57
|
+
field, *rest = fields
|
|
58
|
+
rows.group_by { |row| row[field] }.transform_values do |group|
|
|
59
|
+
stripped = group.map { |row| row.reject { |key, _| key == field } }
|
|
60
|
+
next nest_rows(stripped, rest) unless rest.empty?
|
|
61
|
+
raise ArgumentError, "nest_rows reached a key path #{stripped.length} rows share" unless stripped.length == 1
|
|
62
|
+
|
|
63
|
+
stripped[0]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Fuzzing
|
|
3
|
+
module Properties
|
|
4
|
+
# Features a replay could never observe violated, because construction
|
|
5
|
+
# makes the violation impossible to produce — not untested, but
|
|
6
|
+
# unfalsifiable. Each entry names the runtime path that guarantees it;
|
|
7
|
+
# add one only after reading and confirming that path (mirrors the
|
|
8
|
+
# discipline spec/fuzzing/meta_domain_coverage_spec.rb's KNOWN_GAPS demands
|
|
9
|
+
# in the other direction).
|
|
10
|
+
GUARANTEED_BY_CONSTRUCTION = {
|
|
11
|
+
"Aggregate#attributes" => "every field's pattern/closed-set/type passes through Value.build's one coercion " \
|
|
12
|
+
"door (value/coercion.rb#check_patterns, value/admission.rb) before it can exist " \
|
|
13
|
+
"— a stored value that violated its own declared shape was never producible to " \
|
|
14
|
+
"begin with",
|
|
15
|
+
"Aggregate#value_objects" => "the shape being coerced above — same door, same guarantee",
|
|
16
|
+
# S17, ADR 0026 — saga_advances_follow_declared_handlers already walks
|
|
17
|
+
# this list to find event_type/from_state/to_state; same door, same guarantee.
|
|
18
|
+
"ProcessManager#handlers" => "saga_advances_follow_declared_handlers already walks this list to find " \
|
|
19
|
+
"event_type/from_state/to_state — same door, same guarantee",
|
|
20
|
+
"Aggregate#identified_by" => "CommandInterpreter's data-driven dispatch order refuses AlreadyExists " \
|
|
21
|
+
"(command_interpreter.rb, command.creates?) for every creating command uniformly, " \
|
|
22
|
+
"before a duplicate id can ever be stored — collision is refused at the door, not " \
|
|
23
|
+
"produced and later caught",
|
|
24
|
+
"Entity#identified_by" => "EntityElement.check_entity_collision (runtime/entity_element.rb, moved there " \
|
|
25
|
+
"BUG#145 so both call sites share it) checks Array(current) against every part " \
|
|
26
|
+
"of the entity's own identity before an append can land — MutationApplier#" \
|
|
27
|
+
"entity_element's aggregate-owned call (Workspace.boards, on both branches " \
|
|
28
|
+
"identity arrives by: caller-supplied, or composite) AND EntityElement#" \
|
|
29
|
+
"appended_to_element's entity-owned, nested-one-hop-further call (Board.cards — " \
|
|
30
|
+
"unconditional, no auto-mint branch exists at that depth) — the same " \
|
|
31
|
+
"AlreadyExists refusal Aggregate#identified_by gets above, one or two levels " \
|
|
32
|
+
"down. Auto-minted (aggregate-owned) entities never reach the check " \
|
|
33
|
+
"(current.size + 1 can't repeat unless something remove:s from the list between " \
|
|
34
|
+
"mints, which no real domain does today — see the comment on #entity_element " \
|
|
35
|
+
"itself)",
|
|
36
|
+
"Command#attributes" => "command arguments are coerced through the SAME Value.build door as any other " \
|
|
37
|
+
"attribute — an accepted dispatch's own args already passed pattern/admits/invariant checks",
|
|
38
|
+
"Command#emits" => "CommandRules::Emission#emit iterates command.emits ITSELF to construct every " \
|
|
39
|
+
"announced Event (command_rules/emission.rb) — there is no other path to emit, so " \
|
|
40
|
+
"a command can never announce a name its own declaration doesn't list",
|
|
41
|
+
"Query#attributes" => "query arguments are coerced through the same Value.build door — same guarantee as " \
|
|
42
|
+
"Command#attributes",
|
|
43
|
+
"Query#returns" => "every row a port answers is built as the returned value object by Value.build " \
|
|
44
|
+
"(QueryInterpreter#shaped) before it enters the domain — an answer of any other " \
|
|
45
|
+
"shape is refused, so none can be accepted",
|
|
46
|
+
"Entity#attributes" => "same coercion door, one level in — an entity's own attributes are Value-typed exactly " \
|
|
47
|
+
"the way an aggregate's are",
|
|
48
|
+
"ValueObject#attributes" => "the shape Value.build enforces IS this declaration — the guarantee and the " \
|
|
49
|
+
"feature are the same fact seen from two sides",
|
|
50
|
+
"ValueObject#invariants" => "run inside the SAME coercion call (coercion.rb, before construction returns) " \
|
|
51
|
+
"that pattern-checks a VO's fields — a VO whose invariant did not hold could not " \
|
|
52
|
+
"finish being built",
|
|
53
|
+
"ValueObject#rows" => "closed-set membership is checked in value/admission.rb, the second half of the same " \
|
|
54
|
+
"one construction door",
|
|
55
|
+
# S17, ADR 0026 — Member is a genuine entity, so this reads Member#pairs,
|
|
56
|
+
# not Member#shape. ValueObject#members is the same fact ValueObject#rows
|
|
57
|
+
# counts, seen from the other side.
|
|
58
|
+
"ValueObject#members" => "the members list IS what ValueObject#rows counts — same door, same guarantee",
|
|
59
|
+
"Member#pairs" => "one level into ValueObject#rows — same door"
|
|
60
|
+
}.freeze
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|