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
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Bluebook
|
|
3
3
|
module MetaValidator
|
|
4
|
-
# What the language says about
|
|
4
|
+
# What the language says about itself, read back as something walkable.
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# belongs to which list is not derivable from a
|
|
9
|
-
#
|
|
10
|
-
#
|
|
6
|
+
# ## Why a plan, not a hand-written branch per category
|
|
7
|
+
#
|
|
8
|
+
# "Which append command belongs to which list is not derivable from a
|
|
9
|
+
# name" sounds like a reason to hand-write one branch per category —
|
|
10
|
+
# and is beside the point. It is derivable from the language's own IR,
|
|
11
|
+
# because every append command declares its target:
|
|
11
12
|
#
|
|
12
13
|
# command "Argument" do
|
|
13
14
|
# reference_to Command
|
|
@@ -18,13 +19,13 @@ module Hecks
|
|
|
18
19
|
# appender for the `arguments` list, and the map binds each value-object
|
|
19
20
|
# field to the command argument that fills it. Nothing is matched by name.
|
|
20
21
|
#
|
|
21
|
-
# The same reading recovers the containment tree. A command with
|
|
22
|
+
# The same reading recovers the containment tree. A command with no
|
|
22
23
|
# self-reference is the creating one, and the `*_id` argument it carries
|
|
23
24
|
# names the parent — so Bluebook -> Aggregate -> Command / ValueObject /
|
|
24
25
|
# Query / Entity, ValueObject -> Member, ProcessManager -> Handler ->
|
|
25
26
|
# Dispatch all fall out of the declarations rather than being restated here.
|
|
26
27
|
#
|
|
27
|
-
# Usage
|
|
28
|
+
# ## Usage
|
|
28
29
|
#
|
|
29
30
|
# plan = Plan.for(MetaValidator.grammar_registry)
|
|
30
31
|
# plan.category("Command").parent # => "Aggregate"
|
|
@@ -52,28 +53,48 @@ module Hecks
|
|
|
52
53
|
# Every verb this category declares, in declaration order. `alternates`
|
|
53
54
|
# matters here: two commands can append to one list, and a verb missing
|
|
54
55
|
# from this is a verb the coverage gate stops watching.
|
|
56
|
+
#
|
|
57
|
+
# @return [Array<String>] every command name this category declares
|
|
58
|
+
# (the creating command, every setter, appender, alternate
|
|
59
|
+
# appender, and sealer), `nil` entries dropped
|
|
55
60
|
def verbs
|
|
56
61
|
[declare, *setters.map(&:verb), *appends.values.map(&:verb),
|
|
57
62
|
*alternates.map(&:verb), *sealers].compact
|
|
58
63
|
end
|
|
59
64
|
|
|
60
|
-
#
|
|
65
|
+
# Does this argument carry an ID? A reference is the id of a head, and
|
|
61
66
|
# an id is a scalar — so the judge offers it bare, where every other
|
|
62
67
|
# field goes as a one-field value object. The language answers this
|
|
63
68
|
# about itself, so declaring a new reference needs no change here.
|
|
69
|
+
#
|
|
70
|
+
# @param verb [String] the command name declaring `argument`
|
|
71
|
+
# @param argument [String] the argument name to check
|
|
72
|
+
# @return [Boolean] whether `argument` on `verb` is a reference
|
|
64
73
|
def references?(verb, argument)
|
|
65
74
|
Array(references[verb.to_s]).include?(argument.to_s)
|
|
66
75
|
end
|
|
67
76
|
|
|
77
|
+
# Reports whether this category is the root of the containment
|
|
78
|
+
# tree.
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean] whether this category has no parent — the root
|
|
81
|
+
# of the containment tree
|
|
68
82
|
def root? = parent.nil?
|
|
69
83
|
end
|
|
70
84
|
|
|
85
|
+
# Reads the language's own self-description off `registry`.
|
|
86
|
+
#
|
|
87
|
+
# @param registry [Runtime::Registry] a registry with the language's
|
|
88
|
+
# own "Bluebook" chapter already judged and assembled
|
|
89
|
+
# @return [Plan] the plan, built from that chapter's own aggregates
|
|
71
90
|
def self.for(registry)
|
|
72
91
|
new(registry.bluebook("Bluebook"))
|
|
73
92
|
end
|
|
74
93
|
|
|
75
94
|
attr_reader :categories
|
|
76
95
|
|
|
96
|
+
# @param meta [Bluebook::Chapter] the language's own assembled
|
|
97
|
+
# "Bluebook" chapter
|
|
77
98
|
def initialize(meta)
|
|
78
99
|
@categories = {}
|
|
79
100
|
meta.aggregates.each do |aggregate|
|
|
@@ -84,33 +105,33 @@ module Hecks
|
|
|
84
105
|
|
|
85
106
|
@categories[aggregate.hecks_name] = read(aggregate)
|
|
86
107
|
|
|
87
|
-
# S17, ADR 0026 — Member/Handler/Dispatch are
|
|
108
|
+
# S17, ADR 0026 — Member/Handler/Dispatch are entities now
|
|
88
109
|
# (`entity "Member" do ... end`, nested under `ValueObject`/
|
|
89
110
|
# `ProcessManager`/`Handler`), not their own top-level
|
|
90
111
|
# aggregates — so `meta.aggregates` alone no longer finds
|
|
91
112
|
# them the way it always found a standalone `aggregate
|
|
92
|
-
# "Member"`. Each
|
|
113
|
+
# "Member"`. Each still needs its own named category here:
|
|
93
114
|
# `Assembly::Contracts` keeps a bespoke entry for each
|
|
94
115
|
# (Member's own open-map `pairs`, Dispatch's own open-map
|
|
95
116
|
# `with_spec`), distinct from the single generic "Entity"
|
|
96
|
-
# category every
|
|
117
|
+
# category every ordinary real-corpus entity (LedgerEntry,
|
|
97
118
|
# Withdrawal, ...) is described through instead. Safe to
|
|
98
|
-
# walk
|
|
99
|
-
# unconditionally — `Plan` only ever reads the
|
|
100
|
-
#
|
|
119
|
+
# walk every meta-domain aggregate's own `.entities`
|
|
120
|
+
# unconditionally — `Plan` only ever reads the meta-
|
|
121
|
+
# domain's own self-description (`Plan.for(MetaValidator.
|
|
101
122
|
# grammar_registry)`), which never declares a generic,
|
|
102
|
-
# nameless entity of its own the way a
|
|
123
|
+
# nameless entity of its own the way a real domain's
|
|
103
124
|
# `LedgerEntry` is; the only entities the meta-domain
|
|
104
125
|
# itself ever declares are exactly the three this ADR
|
|
105
|
-
# names. `entity_owned: true` records
|
|
126
|
+
# names. `entity_owned: true` records why this is a
|
|
106
127
|
# category at all — the real runtime has no top-level
|
|
107
|
-
# aggregate named "Member" to dispatch a
|
|
108
|
-
# any more, so the judge has to build a
|
|
128
|
+
# aggregate named "Member" to dispatch a bare verb into
|
|
129
|
+
# any more, so the judge has to build a dotted one instead
|
|
109
130
|
# (see `Judge#verb_for`).
|
|
110
131
|
#
|
|
111
|
-
#
|
|
132
|
+
# Recurses — `Dispatch` nests inside `Handler`, which nests
|
|
112
133
|
# inside `ProcessManager`, two levels deep, not one. Each
|
|
113
|
-
# nested entity's own `parent` names the
|
|
134
|
+
# nested entity's own `parent` names the direct owner it was
|
|
114
135
|
# actually found under (Dispatch's is "Handler", not
|
|
115
136
|
# "ProcessManager") — `read`'s own `owner:` argument already
|
|
116
137
|
# takes whichever name is passed, so walking one level deeper
|
|
@@ -121,20 +142,34 @@ module Hecks
|
|
|
121
142
|
@categories.freeze
|
|
122
143
|
end
|
|
123
144
|
|
|
145
|
+
# Looks up one category by name.
|
|
146
|
+
#
|
|
147
|
+
# @param name [String, Symbol] the category name, such as
|
|
148
|
+
# `"Command"` or `"ValueObject"`
|
|
149
|
+
# @return [Category, nil] the named category, or `nil` if the
|
|
150
|
+
# language declares no such category
|
|
124
151
|
def category(name) = @categories[name.to_s]
|
|
152
|
+
|
|
153
|
+
# Lists every category this plan holds.
|
|
154
|
+
#
|
|
155
|
+
# @return [Array<String>] every category name this plan holds
|
|
125
156
|
def names = @categories.keys
|
|
126
157
|
|
|
127
158
|
# Every verb the language declares, spelled as the judge would
|
|
128
|
-
# dispatch it. S17, ADR 0026 — an
|
|
159
|
+
# dispatch it. S17, ADR 0026 — an entity-owned category (its
|
|
129
160
|
# own `entity_owned` flag) has no real top-level aggregate the
|
|
130
|
-
# runtime can route a
|
|
131
|
-
# spelled
|
|
161
|
+
# runtime can route a bare verb into any more, so it is
|
|
162
|
+
# spelled dotted here too — `Bluebook::ValueObject.Member.
|
|
132
163
|
# Declare`, `Bluebook::ProcessManager.Handler.Dispatch.Bind` —
|
|
133
164
|
# matching `Judge#verb_for`/`#dotted_prefix`'s own build
|
|
134
165
|
# exactly (recursing the same way, for the same reason: an
|
|
135
166
|
# entity-owned category's own parent may itself be entity-
|
|
136
167
|
# owned), so this stays what it already is: the judge's own
|
|
137
168
|
# coverage promise, not a second guess at it.
|
|
169
|
+
#
|
|
170
|
+
# @return [Array<String>] every verb the language declares, dotted
|
|
171
|
+
# and prefixed with `"Bluebook::"`, such as `"Bluebook::Aggregate.
|
|
172
|
+
# Command.Argument"`
|
|
138
173
|
def verbs
|
|
139
174
|
@categories.flat_map do |name, category|
|
|
140
175
|
category.verbs.map { |verb| "Bluebook::#{dotted_prefix(name)}.#{verb}" }
|
|
@@ -147,8 +182,8 @@ module Hecks
|
|
|
147
182
|
# found entity's own `.entities` in turn — S17, ADR 0026's
|
|
148
183
|
# two-level chain (`Dispatch`, inside `Handler`, inside
|
|
149
184
|
# `ProcessManager`). `owner` is passed down explicitly rather
|
|
150
|
-
# than re-derived, because it names whichever construct
|
|
151
|
-
# call actually found the entity under — the
|
|
185
|
+
# than re-derived, because it names whichever construct this
|
|
186
|
+
# call actually found the entity under — the direct parent, not
|
|
152
187
|
# the root.
|
|
153
188
|
def add_nested_entities(owner)
|
|
154
189
|
owner.entities.each do |entity|
|
|
@@ -159,9 +194,9 @@ module Hecks
|
|
|
159
194
|
end
|
|
160
195
|
end
|
|
161
196
|
|
|
162
|
-
#
|
|
197
|
+
# The full dotted prefix a category's own verbs hang off —
|
|
163
198
|
# mirrors `Judge#dotted_prefix` exactly (S17, ADR 0026): the
|
|
164
|
-
# plain name for an ordinary category, or its
|
|
199
|
+
# plain name for an ordinary category, or its parent's own
|
|
165
200
|
# prefix with this category's name appended, for an entity-
|
|
166
201
|
# owned one, recursing because the parent may itself be
|
|
167
202
|
# entity-owned.
|
|
@@ -172,28 +207,28 @@ module Hecks
|
|
|
172
207
|
"#{dotted_prefix(found.parent)}.#{name}"
|
|
173
208
|
end
|
|
174
209
|
|
|
175
|
-
# `owner:`/`entity_owned:` — S17, ADR 0026. An
|
|
210
|
+
# `owner:`/`entity_owned:` — S17, ADR 0026. An aggregate-level
|
|
176
211
|
# creating command carries its own parent as a `reference_to`
|
|
177
212
|
# argument (read via `parent_reference_of` below), the same
|
|
178
|
-
# way it always has. An
|
|
213
|
+
# way it always has. An entity-level one never does — `entity
|
|
179
214
|
# "Member" do ... end`'s own creating command reaches its
|
|
180
|
-
# parent through the
|
|
215
|
+
# parent through the dotted call itself (`ValueObject.Member.
|
|
181
216
|
# Declare`), the same reason an ordinary entity's own commands
|
|
182
217
|
# never declare `reference_to` either (entity.md's own
|
|
183
|
-
# reference page states this). So the
|
|
218
|
+
# reference page states this). So the owning aggregate's name
|
|
184
219
|
# is passed in directly here, by the caller who already knows
|
|
185
220
|
# it (the same `.entities` walk that found this node), rather
|
|
186
221
|
# than derived from an argument that was never going to be
|
|
187
222
|
# there.
|
|
188
223
|
def read(aggregate, owner: nil, entity_owned: false)
|
|
189
|
-
# An
|
|
224
|
+
# An entity-owned category has no creating command of its own to find.
|
|
190
225
|
# `creating_command` tests `command.references.nil?` — the same test
|
|
191
|
-
# a
|
|
226
|
+
# a real entity's own commands pass too, since `entity "Member" do
|
|
192
227
|
# command "Pair" ... end end` never writes `reference_to` (an
|
|
193
228
|
# entity's commands never do — banking's own LedgerEntry.Amend
|
|
194
229
|
# doesn't either). Calling it here would have it seize on Member's
|
|
195
|
-
# own "Pair" and call
|
|
196
|
-
# a Member is created by `ValueObject.Member`, its
|
|
230
|
+
# own "Pair" and call that the creating command, which it is not:
|
|
231
|
+
# a Member is created by `ValueObject.Member`, its owner's own bare
|
|
197
232
|
# append command, the same way a real LedgerEntry is created by
|
|
198
233
|
# `Account.LogEntry`, never by a dotted verb of its own.
|
|
199
234
|
declare = entity_owned ? nil : declaration_command(aggregate)
|
|
@@ -211,15 +246,15 @@ module Hecks
|
|
|
211
246
|
alternates: alternates_in(rest),
|
|
212
247
|
setters: setters_in(rest),
|
|
213
248
|
sealers: sealers_in(rest),
|
|
214
|
-
#
|
|
249
|
+
# Every command, not `rest` — the creating command carries the parent
|
|
215
250
|
# link, which is the most common reference of all.
|
|
216
251
|
references: references_in(aggregate.commands),
|
|
217
|
-
#
|
|
218
|
-
# than restated. The judge has to know a record's id
|
|
252
|
+
# How the category names its records, read from the language rather
|
|
253
|
+
# than restated. The judge has to know a record's id before it
|
|
219
254
|
# dispatches, because the children it walks next carry it as their
|
|
220
255
|
# parent — so it derives the same join the runtime will, off the same
|
|
221
|
-
# declaration
|
|
222
|
-
#
|
|
256
|
+
# declaration: a hand-written branch per category, disagreeing with
|
|
257
|
+
# the runtime by even one separator, would be a broken reference.
|
|
223
258
|
identity_paths: aggregate.identity_paths,
|
|
224
259
|
entity_owned: entity_owned
|
|
225
260
|
)
|
|
@@ -261,7 +296,7 @@ module Hecks
|
|
|
261
296
|
aggregate.attributes.find(&:reference?)
|
|
262
297
|
end
|
|
263
298
|
|
|
264
|
-
# What the creating command sets directly.
|
|
299
|
+
# What the creating command sets directly. Every reference
|
|
265
300
|
# argument is dropped, not just the parent link: a reference is
|
|
266
301
|
# not a field. Command.Declare carries `entity_id` as well as
|
|
267
302
|
# the parent `aggregate` reference, because an entity declares
|
|
@@ -279,7 +314,7 @@ module Hecks
|
|
|
279
314
|
Array(command.mutations).each do |mutation|
|
|
280
315
|
next unless mutation.op == :append
|
|
281
316
|
|
|
282
|
-
#
|
|
317
|
+
# First wins, not last. Two commands can append to the same list —
|
|
283
318
|
# Aggregate.Attribute and Aggregate.Reference both extend `attributes`,
|
|
284
319
|
# because a reference's type is not a value object and cannot go
|
|
285
320
|
# through the same verb. Overwriting would have let the one declared
|
|
@@ -290,7 +325,7 @@ module Hecks
|
|
|
290
325
|
end
|
|
291
326
|
end
|
|
292
327
|
|
|
293
|
-
# The appenders
|
|
328
|
+
# The appenders displaced by first-wins — Aggregate.Reference behind
|
|
294
329
|
# Aggregate.Attribute. The walk reaches them by reading the row, not the
|
|
295
330
|
# plan, but they are still verbs the language declares and the coverage
|
|
296
331
|
# gate has to see them.
|
|
@@ -311,7 +346,7 @@ module Hecks
|
|
|
311
346
|
end
|
|
312
347
|
end
|
|
313
348
|
|
|
314
|
-
# Commands that
|
|
349
|
+
# Commands that set rather than append. Lifecycle sets two targets at once,
|
|
315
350
|
# so a setter is keyed by its verb and carries every target it writes.
|
|
316
351
|
def setters_in(commands)
|
|
317
352
|
commands.filter_map do |command|
|
|
@@ -324,7 +359,7 @@ module Hecks
|
|
|
324
359
|
end
|
|
325
360
|
end
|
|
326
361
|
|
|
327
|
-
# Commands that change nothing — they exist to be
|
|
362
|
+
# Commands that change nothing — they exist to be refused. Aggregate.Seal is
|
|
328
363
|
# the whole-document check: dispatched once everything is declared, carrying
|
|
329
364
|
# only givens. A category with no sealer simply has no such rule.
|
|
330
365
|
def sealers_in(commands)
|
|
@@ -3,7 +3,7 @@ module Hecks
|
|
|
3
3
|
module MetaValidator
|
|
4
4
|
# Offers a built .port to the language that describes ports.
|
|
5
5
|
#
|
|
6
|
-
# A port is a
|
|
6
|
+
# A port is a sibling of a bluebook, the same shape WorldJudge already
|
|
7
7
|
# is one level over — its own file, its own door, judged through its
|
|
8
8
|
# own self-hosted language (port.bluebook) rather than left as a plain
|
|
9
9
|
# Ruby struct nothing checks. Whole-project table-unification survey,
|
|
@@ -11,6 +11,7 @@ module Hecks
|
|
|
11
11
|
class PortJudge
|
|
12
12
|
attr_reader :refusals
|
|
13
13
|
|
|
14
|
+
# @param port [Bluebook::Port] the built port to judge
|
|
14
15
|
def initialize(port)
|
|
15
16
|
@port = port
|
|
16
17
|
@refusals = []
|
|
@@ -34,7 +35,7 @@ module Hecks
|
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def send_to(verb, label, **payload)
|
|
37
|
-
offer(label) { @runtime.
|
|
38
|
+
offer(label) { @runtime.dispatch_flat(verb, args(payload)) }
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def judge!
|