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
|
@@ -4,35 +4,19 @@ module Hecks
|
|
|
4
4
|
module Bluebook
|
|
5
5
|
module Behaviour
|
|
6
6
|
# What an aggregate does, as opposed to what it holds.
|
|
7
|
-
#
|
|
8
|
-
# The holding half — the field list, the readers, the emission — is
|
|
9
|
-
# the same list the language already declares in
|
|
10
|
-
# `language/bluebook/aggregate.bluebook`, said a second and third
|
|
11
|
-
# time in Ruby. This half is not: derived identity, the name
|
|
12
|
-
# indexes, the owner stamping and the finders are decisions about
|
|
13
|
-
# how the declared shape is used, and no grammar states them.
|
|
14
|
-
#
|
|
15
|
-
# Split so the holding half can be generated from the language
|
|
16
|
-
# without any of this being in the blast radius of a regeneration.
|
|
17
|
-
# Everything here is hand-written and permanent.
|
|
18
|
-
#
|
|
19
|
-
# The three traits are shared with Entity (and, for `Indexed`,
|
|
20
|
-
# with Command and PortOperation) — see behaviour/traits.rb on why
|
|
21
|
-
# they are one module rather than four copies.
|
|
7
|
+
# Hand-written, so regenerating the declared field list never touches it.
|
|
22
8
|
module Aggregate
|
|
23
9
|
include Identified
|
|
24
10
|
include Indexed
|
|
25
11
|
include Owns
|
|
26
12
|
|
|
27
|
-
# An aggregate
|
|
28
|
-
#
|
|
13
|
+
# An aggregate joins its chapter's namespace with "::" ("Pizzas::Pizza");
|
|
14
|
+
# everything else joins its owner with ".".
|
|
29
15
|
#
|
|
30
16
|
# @return [String] the literal string `"::"`
|
|
31
17
|
def hecks_separator = "::"
|
|
32
18
|
|
|
33
|
-
# The hook the generated constructor calls once every declared
|
|
34
|
-
# field is assigned. Nothing here is derivable from the
|
|
35
|
-
# declaration, which is exactly why it is not generated.
|
|
19
|
+
# The hook the generated constructor calls once every declared field is assigned.
|
|
36
20
|
#
|
|
37
21
|
# @return [Bluebook::Aggregate] self, once identity is derived, every
|
|
38
22
|
# declaration is indexed and its commands, value objects, entities and
|
|
@@ -40,8 +24,7 @@ module Hecks
|
|
|
40
24
|
def settle
|
|
41
25
|
derive_identity
|
|
42
26
|
index_declarations
|
|
43
|
-
# An entity stamps its own commands and queries when
|
|
44
|
-
# declared, so the chain closes downward from here.
|
|
27
|
+
# An entity stamps its own commands and queries when declared.
|
|
45
28
|
stamp(@commands, @value_objects, @entities, @queries)
|
|
46
29
|
self
|
|
47
30
|
end
|
|
@@ -56,10 +39,7 @@ module Hecks
|
|
|
56
39
|
@commands_by_name = index_by_hecks_name(@commands)
|
|
57
40
|
@queries_by_name = index_by_hecks_name(@queries)
|
|
58
41
|
@ports_by_name = @ports.to_h { |port| [port.name, port] }
|
|
59
|
-
#
|
|
60
|
-
# `Indexed#attribute` already uses; `GuardState` asks for one
|
|
61
|
-
# by name at every dispatch, the rebuild sweep walks all of
|
|
62
|
-
# them once per pass.
|
|
42
|
+
# Keyed by symbol, like `Indexed#attribute` (ADR 0025).
|
|
63
43
|
@projected_fields_by_name = @projected_fields.to_h { |field| [field.name, field] }
|
|
64
44
|
end
|
|
65
45
|
|
|
@@ -70,11 +50,7 @@ module Hecks
|
|
|
70
50
|
# `nil` if none is declared under that name
|
|
71
51
|
def projected_field(named) = @projected_fields_by_name[named.to_sym]
|
|
72
52
|
|
|
73
|
-
#
|
|
74
|
-
# path) and the declared name is `hecks_name`. This finder is on its way
|
|
75
|
-
# out — once an attribute's type is the class there is nothing to find —
|
|
76
|
-
# but every consumer still asks by type string, so it stays until they
|
|
77
|
-
# stop.
|
|
53
|
+
# Finds a value object by declared name; `name` on the class is the constant path.
|
|
78
54
|
#
|
|
79
55
|
# @param named [String, Symbol] the value object's declared name
|
|
80
56
|
# @return [Class, nil] the value object class (a `Bluebook::ValueObject`
|
|
@@ -88,14 +64,9 @@ module Hecks
|
|
|
88
64
|
# none is attached under that name
|
|
89
65
|
def port(named) = @ports_by_name[named.to_s]
|
|
90
66
|
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# port (persistence, projection, ...). So this attaches after the
|
|
95
|
-
# aggregate already exists and is registered — `HecksagonBuilder`
|
|
96
|
-
# calls it once per `port` declaration, having already stamped each
|
|
97
|
-
# operation's reference attributes with `declared_in = self`, since
|
|
98
|
-
# nothing upstream of a hecksagon load does that for it.
|
|
67
|
+
# Attaches a port declared in the hecksagon, after the aggregate exists.
|
|
68
|
+
# `HecksagonBuilder` stamps each operation's reference attributes with
|
|
69
|
+
# `declared_in = self` before calling it.
|
|
99
70
|
#
|
|
100
71
|
# @param port [Bluebook::DomainPort] the aggregate-scoped port to attach
|
|
101
72
|
# @return [void]
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Bluebook
|
|
3
3
|
module Behaviour
|
|
4
|
-
# **What an attribute does
|
|
5
|
-
# default, optional, pattern, admits — is what the language states
|
|
6
|
-
# in `aggregate.bluebook`'s own `Field`. These are the questions
|
|
7
|
-
# readers ask about that shape, which no declaration states.
|
|
4
|
+
# **What an attribute does**: the questions readers ask about its declared shape.
|
|
8
5
|
module Attribute
|
|
9
6
|
# Says whether this attribute was declared `list`.
|
|
10
7
|
#
|
|
@@ -21,16 +18,8 @@ module Hecks
|
|
|
21
18
|
# @return [Boolean] whether this attribute's type is a `reference_to` another aggregate
|
|
22
19
|
def reference? = @type.is_a?(Reference)
|
|
23
20
|
|
|
24
|
-
# May this fact be left out?
|
|
25
|
-
#
|
|
26
|
-
# Required is the default and by far the common case — a command takes
|
|
27
|
-
# the arguments it declares, and all of them — so the exception is what
|
|
28
|
-
# gets marked. Marking the other way would annotate almost every
|
|
29
|
-
# attribute in the corpus to say nothing.
|
|
30
|
-
#
|
|
31
|
-
# Only a command enforces this. An aggregate's own attributes are filled
|
|
32
|
-
# by the commands that set them, and a value object's by its
|
|
33
|
-
# constructor ; neither is a payload anyone hands in.
|
|
21
|
+
# May this fact be left out? Required is the default; only a command enforces
|
|
22
|
+
# this, since aggregate and value object attributes are not caller payloads.
|
|
34
23
|
#
|
|
35
24
|
# @return [Boolean] whether a command may omit this attribute from its payload
|
|
36
25
|
def optional? = @optional
|
|
@@ -3,22 +3,15 @@ require_relative "traits"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Bluebook
|
|
5
5
|
module Behaviour
|
|
6
|
-
#
|
|
7
|
-
# bluebook holds; these are the finders over it, plus `verbs
|
|
8
|
-
# chapter's own list of every dispatchable name, which is derived
|
|
9
|
-
# from the aggregates rather than declared anywhere.
|
|
6
|
+
# What a chapter does. The declared half is the roll-call of what a
|
|
7
|
+
# bluebook holds; these are the finders over it, plus `verbs`.
|
|
10
8
|
module Chapter
|
|
11
9
|
include Owns
|
|
12
10
|
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# owner chain (nothing declares it, it is what having no owner
|
|
16
|
-
# means), the ports table — which a `.hecksagon` fills later, so
|
|
17
|
-
# the bluebook cannot declare it — and stamping its own children,
|
|
18
|
-
# the same act an Aggregate performs one level down.
|
|
11
|
+
# Marks this chapter the root of the owner chain, attaches the ports
|
|
12
|
+
# table (filled later by a `.hecksagon`), and stamps ownership.
|
|
19
13
|
#
|
|
20
|
-
# @return [Bluebook::Chapter] self
|
|
21
|
-
# stamping are all set up
|
|
14
|
+
# @return [Bluebook::Chapter] self
|
|
22
15
|
def settle
|
|
23
16
|
@hecks_root = true
|
|
24
17
|
@ports = []
|
|
@@ -47,11 +40,7 @@ module Hecks
|
|
|
47
40
|
# by that name
|
|
48
41
|
def port(named) = @ports_by_name[named.to_s]
|
|
49
42
|
|
|
50
|
-
# What this chapter declared it provides
|
|
51
|
-
# for one capability, or nil when it declares none. Read by
|
|
52
|
-
# everything that resolves a capability's provider from what a
|
|
53
|
-
# chapter declares, rather than from the chapter's own name
|
|
54
|
-
# (`Registry#authorization_provider_for`).
|
|
43
|
+
# What this chapter declared it provides for one capability.
|
|
55
44
|
#
|
|
56
45
|
# @param capability [String, Symbol] the capability's name, such as
|
|
57
46
|
# `Bluebook::Capabilities::AUTHORIZATION`
|
|
@@ -80,9 +69,8 @@ module Hecks
|
|
|
80
69
|
local && "#{name}::#{local}"
|
|
81
70
|
end
|
|
82
71
|
|
|
83
|
-
# A port
|
|
84
|
-
#
|
|
85
|
-
# aggregate's own ports do.
|
|
72
|
+
# A port attaches after the chapter already exists, once its
|
|
73
|
+
# hecksagon is built — the same way an aggregate's own ports do.
|
|
86
74
|
#
|
|
87
75
|
# @param port [Bluebook::DomainPort] the operations-shaped port to attach
|
|
88
76
|
# @return [void]
|
|
@@ -91,33 +79,20 @@ module Hecks
|
|
|
91
79
|
@ports_by_name[port.name] = port
|
|
92
80
|
end
|
|
93
81
|
|
|
94
|
-
# A
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
# on purpose: which FOREIGN domain's event this chapter reacts to
|
|
101
|
-
# is a wiring/context-mapping decision, not a fact the domain
|
|
102
|
-
# states about its own model.
|
|
82
|
+
# A translated reaction also attaches after the chapter already
|
|
83
|
+
# exists: which foreign domain's event it reacts to is a wiring
|
|
84
|
+
# decision, not a fact the domain states about its own model.
|
|
85
|
+
#
|
|
86
|
+
# @param policy [Bluebook::Policy] the translated reaction to attach
|
|
87
|
+
# @return [Array<Bluebook::Policy>] this chapter's policies, with `policy` appended
|
|
103
88
|
def add_policy(policy)
|
|
104
89
|
@policies << policy
|
|
105
90
|
end
|
|
106
91
|
|
|
107
92
|
# Every dispatchable name this chapter answers to, spelled exactly
|
|
108
|
-
# as Dispatcher#dispatch takes it. Derived from the aggregates,
|
|
109
|
-
# never declared
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
# Recurses into entities, not just an aggregate's own direct
|
|
113
|
-
# commands — `Dispatcher#dispatch` already routes a dotted
|
|
114
|
-
# `Domain::Aggregate.Entity.Command` verb to `EntityInterpreter`
|
|
115
|
-
# (a command_name with a "." in it), so a verb this method left
|
|
116
|
-
# out was never "not a verb," only one this list forgot to name.
|
|
117
|
-
# Ported from the same recursive shape `spec/judge_coverage_spec.rb`
|
|
118
|
-
# already proved out for the meta-domain's own grammar (S17, ADR
|
|
119
|
-
# 0026) — entities nest arbitrarily deep (`Dispatch`, inside
|
|
120
|
-
# `Handler`), so one flat level isn't enough.
|
|
93
|
+
# as `Dispatcher#dispatch` takes it. Derived from the aggregates,
|
|
94
|
+
# never declared, and recurses into entities since a command can be
|
|
95
|
+
# nested arbitrarily deep.
|
|
121
96
|
#
|
|
122
97
|
# @return [Array<String>] every command verb reachable on this chapter, spelled
|
|
123
98
|
# `"Domain::Aggregate.command"` or, nested, `"Domain::Aggregate.Entity.command"`
|
|
@@ -3,13 +3,11 @@ require_relative "traits"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Bluebook
|
|
5
5
|
module Behaviour
|
|
6
|
-
# **What a command does**. Extended, not included
|
|
7
|
-
# class, one per declared verb.
|
|
6
|
+
# **What a command does**. Extended, not included: a command is a class per verb.
|
|
8
7
|
module Command
|
|
9
8
|
include Indexed
|
|
10
9
|
|
|
11
|
-
#
|
|
12
|
-
# dispatch asks this finder by name.
|
|
10
|
+
# Indexes the attributes once; they are final once absorbed.
|
|
13
11
|
#
|
|
14
12
|
# @return [Class] self — the command class, once its attributes are
|
|
15
13
|
# indexed
|
|
@@ -21,25 +19,15 @@ module Hecks
|
|
|
21
19
|
# The construct this verb acts upon — the construct itself, not its name.
|
|
22
20
|
#
|
|
23
21
|
# A verb declared on an entity always acts on that piece. It never
|
|
24
|
-
# self-references,
|
|
25
|
-
#
|
|
26
|
-
# `acts_on` off `creates?` alone would report that `LedgerEntry.Amend`
|
|
27
|
-
# brings a ledger entry into being. Three of banking's commands were
|
|
28
|
-
# about to say exactly that, and nothing would have contradicted them.
|
|
29
|
-
#
|
|
30
|
-
# On an aggregate, a creating command acts on no existing root, so nil is
|
|
31
|
-
# the truth: there is nothing there yet.
|
|
22
|
+
# self-references, so `creates?` is true for it and cannot decide this alone.
|
|
23
|
+
# A creating command on an aggregate acts on nothing yet, so nil.
|
|
32
24
|
#
|
|
33
25
|
# @return [Class, Bluebook::Aggregate, nil] the entity class (a
|
|
34
26
|
# `Bluebook::Entity` subclass) this verb acts on when declared on an
|
|
35
27
|
# entity, the aggregate instance when declared on an aggregate and
|
|
36
28
|
# non-creating, or `nil` for a creating command
|
|
37
29
|
def acts_on
|
|
38
|
-
# Fully qualified
|
|
39
|
-
# the bare name `Entity` resolves to Behaviour::Entity — this
|
|
40
|
-
# module's sibling — not to the construct. Comparing a Class to
|
|
41
|
-
# a Module answers nil, so the guard silently fell through and
|
|
42
|
-
# every entity verb reported acting on nothing.
|
|
30
|
+
# Fully qualified: a bare `Entity` here resolves to Behaviour::Entity, not the construct.
|
|
43
31
|
return hecks_owner if hecks_owner.is_a?(Class) && hecks_owner < Bluebook::Entity
|
|
44
32
|
|
|
45
33
|
creates? ? nil : hecks_owner
|
|
@@ -51,54 +39,18 @@ module Hecks
|
|
|
51
39
|
# it declares no `reference_to` back to its own owner
|
|
52
40
|
def creates? = @references.nil?
|
|
53
41
|
|
|
54
|
-
# Every reason this verb can refuse on a rule
|
|
55
|
-
#
|
|
56
|
-
# after "refused — " when a guard is not met (see
|
|
57
|
-
# command_rules/admissibility.rb's GivenNotMet/EnsuresNotMet). A
|
|
58
|
-
# property that asks "did the runtime only ever refuse for a rule
|
|
59
|
-
# the language wrote" reads this rather than re-deriving the two
|
|
60
|
-
# collections; `compact` because a rule's description is optional
|
|
61
|
-
# (behavior.bluebook's Rule) and an unnamed one quotes nothing.
|
|
42
|
+
# Every reason this verb can refuse on a rule: the descriptions of its givens and
|
|
43
|
+
# ensures, as the runtime quotes them after "refused — ". Unnamed rules are skipped.
|
|
62
44
|
#
|
|
63
45
|
# @return [Array<String>] every named given's and ensure's own
|
|
64
46
|
# description text, skipping unnamed rules
|
|
65
47
|
def guard_descriptions = (@givens + @ensures).map(&:description).compact
|
|
66
48
|
|
|
67
|
-
# The argument name that addresses an instance of `aggregate_name`
|
|
68
|
-
# for this command — the one fact `PolicyInterpreter`'s own
|
|
69
|
-
# `for_each` fan-out needs and, until this reading existed, had
|
|
70
|
-
# to guess at (see git blame: `Behaviour::Policy
|
|
71
|
-
# #fan_out_reference_key`, which hardcoded `<aggregate>_id`
|
|
72
|
-
# unconditionally and refused every dispatch to a self-
|
|
73
|
-
# addressing command as a result — `Account.Freeze`, addressed
|
|
74
|
-
# by `number`/`account`, not `account_id`).
|
|
75
|
-
#
|
|
76
|
-
# Two shapes, the same two `CommandBuilder#reference_to` already
|
|
77
|
-
# tells apart at declare time (command_builder.rb's own comment
|
|
78
|
-
# on `cross_reference` — "`as:` means a named attribute... a
|
|
79
|
-
# command can point at another instance of its own kind"):
|
|
80
|
-
#
|
|
81
|
-
# self-addressing — `references == aggregate_name` (this verb
|
|
82
|
-
# is declared on the very aggregate it acts on, `reference_to
|
|
83
|
-
# Account` on a command Account itself owns). No attribute was
|
|
84
|
-
# minted for it at all; the same bare key
|
|
85
|
-
# `CommandInterpreter::ArgumentGate#reference_key` already
|
|
86
|
-
# accepts as "addressing, not describing" is reused here
|
|
87
|
-
# rather than re-derived — one door, not two.
|
|
88
|
-
#
|
|
89
|
-
# cross-referencing — a real, declared reference-typed
|
|
90
|
-
# attribute whose own target is `aggregate_name` (`customer_id`
|
|
91
|
-
# on `Account.Open`, or whatever `as:` named it). Its name is
|
|
92
|
-
# the key, exactly as declared — never re-derived from the
|
|
93
|
-
# target's name, because an `as:` reference's name and its
|
|
94
|
-
# target's snake case can legitimately differ (`Transfer`'s own
|
|
95
|
-
# `source`/`destination`, both `Reference<Account>`).
|
|
49
|
+
# The argument name that addresses an instance of `aggregate_name` for this command.
|
|
96
50
|
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
# expected to treat `nil` as "this command cannot be addressed by
|
|
101
|
-
# a row of this aggregate," not to fall back on a guess.
|
|
51
|
+
# Self-addressing commands (`references == aggregate_name`) use the bare reference
|
|
52
|
+
# key. Cross-referencing ones use the declared reference attribute's own name, never
|
|
53
|
+
# re-derived from the target, since `as:` names can differ.
|
|
102
54
|
#
|
|
103
55
|
# @param aggregate_name [String, Symbol] the aggregate a fan-out dispatch is
|
|
104
56
|
# addressing an instance of
|
|
@@ -112,14 +64,10 @@ module Hecks
|
|
|
112
64
|
end
|
|
113
65
|
end
|
|
114
66
|
|
|
115
|
-
# **A mutation's own readings**. Included
|
|
116
|
-
# a Struct, so these are instance methods.
|
|
67
|
+
# **A mutation's own readings**. Included, not extended: Mutation is a Struct.
|
|
117
68
|
module Mutation
|
|
118
|
-
# An append binds several fields at once, each from
|
|
119
|
-
#
|
|
120
|
-
# the same self-describing form a where-clause's own value already
|
|
121
|
-
# uses, rather than a bare Symbol paired with an inspected literal —
|
|
122
|
-
# see Hecks::Literal.
|
|
69
|
+
# An append binds several fields at once, each from a command argument (a Symbol)
|
|
70
|
+
# or a literal, spelled through `Literal.render`.
|
|
123
71
|
#
|
|
124
72
|
# @return [Hash{Symbol => String}] the append's field bindings, each
|
|
125
73
|
# value rendered through `Literal.render`
|
|
@@ -13,16 +13,8 @@ module Hecks
|
|
|
13
13
|
# @return [nil] always `nil`
|
|
14
14
|
def references = nil
|
|
15
15
|
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
# both name where its receiver comes from, never a birth). Answered
|
|
19
|
-
# explicitly, not derived from `references` the way `Command
|
|
20
|
-
# #creates?` is (`references.nil?` would read every operation as
|
|
21
|
-
# creating, since `references` above is unconditionally nil) —
|
|
22
|
-
# needed so `ReactionInvocation#source_receiver_for` can call
|
|
23
|
-
# `target.command.creates?` on a port operation the same way it
|
|
24
|
-
# already does on an ordinary command, and correctly lift a
|
|
25
|
-
# same-aggregate policy's own Event.id as the operation's receiver.
|
|
16
|
+
# A port operation always acts on an existing aggregate. Answered explicitly
|
|
17
|
+
# because `references.nil?` would read every operation as creating.
|
|
26
18
|
#
|
|
27
19
|
# @return [Boolean] always `false`
|
|
28
20
|
def creates? = false
|
|
@@ -37,16 +29,8 @@ module Hecks
|
|
|
37
29
|
@attributes.find { |attribute| attribute.reference? && attribute.type.target_name == owner_name.to_s }
|
|
38
30
|
end
|
|
39
31
|
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# unconditionally nil (above), so it never means "this verb is
|
|
43
|
-
# declared on the very aggregate it acts on" the way a command's
|
|
44
|
-
# does; a port operation's only path back to its owner is a real,
|
|
45
|
-
# declared reference-typed attribute, which is exactly what
|
|
46
|
-
# `identity_attribute` already finds. Needed for the identical
|
|
47
|
-
# reason `Command#addressing_key_for` is: `ReactionInvocation
|
|
48
|
-
# #aggregate_aliases` calls it on whatever `target.command` holds,
|
|
49
|
-
# a `PortOperation` now included since a policy can trigger one.
|
|
32
|
+
# Like `Command#addressing_key_for` without the self-addressing branch: the
|
|
33
|
+
# reference attribute is the only path back to the owner.
|
|
50
34
|
#
|
|
51
35
|
# @param aggregate_name [String, Symbol] the name of the aggregate a row of which
|
|
52
36
|
# would address this operation
|
|
@@ -6,12 +6,8 @@ module Hecks
|
|
|
6
6
|
# **What an entity does**. Extended, not included — an entity is a
|
|
7
7
|
# class, so this is singleton behaviour.
|
|
8
8
|
#
|
|
9
|
-
# `settle` is
|
|
10
|
-
#
|
|
11
|
-
# by subclassing rather than by `new`. The traits are the same
|
|
12
|
-
# ones, which is the whole point of them being traits: an entity's
|
|
13
|
-
# identity is derived exactly as an aggregate's is, and was written
|
|
14
|
-
# out twice before anyone could see that.
|
|
9
|
+
# `settle` is reached from `absorb` rather than a constructor, because a declared
|
|
10
|
+
# entity is built by subclassing.
|
|
15
11
|
module Entity
|
|
16
12
|
include Identified
|
|
17
13
|
include Indexed
|
|
@@ -36,32 +32,16 @@ module Hecks
|
|
|
36
32
|
@queries_by_name = index_by_hecks_name(@queries)
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# real reader rather than a hardcoded empty list for two
|
|
42
|
-
# reasons at once: `Value::Coercion#for_attribute` calls
|
|
43
|
-
# `.entities` on whatever owner it is handed — an aggregate's or
|
|
44
|
-
# an entity's own — the moment it meets any `list_of(...)`
|
|
45
|
-
# attribute (entity-typed or not — `hydrate_entity_list`'s own
|
|
46
|
-
# fallback, `return value unless entity`, only runs once
|
|
47
|
-
# `.entities` has already answered) ; and `EntityInterpreter`
|
|
48
|
-
# now walks a dotted chain of entities one level at a time
|
|
49
|
-
# (`walk_entity_chain`) exactly the way an aggregate's own
|
|
50
|
-
# `.entities` is walked for its direct children. Entity's own
|
|
51
|
-
# header comment already promises it stays "structurally
|
|
52
|
-
# interchangeable with an aggregate" for exactly this reason.
|
|
35
|
+
# Nested entities, structurally interchangeable with an aggregate's `entities`:
|
|
36
|
+
# `Value::Coercion#for_attribute` and `EntityInterpreter` both read it (ADR 0026).
|
|
53
37
|
#
|
|
54
38
|
# @return [Array<Class>] this entity's own nested entities (each a `Bluebook::Entity`
|
|
55
39
|
# subclass), or `[]` if it declares none
|
|
56
40
|
def entities = @entities || []
|
|
57
41
|
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
# `settle` because `declare` stamps after absorbing, once the
|
|
62
|
-
# subclass that will own them exists. `@entities` too now
|
|
63
|
-
# (S17, ADR 0026) — a nested entity states its own owner chain
|
|
64
|
-
# exactly the way a nested command does.
|
|
42
|
+
# Stamps this entity as owner of its commands, queries and nested entities, so
|
|
43
|
+
# verbs read `Banking::Account.Ledger.Deposit`. Separate from `settle` because
|
|
44
|
+
# `declare` stamps after the owning subclass exists.
|
|
65
45
|
#
|
|
66
46
|
# @return [void]
|
|
67
47
|
def stamp_children = stamp(@commands, @queries, @entities)
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Bluebook
|
|
3
3
|
module Behaviour
|
|
4
|
-
#
|
|
4
|
+
# Lookups over a hecksagon's declared binds.
|
|
5
5
|
module Hecksagon
|
|
6
|
-
#
|
|
7
|
-
# falls back to a domain-level default (`b.aggregate.nil?` — see
|
|
8
|
-
# `HecksagonBuilder#method_missing`). Checked directly rather than
|
|
9
|
-
# via `aggregate_name`/`Naming.demodulise`, which would need its own
|
|
10
|
-
# nil-handling for the default row.
|
|
6
|
+
# Finds the bind for an aggregate and verb, falling back to the domain-level default.
|
|
11
7
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
8
|
+
# The default row is matched with `b.aggregate.nil?` rather than via
|
|
9
|
+
# `aggregate_name`, which would need its own nil handling.
|
|
10
|
+
#
|
|
11
|
+
# @param aggregate_name [String, Symbol]
|
|
12
|
+
# @param verb [String, Symbol]
|
|
13
|
+
# @return [Bluebook::Bind, nil]
|
|
17
14
|
def bind_for(aggregate_name, verb)
|
|
18
15
|
@binds.find { |b| b.aggregate_name == aggregate_name.to_s && b.verb.to_s == verb.to_s } ||
|
|
19
16
|
@binds.find { |b| b.aggregate.nil? && b.verb.to_s == verb.to_s }
|
|
20
17
|
end
|
|
21
18
|
|
|
22
|
-
# Every bind for `verb
|
|
23
|
-
# the domain-level default.
|
|
19
|
+
# Every bind for `verb`; aggregate-specific ones win as a group over the default.
|
|
24
20
|
#
|
|
25
|
-
# @param aggregate_name [String, Symbol]
|
|
26
|
-
# @param verb [String, Symbol]
|
|
27
|
-
# @return [Array<Bluebook::Bind>]
|
|
28
|
-
# `verb` when any are declared, otherwise every domain-level default
|
|
29
|
-
# bind for `verb`
|
|
21
|
+
# @param aggregate_name [String, Symbol]
|
|
22
|
+
# @param verb [String, Symbol]
|
|
23
|
+
# @return [Array<Bluebook::Bind>]
|
|
30
24
|
def binds_for(aggregate_name, verb)
|
|
31
25
|
specific = @binds.select { |b| b.aggregate_name == aggregate_name.to_s && b.verb.to_s == verb.to_s }
|
|
32
26
|
return specific if specific.any?
|
|
@@ -35,34 +29,22 @@ module Hecks
|
|
|
35
29
|
end
|
|
36
30
|
end
|
|
37
31
|
|
|
38
|
-
#
|
|
39
|
-
# entry falling back to the verb's own.
|
|
32
|
+
# Settings lookup for a world, with adapter-specific entries falling back to the verb's own.
|
|
40
33
|
module World
|
|
41
|
-
#
|
|
34
|
+
# The settings declared for a port verb.
|
|
42
35
|
#
|
|
43
|
-
# @param verb [String, Symbol]
|
|
44
|
-
# @return [Hash{Symbol => Object}]
|
|
45
|
-
# `{}` when none are declared
|
|
36
|
+
# @param verb [String, Symbol] such as `"persistence"`
|
|
37
|
+
# @return [Hash{Symbol => Object}] empty when none are declared
|
|
46
38
|
def for_verb(verb) = @settings.fetch(verb.to_s, {})
|
|
47
39
|
|
|
48
|
-
# The generic
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# unrelated one. Real, corpus-caught bug: a hecksagon binding two
|
|
52
|
-
# aggregates to two different adapters under the same verb (one to
|
|
53
|
-
# Heki, one to Memory) sent Memory's lookup down Heki's generic
|
|
54
|
-
# entry, then failed `check_settings` with "Memory does not
|
|
55
|
-
# declare :dir" — the generic entry's own `settings[:adapter]`
|
|
56
|
-
# names Heki, not Memory, so the fallback was never actually for
|
|
57
|
-
# this bind. `{}` is exactly right when nothing was configured for
|
|
58
|
-
# this adapter — Memory, which takes no values at all.
|
|
40
|
+
# The generic verb entry only answers for the adapter it names. Falling back to it
|
|
41
|
+
# unconditionally would apply one adapter's settings (Heki's `dir`) to another
|
|
42
|
+
# (Memory), which then fails `check_settings`.
|
|
59
43
|
#
|
|
60
|
-
# @param verb [String, Symbol]
|
|
61
|
-
# @param adapter [String, Symbol]
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
# declared, the generic verb settings when they name this same
|
|
65
|
-
# adapter, or `{}` otherwise
|
|
44
|
+
# @param verb [String, Symbol]
|
|
45
|
+
# @param adapter [String, Symbol] such as `"Heki"`
|
|
46
|
+
# @return [Hash{Symbol => Object}] the adapter-qualified settings, else the generic
|
|
47
|
+
# ones when they name this adapter, else `{}`
|
|
66
48
|
def for_binding(verb, adapter)
|
|
67
49
|
qualified = @settings["#{verb}:#{adapter.to_s.downcase}"]
|
|
68
50
|
return qualified if qualified
|
|
@@ -1,50 +1,37 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Bluebook
|
|
3
3
|
module Behaviour
|
|
4
|
-
#
|
|
5
|
-
# state and a transition list. Everything here reads that — which
|
|
6
|
-
# states exist, which transition a command takes, and how one
|
|
7
|
-
# declared transition expands into the several rows the emission
|
|
8
|
-
# carries when `from` names more than one source state.
|
|
4
|
+
# Readings over a lifecycle's field, starting state and transition list.
|
|
9
5
|
module Lifecycle
|
|
10
|
-
#
|
|
6
|
+
# Every state this lifecycle can be in.
|
|
11
7
|
#
|
|
12
|
-
# @return [Array<String>]
|
|
13
|
-
# default plus each declared transition's own target, deduplicated
|
|
8
|
+
# @return [Array<String>] the default plus each transition's target, deduplicated
|
|
14
9
|
def states
|
|
15
10
|
([default] + transitions.map { |_command, t| t.target }).uniq
|
|
16
11
|
end
|
|
17
12
|
|
|
18
|
-
#
|
|
13
|
+
# Every transition a command declares.
|
|
19
14
|
#
|
|
20
|
-
# @param command [String, Symbol]
|
|
21
|
-
#
|
|
22
|
-
# @return [Array<Bluebook::StateTransition>] every transition declared
|
|
23
|
-
# for `command`
|
|
15
|
+
# @param command [String, Symbol]
|
|
16
|
+
# @return [Array<Bluebook::StateTransition>]
|
|
24
17
|
def transitions_for(command)
|
|
25
18
|
transitions.select { |name, _| name == command.to_s }.map { |_, t| t }
|
|
26
19
|
end
|
|
27
20
|
|
|
28
|
-
#
|
|
21
|
+
# The state a command moves the record to.
|
|
29
22
|
#
|
|
30
|
-
# @param command [String, Symbol]
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
# @return [String, nil] the state `command` moves the record to, or
|
|
36
|
-
# `nil` when `command` declares no transition at all
|
|
37
|
-
# @raise [Runtime::WiringError] if `command` declares transitions but
|
|
38
|
-
# none of them admits `current_state`
|
|
23
|
+
# @param command [String, Symbol]
|
|
24
|
+
# @param current_state [String, Symbol, nil] picks the transition that admits it;
|
|
25
|
+
# `nil` takes the first declared transition
|
|
26
|
+
# @return [String, nil] `nil` when `command` declares no transition
|
|
27
|
+
# @raise [Runtime::WiringError] if transitions are declared but none admits `current_state`
|
|
39
28
|
def target_for(command, current_state = nil)
|
|
40
29
|
match_transition(command, current_state)&.target
|
|
41
30
|
end
|
|
42
31
|
|
|
43
32
|
private
|
|
44
33
|
|
|
45
|
-
#
|
|
46
|
-
# than one source state — the emission carries them flat, so the
|
|
47
|
-
# fan-out happens here rather than in whatever reads it.
|
|
34
|
+
# A transition whose `from` names several states becomes one row per source state.
|
|
48
35
|
def expand(command, transition)
|
|
49
36
|
sources = transition.from.nil? ? [nil] : Array(transition.from)
|
|
50
37
|
|
|
@@ -58,20 +45,8 @@ module Hecks
|
|
|
58
45
|
return nil if matches.empty?
|
|
59
46
|
return matches.first unless current_state
|
|
60
47
|
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
# them actually admitted `current_state`, picking a `target`
|
|
64
|
-
# that command dispatch would in fact refuse (that
|
|
65
|
-
# refusal is `CommandRules::Admissibility#admissible_transition`'s
|
|
66
|
-
# own job, which raises `LifecycleRefused` for exactly this
|
|
67
|
-
# case rather than guessing — this module has no state subject
|
|
68
|
-
# to build that refusal message from, only the two bare
|
|
69
|
-
# values callers passed in). Zero production callers reach
|
|
70
|
-
# this branch today (both real dispatch paths that check a
|
|
71
|
-
# transition go through `admissible_transition`, not
|
|
72
|
-
# `target_for`/`match_transition`), so this raise is a
|
|
73
|
-
# backstop, not a live behaviour change — same shape as
|
|
74
|
-
# `CommandRules::Arithmetic#sign_of`'s own fix.
|
|
48
|
+
# No `|| matches.first`: that would return a target command dispatch refuses.
|
|
49
|
+
# `CommandRules::Admissibility#admissible_transition` owns the real refusal.
|
|
75
50
|
matches.find { |t| applies_from?(t, current_state) } ||
|
|
76
51
|
raise(Runtime::WiringError,
|
|
77
52
|
"no transition for #{command.inspect} admits state #{current_state.inspect} " \
|