hecks 2.8.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 +4 -6
- 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 +17 -98
- 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 +5 -48
- 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 +31 -141
- 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 +14 -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 +25 -31
- 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 +16 -69
- 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 -194
- 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 -111
- 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 +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
- 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 +6 -21
- data/lib/hecks/bluebook/model_check.rb +100 -597
- 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 +4 -23
- data/lib/hecks/cli/document.rb +3 -21
- data/lib/hecks/cli/ir.rb +3 -5
- data/lib/hecks/cli/mcp.rb +2 -3
- data/lib/hecks/cli/mcp_door.rb +19 -114
- data/lib/hecks/cli/model_check.rb +18 -85
- data/lib/hecks/cli/project_cli.rb +7 -40
- data/lib/hecks/cli/project_diagrams.rb +0 -7
- data/lib/hecks/cli/run.rb +12 -58
- data/lib/hecks/cli/smoke_test.rb +2 -16
- data/lib/hecks/cli/stores.rb +1 -2
- data/lib/hecks/cli.rb +18 -24
- 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 +82 -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 +9 -90
- 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 +61 -64
- 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 +6 -25
- 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 +18 -124
- 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 +150 -678
- 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 +2 -15
- 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 +42 -134
- 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 +3 -6
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/gem_publisher.rb +2 -3
- data/lib/hecks/release/runner/npm_publisher.rb +6 -20
- data/lib/hecks/release/runner/preflight.rb +4 -19
- data/lib/hecks/release/runner/tagger.rb +2 -9
- data/lib/hecks/release/runner.rb +3 -32
- 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 +124 -306
- 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 +64 -219
- 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 +117 -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 +99 -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 +141 -568
- 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.rb +26 -81
- 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 +3 -2
|
@@ -4,8 +4,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
4
4
|
|
|
5
5
|
reference_to Bluebook
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
# the same reason.
|
|
7
|
+
# The chapter it belongs to, and its name, as for a policy.
|
|
9
8
|
identified_by :bluebook, :name
|
|
10
9
|
|
|
11
10
|
attribute :name, ProcessManagerName
|
|
@@ -13,10 +12,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
13
12
|
attribute :starts_on, ProcessManagerText
|
|
14
13
|
attribute :ends_on, ProcessManagerText
|
|
15
14
|
attribute :states, list_of(SagaState)
|
|
16
|
-
#
|
|
17
|
-
# an entity rather than its own root aggregate. `list_of(Handler)`
|
|
18
|
-
# forward-references it the same way banking's own `attribute :ledger,
|
|
19
|
-
# list_of(LedgerEntry)` names LedgerEntry before it is declared.
|
|
15
|
+
# Handler is a nested entity (below); list_of forward-references it.
|
|
20
16
|
attribute :handlers, list_of(Handler)
|
|
21
17
|
|
|
22
18
|
value_object "ProcessManagerName" do
|
|
@@ -32,15 +28,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
32
28
|
attribute :name, String
|
|
33
29
|
end
|
|
34
30
|
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# entity cannot declare its own `value_object` (EntityBuilder has no
|
|
38
|
-
# such method — a piece borrows its owning aggregate's, the same way
|
|
39
|
-
# LedgerEntry borrows Account's Money), so these live here now, at
|
|
40
|
-
# the ROOT, where BOTH `entity "Handler"` and its own nested `entity
|
|
41
|
-
# "Dispatch"` can still reach them — a piece mints no value objects
|
|
42
|
-
# of its own AT ANY DEPTH, so there is exactly one pool however deep
|
|
43
|
-
# the nesting goes (`EntityBuilder#entity`'s own comment).
|
|
31
|
+
# Value objects live at the root: an entity mints none of its own at any depth, so Handler and
|
|
32
|
+
# its nested Dispatch share this one pool.
|
|
44
33
|
value_object "HandlerText" do
|
|
45
34
|
attribute :value, String
|
|
46
35
|
end
|
|
@@ -54,36 +43,15 @@ Hecks.bluebook "Bluebook" do
|
|
|
54
43
|
attribute :value, String
|
|
55
44
|
end
|
|
56
45
|
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
# own comment on the identical choice): that one orders process
|
|
61
|
-
# managers among a CHAPTER's siblings ; this one orders dispatches
|
|
62
|
-
# within ONE handler. Same shape, different fact.
|
|
63
|
-
#
|
|
64
|
-
# Part of `identified_by`, below, alongside `command_name` — a real
|
|
65
|
-
# handler fans the SAME command out more than once with different
|
|
66
|
-
# `with:` bindings each leg (item #151's own real example: one
|
|
67
|
-
# BodyPulse handler dispatching Signal.FireSignal once per organ),
|
|
68
|
-
# and `command_name` alone collided the instant it did: the Judge's
|
|
69
|
-
# own `entity_duplicate` check raised the moment a second dispatch of
|
|
70
|
-
# the same command was declared, an uncaught crash for a legitimate,
|
|
71
|
-
# common pattern. `position` names WHICH send this is and is safe to
|
|
72
|
-
# fold into identity exactly where it would not be for Handler's own
|
|
73
|
-
# `from_state` (a real business value) — a Dispatch is declared once,
|
|
74
|
-
# at load time, and never re-addressed by identity afterward.
|
|
46
|
+
# Orders one handler's dispatches; Position orders process managers within a chapter.
|
|
47
|
+
# Part of Dispatch identity: a handler may send the same command several times with different
|
|
48
|
+
# `with:` bindings, so command_name alone collides.
|
|
75
49
|
value_object "DispatchPosition" do
|
|
76
50
|
attribute :value, Integer
|
|
77
51
|
end
|
|
78
52
|
|
|
79
|
-
# The
|
|
80
|
-
#
|
|
81
|
-
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
82
|
-
# SOURCE — the IR is a contract read straight from this file,
|
|
83
|
-
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
84
|
-
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
85
|
-
# does not say how it is ordered is answered in identity order, which is
|
|
86
|
-
# right for every other ask and fatal for the one that is the SOURCE.
|
|
53
|
+
# Declaration order among siblings. The IR is read index for index, so the language
|
|
54
|
+
# holds it rather than inheriting whatever order a store iterates.
|
|
87
55
|
value_object "Position" do
|
|
88
56
|
attribute :value, Integer
|
|
89
57
|
end
|
|
@@ -103,12 +71,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
103
71
|
attribute :name, ProcessManagerName
|
|
104
72
|
attribute :correlates_by, ProcessManagerText
|
|
105
73
|
attribute :starts_on, ProcessManagerText
|
|
106
|
-
# A
|
|
107
|
-
# this optional — ProcessManagerBuilder defaults `@ends_on` to nil,
|
|
108
|
-
# validates only correlates_by/starts_on/states/handlers,
|
|
109
|
-
# and fills it only if the line is written. The
|
|
110
|
-
# language was the one saying it was required, and nothing in the corpus
|
|
111
|
-
# had to disagree because every procedure in it happens to end.
|
|
74
|
+
# A procedure need not declare an ending; ProcessManagerBuilder defaults @ends_on to nil.
|
|
112
75
|
attribute :ends_on, ProcessManagerText, optional: true
|
|
113
76
|
|
|
114
77
|
attribute :position, Position, optional: true
|
|
@@ -132,27 +95,15 @@ Hecks.bluebook "Bluebook" do
|
|
|
132
95
|
emits SagaStateAttached
|
|
133
96
|
end
|
|
134
97
|
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
# created through its own dotted verb — banking's own LedgerEntry is
|
|
138
|
-
# created by `Account.LogEntry`, an ordinary append on the OWNER,
|
|
139
|
-
# never by a `LedgerEntry.Declare` of its own
|
|
140
|
-
# (`EntityInterpreter#element_of` only LOCATES an element already on
|
|
141
|
-
# the list — it has no path that creates one). So Handler's creation
|
|
142
|
-
# moved here, onto ProcessManager, mirroring `State` beside it: a
|
|
143
|
-
# bare, aggregate-level append.
|
|
98
|
+
# Handler creation lives here, not on Handler: an entity is created by an append on its owner,
|
|
99
|
+
# never by a dotted verb of its own.
|
|
144
100
|
command "Handler" do
|
|
145
101
|
role "Language"
|
|
146
102
|
goal "Open a handler inside a process manager"
|
|
147
103
|
|
|
148
104
|
attribute :event_type, HandlerText
|
|
149
|
-
# A
|
|
150
|
-
#
|
|
151
|
-
# spelling the runtime reads, and it refuses anything else —
|
|
152
|
-
# `single_transition` raises unless the hash holds exactly one from => to
|
|
153
|
-
# pair, so a leg without one
|
|
154
|
-
# is never built at all. `optional: true` here was
|
|
155
|
-
# the language admitting a leg the runtime cannot parse.
|
|
105
|
+
# A leg always names its from state: the runtime refuses a transition without exactly one
|
|
106
|
+
# from => to pair.
|
|
156
107
|
attribute :from_state, HandlerText
|
|
157
108
|
attribute :to_state, HandlerText
|
|
158
109
|
|
|
@@ -161,59 +112,27 @@ Hecks.bluebook "Bluebook" do
|
|
|
161
112
|
emits LegDeclared
|
|
162
113
|
end
|
|
163
114
|
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
# manager, held nothing — ProcessManagerHandler has no such reader,
|
|
167
|
-
# so every Handler record's saga was empty — and repeated the parent
|
|
168
|
-
# that its own containment already carries. A field that names the
|
|
169
|
-
# wrong thing, holds nothing, and duplicates the reference beside it.
|
|
170
|
-
#
|
|
171
|
-
# `event_type` is an event name, or one of the Trigger vocabulary's
|
|
172
|
-
# members when the leg answers something no aggregate announces — but
|
|
173
|
-
# NOT, alone, Handler's own identity any more (items #151/#152's own
|
|
174
|
-
# finding): a state machine legitimately answers the SAME event
|
|
175
|
-
# differently depending on which state it is currently in — one event
|
|
176
|
-
# name, several distinct legs (a BodyPulse handler that moves
|
|
177
|
-
# `attentive -> attentive` and, separately, `sleeping_light ->
|
|
178
|
-
# sleeping_light`) — and `event_type` alone collided the instant a
|
|
179
|
-
# real corpus declared that shape: the Judge's own `entity_duplicate`
|
|
180
|
-
# check raised `AlreadyExists` the moment the second leg was declared,
|
|
181
|
-
# an uncaught crash, not a refusal, for a common, legitimate pattern.
|
|
182
|
-
# `from_state` joins it below for exactly this reason — a real
|
|
183
|
-
# business value, not a stand-in for missing meaning, the same
|
|
184
|
-
# distinction `DispatchPosition`'s own comment (above) draws for its
|
|
185
|
-
# sibling `Dispatch`. The process manager this leg belongs to stays
|
|
186
|
-
# structural (which list this element sits in), never a stored field.
|
|
115
|
+
# One handler, nested under its process manager. event_type alone is not identity: one
|
|
116
|
+
# event can drive several legs from different states, so from_state joins it.
|
|
187
117
|
entity "Handler" do
|
|
188
118
|
description "One handler inside a process manager — the event it answers, the state move it makes, and the commands it sends. Nested under the process manager because a handler holds nested dispatches, which hold nested bindings."
|
|
189
119
|
|
|
190
120
|
attribute :event_type, HandlerText
|
|
191
121
|
attribute :from_state, HandlerText
|
|
192
122
|
attribute :to_state, HandlerText
|
|
193
|
-
# S17, ADR 0026 — Dispatch nested here too (see `entity "Dispatch"`,
|
|
194
|
-
# below), one level further in than Handler itself.
|
|
195
123
|
attribute :dispatches, list_of(Dispatch)
|
|
196
124
|
|
|
197
|
-
# BOTH FIELDS TOGETHER — see the class-level comment above.
|
|
198
125
|
identified_by :event_type, :from_state
|
|
199
126
|
|
|
200
|
-
#
|
|
201
|
-
#
|
|
202
|
-
# through its own dotted verb. Reached as a DOTTED verb itself
|
|
203
|
-
# (`ProcessManager.Handler.Dispatch`) since Handler, the owner
|
|
204
|
-
# doing the creating here, is an entity too, not a real aggregate
|
|
205
|
-
# with a bare verb of its own to dispatch into.
|
|
127
|
+
# Dispatch creation lives on the owner, reached as the dotted verb
|
|
128
|
+
# ProcessManager.Handler.Dispatch because Handler is an entity.
|
|
206
129
|
command "Dispatch" do
|
|
207
130
|
role "Language"
|
|
208
131
|
goal "Open a dispatch inside a handler"
|
|
209
132
|
|
|
210
133
|
attribute :command_name, DispatchText
|
|
211
|
-
#
|
|
212
|
-
#
|
|
213
|
-
# already relies on (`Judge#appends`), which fills this from
|
|
214
|
-
# where the walk found the dispatch, not from a field the row
|
|
215
|
-
# happens to hold. No real `.bluebook` author ever calls this
|
|
216
|
-
# verb directly; only the Judge's own replay does.
|
|
134
|
+
# The walk index, filled by the Judge's replay from where it found the dispatch; never
|
|
135
|
+
# author-supplied.
|
|
217
136
|
attribute :position, DispatchPosition
|
|
218
137
|
|
|
219
138
|
sets :dispatches, append: { command_name: :command_name, position: :position }
|
|
@@ -221,19 +140,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
221
140
|
emits SendDeclared
|
|
222
141
|
end
|
|
223
142
|
|
|
224
|
-
#
|
|
225
|
-
#
|
|
226
|
-
# its Handler" (the ADR's own words). The bindings are an open
|
|
227
|
-
# map, which no value object can hold — that was always a reason
|
|
228
|
-
# it could not be one, never a reason it could not be an entity.
|
|
229
|
-
# `command_name` ALONE used to be Dispatch's own identity, the same
|
|
230
|
-
# shape Handler's own `event_type` took one level up — and collided
|
|
231
|
-
# the same way, for the same real reason (item #151): one handler
|
|
232
|
-
# fanning the SAME command out several times with different `with:`
|
|
233
|
-
# bindings each time (one BodyPulse handler dispatching
|
|
234
|
-
# Signal.FireSignal once per organ). `position` joins it below —
|
|
235
|
-
# see `DispatchPosition`'s own comment for why that field, unlike
|
|
236
|
-
# Handler's `from_state`, is safe to fold into identity.
|
|
143
|
+
# One command a handler dispatches. Identity is command_name plus position, since a
|
|
144
|
+
# handler may send the same command several times with different bindings.
|
|
237
145
|
entity "Dispatch" do
|
|
238
146
|
description "One command a handler dispatches, with the arguments it binds. Nested under the handler because the bindings are an open map, which no value object can hold."
|
|
239
147
|
|
|
@@ -256,23 +164,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
256
164
|
emits BindingAttached
|
|
257
165
|
end
|
|
258
166
|
|
|
259
|
-
#
|
|
260
|
-
#
|
|
261
|
-
# `with_spec` above one-for-one, rather than a nested (or
|
|
262
|
-
# self-referential) second `Dispatch`: an entity's own attribute
|
|
263
|
-
# type has to resolve against a value object, and neither a
|
|
264
|
-
# self-reference to `Dispatch` (written from inside its own
|
|
265
|
-
# block, before it exists to reference) nor a plain nested
|
|
266
|
-
# entity reference passes that check the way `Handler.
|
|
267
|
-
# dispatches: list_of(Dispatch)` does — that one resolves a
|
|
268
|
-
# SIBLING already fully built by the time deferred construction
|
|
269
|
-
# (ADR 0028) finishes; a dispatch compensating for itself has no
|
|
270
|
-
# such sibling. `compensates_command_name` absent means no
|
|
271
|
-
# compensation; present, together with whatever
|
|
272
|
-
# `compensates_with_spec` holds, is everything
|
|
273
|
-
# `Reconstruction#dispatch` needs to assemble the SAME
|
|
274
|
-
# `DispatchSpec` shape `compensates` (the real, author-facing
|
|
275
|
-
# word) fills.
|
|
167
|
+
# The dispatch this one compensates for, as flat fields: an entity attribute must
|
|
168
|
+
# resolve against a value object, so a self-referential Dispatch is not possible.
|
|
276
169
|
attribute :compensates_command_name, DispatchText, optional: true
|
|
277
170
|
attribute :compensates_with_spec, list_of(Binding)
|
|
278
171
|
|
|
@@ -301,9 +194,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
301
194
|
end
|
|
302
195
|
end
|
|
303
196
|
|
|
304
|
-
#
|
|
305
|
-
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
306
|
-
# Contexts represented here: ProcessManager, Handler.
|
|
197
|
+
# Keyword and argument rows for process managers and handlers.
|
|
307
198
|
value_object "KeywordSeed" do
|
|
308
199
|
attribute :word, String
|
|
309
200
|
attribute :context, String, admits: "Syntax::Context"
|
|
@@ -317,27 +208,13 @@ Hecks.bluebook "Bluebook" do
|
|
|
317
208
|
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
318
209
|
|
|
319
210
|
member word: "correlates_by", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "correlates_by"
|
|
320
|
-
#
|
|
321
|
-
#
|
|
322
|
-
# Transfer::TransferSettled`, same `kind: "constant"` + `kind:
|
|
323
|
-
# "text"` ArgumentSeed pair `emits`/policy's own `on` already
|
|
324
|
-
# carry (this row's own comment there). Now `calls:`-routed
|
|
325
|
-
# (`starts_on_impl`/`ends_on_impl`, hand-written — GenericDispatch's
|
|
326
|
-
# own `COERCE_BY_KIND` has no "constant" entry, so a bare
|
|
327
|
-
# constant needs the same `Naming.event_ref` resolution `on_impl`/
|
|
328
|
-
# `transition_impl` already do, not the plain `.to_s` a single
|
|
329
|
-
# `kind: "text"` row used to get for free).
|
|
211
|
+
# starts_on and ends_on accept a bare constant or text; they route through hand-written impls
|
|
212
|
+
# because COERCE_BY_KIND has no "constant" entry and Naming.event_ref must resolve it.
|
|
330
213
|
member word: "starts_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "starts_on_impl"
|
|
331
214
|
member word: "ends_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "ends_on_impl"
|
|
332
215
|
member word: "transition", context: "ProcessManager", body: "keywords", inner: "Handler", opens: "Handler", fills: "", calls: "transition_impl"
|
|
333
216
|
member word: "transition", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "transition_impl"
|
|
334
|
-
#
|
|
335
|
-
# `body: "none"` was already the only row (`opens: "Dispatch"`
|
|
336
|
-
# already anticipated a block, unused until now); `body:
|
|
337
|
-
# "keywords"` is the new one, opening `compensates` on the
|
|
338
|
-
# dispatch it sits inside (per-dispatch saga compensation — see
|
|
339
|
-
# `ProcessManagerBuilder::HandlerBuilder#dispatch_impl`'s own
|
|
340
|
-
# comment).
|
|
217
|
+
# Two rows per dispatch: one with a block (opening `compensates`), one without.
|
|
341
218
|
member word: "dispatch", context: "Handler", body: "keywords", inner: "Dispatch", opens: "Dispatch", fills: "", calls: "dispatch_impl"
|
|
342
219
|
member word: "dispatch", context: "Handler", body: "none", inner: "", opens: "Dispatch", fills: "", calls: "dispatch_impl"
|
|
343
220
|
member word: "compensates", context: "Dispatch", body: "none", inner: "", opens: "", fills: "", calls: "compensates_impl"
|
|
@@ -4,7 +4,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
4
4
|
|
|
5
5
|
reference_to Bluebook
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# The chapter it belongs to, and its name.
|
|
8
8
|
identified_by :bluebook, :name
|
|
9
9
|
|
|
10
10
|
attribute :name, ReadModelName
|
|
@@ -13,26 +13,23 @@ Hecks.bluebook "Bluebook" do
|
|
|
13
13
|
attribute :reference_name, ReadModelText
|
|
14
14
|
attribute :reference_target, ReadModelText
|
|
15
15
|
attribute :aggregate_heads, list_of(Head)
|
|
16
|
-
# The same open map a query carries
|
|
17
|
-
# inherits every specification option an ask has, so it holds them the same way.
|
|
16
|
+
# The same open map a query carries (see Query's AskOption).
|
|
18
17
|
attribute :options, list_of(ProjectionOption)
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# arbitrary NUMBER of fields, the same reason `aggregate_heads`/
|
|
22
|
-
# `options` are lists rather than fixed attributes.
|
|
18
|
+
# Fields whose values nest the eligible head's rows, in declared order; a list because the
|
|
19
|
+
# number of fields is open.
|
|
23
20
|
attribute :group_by, list_of(GroupByField)
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# rather than of `options` — same permissive `ReadModelText` shape,
|
|
27
|
-
# and the same UNmarked-optional spelling `reference_name`/
|
|
28
|
-
# `reference_target` already use just above (permissiveness lives
|
|
29
|
-
# in `ReadModelText`'s own lack of an invariant, not in an
|
|
30
|
-
# `optional:` flag this chapter's aggregate-level attributes never
|
|
31
|
-
# carry) — "true"/"" for `count`, a field name or "" for
|
|
32
|
-
# `median_field`, both legitimately absent on a read model that
|
|
33
|
-
# declares neither.
|
|
21
|
+
# The other reductions over the one eligible head; empty when none is declared
|
|
22
|
+
# (ADR 0078 — a read model reports one shape, so at most one is ever set).
|
|
34
23
|
attribute :count, ReadModelText, optional: true
|
|
35
24
|
attribute :median_field, ReadModelText, optional: true
|
|
25
|
+
attribute :sum_field, ReadModelText, optional: true
|
|
26
|
+
attribute :avg_field, ReadModelText, optional: true
|
|
27
|
+
attribute :min_field, ReadModelText, optional: true
|
|
28
|
+
attribute :max_field, ReadModelText, optional: true
|
|
29
|
+
attribute :percentile_field, ReadModelText, optional: true
|
|
30
|
+
attribute :percentile_at, ReadModelText, optional: true
|
|
31
|
+
attribute :any_field, ReadModelText, optional: true
|
|
32
|
+
attribute :all_field, ReadModelText, optional: true
|
|
36
33
|
|
|
37
34
|
value_object "ReadModelName" do
|
|
38
35
|
attribute :value, String
|
|
@@ -40,8 +37,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
40
37
|
end
|
|
41
38
|
|
|
42
39
|
value_object "ReadModelText" do
|
|
43
|
-
#
|
|
44
|
-
# legitimately empty on a read model that has not named them yet
|
|
40
|
+
# Deliberately permissive: query_name and the reference fields may be legitimately empty.
|
|
45
41
|
attribute :value, String
|
|
46
42
|
end
|
|
47
43
|
|
|
@@ -60,7 +56,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
60
56
|
attribute :option, String
|
|
61
57
|
attribute :key, String
|
|
62
58
|
attribute :value, String
|
|
63
|
-
#
|
|
59
|
+
# Only some options carry an `at`.
|
|
64
60
|
attribute :at, String, optional: true
|
|
65
61
|
end
|
|
66
62
|
|
|
@@ -69,14 +65,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
69
65
|
invariant("a group_by field is named") { !field.to_s.empty? }
|
|
70
66
|
end
|
|
71
67
|
|
|
72
|
-
# The
|
|
73
|
-
#
|
|
74
|
-
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
75
|
-
# SOURCE — the IR is a contract read straight from this file,
|
|
76
|
-
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
77
|
-
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
78
|
-
# does not say how it is ordered is answered in identity order, which is
|
|
79
|
-
# right for every other ask and fatal for the one that is the SOURCE.
|
|
68
|
+
# Declaration order among siblings. The IR is read index for index, so the language
|
|
69
|
+
# holds it rather than inheriting whatever order a store iterates.
|
|
80
70
|
value_object "Position" do
|
|
81
71
|
attribute :value, Integer
|
|
82
72
|
end
|
|
@@ -96,10 +86,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
96
86
|
attribute :name, ReadModelName
|
|
97
87
|
attribute :description, ProjectionPurpose, optional: true
|
|
98
88
|
attribute :query_name, ReadModelText
|
|
99
|
-
#
|
|
100
|
-
# declared at all) has neither. Permanently empty, not "not yet
|
|
101
|
-
# set" — see Gather's own comment below for why that distinction
|
|
102
|
-
# matters.
|
|
89
|
+
# Optional: a rootless read model (no `reference_to`) permanently has neither (see Gather).
|
|
103
90
|
attribute :reference_name, ReadModelText, optional: true
|
|
104
91
|
attribute :reference_target, ReadModelText, optional: true
|
|
105
92
|
|
|
@@ -118,26 +105,14 @@ Hecks.bluebook "Bluebook" do
|
|
|
118
105
|
role "Language"
|
|
119
106
|
goal "Attach one aggregate head to the read model"
|
|
120
107
|
|
|
121
|
-
# A
|
|
122
|
-
# `
|
|
123
|
-
# so the builder cannot produce one
|
|
124
|
-
# without it — the field is a plain
|
|
125
|
-
# required, non-empty name. `as` and
|
|
126
|
-
# `many` are both DERIVED from it when the author does not spell them, which
|
|
127
|
-
# is the clearest statement that it is the part that cannot be missing.
|
|
108
|
+
# A head is the aggregate it names; add_aggregate_head is only reached from `include Target`.
|
|
109
|
+
# `as` and `many` are derived from it when the author does not spell them.
|
|
128
110
|
attribute :aggregate, ReadModelText
|
|
129
111
|
attribute :as, ReadModelText
|
|
130
112
|
attribute :many, ReadModelText
|
|
131
113
|
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
# that rule was really "this read model must have SOME reference, ever"
|
|
135
|
-
# — exactly the constraint a ROOTLESS read model (bulk, no root,
|
|
136
|
-
# `group_by`'s own real use) deliberately doesn't meet, permanently,
|
|
137
|
-
# on purpose, not by omission. Removed rather than relaxed: there is
|
|
138
|
-
# no runtime fact left here that distinguishes "forgot to declare a
|
|
139
|
-
# reference" from "declared rootless on purpose" — both look
|
|
140
|
-
# identical (`reference_target` empty) by the time Gather is judged.
|
|
114
|
+
# No "reference_target must be set" given: a rootless read model (bulk, group_by) permanently
|
|
115
|
+
# lacks one, which is indistinguishable from forgetting to declare it.
|
|
141
116
|
|
|
142
117
|
sets :aggregate_heads, append: { aggregate: :aggregate, as: :as, many: :many }
|
|
143
118
|
|
|
@@ -157,14 +132,8 @@ Hecks.bluebook "Bluebook" do
|
|
|
157
132
|
emits GroupByFieldAdded
|
|
158
133
|
end
|
|
159
134
|
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
# (aggregate.bluebook) — a command carrying its own value and a bare
|
|
163
|
-
# `sets field, to: field` copying it onto the record, rather
|
|
164
|
-
# than an `append:` (they are not lists, and there is only ever one
|
|
165
|
-
# of each). `count`/`median_field` are declared here, not folded
|
|
166
|
-
# into `Declare`, for the same reason `GroupBy` is its own command
|
|
167
|
-
# above: neither is known until the DSL body runs past `include`.
|
|
135
|
+
# count and median are late-set scalars, like Lifecycle's state_field: one value each, copied
|
|
136
|
+
# by `sets`, and unknown until the DSL body runs past `include`.
|
|
168
137
|
command "Count" do
|
|
169
138
|
role "Language"
|
|
170
139
|
goal "Mark the read model as a bare row count over its one eligible collection"
|
|
@@ -187,13 +156,91 @@ Hecks.bluebook "Bluebook" do
|
|
|
187
156
|
emits MedianFieldSet
|
|
188
157
|
end
|
|
189
158
|
|
|
159
|
+
command "Sum" do
|
|
160
|
+
role "Language"
|
|
161
|
+
goal "Mark the read model as the total of one numeric field across its one eligible collection"
|
|
162
|
+
|
|
163
|
+
given("a sum field is named") { !sum_field.value.to_s.empty? }
|
|
164
|
+
|
|
165
|
+
sets :sum_field
|
|
166
|
+
|
|
167
|
+
emits SumFieldSet
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
command "Avg" do
|
|
171
|
+
role "Language"
|
|
172
|
+
goal "Mark the read model as the mean of one numeric field across its one eligible collection"
|
|
173
|
+
|
|
174
|
+
given("an avg field is named") { !avg_field.value.to_s.empty? }
|
|
175
|
+
|
|
176
|
+
sets :avg_field
|
|
177
|
+
|
|
178
|
+
emits AvgFieldSet
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
command "Min" do
|
|
182
|
+
role "Language"
|
|
183
|
+
goal "Mark the read model as the smallest value of one numeric field across its one eligible collection"
|
|
184
|
+
|
|
185
|
+
given("a min field is named") { !min_field.value.to_s.empty? }
|
|
186
|
+
|
|
187
|
+
sets :min_field
|
|
188
|
+
|
|
189
|
+
emits MinFieldSet
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
command "Max" do
|
|
193
|
+
role "Language"
|
|
194
|
+
goal "Mark the read model as the largest value of one numeric field across its one eligible collection"
|
|
195
|
+
|
|
196
|
+
given("a max field is named") { !max_field.value.to_s.empty? }
|
|
197
|
+
|
|
198
|
+
sets :max_field
|
|
199
|
+
|
|
200
|
+
emits MaxFieldSet
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
command "Percentile" do
|
|
204
|
+
role "Language"
|
|
205
|
+
goal "Mark the read model as one interpolated rank of one numeric field across its one eligible collection"
|
|
206
|
+
|
|
207
|
+
given("a percentile field is named") { !percentile_field.value.to_s.empty? }
|
|
208
|
+
|
|
209
|
+
sets :percentile_field
|
|
210
|
+
sets :percentile_at
|
|
211
|
+
|
|
212
|
+
emits PercentileFieldSet
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
command "Any" do
|
|
216
|
+
role "Language"
|
|
217
|
+
goal "Mark the read model as whether any row's boolean field is true across its one eligible collection"
|
|
218
|
+
|
|
219
|
+
given("an any field is named") { !any_field.value.to_s.empty? }
|
|
220
|
+
|
|
221
|
+
sets :any_field
|
|
222
|
+
|
|
223
|
+
emits AnyFieldSet
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
command "All" do
|
|
227
|
+
role "Language"
|
|
228
|
+
goal "Mark the read model as whether every row's boolean field is true across its one eligible collection"
|
|
229
|
+
|
|
230
|
+
given("an all field is named") { !all_field.value.to_s.empty? }
|
|
231
|
+
|
|
232
|
+
sets :all_field
|
|
233
|
+
|
|
234
|
+
emits AllFieldSet
|
|
235
|
+
end
|
|
236
|
+
|
|
190
237
|
command "Option" do
|
|
191
238
|
role "Language"
|
|
192
239
|
goal "Attach one part of one specification option to the read model"
|
|
193
240
|
|
|
194
241
|
attribute :option, ReadModelText
|
|
195
242
|
attribute :key, ReadModelText
|
|
196
|
-
# Same reading as Query.Option
|
|
243
|
+
# Same reading as Query.Option: an option key may stand alone.
|
|
197
244
|
attribute :value, ReadModelText, optional: true
|
|
198
245
|
attribute :at, ReadModelText, optional: true
|
|
199
246
|
|
|
@@ -204,9 +251,7 @@ Hecks.bluebook "Bluebook" do
|
|
|
204
251
|
emits OptionAttached
|
|
205
252
|
end
|
|
206
253
|
|
|
207
|
-
#
|
|
208
|
-
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
209
|
-
# Contexts represented here: ReadModel.
|
|
254
|
+
# Keyword and argument rows for read models; SyntaxBoot discovers every aggregate-local table.
|
|
210
255
|
value_object "KeywordSeed" do
|
|
211
256
|
attribute :word, String
|
|
212
257
|
attribute :context, String, admits: "Syntax::Context"
|
|
@@ -225,6 +270,13 @@ Hecks.bluebook "Bluebook" do
|
|
|
225
270
|
member word: "group_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "group_by", calls: "group_by_impl"
|
|
226
271
|
member word: "count", context: "ReadModel", body: "none", inner: "", opens: "", fills: "count"
|
|
227
272
|
member word: "median", context: "ReadModel", body: "none", inner: "", opens: "", fills: "median_field"
|
|
273
|
+
member word: "sum", context: "ReadModel", body: "none", inner: "", opens: "", fills: "sum_field"
|
|
274
|
+
member word: "avg", context: "ReadModel", body: "none", inner: "", opens: "", fills: "avg_field"
|
|
275
|
+
member word: "min", context: "ReadModel", body: "none", inner: "", opens: "", fills: "min_field"
|
|
276
|
+
member word: "max", context: "ReadModel", body: "none", inner: "", opens: "", fills: "max_field"
|
|
277
|
+
member word: "percentile", context: "ReadModel", body: "none", inner: "", opens: "", fills: "percentile_field", calls: "percentile_impl"
|
|
278
|
+
member word: "any", context: "ReadModel", body: "none", inner: "", opens: "", fills: "any_field"
|
|
279
|
+
member word: "all", context: "ReadModel", body: "none", inner: "", opens: "", fills: "all_field"
|
|
228
280
|
member word: "where", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "where_impl"
|
|
229
281
|
member word: "order_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "order_by_impl"
|
|
230
282
|
member word: "authorize", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "authorize_impl"
|
|
@@ -256,9 +308,23 @@ Hecks.bluebook "Bluebook" do
|
|
|
256
308
|
member keyword: "include", context: "ReadModel", at: "", named: "as", kind: "symbol", required: "false", fills: "as"
|
|
257
309
|
member keyword: "group_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "group_by", variadic: "true"
|
|
258
310
|
member keyword: "median", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "median_field"
|
|
311
|
+
member keyword: "sum", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "sum_field"
|
|
312
|
+
member keyword: "avg", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "avg_field"
|
|
313
|
+
member keyword: "min", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "min_field"
|
|
314
|
+
member keyword: "max", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "max_field"
|
|
315
|
+
member keyword: "percentile", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "percentile_field"
|
|
316
|
+
member keyword: "percentile", context: "ReadModel", at: "", named: "at", kind: "number", required: "true", fills: "percentile_at"
|
|
317
|
+
member keyword: "any", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "any_field"
|
|
318
|
+
member keyword: "all", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "all_field"
|
|
259
319
|
member keyword: "where", context: "ReadModel", at: "1", named: "", kind: "pairs", required: "true", fills: ""
|
|
320
|
+
# ADR 0055: which many-side `include`d aggregate (by type) this option applies to —
|
|
321
|
+
# only recognized here, in ReadModel context, since a plain Query has no such
|
|
322
|
+
# disambiguation to make (rust/parser's own query_derive::refuse_on_target keeps
|
|
323
|
+
# refusing it there instead).
|
|
324
|
+
member keyword: "where", context: "ReadModel", at: "", named: "on", kind: "constant", required: "false", fills: "target"
|
|
260
325
|
member keyword: "order_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "field"
|
|
261
326
|
member keyword: "order_by", context: "ReadModel", at: "2", named: "", kind: "symbol", required: "false", fills: "direction"
|
|
327
|
+
member keyword: "order_by", context: "ReadModel", at: "", named: "on", kind: "constant", required: "false", fills: "target"
|
|
262
328
|
member keyword: "authorize", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "policy"
|
|
263
329
|
member keyword: "authorize", context: "ReadModel", at: "", named: "tenant", kind: "symbol", required: "false", fills: "tenant"
|
|
264
330
|
member keyword: "inspect_query", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "false", fills: "mode"
|