hecks 1.3.0 → 1.4.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 +7 -7
- data/lib/hecks/adapters/driven/d1.rb +187 -23
- data/lib/hecks/adapters/driven/folder.rb +10 -10
- data/lib/hecks/adapters/driven/google_authentication.rb +8 -8
- data/lib/hecks/adapters/driven/governance_authorization.rb +31 -13
- data/lib/hecks/adapters/driven/heki/journal.rb +5 -4
- data/lib/hecks/adapters/driven/heki/saga_store.rb +5 -5
- data/lib/hecks/adapters/driven/heki.rb +13 -7
- data/lib/hecks/adapters/driven/identity_registry.rb +2 -2
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +3 -3
- data/lib/hecks/adapters/driven/lambda/client.rb +34 -9
- data/lib/hecks/adapters/driven/lambda.rb +39 -33
- data/lib/hecks/adapters/driven/local_storage.rb +17 -10
- data/lib/hecks/adapters/driven/memory.rb +205 -9
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +1 -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 +4 -4
- 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.rb +4 -4
- data/lib/hecks/adapters/driving/github_webhook.rb +18 -18
- data/lib/hecks/behaviors/dsl.rb +2 -2
- data/lib/hecks/behaviors/expectations.rb +23 -23
- data/lib/hecks/behaviors/ir.rb +1 -1
- data/lib/hecks/behaviors/rspec.rb +1 -1
- data/lib/hecks/behaviors/runner.rb +2 -2
- data/lib/hecks/behaviors.rb +1 -1
- data/lib/hecks/bluebook/aggregate.rb +13 -13
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +10 -10
- data/lib/hecks/bluebook/assembly/build.rb +1 -1
- data/lib/hecks/bluebook/assembly/contract.rb +39 -16
- data/lib/hecks/bluebook/assembly/contracts.rb +40 -38
- data/lib/hecks/bluebook/assembly/marks.rb +18 -18
- data/lib/hecks/bluebook/assembly/specializer.rb +19 -21
- data/lib/hecks/bluebook/assembly.rb +9 -9
- data/lib/hecks/bluebook/attribute.rb +9 -9
- data/lib/hecks/bluebook/behaviour/aggregate.rb +11 -11
- data/lib/hecks/bluebook/behaviour/attribute.rb +5 -5
- data/lib/hecks/bluebook/behaviour/chapter.rb +23 -5
- data/lib/hecks/bluebook/behaviour/command.rb +23 -23
- data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -7
- data/lib/hecks/bluebook/behaviour/entity.rb +8 -8
- data/lib/hecks/bluebook/behaviour/hexagon.rb +4 -4
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +5 -5
- data/lib/hecks/bluebook/behaviour/policy.rb +12 -12
- data/lib/hecks/bluebook/behaviour/process_manager.rb +7 -7
- data/lib/hecks/bluebook/behaviour/query.rb +1 -1
- data/lib/hecks/bluebook/behaviour/read_model.rb +8 -8
- data/lib/hecks/bluebook/behaviour/traits.rb +12 -12
- data/lib/hecks/bluebook/behaviour/value_object.rb +6 -6
- data/lib/hecks/bluebook/capabilities.rb +27 -0
- data/lib/hecks/bluebook/chapter.rb +28 -9
- data/lib/hecks/bluebook/command.rb +12 -12
- data/lib/hecks/bluebook/domain_port.rb +9 -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 +96 -96
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +41 -41
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +22 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +111 -74
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +48 -30
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +103 -103
- 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 +56 -56
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +89 -30
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +17 -17
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
- data/lib/hecks/bluebook/dsl/policy_builder.rb +30 -21
- 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 +35 -35
- data/lib/hecks/bluebook/dsl/query_builder.rb +5 -5
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +34 -34
- data/lib/hecks/bluebook/dsl/rule_reference.rb +41 -39
- data/lib/hecks/bluebook/dsl/translation_builder.rb +9 -9
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +16 -16
- 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 +11 -11
- data/lib/hecks/bluebook/expression/ast_json.rb +20 -20
- data/lib/hecks/bluebook/expression/ast_reader.rb +3 -3
- data/lib/hecks/bluebook/expression/canonical_form.rb +9 -9
- data/lib/hecks/bluebook/expression/evaluator.rb +18 -18
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +18 -18
- data/lib/hecks/bluebook/expression/resolver.rb +60 -62
- data/lib/hecks/bluebook/hexagon.rb +1 -1
- data/lib/hecks/bluebook/lifecycle.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/judge.rb +101 -87
- data/lib/hecks/bluebook/meta_validator/plan.rb +39 -39
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -2
- data/lib/hecks/bluebook/meta_validator/readings.rb +43 -43
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +44 -37
- data/lib/hecks/bluebook/meta_validator/shapes.rb +25 -21
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +145 -31
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +6 -6
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +5 -5
- data/lib/hecks/bluebook/meta_validator.rb +70 -70
- data/lib/hecks/bluebook/model_check.rb +170 -84
- data/lib/hecks/bluebook/pattern_subset.rb +9 -9
- data/lib/hecks/bluebook/policy.rb +15 -13
- data/lib/hecks/bluebook/process_manager.rb +14 -14
- data/lib/hecks/bluebook/project_register.rb +6 -6
- data/lib/hecks/bluebook/query.rb +4 -4
- data/lib/hecks/bluebook/read_model.rb +14 -14
- data/lib/hecks/bluebook/reference.rb +8 -8
- data/lib/hecks/bluebook/smoke_test.rb +19 -19
- data/lib/hecks/bluebook/synthesizer.rb +12 -12
- data/lib/hecks/bluebook/translation.rb +4 -4
- data/lib/hecks/bluebook/value_object.rb +6 -6
- data/lib/hecks/bluebook.rb +2 -2
- data/lib/hecks/codemod/legacy_dispatch_args.rb +299 -0
- data/lib/hecks/codemod/legacy_dispatch_recorder.rb +186 -0
- data/lib/hecks/codemod.rb +36 -35
- data/lib/hecks/construct.rb +6 -6
- data/lib/hecks/corpus.rb +317 -0
- data/lib/hecks/deprecation.rb +95 -0
- data/lib/hecks/doc/reference.rb +19 -19
- data/lib/hecks/embryonaut_bluebook.rb +11 -11
- 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 +79 -32
- data/lib/hecks/facade/json_door.rb +106 -25
- data/lib/hecks/facade/surface/aggregate_door.rb +42 -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 +180 -19
- data/lib/hecks/forms/html.rb +51 -7
- data/lib/hecks/forms/index_renderer.rb +14 -2
- data/lib/hecks/forms/params.rb +120 -23
- data/lib/hecks/forms/port_argument.rb +2 -2
- data/lib/hecks/forms/query_form_renderer.rb +2 -2
- data/lib/hecks/forms/record_renderer.rb +2 -2
- data/lib/hecks/forms/record_table.rb +1 -1
- data/lib/hecks/forms/value_object_shape.rb +3 -3
- data/lib/hecks/forms.rb +24 -4
- data/lib/hecks/fqn.rb +1 -1
- data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
- data/lib/hecks/framework.rb +48 -17
- data/lib/hecks/freezer.rb +11 -11
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +90 -90
- data/lib/hecks/fuzzing/combination_miner.rb +119 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +140 -45
- data/lib/hecks/fuzzing/coverage_campaign.rb +118 -0
- data/lib/hecks/fuzzing/differential.rb +158 -0
- data/lib/hecks/fuzzing/domain_generator.rb +694 -0
- data/lib/hecks/fuzzing/era_boundary.rb +37 -18
- data/lib/hecks/fuzzing/form_census.rb +35 -20
- data/lib/hecks/fuzzing/generated_domain_check.rb +95 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +6 -6
- data/lib/hecks/fuzzing/isolated_boot.rb +62 -62
- data/lib/hecks/fuzzing/nondeterministic.rb +67 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +19 -21
- data/lib/hecks/fuzzing/properties/corrections.rb +9 -9
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +154 -49
- data/lib/hecks/fuzzing/properties/guards.rb +42 -42
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +32 -32
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +22 -35
- data/lib/hecks/fuzzing/properties/outbox.rb +24 -24
- data/lib/hecks/fuzzing/properties/querying.rb +17 -17
- data/lib/hecks/fuzzing/properties.rb +64 -40
- data/lib/hecks/fuzzing/qa_settings.rb +152 -0
- data/lib/hecks/fuzzing/replay.rb +114 -114
- data/lib/hecks/fuzzing/rotation_priority.rb +10 -10
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +113 -0
- data/lib/hecks/fuzzing/self_consistency.rb +141 -112
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +35 -35
- 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 +58 -31
- data/lib/hecks/fuzzing/sequence_generator.rb +111 -23
- data/lib/hecks/fuzzing/shrinker.rb +197 -0
- data/lib/hecks/fuzzing/structural_skips.rb +23 -130
- data/lib/hecks/fuzzing/sweep_depth.rb +4 -4
- data/lib/hecks/fuzzing/target_capabilities.rb +49 -18
- data/lib/hecks/fuzzing/value_generator.rb +14 -14
- data/lib/hecks/fuzzing.rb +5 -0
- data/lib/hecks/grammar/evolve.rb +10 -10
- data/lib/hecks/grammar.rb +7 -7
- data/lib/hecks/ir.rb +13 -13
- 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/oidc.json +5 -0
- data/lib/hecks/literal.rb +9 -9
- data/lib/hecks/naming.rb +25 -25
- data/lib/hecks/ports/access_control.rb +58 -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 +53 -11
- data/lib/hecks/ports/clock.rb +42 -23
- data/lib/hecks/ports/extraction.rb +16 -0
- data/lib/hecks/ports/identity_assignment.rb +24 -2
- data/lib/hecks/ports/identity_generation.rb +17 -3
- data/lib/hecks/ports/identity_resolution.rb +18 -1
- 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 +28 -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 +57 -4
- 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 +42 -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 +18 -19
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +5 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +1 -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 +3 -3
- data/lib/hecks/ports/query/ordering.rb +6 -6
- data/lib/hecks/ports/query.rb +35 -0
- data/lib/hecks/projections/bootstrap_table.rb +112 -0
- data/lib/hecks/projections/diagrams.rb +75 -75
- data/lib/hecks/projections/glossary/html.rb +3 -3
- data/lib/hecks/projections/glossary/markdown.rb +3 -3
- data/lib/hecks/projections/glossary/mermaid.rb +1 -1
- data/lib/hecks/projections/glossary/sections.rb +1 -1
- data/lib/hecks/projections/glossary/sentences.rb +5 -5
- data/lib/hecks/projections/glossary.rb +15 -15
- data/lib/hecks/projections/ir.rb +1 -1
- data/lib/hecks/projections/model/deviations.rb +18 -17
- data/lib/hecks/projections/model.rb +25 -21
- data/lib/hecks/projections/oidc.rb +7 -7
- data/lib/hecks/projections/parser_table.rb +5 -5
- data/lib/hecks/projections/reference.rb +3 -3
- data/lib/hecks/projections/rust_vocabulary.rb +443 -0
- data/lib/hecks/projections/shape.rb +2 -2
- data/lib/hecks/projections/statements.rb +11 -11
- data/lib/hecks/projections/vocabulary.rb +9 -9
- data/lib/hecks/projections.rb +5 -3
- data/lib/hecks/projector/cli_projector.rb +29 -29
- data/lib/hecks/projector/docs_projector.rb +13 -13
- data/lib/hecks/projector/exporter.rb +42 -21
- data/lib/hecks/projector/ir_projector.rb +1 -1
- data/lib/hecks/projector/narrate_projector.rb +11 -11
- data/lib/hecks/projector/target.rb +13 -13
- data/lib/hecks/projector.rb +15 -15
- data/lib/hecks/query_ir.rb +47 -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 +57 -13
- 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 +3 -3
- data/lib/hecks/router/namespace_installer.rb +3 -3
- data/lib/hecks/router.rb +1 -1
- data/lib/hecks/runtime/aggregate_lock.rb +11 -11
- data/lib/hecks/runtime/boot_gates.rb +3 -3
- data/lib/hecks/runtime/caller.rb +8 -8
- data/lib/hecks/runtime/capability_graph.rb +2 -2
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +22 -25
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +42 -63
- data/lib/hecks/runtime/command_interpreter.rb +159 -102
- data/lib/hecks/runtime/command_rules/admissibility.rb +69 -69
- data/lib/hecks/runtime/command_rules/arithmetic.rb +137 -91
- 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 +35 -35
- data/lib/hecks/runtime/command_rules.rb +3 -0
- data/lib/hecks/runtime/dependency_planning.rb +11 -11
- data/lib/hecks/runtime/dispatcher.rb +283 -90
- data/lib/hecks/runtime/entity_element.rb +151 -67
- data/lib/hecks/runtime/entity_interpreter.rb +108 -82
- data/lib/hecks/runtime/errors.rb +19 -19
- data/lib/hecks/runtime/event.rb +6 -6
- data/lib/hecks/runtime/identity.rb +22 -22
- data/lib/hecks/runtime/instance.rb +39 -14
- data/lib/hecks/runtime/interpreting.rb +12 -12
- data/lib/hecks/runtime/invocation.rb +276 -0
- data/lib/hecks/runtime/loader.rb +14 -14
- data/lib/hecks/runtime/outbox.rb +23 -23
- data/lib/hecks/runtime/policy_interpreter.rb +54 -54
- data/lib/hecks/runtime/port_operation_interpreter.rb +22 -19
- data/lib/hecks/runtime/query_interpreter.rb +55 -64
- data/lib/hecks/runtime/reaction_invocation.rb +20 -20
- data/lib/hecks/runtime/read_model_interpreter.rb +40 -40
- data/lib/hecks/runtime/rebuild_sweep.rb +4 -4
- data/lib/hecks/runtime/reference_hop.rb +6 -6
- data/lib/hecks/runtime/refusal_wording.rb +92 -115
- data/lib/hecks/runtime/registry/saga_persistence.rb +21 -21
- data/lib/hecks/runtime/registry/verification.rb +36 -26
- data/lib/hecks/runtime/registry.rb +45 -28
- data/lib/hecks/runtime/remote_dispatcher.rb +38 -23
- data/lib/hecks/runtime/routing.rb +10 -153
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +17 -17
- data/lib/hecks/runtime/saga_interpreter.rb +64 -64
- data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
- data/lib/hecks/runtime/tenant_check.rb +9 -9
- data/lib/hecks/runtime/tenant_scope.rb +5 -5
- data/lib/hecks/runtime/value/admission.rb +75 -30
- data/lib/hecks/runtime/value/coercion.rb +318 -127
- data/lib/hecks/runtime/value/entity_list_coercion.rb +34 -34
- data/lib/hecks/runtime/value.rb +21 -21
- data/lib/hecks/runtime.rb +7 -7
- data/lib/hecks/storehouse.rb +64 -64
- data/lib/hecks/version.rb +3 -3
- data/lib/hecks/vocabulary.rb +205 -4
- data/lib/hecks.rb +13 -11
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +11 -11
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +14 -12
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +11 -11
- metadata +22 -2
|
@@ -20,14 +20,12 @@ module Hecks
|
|
|
20
20
|
SIGN_TESTS = Hecks::Vocabulary.fetch("SignTest")
|
|
21
21
|
|
|
22
22
|
# Which Comparison operator each sign test is sugar for, against the
|
|
23
|
-
# literal 0 —
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
SIGN_TEST_OPERATORS =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"zero?" => "=="
|
|
30
|
-
}.freeze
|
|
23
|
+
# literal 0 — Vocabulary::SignTest's own compares_via
|
|
24
|
+
# (language/bluebook/vocabulary.bluebook), read off the generated
|
|
25
|
+
# table rather than typed a second time.
|
|
26
|
+
SIGN_TEST_OPERATORS = Hecks::Vocabulary.rows("SignTest")
|
|
27
|
+
.to_h { |row| [row["name"], row["compares_via"]] }
|
|
28
|
+
.freeze
|
|
31
29
|
|
|
32
30
|
# The leaf grammar an expression's dotted/arithmetic side parses into.
|
|
33
31
|
# Which node a string produces is a pure function of the string, so
|
|
@@ -40,7 +38,7 @@ module Hecks
|
|
|
40
38
|
StringLiteral = Struct.new(:value, keyword_init: true)
|
|
41
39
|
BoolLiteral = Struct.new(:value, keyword_init: true)
|
|
42
40
|
# `["active", "suspended"]` — a literal set, the haystack half of
|
|
43
|
-
# an `.include?`. Vocabulary::IncludeHaystack has always
|
|
41
|
+
# an `.include?`. Vocabulary::IncludeHaystack has always admitted
|
|
44
42
|
# Array (and Evaluator#includes? has always had a `when Array`
|
|
45
43
|
# arm), but nothing could produce one: there was no array-literal
|
|
46
44
|
# node, so `["a", "b"].include?(x)` fell through to Lookup and
|
|
@@ -66,18 +64,18 @@ module Hecks
|
|
|
66
64
|
Size = Struct.new(:receiver, keyword_init: true)
|
|
67
65
|
Lookup = Struct.new(:path, keyword_init: true)
|
|
68
66
|
|
|
69
|
-
#
|
|
67
|
+
# Update 2026-08-27: every "vendored addition, not (yet) upstream
|
|
70
68
|
# hecks" comment on this file's own MatchesRegex/Presence/Split/
|
|
71
69
|
# First/Last/StartsWith/EndsWith below (plus ArrayLiteral above)
|
|
72
|
-
# described a
|
|
70
|
+
# described a real gap, found the hard way, in the history each
|
|
73
71
|
# comment tells — and that history stays exactly as written,
|
|
74
|
-
# on purpose. What changed is the
|
|
72
|
+
# on purpose. What changed is the present tense claim "not (yet)
|
|
75
73
|
# upstream": a review of this exact migration found these eight
|
|
76
|
-
# symbols had working Ruby parse/interpret arms but had
|
|
74
|
+
# symbols had working Ruby parse/interpret arms but had never
|
|
77
75
|
# gone through Propose -> Render -> Admit
|
|
78
76
|
# (lib/hecks/grammar/expression_operators.json) the way every
|
|
79
77
|
# other operator here has — a closed-vocabulary guard
|
|
80
|
-
# (spec/operator_conformance_spec.rb) built entirely over
|
|
78
|
+
# (spec/operator_conformance_spec.rb) built entirely over tables
|
|
81
79
|
# structurally could not see hand-coded Struct/parse/interpret
|
|
82
80
|
# additions, so eight operators ran in Ruby, admitted nowhere,
|
|
83
81
|
# invisible to the one guard whose whole job was "reads in every
|
|
@@ -88,13 +86,13 @@ module Hecks
|
|
|
88
86
|
#
|
|
89
87
|
# `receiver.match?(/pattern/)` -- vendored addition, not (yet)
|
|
90
88
|
# upstream hecks (migration plan task 8): confirmed the
|
|
91
|
-
#
|
|
89
|
+
# single most impactful corpus-wide dispatch-time gap of the
|
|
92
90
|
# whole migration -- `.match?(regex)` appears in nearly every
|
|
93
91
|
# value_object's format-validation rule across every corpus
|
|
94
92
|
# this migration touched (email/phone/ISO-8601-timestamp/zip
|
|
95
|
-
# patterns, dozens of files), and had
|
|
93
|
+
# patterns, dozens of files), and had no parse support at all:
|
|
96
94
|
# it fell all the way through to the `Lookup` catch-all below,
|
|
97
|
-
# which tried to split the
|
|
95
|
+
# which tried to split the entire ".match?(/\A\d{5}\z/)" text
|
|
98
96
|
# on "." as if it were a dotted attribute path, and crashed with
|
|
99
97
|
# an opaque "no implicit conversion of Symbol into Integer"
|
|
100
98
|
# somewhere downstream -- confirmed live via a real dispatch,
|
|
@@ -118,13 +116,13 @@ module Hecks
|
|
|
118
116
|
Presence = Struct.new(:receiver, :negated, keyword_init: true)
|
|
119
117
|
|
|
120
118
|
# `.set?`/`.unset?` -- sibling of `.present?`/`.blank?` immediately
|
|
121
|
-
# above, added for a
|
|
119
|
+
# above, added for a deliberately narrower question, spelled out in
|
|
122
120
|
# the name so choosing between the two pairs is a choice, not a
|
|
123
121
|
# trap: `.present?` means "not EMPTY" (Rails-standard -- nil/false,
|
|
124
|
-
# and an
|
|
122
|
+
# and an empty String/Array/Hash, are blank; nothing else is),
|
|
125
123
|
# which quietly answers "was this ever assigned" and "does the
|
|
126
|
-
# assigned value happen to be empty" as the
|
|
127
|
-
# optional field whose only legitimate unset state
|
|
124
|
+
# assigned value happen to be empty" as the same question. For an
|
|
125
|
+
# optional field whose only legitimate unset state is nil, that
|
|
128
126
|
# conflation is a real trap -- confirmed live: a corpus author
|
|
129
127
|
# reaching for `superseded_by.blank?` to guard an optional
|
|
130
128
|
# reference burned real time before landing on "just don't guard
|
|
@@ -144,7 +142,7 @@ module Hecks
|
|
|
144
142
|
# `value.split("::").length == 4 && value.split("::").all? { |s|
|
|
145
143
|
# s.length > 0 }` -- `.split(` matched none of this grammar's
|
|
146
144
|
# known suffixes, so it fell through to the `Lookup` catch-all,
|
|
147
|
-
# which split the
|
|
145
|
+
# which split the raw expression text on "." (not the runtime
|
|
148
146
|
# value) and crashed with `TypeError: no implicit conversion of
|
|
149
147
|
# Symbol into Integer` the moment `String#[]` was handed a
|
|
150
148
|
# Symbol segment -- meaning every command taking a Phrase was
|
|
@@ -213,13 +211,13 @@ module Hecks
|
|
|
213
211
|
end
|
|
214
212
|
|
|
215
213
|
# A grammar's own dispatch table — one `return Node.new(...) if
|
|
216
|
-
# expr =~ /pattern/` per leaf production, in a
|
|
214
|
+
# expr =~ /pattern/` per leaf production, in a fixed precedence
|
|
217
215
|
# order (`.length` before the generic suffixes, sign tests before
|
|
218
216
|
# the rest, etc. — see this file's own history comments on why
|
|
219
217
|
# several of these were added in exactly this position). Each
|
|
220
218
|
# branch is already one line; splitting the table into smaller
|
|
221
219
|
# methods would not shrink any single check, only hide the
|
|
222
|
-
# precedence order this method's own line-by-line sequence
|
|
220
|
+
# precedence order this method's own line-by-line sequence is.
|
|
223
221
|
# rubocop:disable-next Metrics/AbcSize
|
|
224
222
|
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
225
223
|
# rubocop:disable-next Metrics/MethodLength
|
|
@@ -299,7 +297,7 @@ module Hecks
|
|
|
299
297
|
# `parse`'s own dispatch table, mirrored: one `when` per leaf node
|
|
300
298
|
# type it can produce, each already delegating to a small named
|
|
301
299
|
# helper (add, apply_sign_test, emptiness_of, ...) — the case
|
|
302
|
-
# itself
|
|
300
|
+
# itself is the closed, declared set this method exists to
|
|
303
301
|
# exhaust; the `else` backstop's own comment explains why a
|
|
304
302
|
# missing arm is a bug this method is built to make loud, not
|
|
305
303
|
# quiet.
|
|
@@ -365,8 +363,8 @@ module Hecks
|
|
|
365
363
|
|
|
366
364
|
# `.present?`/`.blank?` -- vendored addition, see the
|
|
367
365
|
# `Presence` struct's own comment above. `nil` and `false` are
|
|
368
|
-
# blank ; a String/Array/Hash is blank when
|
|
369
|
-
# falsy -- a VO-wrapped field that
|
|
366
|
+
# blank ; a String/Array/Hash is blank when empty, not merely
|
|
367
|
+
# falsy -- a VO-wrapped field that is assigned (`{value: "x"}`,
|
|
370
368
|
# `Value#to_h`'d first) is present regardless of what its own
|
|
371
369
|
# inner value holds, matching how every VO-typed field in this
|
|
372
370
|
# corpus is actually shaped once set at all.
|
|
@@ -389,7 +387,7 @@ module Hecks
|
|
|
389
387
|
# `receiver.match?(/pattern/)` -- vendored addition, see the
|
|
390
388
|
# `MatchesRegex` struct's own comment above. `receiver_value` is
|
|
391
389
|
# coerced to a plain String first -- inlined here rather than
|
|
392
|
-
# calling `Evaluator#string_of` (a
|
|
390
|
+
# calling `Evaluator#string_of` (a different module_function
|
|
393
391
|
# module; not actually in scope from inside Resolver despite
|
|
394
392
|
# `Modulo`'s own parse rule above calling a same-named
|
|
395
393
|
# `match_call` that has the identical cross-module problem --
|
|
@@ -410,7 +408,7 @@ module Hecks
|
|
|
410
408
|
Regexp.new(pattern, options).match?(text)
|
|
411
409
|
rescue RegexpError => e
|
|
412
410
|
# M9: a malformed pattern between the slashes (an unclosed
|
|
413
|
-
# character class, say) is a defect in the
|
|
411
|
+
# character class, say) is a defect in the expression text
|
|
414
412
|
# itself, exactly the same category of author mistake an
|
|
415
413
|
# unresolvable attribute name already refuses for — `Regexp.new`
|
|
416
414
|
# raising a raw `RegexpError` crossed this sublanguage's own
|
|
@@ -420,7 +418,7 @@ module Hecks
|
|
|
420
418
|
end
|
|
421
419
|
|
|
422
420
|
# The elements of a bracketed literal, or nil if this isn't one.
|
|
423
|
-
# Splits on
|
|
421
|
+
# Splits on top-level commas only — quote-aware and depth-aware,
|
|
424
422
|
# the same discipline `split_addition` already applies, so a
|
|
425
423
|
# nested array or a comma inside a string element stays whole.
|
|
426
424
|
def array_elements(expr)
|
|
@@ -455,9 +453,9 @@ module Hecks
|
|
|
455
453
|
elements.reject(&:empty?)
|
|
456
454
|
end
|
|
457
455
|
|
|
458
|
-
#
|
|
456
|
+
# Braces count toward depth, exactly as parens do — a `+` inside a
|
|
459
457
|
# block predicate's own `{ |x| ... }` body is not this expression's
|
|
460
|
-
# own addition. `parse` tries addition
|
|
458
|
+
# own addition. `parse` tries addition before `parse_block_opener`,
|
|
461
459
|
# so a paren-only depth count split
|
|
462
460
|
# kings.any? { |k| k.square.file == to.file + 1 && ... }
|
|
463
461
|
# at that inner `+`, turning the whole expression into a nonsense
|
|
@@ -483,7 +481,7 @@ module Hecks
|
|
|
483
481
|
# Phase 7 of the equivalence-gap plan): `ArrayLiteral` can
|
|
484
482
|
# appear as a general sub-expression now, not only as
|
|
485
483
|
# `.include?`'s own haystack, so an array element containing
|
|
486
|
-
# its own top-level `+` (`[0, 0 + 0]`) used to read as
|
|
484
|
+
# its own top-level `+` (`[0, 0 + 0]`) used to read as this
|
|
487
485
|
# expression's own addition split point -- the whole
|
|
488
486
|
# receiver before `.all?`/`.any?`/etc. torn in half before
|
|
489
487
|
# `parse_block_opener` ever saw it as one atomic leaf.
|
|
@@ -629,48 +627,48 @@ module Hecks
|
|
|
629
627
|
Evaluator.apply(node.operator, number, 0)
|
|
630
628
|
end
|
|
631
629
|
|
|
632
|
-
#
|
|
630
|
+
# Found live via the type-directed bounded-exhaustive expression
|
|
633
631
|
# generator (Phase 7, equivalence-gap plan — spec/
|
|
634
632
|
# bounded_exhaustive_expression_spec.rb): `.modulo(`'s own
|
|
635
633
|
# argument position accepts any numeric sub-expression, including
|
|
636
|
-
#
|
|
634
|
+
# another `.modulo(...)` call — `0.modulo(num_b.modulo(-1))` is
|
|
637
635
|
# perfectly well-typed — but `expr.rindex(marker)` finds the
|
|
638
|
-
#
|
|
639
|
-
#
|
|
640
|
-
# it found the
|
|
636
|
+
# rightmost (innermost) `.modulo(` in the whole string, not the
|
|
637
|
+
# outermost one a nested call needs split at. For that expression
|
|
638
|
+
# it found the inner `.modulo(` (inside `num_b.modulo(-1)`) and
|
|
641
639
|
# split there, producing a receiver of `"0.modulo(num_b"` and a
|
|
642
640
|
# divisor of `"-1)"` — both garbage, both re-parsed as bogus
|
|
643
641
|
# `Lookup` paths, both then refusing with "cannot resolve" — a
|
|
644
|
-
#
|
|
642
|
+
# silent misparse that happened to fail safe into a real
|
|
645
643
|
# `EvaluationError` rather than a raw crash, which is exactly why
|
|
646
644
|
# this had gone unnoticed: nothing before this generator existed
|
|
647
645
|
# ever fed `.modulo` a nested `.modulo` call, random fuzzing
|
|
648
646
|
# essentially never manufactures that specific shape by chance,
|
|
649
|
-
# and the resulting refusal
|
|
647
|
+
# and the resulting refusal looks like an ordinary, correct one
|
|
650
648
|
# unless you already know every name this generator's own
|
|
651
649
|
# synthetic state declares (real corpus authors would see this as
|
|
652
650
|
# a mysterious "cannot resolve" on text they never wrote).
|
|
653
651
|
#
|
|
654
652
|
# Fixed the same way `split_addition`/`Evaluator.top_level_index`
|
|
655
653
|
# already handle nested `(`/`{` elsewhere in this exact file:
|
|
656
|
-
# find the
|
|
657
|
-
# then track paren/quote depth from there to find
|
|
654
|
+
# find the first (leftmost, outermost) occurrence of the marker,
|
|
655
|
+
# then track paren/quote depth from there to find its own
|
|
658
656
|
# matching close — not just strip the string's own trailing `)`
|
|
659
657
|
# and hope it belongs to this call.
|
|
660
|
-
# Not just the
|
|
661
|
-
# (`x.modulo(a).modulo(b)`, the receiver of the
|
|
658
|
+
# Not just the first occurrence, either — `.modulo` also chains
|
|
659
|
+
# (`x.modulo(a).modulo(b)`, the receiver of the outer call itself
|
|
662
660
|
# ending in a `.modulo(...)` call), a second real shape the
|
|
663
661
|
# leftmost-occurrence-only version of this fix still mis-parsed:
|
|
664
662
|
# the first `.modulo(`'s own matching close paren lands mid-
|
|
665
663
|
# string (right after `a)`, before the second `.modulo(b)`), so
|
|
666
664
|
# it correctly fails the "reaches the end" check below and must
|
|
667
|
-
# be tried again at the
|
|
668
|
-
# Trying occurrences strictly left to right and taking the
|
|
665
|
+
# be tried again at the next occurrence rather than giving up.
|
|
666
|
+
# Trying occurrences strictly left to right and taking the first
|
|
669
667
|
# one whose matching close reaches the string's last character
|
|
670
|
-
# handles both shapes with the same rule: for
|
|
668
|
+
# handles both shapes with the same rule: for nesting
|
|
671
669
|
# (`.modulo(x.modulo(y))`), the leftmost (outer) occurrence's own
|
|
672
670
|
# paren-depth tracking already walks straight through the inner
|
|
673
|
-
# call to the true final `)`; for
|
|
671
|
+
# call to the true final `)`; for chaining, the leftmost
|
|
674
672
|
# occurrence's close lands short and is rejected, so the next
|
|
675
673
|
# occurrence (the true outermost call) is tried instead.
|
|
676
674
|
def match_call(expr, marker)
|
|
@@ -685,7 +683,7 @@ module Hecks
|
|
|
685
683
|
end
|
|
686
684
|
|
|
687
685
|
# `matching_brace` (resolver/block_predicates.rb)'s own twin, one
|
|
688
|
-
# bracket pair over: `start` is the index just past the
|
|
686
|
+
# bracket pair over: `start` is the index just past the opening
|
|
689
687
|
# `(` already consumed by the caller (depth starts at 1, not 0,
|
|
690
688
|
# for the same reason).
|
|
691
689
|
def matching_paren(expr, start)
|
|
@@ -709,12 +707,12 @@ module Hecks
|
|
|
709
707
|
nil
|
|
710
708
|
end
|
|
711
709
|
|
|
712
|
-
# Both operands are coerced to a real Integer/Float
|
|
713
|
-
# zero-check, and the check reads the
|
|
710
|
+
# Both operands are coerced to a real Integer/Float before the
|
|
711
|
+
# zero-check, and the check reads the coerced divisor — not the
|
|
714
712
|
# raw `divisor_value` (which might not even respond to `.zero?`,
|
|
715
713
|
# a String for instance) and not a `.to_i`-truncated stand-in for
|
|
716
714
|
# it either. The old order checked a truncated `divisor.to_i`
|
|
717
|
-
#
|
|
715
|
+
# after already validating the untruncated value wasn't zero, so
|
|
718
716
|
# a divisor merely small (`0.3`, truncating to `0`) sailed past
|
|
719
717
|
# the guard and then blew up `Integer#%` with a raw
|
|
720
718
|
# `ZeroDivisionError` the moment it reached zero anyway.
|
|
@@ -785,7 +783,7 @@ module Hecks
|
|
|
785
783
|
# from_identifier`/`Value::Coercion#fields_for`'s own single-
|
|
786
784
|
# field auto-unwrap already treats as "this VO IS its scalar"
|
|
787
785
|
# everywhere else in this runtime) came back as the `Value`
|
|
788
|
-
# wrapper itself, never unwrapped for
|
|
786
|
+
# wrapper itself, never unwrapped for reading -- so `Value#==`
|
|
789
787
|
# (which only ever equals another `Value` instance) silently
|
|
790
788
|
# refused every `guarantees "..." do status == "active" end` /
|
|
791
789
|
# `expects "..." do trash_day.present? end`-shaped bare
|
|
@@ -797,12 +795,12 @@ module Hecks
|
|
|
797
795
|
# predicate. Scoped narrowly to the single-field `{value: X}`
|
|
798
796
|
# shape only.
|
|
799
797
|
#
|
|
800
|
-
#
|
|
798
|
+
# Update 2026-08-18: originally scoped to unwrap only the bare
|
|
801
799
|
# (undotted) case, on the belief that a dotted lookup only ever
|
|
802
|
-
# reaches into a VO's
|
|
800
|
+
# reaches into a VO's own field (`field.value`, `field.sub_
|
|
803
801
|
# field`) and so should keep walking `#[]` untouched. That
|
|
804
802
|
# belief held for the single-hop case but not for the general
|
|
805
|
-
# one: a dotted lookup that
|
|
803
|
+
# one: a dotted lookup that navigates through an entity/list
|
|
806
804
|
# element to a nested field (`leg.voyage`, where `voyage` is
|
|
807
805
|
# itself a single-field VO) landed on the very same unwrapped-
|
|
808
806
|
# `Value` shape the bare case fixed, and hit the identical
|
|
@@ -810,26 +808,26 @@ module Hecks
|
|
|
810
808
|
# literal or another unwrapped VO returned false for everything,
|
|
811
809
|
# no error. The terminal value of a dotted walk deserves the
|
|
812
810
|
# same "this VO IS its scalar" treatment as a bare lookup's
|
|
813
|
-
# result; only the
|
|
811
|
+
# result; only the intermediate hops need raw `#[]` addressing
|
|
814
812
|
# to keep navigating. `unwrap_scalar` is idempotent on an
|
|
815
813
|
# already-raw scalar (a String/Integer doesn't respond to
|
|
816
814
|
# `#to_h`), so this is safe for the existing `field.value`-
|
|
817
815
|
# shaped dotted lookups too -- they already returned a raw
|
|
818
816
|
# scalar and are unaffected.
|
|
819
|
-
#
|
|
820
|
-
# the unwrap used to gate on the sole key being literally
|
|
817
|
+
# Update (single-element value objects strictly answer `.value`):
|
|
818
|
+
# the unwrap used to gate on the sole key being literally named
|
|
821
819
|
# `:value` — correct for the shorthand/closed-set shapes that
|
|
822
820
|
# motivated it, but a lie of omission for `Money{amount}` and
|
|
823
821
|
# every other single-field value object whose author picked a
|
|
824
|
-
# domain name for the field: the
|
|
822
|
+
# domain name for the field: the same "this VO IS its scalar"
|
|
825
823
|
# reading ([[feedback_name_the_scalar_field]], `Behaviour::
|
|
826
824
|
# ValueObject#sole_attribute`) applies regardless of what the
|
|
827
825
|
# sole field happens to be called, and the name gate made a bare
|
|
828
826
|
# `balance > 0` work for a `Balance{value}` while silently
|
|
829
|
-
# comparing a whole VO for a `Balance{amount}`. Now the
|
|
827
|
+
# comparing a whole VO for a `Balance{amount}`. Now the count is
|
|
830
828
|
# the gate, never the name. A declared `Runtime::Value` reads
|
|
831
829
|
# its own `sole_attribute` (the declaration's answer, not the
|
|
832
|
-
# stored hash's); any
|
|
830
|
+
# stored hash's); any other to_h-able (a Struct, a bespoke
|
|
833
831
|
# wrapper with no declaration to consult) keeps the original
|
|
834
832
|
# `{value: X}`-only unwrap, so nothing that never was a value
|
|
835
833
|
# object gains a surprise unwrapping. `rust/src/kernel/json.rs`'s
|
|
@@ -48,7 +48,7 @@ module Hecks
|
|
|
48
48
|
|
|
49
49
|
# The built form of a `.world` file, produced by `DSL::WorldBuilder` —
|
|
50
50
|
# a domain's own `realm`/`latest` version markers and its adapter bind
|
|
51
|
-
#
|
|
51
|
+
# settings (as opposed to `Hecksagon`'s own bind list, above).
|
|
52
52
|
# `Behaviour::World` supplies the settings lookups (`for_verb`/
|
|
53
53
|
# `for_binding`); this class holds only the declared data.
|
|
54
54
|
class World
|
|
@@ -3,7 +3,7 @@ require_relative "behaviour/lifecycle"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Bluebook
|
|
5
5
|
# One declared `transition` row — the state a command moves an
|
|
6
|
-
# aggregate or entity
|
|
6
|
+
# aggregate or entity to, and, when guarded, the state(s) it must
|
|
7
7
|
# currently be in (`from:`) for the transition to apply. An unguarded
|
|
8
8
|
# transition (`from: nil`) applies from any current state.
|
|
9
9
|
class StateTransition
|