hecks 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +11 -0
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +18 -99
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres.rb +145 -134
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +7 -30
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +15 -37
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +17 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +38 -26
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +10 -48
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +14 -63
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +17 -65
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -189
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +19 -106
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +37 -660
- data/lib/hecks/bluebook/hexagon.rb +5 -28
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +54 -268
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -308
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +79 -349
- data/lib/hecks/bluebook/model_check/client_profile.rb +10 -91
- data/lib/hecks/bluebook/model_check.rb +102 -600
- data/lib/hecks/bluebook/pattern_subset.rb +11 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +9 -48
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +8 -98
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +84 -0
- data/lib/hecks/cli/document.rb +86 -0
- data/lib/hecks/cli/ir.rb +45 -0
- data/lib/hecks/cli/mcp.rb +31 -0
- data/lib/hecks/cli/mcp_door.rb +366 -0
- data/lib/hecks/cli/model_check.rb +203 -0
- data/lib/hecks/cli/project_cli.rb +90 -0
- data/lib/hecks/cli/project_diagrams.rb +36 -0
- data/lib/hecks/cli/run.rb +173 -0
- data/lib/hecks/cli/smoke_test.rb +45 -0
- data/lib/hecks/cli/stores.rb +53 -0
- data/lib/hecks/cli.rb +160 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +4 -71
- data/lib/hecks/facade/cli_door.rb +24 -106
- data/lib/hecks/facade/cli_runner.rb +28 -172
- data/lib/hecks/facade/command_request.rb +13 -33
- data/lib/hecks/facade/handle.rb +34 -121
- data/lib/hecks/facade/json_door.rb +31 -146
- data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
- data/lib/hecks/facade/surface/chapter.rb +10 -54
- data/lib/hecks/facade/surface.rb +8 -23
- data/lib/hecks/facade.rb +10 -25
- data/lib/hecks/forms/app.rb +15 -70
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +30 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +12 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +98 -197
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_door_scope.rb +95 -0
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +62 -65
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +7 -26
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +22 -122
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +23 -103
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projections/bootstrap_table.rb +11 -43
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +35 -202
- data/lib/hecks/projections/deploy/lambda.rb +151 -679
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +2 -58
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +47 -146
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +20 -582
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +15 -42
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +9 -28
- data/lib/hecks/projections/reference.rb +9 -16
- data/lib/hecks/projections/rust_vocabulary.rb +12 -250
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +60 -375
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +46 -138
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +93 -0
- data/lib/hecks/release/runner/commands.rb +66 -0
- data/lib/hecks/release/runner/console.rb +52 -0
- data/lib/hecks/release/runner/gem_publisher.rb +43 -0
- data/lib/hecks/release/runner/git.rb +48 -0
- data/lib/hecks/release/runner/npm_publisher.rb +75 -0
- data/lib/hecks/release/runner/preflight.rb +104 -0
- data/lib/hecks/release/runner/published.rb +55 -0
- data/lib/hecks/release/runner/tagger.rb +80 -0
- data/lib/hecks/release/runner.rb +215 -0
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +12 -36
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
- data/lib/hecks/runtime/command_interpreter.rb +125 -307
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +30 -102
- data/lib/hecks/runtime/dispatcher.rb +82 -241
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +65 -220
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +11 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +48 -186
- data/lib/hecks/runtime/outbox.rb +38 -261
- data/lib/hecks/runtime/policy_interpreter.rb +38 -200
- data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
- data/lib/hecks/runtime/query_interpreter.rb +45 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/read_model_interpreter.rb +139 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +8 -89
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +52 -225
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +103 -244
- data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +155 -641
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value.rb +12 -84
- data/lib/hecks/runtime.rb +17 -65
- data/lib/hecks/storehouse.rb +146 -567
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks/vocabulary.rb +5 -0
- data/lib/hecks.rb +32 -82
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- metadata +30 -59
- data/lib/hecks/bench/cli.rb +0 -74
- data/lib/hecks/bench/environment.rb +0 -100
- data/lib/hecks/bench/postgres_probe.rb +0 -41
- data/lib/hecks/bench/report.rb +0 -116
- data/lib/hecks/bench/ruby_runner.rb +0 -151
- data/lib/hecks/bench/run.rb +0 -55
- data/lib/hecks/bench/rust_runner.rb +0 -165
- data/lib/hecks/bench/stats.rb +0 -75
- data/lib/hecks/bench/suite.rb +0 -172
- data/lib/hecks/bench/workload.rb +0 -137
- data/lib/hecks/bench.rb +0 -28
- data/lib/hecks/codemod.rb +0 -443
- data/lib/hecks/corpus.rb +0 -479
- data/lib/hecks/doc/reference.rb +0 -585
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -684
- data/lib/hecks/fuzzing/combination_miner.rb +0 -178
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +0 -469
- data/lib/hecks/fuzzing/coverage_campaign.rb +0 -161
- data/lib/hecks/fuzzing/differential.rb +0 -192
- data/lib/hecks/fuzzing/domain_generator.rb +0 -871
- data/lib/hecks/fuzzing/era_boundary.rb +0 -154
- data/lib/hecks/fuzzing/form_census.rb +0 -285
- data/lib/hecks/fuzzing/generated_domain_check.rb +0 -171
- data/lib/hecks/fuzzing/invalid_value_generator.rb +0 -125
- data/lib/hecks/fuzzing/isolated_boot.rb +0 -658
- data/lib/hecks/fuzzing/nondeterministic.rb +0 -79
- data/lib/hecks/fuzzing/persistence_parity.rb +0 -253
- data/lib/hecks/fuzzing/properties/corrections.rb +0 -125
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +0 -688
- data/lib/hecks/fuzzing/properties/guards.rb +0 -398
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +0 -399
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +0 -137
- data/lib/hecks/fuzzing/properties/outbox.rb +0 -180
- data/lib/hecks/fuzzing/properties/querying.rb +0 -260
- data/lib/hecks/fuzzing/properties.rb +0 -267
- data/lib/hecks/fuzzing/qa_settings.rb +0 -164
- data/lib/hecks/fuzzing/replay.rb +0 -930
- data/lib/hecks/fuzzing/rotation_priority.rb +0 -114
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +0 -139
- data/lib/hecks/fuzzing/self_consistency.rb +0 -825
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +0 -532
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +0 -171
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +0 -127
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +0 -116
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +0 -138
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +0 -344
- data/lib/hecks/fuzzing/sequence_generator.rb +0 -311
- data/lib/hecks/fuzzing/shrinker.rb +0 -309
- data/lib/hecks/fuzzing/structural_skips.rb +0 -53
- data/lib/hecks/fuzzing/sweep_depth.rb +0 -61
- data/lib/hecks/fuzzing/target_capabilities.rb +0 -255
- data/lib/hecks/fuzzing/value_generator.rb +0 -340
- data/lib/hecks/fuzzing.rb +0 -23
- data/lib/hecks/grammar/evolve.rb +0 -524
- data/lib/hecks/query_ir.rb +0 -482
|
@@ -2,13 +2,8 @@ require_relative "word_gate"
|
|
|
2
2
|
module Hecks
|
|
3
3
|
module Bluebook
|
|
4
4
|
module DSL
|
|
5
|
-
# Parses a `process_manager "Name" do ... end` block into a
|
|
6
|
-
#
|
|
7
|
-
# correlates its instances (`correlates_by`), and the `transition`-
|
|
8
|
-
# declared state machine whose `dispatch`es (each optionally paired
|
|
9
|
-
# with its own per-dispatch `compensates`) become its handlers. States
|
|
10
|
-
# are derived from the transitions rather than declared separately
|
|
11
|
-
# (S7, ADR 0025).
|
|
5
|
+
# Parses a `process_manager "Name" do ... end` block into a `ProcessManager`; its states
|
|
6
|
+
# are derived from its `transition`s (ADR 0025).
|
|
12
7
|
class ProcessManagerBuilder
|
|
13
8
|
GRAMMAR_CONTEXT = "ProcessManager".freeze
|
|
14
9
|
|
|
@@ -24,16 +19,9 @@ module Hecks
|
|
|
24
19
|
|
|
25
20
|
# Records the event that begins a fresh instance of this process manager.
|
|
26
21
|
#
|
|
27
|
-
# `starts_on Transfer::TransferRequested
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
# resolve an event reference — but through `Naming.
|
|
31
|
-
# event_name_ref`, not `Naming.event_ref` (that method's own
|
|
32
|
-
# header has the full account: `SagaInterpreter` matches
|
|
33
|
-
# `pm.starts_on`/`pm.ends_on` against a bare `event.name`, never
|
|
34
|
-
# a "." qualified one). A plain String still passes through
|
|
35
|
-
# unchanged, both for `shadow_parse` and for any corpus site a
|
|
36
|
-
# future pass hasn't migrated yet.
|
|
22
|
+
# `starts_on Transfer::TransferRequested`: a bare constant, stored as the bare event
|
|
23
|
+
# name (`Naming.event_name_ref`) because `SagaInterpreter` matches an undotted name.
|
|
24
|
+
# A plain String passes through unchanged.
|
|
37
25
|
#
|
|
38
26
|
# @param event_ref [Symbol, String, Module] the event, as a bare constant (a
|
|
39
27
|
# `ScopedConstant` module `ConstShim` resolves) or quoted text
|
|
@@ -42,9 +30,7 @@ module Hecks
|
|
|
42
30
|
@starts_on = Naming.event_name_ref(event_ref)
|
|
43
31
|
end
|
|
44
32
|
|
|
45
|
-
# Records the event this process manager
|
|
46
|
-
#
|
|
47
|
-
# `ends_on` — same reasoning as `starts_on_impl`, above.
|
|
33
|
+
# Records the event that closes out this process manager's instance.
|
|
48
34
|
#
|
|
49
35
|
# @param event_ref [Symbol, String, Module] the event, as a bare constant (a
|
|
50
36
|
# `ScopedConstant` module `ConstShim` resolves) or quoted text
|
|
@@ -53,67 +39,14 @@ module Hecks
|
|
|
53
39
|
@ends_on = Naming.event_name_ref(event_ref)
|
|
54
40
|
end
|
|
55
41
|
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
# kind-driven coerce-and-assign with nothing else, executed by
|
|
59
|
-
# `GenericDispatch`.
|
|
60
|
-
#
|
|
61
|
-
# `starts_on`/`ends_on` are hand-written rather than table-driven
|
|
62
|
-
# the same way, because ADR 0025 S6 gives each a second,
|
|
63
|
-
# `kind: "constant"` ArgumentSeed row (`starts_on
|
|
64
|
-
# Transfer::TransferRequested`) — `GenericDispatch::COERCE_BY_KIND`
|
|
65
|
-
# only knows `"text"`/`"symbol"`, and `shape_for` refuses to pick a
|
|
66
|
-
# `single_fill` shape at all once two Argument rows share a
|
|
67
|
-
# `fills:` target (`arguments.size == 1` below), so both words are
|
|
68
|
-
# `calls:`-routed like `transition` already is.
|
|
69
|
-
|
|
70
|
-
# Records one leg of this process manager's state machine: the event that takes it, the
|
|
71
|
-
# state(s) it applies from, and the dispatches (and optional compensation) it fires.
|
|
72
|
-
#
|
|
73
|
-
# One state-machine vocabulary (S7, ADR 0025 — "events and
|
|
74
|
-
# reactions"): the same word `Lifecycle#transition` already
|
|
75
|
-
# carries, one level over — `transition "AccountDebited" =>
|
|
76
|
-
# "awaiting_credit", from: "requested" do ... end` replaces `on
|
|
77
|
-
# "AccountDebited", transition: { "requested" => "awaiting_
|
|
78
|
-
# credit" } do ... end`. Same bare rocket-pair argument shape
|
|
79
|
-
# (not a named `transition:` kwarg wrapping a second Hash), same
|
|
80
|
-
# `from:` — including the array form Lifecycle's own commands
|
|
81
|
-
# could already take and a process manager's own events could
|
|
82
|
-
# not — and the states a procedure runs on are derived from the
|
|
83
|
-
# transitions that name them, the same way `Behaviour::Lifecycle
|
|
84
|
-
# #states` already derives an aggregate's ; `state "x"` lines
|
|
85
|
-
# duplicated exactly what the transition list already said,
|
|
86
|
-
# and could drift from it (`validate!`'s own "undeclared state"
|
|
87
|
-
# check existed only because they could).
|
|
42
|
+
# Records one leg of the state machine: the event that takes it, the state(s) it
|
|
43
|
+
# applies from, and the dispatches (with optional compensations) it fires.
|
|
88
44
|
#
|
|
89
|
-
#
|
|
90
|
-
# against the real corpus rather than assumed: Settlement's own
|
|
91
|
-
# `ends_on "TransferSettled"` names an event none of its own
|
|
92
|
-
# transitions ever handle (`Transfer.Settle`'s own emission, a
|
|
93
|
-
# full step downstream of the transition that dispatches it),
|
|
94
|
-
# so "the terminal state's own event" is not a fact the
|
|
95
|
-
# transition graph carries — deriving it would either be wrong
|
|
96
|
-
# for this exact corpus member or need a second new word to
|
|
97
|
-
# cover the case, which is not less vocabulary than keeping the
|
|
98
|
-
# one that already says it correctly.
|
|
99
|
-
#
|
|
100
|
-
# Expands immediately, unlike `Lifecycle#transition` (which
|
|
101
|
-
# defers to `Behaviour::Lifecycle#expand`, called at emission
|
|
102
|
-
# time) — `ProcessManager`'s own IR constructor takes `states:`/
|
|
103
|
-
# `handlers:` exactly as it always has, so the runtime
|
|
104
|
-
# (`Behaviour::ProcessManager`, `SagaInterpreter`, saga
|
|
105
|
-
# persistence/rehydration) needs no change at all: what changed
|
|
106
|
-
# is how the declaration reaches that same shape, not the shape
|
|
107
|
-
# a real run ever sees or persists.
|
|
108
|
-
# Reached through `calls: "transition_impl"`. Not exercised during boot itself — checked
|
|
109
|
-
# directly, no core/attached chapter declares a `ProcessManager` of its own — though the
|
|
110
|
-
# (context, word) pair is still carried in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`
|
|
111
|
-
# unconditionally, along with every other `calls:`-routed row.
|
|
45
|
+
# States are derived from the transitions, not declared.
|
|
112
46
|
#
|
|
113
47
|
# @param mapping [Hash] one `event => target_state` pair plus a required `from:` key
|
|
114
|
-
# naming the source state(s)
|
|
115
|
-
#
|
|
116
|
-
# @yield the transition's dispatch body, `instance_eval`'d against a fresh `HandlerBuilder`
|
|
48
|
+
# naming the source state(s): a `String`, `Symbol`, or an `Array` of them
|
|
49
|
+
# @yield the transition's dispatch body, `instance_eval`'d against a `HandlerBuilder`
|
|
117
50
|
# @return [void]
|
|
118
51
|
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if `mapping` names
|
|
119
52
|
# no `from:`
|
|
@@ -121,18 +54,8 @@ module Hecks
|
|
|
121
54
|
mapping = mapping.dup
|
|
122
55
|
from = mapping.delete(:from)
|
|
123
56
|
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
# any current state (`Behaviour::Lifecycle#applies_from?`
|
|
127
|
-
# returns true for a nil `from`), a reading `SagaInterpreter#
|
|
128
|
-
# advance_saga`'s own admission check does not share: it tests
|
|
129
|
-
# `instance[:state] == handler.from_state` by plain equality,
|
|
130
|
-
# nothing softer. Leaving that check unchanged (this slice's
|
|
131
|
-
# own scope decision — see the class-level comment on why the
|
|
132
|
-
# runtime stays untouched) means an unconstrained PM
|
|
133
|
-
# transition would build cleanly and then match no instance
|
|
134
|
-
# ever, silently — refused here instead, at the one point that
|
|
135
|
-
# can still see the mistake.
|
|
57
|
+
# `from:` is required: the saga's admission check tests `from_state` by plain equality,
|
|
58
|
+
# so a transition with no `from:` would match no instance.
|
|
136
59
|
if from.nil?
|
|
137
60
|
raise InvalidProcessManager,
|
|
138
61
|
"#{@name}'s transition #{mapping.inspect} names no from: — a process manager's own " \
|
|
@@ -144,23 +67,8 @@ module Hecks
|
|
|
144
67
|
handler.instance_eval(&block) if block
|
|
145
68
|
|
|
146
69
|
mapping.each do |event_type, target|
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
# `Naming.event_name_ref`, not the dotted `Naming.event_ref`
|
|
150
|
-
# transform `PolicyBuilder#on_impl` uses (that method's own
|
|
151
|
-
# header has the full account, found live wiring a real
|
|
152
|
-
# migrated corpus site into `bin/model_check` for the first
|
|
153
|
-
# time: `SagaInterpreter#advance_saga` matches `handler.
|
|
154
|
-
# event_type` against a bare `event.name`, never a "."
|
|
155
|
-
# qualified one — a policy's own cross-aggregate match
|
|
156
|
-
# works differently, splitting the qualifier apart from the
|
|
157
|
-
# name rather than comparing the whole string). Writing the
|
|
158
|
-
# qualifier is still worth it (the same provenance `trigger
|
|
159
|
-
# Account::Debit` gives a reader) — `event_name_ref` keeps
|
|
160
|
-
# only the final segment, so `Account::AccountDebited` and a
|
|
161
|
-
# bare `AccountDebited` store identically. A plain String
|
|
162
|
-
# still passes through unchanged, both for `shadow_parse`
|
|
163
|
-
# and for every corpus site this pass didn't migrate.
|
|
70
|
+
# `event_name_ref` keeps only the final segment: `SagaInterpreter` matches a bare
|
|
71
|
+
# `event.name`, so `Account::AccountDebited` and `AccountDebited` store the same.
|
|
164
72
|
state_transition = StateTransition.new(target: target, from: from)
|
|
165
73
|
expand(Naming.event_name_ref(event_type), state_transition, handler.dispatches).each { |row| @handlers << row }
|
|
166
74
|
end
|
|
@@ -202,12 +110,7 @@ module Hecks
|
|
|
202
110
|
|
|
203
111
|
private
|
|
204
112
|
|
|
205
|
-
# One
|
|
206
|
-
# than one source state — `Behaviour::Lifecycle#expand`'s own
|
|
207
|
-
# comment, the identical fan-out, one level over: a
|
|
208
|
-
# `ProcessManagerHandler` only ever carries a single `from_state`,
|
|
209
|
-
# so a `from: [...]` transition mints one row per source, each
|
|
210
|
-
# carrying the same dispatches.
|
|
113
|
+
# One row per source state, since a `ProcessManagerHandler` carries a single `from_state`.
|
|
211
114
|
def expand(event_type, transition, dispatches)
|
|
212
115
|
sources = transition.from.nil? ? [nil] : Array(transition.from)
|
|
213
116
|
|
|
@@ -221,15 +124,7 @@ module Hecks
|
|
|
221
124
|
end
|
|
222
125
|
end
|
|
223
126
|
|
|
224
|
-
#
|
|
225
|
-
# runs on is already named by some transition's own `from_state`
|
|
226
|
-
# or `to_state`; a state nothing transitions into or out of is
|
|
227
|
-
# not a state this procedure has, the same reading
|
|
228
|
-
# `Behaviour::Lifecycle#states` already gives an aggregate's own
|
|
229
|
-
# field. First-seen order, walking declaration order — `begin_
|
|
230
|
-
# saga`'s own `pm.states.first` is what a fresh instance starts
|
|
231
|
-
# in, so the order has to survive the derivation, not just the
|
|
232
|
-
# membership.
|
|
127
|
+
# First-seen order matters: `pm.states.first` is the state a fresh instance starts in.
|
|
233
128
|
def derived_states
|
|
234
129
|
@handlers.flat_map { |h| [h.from_state, h.to_state] }.reject(&:empty?).uniq
|
|
235
130
|
end
|
|
@@ -240,16 +135,8 @@ module Hecks
|
|
|
240
135
|
"nothing would tie its events to one instance"
|
|
241
136
|
end
|
|
242
137
|
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
# that key as the correlation key, and what a non-scalar key even
|
|
246
|
-
# is stays open (the object itself? its serialised text?).
|
|
247
|
-
# Requiring the dotted spelling —
|
|
248
|
-
# `:"end_to_end.value"` — makes every correlates_by name a scalar
|
|
249
|
-
# by construction, the same discipline `identified_by` already
|
|
250
|
-
# holds a head to. This is a syntactic check, not a type check: it
|
|
251
|
-
# does not know or care whether the field is a value object, only
|
|
252
|
-
# that the declaration cannot leave that question open.
|
|
138
|
+
# Names a scalar (`:"end_to_end.value"`), never a whole field or value object.
|
|
139
|
+
# A syntactic check: the dotted spelling leaves no question about the key's type.
|
|
253
140
|
unless @correlates_by.to_s.include?(".")
|
|
254
141
|
raise InvalidProcessManager, "#{@name} correlates_by #{@correlates_by.inspect}, which names a whole " \
|
|
255
142
|
"field rather than one of its scalars — say which one, e.g. " \
|
|
@@ -269,12 +156,8 @@ module Hecks
|
|
|
269
156
|
refuse_ambiguous_legs!
|
|
270
157
|
end
|
|
271
158
|
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
# the runtime to pick by declaration order, silently. Refused
|
|
275
|
-
# here, where the declaration can still be read whole. (`from:
|
|
276
|
-
# [...]` fan-out counts: `transition E => "a", from: ["x", "y"]`
|
|
277
|
-
# and `transition E => "b", from: "y"` collide on ("E", "y").)
|
|
159
|
+
# A leg is selected by (event, current state), so two legs on the same pair would
|
|
160
|
+
# be picked by declaration order; `from: [...]` fan-out counts.
|
|
278
161
|
def refuse_ambiguous_legs!
|
|
279
162
|
return if MetaValidator.shadow_parsing? # frozen era text is history
|
|
280
163
|
|
|
@@ -292,10 +175,7 @@ module Hecks
|
|
|
292
175
|
end
|
|
293
176
|
end
|
|
294
177
|
|
|
295
|
-
# The body of one `transition ... do ... end` block
|
|
296
|
-
# `dispatch` calls (each optionally opening its own `compensates`
|
|
297
|
-
# via the nested `DispatchBuilder`) that fire when this transition
|
|
298
|
-
# is taken.
|
|
178
|
+
# The body of one `transition ... do ... end` block; collects its `dispatch` calls.
|
|
299
179
|
class HandlerBuilder
|
|
300
180
|
GRAMMAR_CONTEXT = "Handler".freeze
|
|
301
181
|
|
|
@@ -309,34 +189,12 @@ module Hecks
|
|
|
309
189
|
# Records one command this transition dispatches, and, if given a block, the
|
|
310
190
|
# compensation that reverses it.
|
|
311
191
|
#
|
|
312
|
-
# The command
|
|
313
|
-
# references become first-class), same shape and same reasons
|
|
314
|
-
# as `PolicyBuilder#trigger`'s own header — bare constant live,
|
|
315
|
-
# quoted text only under shadow-parsing (S0a's bridge; frozen
|
|
316
|
-
# era text still writes `dispatch "Banking::Account.Debit"`).
|
|
317
|
-
#
|
|
318
|
-
# Reached through `calls: "dispatch_impl"`.
|
|
319
|
-
#
|
|
320
|
-
# An optional block opens `compensates` on this dispatch
|
|
321
|
-
# specifically — per-dispatch saga compensation, replacing a
|
|
322
|
-
# hand-written list at the saga's own `on :refused` leg. Real,
|
|
323
|
-
# live bug this closes: `examples/banking/bluebook/transfers_
|
|
324
|
-
# and_payments.bluebook`'s own `Settlement` saga wrote a
|
|
325
|
-
# compensating reversal by hand that depended on an event only
|
|
326
|
-
# fired if someone dispatched it manually — "the reversal was
|
|
327
|
-
# written and never armed" (that file's own comment). The
|
|
328
|
-
# runtime now tracks which legs actually completed
|
|
329
|
-
# (`SagaInterpreter`'s own `completed_compensations`) and
|
|
330
|
-
# compensates only those, newest first, instead of trusting an
|
|
331
|
-
# author's static list to be complete and correctly ordered.
|
|
192
|
+
# The command is a bare constant; quoted text is accepted only under shadow-parsing.
|
|
332
193
|
#
|
|
333
|
-
# @param command_ref [Symbol, String, Module] the command, as a bare constant
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
#
|
|
337
|
-
# `nil` forwards the triggering context verbatim
|
|
338
|
-
# @yield the dispatch's own `compensates` body, `instance_eval`'d against a
|
|
339
|
-
# `DispatchBuilder`
|
|
194
|
+
# @param command_ref [Symbol, String, Module] the command, as a bare constant
|
|
195
|
+
# @param with [Hash{Symbol => Object}, nil] a projection onto the command's arguments,
|
|
196
|
+
# as in a policy's `trigger ..., with:`; `nil` forwards the triggering context
|
|
197
|
+
# @yield the `compensates` body, run only if this leg completed
|
|
340
198
|
# @return [Bluebook::DispatchSpec] the dispatch just recorded
|
|
341
199
|
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if `command_ref`
|
|
342
200
|
# is quoted text outside shadow-parsing
|
|
@@ -356,11 +214,8 @@ module Hecks
|
|
|
356
214
|
if block
|
|
357
215
|
builder = DispatchBuilder.new
|
|
358
216
|
builder.instance_eval(&block)
|
|
359
|
-
# `instance_variable_get`, not a public
|
|
360
|
-
#
|
|
361
|
-
# never declares, exactly what `spec/syntax_conformance_
|
|
362
|
-
# spec.rb`'s "answers only words the language declares"
|
|
363
|
-
# check exists to catch.
|
|
217
|
+
# `instance_variable_get`, not a public reader: a reader would be a method the
|
|
218
|
+
# grammar never declares (syntax_conformance_spec).
|
|
364
219
|
spec.compensates = builder.instance_variable_get(:@compensates_spec)
|
|
365
220
|
end
|
|
366
221
|
|
|
@@ -368,16 +223,8 @@ module Hecks
|
|
|
368
223
|
spec
|
|
369
224
|
end
|
|
370
225
|
|
|
371
|
-
# The nested scope `dispatch ... do ... end` opens
|
|
372
|
-
#
|
|
373
|
-
# sits inside. Its own `compensates_impl` builds a second
|
|
374
|
-
# `DispatchSpec`, shape-identical to `HandlerBuilder#dispatch_
|
|
375
|
-
# impl`'s own — a compensation takes the exact same two
|
|
376
|
-
# arguments (a bare command constant, an optional `with:`)
|
|
377
|
-
# because it resolves through the identical scope (current
|
|
378
|
-
# event payload, opening event memory, correlation binding)
|
|
379
|
-
# any saga dispatch already does
|
|
380
|
-
# (`SagaInterpreter#dispatch_args`).
|
|
226
|
+
# The nested scope `dispatch ... do ... end` opens; its one word, `compensates`,
|
|
227
|
+
# takes the same arguments as `dispatch` and resolves in the same saga scope.
|
|
381
228
|
class DispatchBuilder
|
|
382
229
|
GRAMMAR_CONTEXT = "Dispatch".freeze
|
|
383
230
|
|
|
@@ -29,17 +29,8 @@ module Hecks
|
|
|
29
29
|
|
|
30
30
|
# Declares a query parameter that names another aggregate's identity.
|
|
31
31
|
#
|
|
32
|
-
# A query
|
|
33
|
-
#
|
|
34
|
-
# just a plain attribute typed as a reference,
|
|
35
|
-
# `AttributeCollector#attribute_impl` already handling a Reference
|
|
36
|
-
# exactly like any other. No "acts on itself" case to
|
|
37
|
-
# distinguish here the way a command's own reference_to has —
|
|
38
|
-
# a query has no root of its own to act on, only parameters.
|
|
39
|
-
#
|
|
40
|
-
# Answers the `reference_to` word through the table's `calls:`
|
|
41
|
-
# column — item #13's full metaprogrammed dispatch (slice 4b).
|
|
42
|
-
# Bootstrap-reachable, in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
|
|
32
|
+
# A plain attribute typed as a reference; a query has no root of its own to act on.
|
|
33
|
+
# Reached through `calls: "reference_to_impl"`.
|
|
43
34
|
#
|
|
44
35
|
# @param type [Module, Symbol, String] the referenced aggregate, written as a bare
|
|
45
36
|
# constant
|
|
@@ -86,31 +77,17 @@ module Hecks
|
|
|
86
77
|
def self.build(name, owner_attributes: [], &block)
|
|
87
78
|
builder = new(name)
|
|
88
79
|
builder.instance_eval(&block) if block
|
|
89
|
-
# `send
|
|
90
|
-
#
|
|
91
|
-
# just internal wiring between this class method and the instance
|
|
92
|
-
# it just built. Kept private below so syntax_conformance_spec's
|
|
93
|
-
# own "every word QueryBuilder answers is declared" check doesn't
|
|
94
|
-
# mistake it for one.
|
|
80
|
+
# `send`: `derive_from_owner!` is internal wiring, not a DSL word, so it stays private
|
|
81
|
+
# (syntax_conformance_spec).
|
|
95
82
|
builder.send(:derive_from_owner!, owner_attributes, block) if block
|
|
96
83
|
builder.build
|
|
97
84
|
end
|
|
98
85
|
|
|
99
86
|
private
|
|
100
87
|
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
# on Submission, whose own `attribute :decision, DecisionRef` already
|
|
105
|
-
# says what `decision` is. Restating `attribute :decision, DecisionRef`
|
|
106
|
-
# a second time inside the query was pure duplication; this derives
|
|
107
|
-
# the same type from the owner instead. Only fills in a name the block
|
|
108
|
-
# body did not already declare explicitly (checked after instance_eval
|
|
109
|
-
# runs, so an existing bluebook still spelling it out both ways keeps
|
|
110
|
-
# working unchanged — this only removes the need to, never refuses
|
|
111
|
-
# the choice to). A block parameter matching nothing on the owner is
|
|
112
|
-
# left alone; MetaValidator's own unresolved-attribute check names it,
|
|
113
|
-
# the same way a typo in a hand-written `attribute` call already does.
|
|
88
|
+
# Fills in a block parameter that names an owner attribute (`query "X" do |decision|`)
|
|
89
|
+
# with the owner's type, unless the body declared it. Unmatched names are left for
|
|
90
|
+
# MetaValidator's unresolved-attribute check.
|
|
114
91
|
def derive_from_owner!(owner_attributes, block)
|
|
115
92
|
block.parameters.each do |kind, param_name|
|
|
116
93
|
next unless %i[req opt].include?(kind)
|
|
@@ -119,22 +96,14 @@ module Hecks
|
|
|
119
96
|
owner_attr = owner_attributes.find { |a| a.name == param_name }
|
|
120
97
|
next unless owner_attr
|
|
121
98
|
|
|
122
|
-
# `Attribute.new` directly,
|
|
123
|
-
#
|
|
124
|
-
# String, `Attribute#spell`'s own doing), not a bareword the
|
|
125
|
-
# bluebook author typed, so it must not run through
|
|
126
|
-
# `AttributeCollector#attribute`'s quoted-type refusal (ADR
|
|
127
|
-
# 0025, "Attributes") — that refusal exists for DSL source
|
|
128
|
-
# text, not for a type already resolved elsewhere and copied.
|
|
99
|
+
# `Attribute.new` directly: `owner_attr.type` is already spelled, so it must not go
|
|
100
|
+
# through the quoted-type refusal meant for DSL source text.
|
|
129
101
|
attributes << Attribute.new(name: param_name, type: owner_attr.type, optional: owner_attr.optional?)
|
|
130
102
|
end
|
|
131
103
|
end
|
|
132
104
|
|
|
133
|
-
# `cursor` parses
|
|
134
|
-
#
|
|
135
|
-
# it here, rather than deleting the word, keeps the declared syntax
|
|
136
|
-
# honest (the language still knows the shape) while refusing to let a
|
|
137
|
-
# bluebook author believe cursor-based pagination actually happens.
|
|
105
|
+
# `cursor` parses and round-trips but no interpreter applies it; refuse it so an author
|
|
106
|
+
# does not believe cursor pagination happens.
|
|
138
107
|
def seal_cursor
|
|
139
108
|
return unless @cursor
|
|
140
109
|
|