hecks 1.3.0 → 1.5.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/lib/hecks/adapters/driven/claude_code.rb +72 -7
- data/lib/hecks/adapters/driven/d1.rb +187 -23
- data/lib/hecks/adapters/driven/folder.rb +83 -10
- data/lib/hecks/adapters/driven/google_authentication.rb +33 -12
- data/lib/hecks/adapters/driven/governance_authorization.rb +87 -18
- data/lib/hecks/adapters/driven/heki/journal.rb +13 -4
- data/lib/hecks/adapters/driven/heki/saga_store.rb +56 -10
- data/lib/hecks/adapters/driven/heki/snapshot.rb +1 -1
- data/lib/hecks/adapters/driven/heki.rb +106 -9
- data/lib/hecks/adapters/driven/identity_registry.rb +12 -2
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +25 -3
- data/lib/hecks/adapters/driven/in_process_key_vault.adapter +3 -0
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +53 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +67 -14
- data/lib/hecks/adapters/driven/lambda.rb +82 -35
- data/lib/hecks/adapters/driven/local_storage.rb +83 -10
- data/lib/hecks/adapters/driven/memory.rb +205 -9
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +21 -1
- data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
- data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
- data/lib/hecks/adapters/driven/postgres.rb +175 -28
- data/lib/hecks/adapters/driven/prism.rb +50 -11
- data/lib/hecks/adapters/driven/secure_random_identity.rb +3 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
- data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
- data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
- data/lib/hecks/adapters/driven/sqlite.rb +181 -21
- data/lib/hecks/adapters/driven/system_clock.rb +3 -0
- data/lib/hecks/adapters/driven/tenant_provisioner.adapter +3 -0
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +66 -0
- data/lib/hecks/adapters/driven.rb +6 -4
- data/lib/hecks/adapters/driving/github_webhook.rb +31 -18
- data/lib/hecks/behaviors/dsl.rb +60 -2
- data/lib/hecks/behaviors/expectations.rb +190 -29
- data/lib/hecks/behaviors/ir.rb +12 -1
- data/lib/hecks/behaviors/rspec.rb +9 -1
- data/lib/hecks/behaviors/runner.rb +21 -2
- data/lib/hecks/behaviors.rb +9 -1
- data/lib/hecks/bluebook/aggregate.rb +43 -13
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +17 -10
- data/lib/hecks/bluebook/assembly/build.rb +26 -5
- data/lib/hecks/bluebook/assembly/contract.rb +98 -23
- data/lib/hecks/bluebook/assembly/contracts.rb +59 -52
- data/lib/hecks/bluebook/assembly/marks.rb +159 -30
- data/lib/hecks/bluebook/assembly/specializer.rb +38 -21
- data/lib/hecks/bluebook/assembly.rb +32 -14
- data/lib/hecks/bluebook/attribute.rb +26 -12
- data/lib/hecks/bluebook/behaviour/aggregate.rb +43 -11
- data/lib/hecks/bluebook/behaviour/attribute.rb +18 -5
- data/lib/hecks/bluebook/behaviour/chapter.rb +76 -5
- data/lib/hecks/bluebook/behaviour/command.rb +55 -25
- data/lib/hecks/bluebook/behaviour/domain_port.rb +27 -7
- data/lib/hecks/bluebook/behaviour/entity.rb +20 -8
- data/lib/hecks/bluebook/behaviour/hexagon.rb +30 -4
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +27 -6
- data/lib/hecks/bluebook/behaviour/policy.rb +42 -17
- data/lib/hecks/bluebook/behaviour/process_manager.rb +39 -8
- data/lib/hecks/bluebook/behaviour/query.rb +6 -1
- data/lib/hecks/bluebook/behaviour/read_model.rb +29 -8
- data/lib/hecks/bluebook/behaviour/traits.rb +48 -12
- data/lib/hecks/bluebook/behaviour/value_object.rb +21 -9
- data/lib/hecks/bluebook/capabilities.rb +27 -0
- data/lib/hecks/bluebook/chapter.rb +51 -9
- data/lib/hecks/bluebook/command.rb +62 -17
- data/lib/hecks/bluebook/domain_port.rb +34 -9
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +282 -123
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +112 -75
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +81 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +486 -117
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +179 -47
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +284 -122
- data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
- data/lib/hecks/bluebook/dsl/entity_builder.rb +191 -61
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +130 -30
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +38 -21
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
- data/lib/hecks/bluebook/dsl/policy_builder.rb +86 -36
- data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +111 -47
- data/lib/hecks/bluebook/dsl/query_builder.rb +37 -8
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +127 -52
- data/lib/hecks/bluebook/dsl/rule_reference.rb +97 -43
- data/lib/hecks/bluebook/dsl/translation_builder.rb +150 -44
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +68 -20
- data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
- data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
- data/lib/hecks/bluebook/entity.rb +40 -11
- data/lib/hecks/bluebook/expression/ast_json.rb +128 -36
- data/lib/hecks/bluebook/expression/ast_reader.rb +32 -3
- data/lib/hecks/bluebook/expression/canonical_form.rb +55 -16
- data/lib/hecks/bluebook/expression/evaluator.rb +221 -43
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +54 -18
- data/lib/hecks/bluebook/expression/resolver.rb +369 -128
- data/lib/hecks/bluebook/hexagon.rb +35 -1
- data/lib/hecks/bluebook/lifecycle.rb +12 -1
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/judge.rb +126 -108
- data/lib/hecks/bluebook/meta_validator/plan.rb +81 -46
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +3 -2
- data/lib/hecks/bluebook/meta_validator/readings.rb +200 -50
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +68 -41
- data/lib/hecks/bluebook/meta_validator/shapes.rb +166 -21
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +286 -46
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +11 -10
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -5
- data/lib/hecks/bluebook/meta_validator.rb +235 -139
- data/lib/hecks/bluebook/model_check.rb +434 -104
- data/lib/hecks/bluebook/pattern_subset.rb +32 -10
- data/lib/hecks/bluebook/policy.rb +15 -13
- data/lib/hecks/bluebook/process_manager.rb +27 -14
- data/lib/hecks/bluebook/project_discovery.rb +5 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +50 -6
- data/lib/hecks/bluebook/query.rb +31 -4
- data/lib/hecks/bluebook/read_model.rb +35 -15
- data/lib/hecks/bluebook/reference.rb +26 -13
- data/lib/hecks/bluebook/smoke_test.rb +46 -23
- data/lib/hecks/bluebook/synthesizer.rb +46 -12
- data/lib/hecks/bluebook/translation.rb +34 -5
- data/lib/hecks/bluebook/value_object.rb +29 -11
- data/lib/hecks/bluebook.rb +5 -6
- data/lib/hecks/codemod.rb +138 -50
- data/lib/hecks/construct.rb +21 -7
- data/lib/hecks/corpus.rb +438 -0
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +19 -0
- data/lib/hecks/doc/reference.rb +200 -31
- data/lib/hecks/embryonaut_bluebook.rb +38 -15
- data/lib/hecks/facade/cli_door.rb +69 -10
- data/lib/hecks/facade/cli_runner.rb +105 -24
- data/lib/hecks/facade/command_request.rb +23 -0
- data/lib/hecks/facade/handle.rb +155 -35
- data/lib/hecks/facade/json_door.rb +106 -25
- data/lib/hecks/facade/surface/aggregate_door.rb +50 -27
- data/lib/hecks/facade/surface/chapter.rb +26 -17
- data/lib/hecks/facade/surface.rb +16 -3
- data/lib/hecks/facade.rb +15 -4
- data/lib/hecks/forms/app.rb +46 -30
- data/lib/hecks/forms/command_form_renderer.rb +70 -9
- data/lib/hecks/forms/field_renderer.rb +142 -6
- data/lib/hecks/forms/field_shape.rb +183 -19
- data/lib/hecks/forms/html.rb +51 -7
- data/lib/hecks/forms/index_renderer.rb +14 -2
- data/lib/hecks/forms/page.rb +14 -0
- data/lib/hecks/forms/params.rb +120 -23
- data/lib/hecks/forms/port_argument.rb +14 -2
- data/lib/hecks/forms/query_form_renderer.rb +65 -2
- data/lib/hecks/forms/record_renderer.rb +60 -2
- data/lib/hecks/forms/record_table.rb +28 -1
- data/lib/hecks/forms/reference_options.rb +24 -0
- data/lib/hecks/forms/value_object_shape.rb +13 -3
- data/lib/hecks/forms.rb +24 -4
- data/lib/hecks/fqn.rb +59 -1
- data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
- data/lib/hecks/framework/bluebook/privacy.bluebook +155 -0
- data/lib/hecks/framework/oidc.json +15 -0
- data/lib/hecks/framework.rb +79 -25
- data/lib/hecks/freezer.rb +27 -11
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +241 -106
- data/lib/hecks/fuzzing/combination_miner.rb +178 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +241 -45
- data/lib/hecks/fuzzing/coverage_campaign.rb +161 -0
- data/lib/hecks/fuzzing/differential.rb +192 -0
- data/lib/hecks/fuzzing/domain_generator.rb +871 -0
- data/lib/hecks/fuzzing/era_boundary.rb +68 -19
- data/lib/hecks/fuzzing/form_census.rb +121 -20
- data/lib/hecks/fuzzing/generated_domain_check.rb +171 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +45 -6
- data/lib/hecks/fuzzing/isolated_boot.rb +137 -80
- data/lib/hecks/fuzzing/nondeterministic.rb +79 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +111 -21
- data/lib/hecks/fuzzing/properties/corrections.rb +34 -9
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +300 -51
- data/lib/hecks/fuzzing/properties/guards.rb +86 -42
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +80 -32
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +40 -35
- data/lib/hecks/fuzzing/properties/outbox.rb +70 -32
- data/lib/hecks/fuzzing/properties/querying.rb +82 -28
- data/lib/hecks/fuzzing/properties.rb +84 -51
- data/lib/hecks/fuzzing/qa_settings.rb +164 -0
- data/lib/hecks/fuzzing/replay.rb +241 -133
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -28
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +139 -0
- data/lib/hecks/fuzzing/self_consistency.rb +315 -137
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +46 -40
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +59 -32
- data/lib/hecks/fuzzing/sequence_generator.rb +158 -23
- data/lib/hecks/fuzzing/shrinker.rb +309 -0
- data/lib/hecks/fuzzing/structural_skips.rb +37 -130
- data/lib/hecks/fuzzing/sweep_depth.rb +12 -4
- data/lib/hecks/fuzzing/target_capabilities.rb +107 -29
- data/lib/hecks/fuzzing/value_generator.rb +110 -22
- data/lib/hecks/fuzzing.rb +5 -0
- data/lib/hecks/grammar/evolve.rb +188 -12
- data/lib/hecks/grammar.rb +53 -7
- data/lib/hecks/ir.rb +51 -20
- data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
- data/lib/hecks/language/bluebook/policy.bluebook +11 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +11 -0
- data/lib/hecks/language/oidc.json +5 -0
- data/lib/hecks/literal.rb +41 -9
- data/lib/hecks/naming.rb +112 -31
- data/lib/hecks/ports/access_control.rb +53 -2
- data/lib/hecks/ports/agent/answers.rb +83 -6
- data/lib/hecks/ports/agent.rb +119 -35
- data/lib/hecks/ports/authentication.rb +44 -4
- data/lib/hecks/ports/authorization.rb +50 -11
- data/lib/hecks/ports/clock.rb +42 -23
- data/lib/hecks/ports/extraction.rb +16 -0
- data/lib/hecks/ports/identity_assignment.rb +23 -2
- data/lib/hecks/ports/identity_generation.rb +17 -3
- data/lib/hecks/ports/identity_resolution.rb +17 -1
- data/lib/hecks/ports/key_vault.port +6 -0
- data/lib/hecks/ports/key_vault.rb +58 -0
- data/lib/hecks/ports/loading.rb +4 -0
- data/lib/hecks/ports/persistence/append_only.rb +172 -8
- data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
- data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
- data/lib/hecks/ports/persistence/execution.rb +4 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
- data/lib/hecks/ports/persistence/plugin.rb +42 -4
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +34 -5
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +95 -6
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +48 -8
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +58 -19
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +96 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +15 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +9 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
- data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
- data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
- data/lib/hecks/ports/persistence/state_codec.rb +319 -0
- data/lib/hecks/ports/persistence.rb +36 -1
- data/lib/hecks/ports/projection.rb +61 -7
- data/lib/hecks/ports/query/in_memory.rb +41 -8
- data/lib/hecks/ports/query/ordering.rb +21 -6
- data/lib/hecks/ports/query.rb +35 -0
- data/lib/hecks/ports.rb +1 -0
- data/lib/hecks/projections/bootstrap_table.rb +147 -0
- data/lib/hecks/projections/diagrams.rb +315 -79
- data/lib/hecks/projections/glossary/html.rb +91 -3
- data/lib/hecks/projections/glossary/markdown.rb +50 -3
- data/lib/hecks/projections/glossary/mermaid.rb +49 -1
- data/lib/hecks/projections/glossary/sections.rb +1 -1
- data/lib/hecks/projections/glossary/sentences.rb +110 -5
- data/lib/hecks/projections/glossary.rb +173 -31
- data/lib/hecks/projections/ir.rb +1 -1
- data/lib/hecks/projections/model/deviations.rb +62 -17
- data/lib/hecks/projections/model.rb +75 -21
- data/lib/hecks/projections/oidc.rb +45 -8
- data/lib/hecks/projections/parser_table.rb +53 -12
- data/lib/hecks/projections/reference.rb +15 -3
- data/lib/hecks/projections/rust_vocabulary.rb +646 -0
- data/lib/hecks/projections/shape.rb +10 -2
- data/lib/hecks/projections/statements.rb +69 -22
- data/lib/hecks/projections/vocabulary.rb +26 -9
- data/lib/hecks/projections.rb +5 -3
- data/lib/hecks/projector/cli_projector.rb +245 -37
- data/lib/hecks/projector/docs_projector.rb +154 -28
- data/lib/hecks/projector/exporter.rb +104 -29
- data/lib/hecks/projector/ir_projector.rb +7 -1
- data/lib/hecks/projector/narrate_projector.rb +144 -23
- data/lib/hecks/projector/target.rb +42 -18
- data/lib/hecks/projector.rb +86 -18
- data/lib/hecks/query_ir.rb +94 -47
- data/lib/hecks/query_specification/common/comparators.rb +19 -3
- data/lib/hecks/query_specification/common/comparison.rb +109 -27
- data/lib/hecks/query_specification/common/dsl.rb +65 -9
- data/lib/hecks/query_specification/common/null_policy.rb +61 -15
- data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
- data/lib/hecks/query_specification/common/options.rb +25 -0
- data/lib/hecks/query_specification/field_path.rb +69 -15
- data/lib/hecks/query_specification/hop_path.rb +57 -20
- data/lib/hecks/query_specification/read_model/specification.rb +4 -0
- data/lib/hecks/rendering.rb +9 -3
- data/lib/hecks/router/namespace_installer.rb +16 -3
- data/lib/hecks/router.rb +56 -1
- data/lib/hecks/runtime/aggregate_lock.rb +20 -11
- data/lib/hecks/runtime/boot_gates.rb +21 -3
- data/lib/hecks/runtime/caller.rb +40 -8
- data/lib/hecks/runtime/capability_graph.rb +13 -2
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +40 -41
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +45 -67
- data/lib/hecks/runtime/command_interpreter.rb +195 -113
- data/lib/hecks/runtime/command_rules/admissibility.rb +231 -80
- data/lib/hecks/runtime/command_rules/arithmetic.rb +154 -96
- data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
- data/lib/hecks/runtime/command_rules/emission.rb +18 -1
- data/lib/hecks/runtime/command_rules/references.rb +145 -55
- data/lib/hecks/runtime/command_rules.rb +3 -0
- data/lib/hecks/runtime/dependency_planning.rb +56 -11
- data/lib/hecks/runtime/dispatcher.rb +263 -92
- data/lib/hecks/runtime/entity_element.rb +304 -67
- data/lib/hecks/runtime/entity_interpreter.rb +149 -88
- data/lib/hecks/runtime/errors.rb +37 -23
- data/lib/hecks/runtime/event.rb +15 -10
- data/lib/hecks/runtime/identity.rb +91 -23
- data/lib/hecks/runtime/instance.rb +103 -18
- data/lib/hecks/runtime/interpreting.rb +24 -16
- data/lib/hecks/runtime/invocation.rb +358 -0
- data/lib/hecks/runtime/loader.rb +105 -19
- data/lib/hecks/runtime/outbox.rb +164 -26
- data/lib/hecks/runtime/policy_interpreter.rb +73 -60
- data/lib/hecks/runtime/port_operation_interpreter.rb +42 -19
- data/lib/hecks/runtime/query_interpreter.rb +93 -74
- data/lib/hecks/runtime/reaction_invocation.rb +73 -28
- data/lib/hecks/runtime/read_model_interpreter.rb +60 -44
- data/lib/hecks/runtime/rebuild_sweep.rb +32 -4
- data/lib/hecks/runtime/reference_hop.rb +48 -6
- data/lib/hecks/runtime/refusal_wording.rb +142 -115
- data/lib/hecks/runtime/registry/saga_persistence.rb +32 -21
- data/lib/hecks/runtime/registry/verification.rb +153 -28
- data/lib/hecks/runtime/registry.rb +202 -32
- data/lib/hecks/runtime/remote_dispatcher.rb +125 -24
- data/lib/hecks/runtime/routing.rb +36 -154
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +25 -27
- data/lib/hecks/runtime/saga_interpreter.rb +90 -76
- data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
- data/lib/hecks/runtime/tenant_check.rb +33 -13
- data/lib/hecks/runtime/tenant_scope.rb +23 -5
- data/lib/hecks/runtime/value/admission.rb +75 -30
- data/lib/hecks/runtime/value/coercion.rb +555 -142
- data/lib/hecks/runtime/value/entity_list_coercion.rb +132 -60
- data/lib/hecks/runtime/value.rb +71 -21
- data/lib/hecks/runtime.rb +39 -7
- data/lib/hecks/storehouse.rb +368 -72
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +130 -0
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +32 -0
- data/lib/hecks/version.rb +3 -3
- data/lib/hecks/vocabulary.rb +205 -4
- data/lib/hecks.rb +91 -11
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +19 -11
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +24 -12
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +38 -14
- metadata +28 -2
|
@@ -7,7 +7,7 @@ module Hecks
|
|
|
7
7
|
# builder collecting every `aggregate`/`read_model`/`policy`/
|
|
8
8
|
# `process_manager` a chapter declares, plus the chapter-wide named-
|
|
9
9
|
# given pools those thread down into (see `#aggregate_impl`'s own
|
|
10
|
-
# comment). `.build` reuses the
|
|
10
|
+
# comment). `.build` reuses the same open builder instance across
|
|
11
11
|
# several files sharing one chapter name (`self.build`'s own comment),
|
|
12
12
|
# so a chapter split across files accumulates rather than each file
|
|
13
13
|
# silently replacing the last.
|
|
@@ -19,6 +19,8 @@ module Hecks
|
|
|
19
19
|
|
|
20
20
|
attr_reader :classification
|
|
21
21
|
|
|
22
|
+
# @param name [String] the chapter's declared name
|
|
23
|
+
# @param version [String, nil] the chapter's pinned version, or nil for unversioned
|
|
22
24
|
def initialize(name, version: nil)
|
|
23
25
|
@name = name
|
|
24
26
|
@version = version
|
|
@@ -26,19 +28,19 @@ module Hecks
|
|
|
26
28
|
@read_models = []
|
|
27
29
|
@policies = []
|
|
28
30
|
@process_managers = []
|
|
29
|
-
#
|
|
31
|
+
# The root of the chapter-wide given pool — one level wider
|
|
30
32
|
# than `AggregateBuilder`'s own `@entity_named_givens` (S10
|
|
31
33
|
# extended across an aggregate's whole entity tree, earlier
|
|
32
34
|
# this arc). See `#given`'s own comment for what this closes.
|
|
33
35
|
@chapter_named_givens = {}
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
+
# Every bare chapter-given reference this chapter's own files
|
|
37
|
+
# left unresolved so far — threaded into every aggregate the
|
|
36
38
|
# same way `@chapter_named_givens` is. See
|
|
37
39
|
# `AggregateBuilder#pending_chapter_given`'s own comment for
|
|
38
40
|
# what queues here and `#resolve_pending_chapter_givens!`,
|
|
39
41
|
# below, for where it drains.
|
|
40
42
|
@chapter_pending_givens = []
|
|
41
|
-
#
|
|
43
|
+
# **One level wider still** — the chapter-wide, entity-scoped pool
|
|
42
44
|
# (the piece analogue of `@chapter_named_givens`, above). See
|
|
43
45
|
# `EntityBuilder#given_impl`'s own comment for what this
|
|
44
46
|
# closes; `docs/implemented/resolution-rules/
|
|
@@ -62,46 +64,105 @@ module Hecks
|
|
|
62
64
|
end
|
|
63
65
|
private :adopt_version
|
|
64
66
|
|
|
67
|
+
# Records the chapter's vision statement.
|
|
68
|
+
#
|
|
69
|
+
# @param value [String] the vision text, as given to `vision "..."`
|
|
70
|
+
# @return [void]
|
|
65
71
|
def vision(value)
|
|
66
72
|
# moved to the language: Vision invariant, on Chapter.Declare
|
|
67
73
|
|
|
68
74
|
@vision = value
|
|
69
75
|
end
|
|
70
76
|
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
77
|
+
# Records the chapter's earlier name, so the storage layer recognizes its own history
|
|
78
|
+
# under that old name instead of minting a brand-new lineage from nothing — a chapter's
|
|
79
|
+
# identity can change, and this is where the new declaration says what it was.
|
|
80
|
+
#
|
|
81
|
+
# @param value [String, Symbol] the chapter's earlier name
|
|
82
|
+
# @return [String] `value`, stringified, as stored
|
|
74
83
|
def formerly_known_as(value) = @formerly_known_as = value.to_s
|
|
75
84
|
|
|
76
|
-
#
|
|
85
|
+
# Names a core grammar context this chapter's sub-language extends.
|
|
86
|
+
#
|
|
87
|
+
# **A sub-language names where it lands**. ADR 0026's own seam: the core
|
|
77
88
|
# grammar does not name its extension points, so this chapter names
|
|
78
|
-
#
|
|
89
|
+
# itself onto them instead — the core contexts (e.g. "Query",
|
|
79
90
|
# "ReadModel") whose own admitted words this chapter's `Syntax`
|
|
80
91
|
# aggregate contributes rows for. Variadic, and accumulating across
|
|
81
92
|
# calls the same reason `identified_by`/`group_by` are: nothing here
|
|
82
93
|
# requires one call to name every context at once.
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
# chapters like Paging use it
|
|
86
|
-
#
|
|
94
|
+
#
|
|
95
|
+
# Reached through `calls: "attaches_to_impl"` rather than `GenericDispatch`'s default —
|
|
96
|
+
# not bootstrap-reachable, since only sub-language chapters like Paging use it, never a
|
|
97
|
+
# core chapter.
|
|
98
|
+
#
|
|
99
|
+
# @param contexts [Array<String>] one or more core grammar context names, such as
|
|
100
|
+
# `"Query"`/`"ReadModel"`
|
|
101
|
+
# @return [Array<String>] every context named so far, this call's included
|
|
87
102
|
def attaches_to_impl(*contexts) = (@attaches_to ||= []).concat(contexts.map(&:to_s))
|
|
88
103
|
|
|
104
|
+
# Records a capability this chapter answers for other domains.
|
|
105
|
+
#
|
|
106
|
+
# A capability this chapter answers for other domains, declared so
|
|
107
|
+
# nothing has to recognise the chapter by name — Governance's
|
|
108
|
+
# `provides "authorization", assignments: ..., grant: ...,
|
|
109
|
+
# transitions: ...`. One row per key, in the order written; what
|
|
110
|
+
# each capability requires is checked once the chapter is whole
|
|
111
|
+
# (`Validation#validate_provisions!`), since the verbs it names may
|
|
112
|
+
# be declared further down the file.
|
|
113
|
+
#
|
|
114
|
+
# @param capability [String] the capability's own name, such as `"authorization"`
|
|
115
|
+
# @param verbs [Hash{Symbol => String}] one command/query reference per capability
|
|
116
|
+
# key, e.g. `grant: "RoleAssignment.Assign"`
|
|
117
|
+
# @return [Array<Bluebook::Chapter::Provision>] every provision row declared so far,
|
|
118
|
+
# this capability's included
|
|
119
|
+
# @raise [Bluebook::DSL::Malformed] if `verbs` is empty
|
|
120
|
+
def provides_impl(capability, **verbs)
|
|
121
|
+
if verbs.empty?
|
|
122
|
+
raise Malformed, "#{@name}'s provides #{capability.inspect} names no verb — say which of this " \
|
|
123
|
+
"chapter's commands and queries answer it"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
rows = verbs.map { |key, verb| Chapter::Provision.new(capability: capability.to_s, key: key.to_s, verb: verb.to_s) }
|
|
127
|
+
(@provides ||= []).concat(rows)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Classifies this chapter as core to the framework, rather than a domain built on it.
|
|
131
|
+
#
|
|
132
|
+
# @return [Symbol] `:core`
|
|
89
133
|
def core = @classification = :core
|
|
134
|
+
|
|
135
|
+
# Classifies this chapter as a supporting piece of the framework, rather than a domain
|
|
136
|
+
# built on it.
|
|
137
|
+
#
|
|
138
|
+
# @return [Symbol] `:supporting`
|
|
90
139
|
def supporting = @classification = :supporting
|
|
140
|
+
|
|
141
|
+
# Classifies this chapter as generic infrastructure, rather than a domain built on it.
|
|
142
|
+
#
|
|
143
|
+
# @return [Symbol] `:generic`
|
|
91
144
|
def generic = @classification = :generic
|
|
92
145
|
|
|
146
|
+
# Declares an aggregate belonging to this chapter.
|
|
147
|
+
#
|
|
93
148
|
# `@chapter_named_givens` is threaded into every aggregate this
|
|
94
149
|
# chapter builds — see `AggregateBuilder#given`'s own comment
|
|
95
|
-
# for the sharing this enables;
|
|
96
|
-
# itself (an aggregate's own
|
|
150
|
+
# for the sharing this enables; not a new top-level DSL word
|
|
151
|
+
# itself (an aggregate's own existing `given` already both
|
|
97
152
|
# declares locally and write-throughs here as a side effect,
|
|
98
153
|
# the identical shape `EntityBuilder#given`'s own write-through
|
|
99
154
|
# to its owner aggregate's pool already takes — no new spelling
|
|
100
155
|
# for "declare a precondition," one level wider, same word).
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
# chapter's own top-level shape is written
|
|
104
|
-
# named in GenericDispatch::BOOTSTRAP_CALLS_FALLBACK
|
|
156
|
+
#
|
|
157
|
+
# Reached through `calls: "aggregate_impl"`, not `GenericDispatch`'s default —
|
|
158
|
+
# bootstrap-reachable (every core/attached chapter's own top-level shape is written
|
|
159
|
+
# with it), so also named in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
|
|
160
|
+
#
|
|
161
|
+
# @param name [String] the aggregate's own name
|
|
162
|
+
# @yield the aggregate body, evaluated against a new `AggregateBuilder`; may be omitted
|
|
163
|
+
# @return [Array<Bluebook::Aggregate>] every aggregate declared so far, this one last
|
|
164
|
+
# @raise [Bluebook::DSL::Malformed] if the aggregate's own body fails any check
|
|
165
|
+
# `AggregateBuilder#build` raises
|
|
105
166
|
def aggregate_impl(name, &)
|
|
106
167
|
@aggregates << AggregateBuilder.build(name, chapter_named_givens: @chapter_named_givens,
|
|
107
168
|
chapter_pending_givens: @chapter_pending_givens,
|
|
@@ -109,6 +170,8 @@ module Hecks
|
|
|
109
170
|
chapter_entity_pending_givens: @chapter_entity_pending_givens, &)
|
|
110
171
|
end
|
|
111
172
|
|
|
173
|
+
# Declares a read model belonging to this chapter.
|
|
174
|
+
#
|
|
112
175
|
# `read_model` is the word (ADR 0025 reverts `report` — the IR
|
|
113
176
|
# construct, the registry API, and the docs filename all said
|
|
114
177
|
# `read_model` the whole time; no era was ever minted under
|
|
@@ -117,30 +180,65 @@ module Hecks
|
|
|
117
180
|
# bridge) for the same reason `has_many` does — frozen era text
|
|
118
181
|
# that used it must keep booting; live source refuses it, naming
|
|
119
182
|
# the replacement.
|
|
183
|
+
#
|
|
184
|
+
# @param name [String] the read model's own name
|
|
185
|
+
# @yield the read model body, evaluated against a new `ReadModelBuilder`
|
|
186
|
+
# @return [Array<Bluebook::ReadModel>] every read model declared so far, this one last
|
|
187
|
+
# @raise [Bluebook::DSL::Malformed] if the body fails any check `ReadModelBuilder#build`
|
|
188
|
+
# raises
|
|
120
189
|
def read_model(name, &)
|
|
121
|
-
# A read model gathers heads from
|
|
190
|
+
# A read model gathers heads from several aggregates, so no single head
|
|
122
191
|
# declares it — the chapter does. Its owner is stamped in `build`, where
|
|
123
192
|
# the chapter namespace exists.
|
|
124
193
|
@read_models << ReadModelBuilder.build(name, &)
|
|
125
194
|
end
|
|
126
195
|
|
|
196
|
+
# The retired spelling of `read_model`, still answered under shadow-parsing so frozen
|
|
197
|
+
# era text keeps booting; live source refuses it and names the replacement.
|
|
198
|
+
#
|
|
199
|
+
# @param name [String] the read model's own name
|
|
200
|
+
# @yield the read model body, evaluated against a new `ReadModelBuilder`
|
|
201
|
+
# @return [Array<Bluebook::ReadModel>] every read model declared so far, this one last,
|
|
202
|
+
# under shadow-parsing
|
|
203
|
+
# @raise [Bluebook::DSL::Malformed] always, outside shadow-parsing — `report` is retired
|
|
127
204
|
def report(name, &)
|
|
128
205
|
return read_model(name, &) if MetaValidator.shadow_parsing?
|
|
129
206
|
|
|
130
207
|
raise Malformed, "report is gone — read_model is the word now"
|
|
131
208
|
end
|
|
132
209
|
|
|
210
|
+
# Declares a policy belonging to this chapter.
|
|
211
|
+
#
|
|
212
|
+
# @param name [String] the policy's own name
|
|
213
|
+
# @yield the policy body, evaluated against a new `PolicyBuilder`
|
|
214
|
+
# @return [Array<Bluebook::Policy>] every chapter-level policy declared so far,
|
|
215
|
+
# this one last
|
|
133
216
|
def policy(name, &)
|
|
134
217
|
@policies << PolicyBuilder.build(name, &)
|
|
135
218
|
end
|
|
136
219
|
|
|
220
|
+
# Declares a process manager (saga) belonging to this chapter.
|
|
221
|
+
#
|
|
222
|
+
# @param name [String] the process manager's own name
|
|
223
|
+
# @yield the process manager body, evaluated against a new `ProcessManagerBuilder`
|
|
224
|
+
# @return [Array<Bluebook::ProcessManager>] every process manager declared so far,
|
|
225
|
+
# this one last
|
|
137
226
|
def process_manager(name, &)
|
|
138
227
|
@process_managers << ProcessManagerBuilder.build(name, &)
|
|
139
228
|
end
|
|
140
229
|
|
|
230
|
+
# Assembles this builder's accumulated declarations into a judged `Chapter`.
|
|
231
|
+
#
|
|
232
|
+
# @return [Bluebook::Chapter] the built chapter, judged by the language when not
|
|
233
|
+
# deferring across a multi-file chapter
|
|
234
|
+
# @raise [Bluebook::DSL::Malformed] if a chapter-wide given reference cannot be
|
|
235
|
+
# resolved, if cross-construct validation fails, or if the language's own
|
|
236
|
+
# whole-document judgment refuses the chapter
|
|
237
|
+
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a process
|
|
238
|
+
# manager's own structural check fails
|
|
141
239
|
def build
|
|
142
240
|
# The chapter is the top of the construct chain — `Bluebook` is a
|
|
143
|
-
#
|
|
241
|
+
# root, and its constructor stamps every aggregate and read model with
|
|
144
242
|
# itself as owner, so every `hecks_fqn` below resolves by walking up
|
|
145
243
|
# to it. No constants are installed at load time : the public door is
|
|
146
244
|
# a per-boot projection, installed by `Loader.bind_runtime` once a
|
|
@@ -152,25 +250,26 @@ module Hecks
|
|
|
152
250
|
process_managers: @process_managers,
|
|
153
251
|
classification: @classification,
|
|
154
252
|
formerly_known_as: @formerly_known_as,
|
|
155
|
-
attaches_to: @attaches_to || []
|
|
253
|
+
attaches_to: @attaches_to || [],
|
|
254
|
+
provides: @provides || [])
|
|
156
255
|
|
|
157
|
-
#
|
|
256
|
+
# **Same reason, same gate** — a bare chapter-given may still be
|
|
158
257
|
# pending (see `AggregateBuilder#pending_chapter_given`) if a
|
|
159
258
|
# file that would resolve it hasn't loaded yet; resolving now
|
|
160
259
|
# would see the same incomplete `@chapter_named_givens`
|
|
161
260
|
# `validate_assembled!` below would. Deferred to
|
|
162
|
-
# `MetaValidator.judge_deferred!` the same way, and
|
|
261
|
+
# `MetaValidator.judge_deferred!` the same way, and before
|
|
163
262
|
# `validate_assembled!` there — nothing downstream should ever
|
|
164
263
|
# read an unresolved placeholder's fields.
|
|
165
264
|
resolve_pending_chapter_givens! unless MetaValidator.deferring?
|
|
166
265
|
resolve_pending_chapter_entity_givens! unless MetaValidator.deferring?
|
|
167
266
|
|
|
168
|
-
# A
|
|
169
|
-
# comment). Every check below needs the
|
|
267
|
+
# A chapter may be split across files (see `self.build`'s own
|
|
268
|
+
# comment). Every check below needs the whole chapter present —
|
|
170
269
|
# a hop, a projection, a correlation key or an event shape can
|
|
171
270
|
# equally name a construct declared in a file that has not
|
|
172
271
|
# loaded yet, and `@aggregates`/`@process_managers` here are
|
|
173
|
-
# only ever as complete as whatever has loaded
|
|
272
|
+
# only ever as complete as whatever has loaded so far. So,
|
|
174
273
|
# exactly like `MetaValidator.call` below, this is skipped
|
|
175
274
|
# while `MetaValidator.defer` is loading the chapter's files
|
|
176
275
|
# and run once instead — by `MetaValidator.judge_deferred!`,
|
|
@@ -187,17 +286,17 @@ module Hecks
|
|
|
187
286
|
MetaValidator.call(bluebook)
|
|
188
287
|
end
|
|
189
288
|
|
|
190
|
-
#
|
|
289
|
+
# The other half of a chapter-wide `given` reference —
|
|
191
290
|
# `AggregateBuilder#pending_chapter_given` recognised an
|
|
192
291
|
# unresolved bare reference and deferred it here, unable to
|
|
193
|
-
# check further: a later file in this
|
|
292
|
+
# check further: a later file in this same chapter might still
|
|
194
293
|
# declare the real thing. Runs once every file has loaded,
|
|
195
294
|
# against the now-complete `@chapter_named_givens` pool — the
|
|
196
|
-
#
|
|
295
|
+
# identical lookup `reference_named_chapter_given` already does,
|
|
197
296
|
# just late enough to see every aggregate's own declarations,
|
|
198
297
|
# not only the ones loaded before the referencing one.
|
|
199
298
|
#
|
|
200
|
-
#
|
|
299
|
+
# Mutates each placeholder `Given` in place rather than
|
|
201
300
|
# replacing it — it is already embedded, by Ruby object
|
|
202
301
|
# reference, in the referencing aggregate's own `preconditions`
|
|
203
302
|
# and in any command (same aggregate) that separately
|
|
@@ -208,6 +307,12 @@ module Hecks
|
|
|
208
307
|
# which only exists on the builder instance still open for this
|
|
209
308
|
# chapter (`MetaValidator.judge_deferred!` reaches it via
|
|
210
309
|
# `registry.bluebook_builder(name)`, guaranteed already present).
|
|
310
|
+
#
|
|
311
|
+
# @return [void]
|
|
312
|
+
# @raise [Bluebook::DSL::Malformed] if a pending reference's own `description` names no
|
|
313
|
+
# precondition any aggregate in this chapter declares, is ambiguous across several
|
|
314
|
+
# aggregates with no `declared_by:` to disambiguate, or `declared_by:` names an
|
|
315
|
+
# aggregate that does not declare it
|
|
211
316
|
def resolve_pending_chapter_givens!
|
|
212
317
|
@chapter_pending_givens.each do |entry|
|
|
213
318
|
resolved = resolve_pending_chapter_given(entry)
|
|
@@ -247,9 +352,15 @@ module Hecks
|
|
|
247
352
|
end
|
|
248
353
|
private :resolve_pending_chapter_given
|
|
249
354
|
|
|
250
|
-
#
|
|
355
|
+
# The entity-scoped analogue, one level down — see
|
|
251
356
|
# `#resolve_pending_chapter_givens!`'s own comment; identical
|
|
252
357
|
# shape, resolved against `@chapter_entity_named_givens` instead.
|
|
358
|
+
#
|
|
359
|
+
# @return [void]
|
|
360
|
+
# @raise [Bluebook::DSL::Malformed] if a pending reference's own `description` names no
|
|
361
|
+
# precondition any piece in this chapter declares, is ambiguous across several pieces
|
|
362
|
+
# with no `declared_by:` to disambiguate, or `declared_by:` names a piece that does
|
|
363
|
+
# not declare it
|
|
253
364
|
def resolve_pending_chapter_entity_givens!
|
|
254
365
|
@chapter_entity_pending_givens.each do |entry|
|
|
255
366
|
resolved = resolve_pending_chapter_entity_given(entry)
|
|
@@ -289,34 +400,55 @@ module Hecks
|
|
|
289
400
|
end
|
|
290
401
|
private :resolve_pending_chapter_entity_given
|
|
291
402
|
|
|
292
|
-
#
|
|
403
|
+
# Builds a `Chapter` from a `Hecks.bluebook "Name" do ... end` block, reusing the same
|
|
404
|
+
# open builder across several files that share one chapter name.
|
|
405
|
+
#
|
|
406
|
+
# A chapter may be declared in several files, meant to merge into one
|
|
293
407
|
# domain — `lib/hecks/language/bluebook/*.bluebook` all open
|
|
294
|
-
# `Hecks.bluebook "Bluebook" do ... end`.
|
|
295
|
-
#
|
|
296
|
-
#
|
|
408
|
+
# `Hecks.bluebook "Bluebook" do ... end`. The registry holds the builder open across
|
|
409
|
+
# calls — the first file for a name creates it, every later file for the same name
|
|
410
|
+
# reuses the same instance — rather than minting a fresh builder per call, which would
|
|
411
|
+
# let a second file with the same chapter name silently replace the first's aggregates
|
|
412
|
+
# instead of adding to them.
|
|
297
413
|
#
|
|
298
|
-
#
|
|
299
|
-
#
|
|
300
|
-
# same instance, so `@aggregates`/`@read_models` accumulate. `#build` is
|
|
301
|
-
# safe to call once per file on the same builder — it constructs a fresh
|
|
414
|
+
# `@aggregates`/`@read_models` accumulate across calls on the reused instance. `#build`
|
|
415
|
+
# is safe to call once per file on the same builder — it constructs a fresh
|
|
302
416
|
# `Bluebook` from whatever is currently held and re-`Namespace.install`s
|
|
303
|
-
# over the previous one, so the
|
|
417
|
+
# over the previous one, so the last file's call leaves every aggregate
|
|
304
418
|
# seen so far reachable, and each call's IR is a strict superset of the
|
|
305
419
|
# one before. `Registry#add_bluebook` still simply stores by name — with
|
|
306
420
|
# this in place, "last write wins" is the cumulative, correct write.
|
|
421
|
+
#
|
|
422
|
+
# @param name [String] the chapter's declared name
|
|
423
|
+
# @param version [String, nil] the chapter's pinned version, or nil for unversioned
|
|
424
|
+
# @yield the chapter's body, `instance_eval`'d against the builder, with a `const_missing`
|
|
425
|
+
# resolver installed so a bare constant resolves to a `ConstShim::ScopedConstant`
|
|
426
|
+
# @return [Bluebook::Chapter] the built, judged chapter
|
|
427
|
+
# @raise [Bluebook::DSL::Malformed] if this call's `version` conflicts with a version
|
|
428
|
+
# already adopted for this chapter name, or if the built chapter fails any check
|
|
429
|
+
# `#build` raises
|
|
430
|
+
# @raise [Bluebook::DSL::ProcessManagerBuilder::InvalidProcessManager] if a process
|
|
431
|
+
# manager's own structural check fails
|
|
307
432
|
def self.build(name, version: nil, &block)
|
|
308
433
|
registry = Hecks.current_registry
|
|
309
|
-
|
|
434
|
+
# WHICH FILE CALLED `Hecks.bluebook`, recorded for
|
|
435
|
+
# `Registry#record_bluebook_source` — two frames up: this
|
|
436
|
+
# method's own caller is `Hecks.bluebook` (hecks.rb), and ITS
|
|
437
|
+
# caller is the real `.bluebook` file's own top-level call site.
|
|
438
|
+
caller_location = caller_locations(2, 1)&.first
|
|
439
|
+
registry&.record_bluebook_source(name, caller_location&.path)
|
|
440
|
+
builder = registry ? registry.bluebook_builder(name) { new(name, version: version) } : new(name, version: version)
|
|
310
441
|
builder.__send__(:adopt_version, version)
|
|
311
|
-
# A bare constant in a bluebook — `attribute :name, PizzaName` — is a
|
|
442
|
+
# A bare constant in a bluebook — `attribute :name, PizzaName` — is a name,
|
|
312
443
|
# not a reference to something Ruby has heard of. `const_missing` hands
|
|
313
444
|
# over a `ConstShim::ScopedConstant` (S0b, const_shim.rb's own comment),
|
|
314
445
|
# and that is still the whole answer for a bare name: `Attribute` spells
|
|
315
|
-
# it with `to_s`, so the `TypeName` wrapper
|
|
316
|
-
#
|
|
446
|
+
# it with `to_s`, so the concept never needed a `TypeName` wrapper class
|
|
447
|
+
# of its own — any such wrapper would exist only long enough to be
|
|
448
|
+
# stringified. The concept still has a home — the
|
|
317
449
|
# language declares `value_object "TypeName"` — it just needed no Ruby
|
|
318
450
|
# class of its own. A Module rather than a Symbol is what also lets
|
|
319
|
-
# `Account::Debit`/`admits: Account::LedgerDirection` answer their
|
|
451
|
+
# `Account::Debit`/`admits: Account::LedgerDirection` answer their own
|
|
320
452
|
# `::` — a plain Symbol cannot.
|
|
321
453
|
resolver = ->(const) { ConstShim::ScopedConstant.for(const) }
|
|
322
454
|
ConstShim.with(resolver) { builder.instance_eval(&block) } if block
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Generated — projected from the language's own Keyword rows (the
|
|
2
|
+
# `calls:`, `resolves_via:` and `disambiguator:` columns of every
|
|
3
|
+
# KeywordSeed under lib/hecks/language/).
|
|
4
|
+
#
|
|
5
|
+
# Do not edit. spec/bootstrap_table_spec.rb re-projects this in memory
|
|
6
|
+
# and refuses a diff — run bin/project_bootstrap_table instead.
|
|
7
|
+
#
|
|
8
|
+
# Plain data, no requires: this is read while the grammar table it was
|
|
9
|
+
# projected from is still being built (`MetaValidator.bootstrapping?`).
|
|
10
|
+
|
|
11
|
+
module Hecks
|
|
12
|
+
module Bluebook
|
|
13
|
+
module DSL
|
|
14
|
+
module BootstrapTable
|
|
15
|
+
# [context, word] => the method a word's whole call forwards to.
|
|
16
|
+
CALLS = {
|
|
17
|
+
["Aggregate", "provenance"] => :provenance_impl,
|
|
18
|
+
["Aggregate", "identified_by"] => :identified_by_impl,
|
|
19
|
+
["Aggregate", "reference_to"] => :reference_to_impl,
|
|
20
|
+
["Aggregate", "has_many"] => :has_many_impl,
|
|
21
|
+
["Aggregate", "has_one"] => :has_one_impl,
|
|
22
|
+
["Aggregate", "belongs_to"] => :belongs_to_impl,
|
|
23
|
+
["Aggregate", "lifecycle"] => :lifecycle_impl,
|
|
24
|
+
["Aggregate", "entity"] => :entity_impl,
|
|
25
|
+
["Aggregate", "query"] => :query_impl,
|
|
26
|
+
["Aggregate", "policy"] => :policy_impl,
|
|
27
|
+
["Aggregate", "command"] => :command_impl,
|
|
28
|
+
["Aggregate", "attribute"] => :attribute_impl,
|
|
29
|
+
["Aggregate", "invariant"] => :invariant_impl,
|
|
30
|
+
["Aggregate", "given"] => :given_impl,
|
|
31
|
+
["Aggregate", "projects"] => :projects_impl,
|
|
32
|
+
["Lifecycle", "transition"] => :transition_impl,
|
|
33
|
+
["Bluebook", "attaches_to"] => :attaches_to_impl,
|
|
34
|
+
["Bluebook", "provides"] => :provides_impl,
|
|
35
|
+
["Bluebook", "aggregate"] => :aggregate_impl,
|
|
36
|
+
["Command", "role"] => :role_impl,
|
|
37
|
+
["Command", "provenance"] => :provenance_impl,
|
|
38
|
+
["Command", "reference_to"] => :reference_to_impl,
|
|
39
|
+
["Command", "given"] => :given_impl,
|
|
40
|
+
["Command", "sets"] => :sets_impl,
|
|
41
|
+
["Command", "then_set"] => :then_set_impl,
|
|
42
|
+
["Command", "delegates_to"] => :delegates_to_impl,
|
|
43
|
+
["Command", "attribute"] => :attribute_impl,
|
|
44
|
+
["Command", "corrects"] => :corrects_impl,
|
|
45
|
+
["Entity", "identified_by"] => :identified_by_impl,
|
|
46
|
+
["Entity", "given"] => :given_impl,
|
|
47
|
+
["Entity", "invariant"] => :invariant_impl,
|
|
48
|
+
["Entity", "command"] => :command_impl,
|
|
49
|
+
["Entity", "query"] => :query_impl,
|
|
50
|
+
["Entity", "lifecycle"] => :lifecycle_impl,
|
|
51
|
+
["Entity", "attribute"] => :attribute_impl,
|
|
52
|
+
["Entity", "reference_to"] => :reference_to_impl,
|
|
53
|
+
["Entity", "has_many"] => :has_many_impl,
|
|
54
|
+
["Entity", "has_one"] => :has_one_impl,
|
|
55
|
+
["Entity", "belongs_to"] => :belongs_to_impl,
|
|
56
|
+
["Entity", "entity"] => :entity_impl,
|
|
57
|
+
["Policy", "on"] => :on_impl,
|
|
58
|
+
["Policy", "trigger"] => :trigger_impl,
|
|
59
|
+
["Policy", "across"] => :across_impl,
|
|
60
|
+
["ProcessManager", "starts_on"] => :starts_on_impl,
|
|
61
|
+
["ProcessManager", "ends_on"] => :ends_on_impl,
|
|
62
|
+
["ProcessManager", "transition"] => :transition_impl,
|
|
63
|
+
["Handler", "dispatch"] => :dispatch_impl,
|
|
64
|
+
["Dispatch", "compensates"] => :compensates_impl,
|
|
65
|
+
["ReadModel", "reference_to"] => :reference_to_impl,
|
|
66
|
+
["ReadModel", "include"] => :include_impl,
|
|
67
|
+
["ReadModel", "group_by"] => :group_by_impl,
|
|
68
|
+
["ReadModel", "where"] => :where_impl,
|
|
69
|
+
["ReadModel", "order_by"] => :order_by_impl,
|
|
70
|
+
["ReadModel", "authorize"] => :authorize_impl,
|
|
71
|
+
["Query", "attribute"] => :attribute_impl,
|
|
72
|
+
["Query", "reference_to"] => :reference_to_impl,
|
|
73
|
+
["Query", "where"] => :where_impl,
|
|
74
|
+
["Query", "order_by"] => :order_by_impl,
|
|
75
|
+
["Query", "authorize"] => :authorize_impl,
|
|
76
|
+
["ValueObject", "attribute"] => :attribute_impl,
|
|
77
|
+
["ValueObject", "one_of"] => :one_of_impl,
|
|
78
|
+
["ValueObject", "invariant"] => :invariant_impl,
|
|
79
|
+
["ValueObject", "member"] => :member_impl,
|
|
80
|
+
["OneOf", "member"] => :member_impl,
|
|
81
|
+
["Type", "list_of"] => :list_of_impl,
|
|
82
|
+
["Type", "one_of"] => :one_of_impl,
|
|
83
|
+
["World", "realm"] => :realm_impl,
|
|
84
|
+
["World", "latest"] => :latest_impl,
|
|
85
|
+
["DomainPort", "operation"] => :tells_impl,
|
|
86
|
+
["DomainPort", "tells"] => :tells_impl,
|
|
87
|
+
["DomainPort", "asks"] => :asks_impl,
|
|
88
|
+
["Hecksagon", "port"] => :port_impl,
|
|
89
|
+
["PortOperation", "reference_to"] => :reference_to_impl,
|
|
90
|
+
["PortOperation", "attribute"] => :attribute_impl,
|
|
91
|
+
["Translation", "aggregate"] => :aggregate_impl,
|
|
92
|
+
["TranslationAggregate", "rename"] => :rename_impl,
|
|
93
|
+
["TranslationAggregate", "move"] => :move_impl,
|
|
94
|
+
["TranslationAggregate", "convert"] => :convert_impl,
|
|
95
|
+
["TranslationAggregate", "retype"] => :retype_impl,
|
|
96
|
+
["TranslationAggregate", "compute"] => :compute_impl,
|
|
97
|
+
["TranslationAggregate", "rekey"] => :rekey_impl,
|
|
98
|
+
["TranslationAggregate", "backfill"] => :backfill_impl,
|
|
99
|
+
["TranslationAggregate", "unresolved"] => :unresolved_impl,
|
|
100
|
+
["Query", "limit"] => :limit_impl,
|
|
101
|
+
["Query", "offset"] => :offset_impl,
|
|
102
|
+
["ReadModel", "limit"] => :limit_impl,
|
|
103
|
+
["ReadModel", "offset"] => :offset_impl
|
|
104
|
+
}.freeze
|
|
105
|
+
|
|
106
|
+
# [word, context] => the RuleReference primitive a bare reference resolves through.
|
|
107
|
+
RESOLVES = {
|
|
108
|
+
["given", "Aggregate"] => { resolves_via: "owner_keyed", disambiguator: "declared_by" }.freeze,
|
|
109
|
+
["given", "Command"] => { resolves_via: "hash_chain" }.freeze,
|
|
110
|
+
["given", "Entity"] => { resolves_via: "owner_keyed", disambiguator: "declared_by" }.freeze,
|
|
111
|
+
["invariant", "ValueObject"] => { resolves_via: "sibling_scan" }.freeze
|
|
112
|
+
}.freeze
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|