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
data/lib/hecks/runtime/outbox.rb
CHANGED
|
@@ -6,25 +6,27 @@ require_relative "../naming"
|
|
|
6
6
|
|
|
7
7
|
module Hecks
|
|
8
8
|
module Runtime
|
|
9
|
-
#
|
|
9
|
+
# **The transactional outbox** — the durable hand-off between "a command
|
|
10
10
|
# committed" and "everything that was owed because it committed":
|
|
11
11
|
# the policies that react to its events, the process managers that
|
|
12
12
|
# advance on them, and (through a policy whose trigger is an
|
|
13
13
|
# outbound port operation) the external effects those reactions
|
|
14
14
|
# cause. `future-features.md` item 8, built.
|
|
15
15
|
#
|
|
16
|
-
#
|
|
16
|
+
# ## The shape
|
|
17
|
+
#
|
|
18
|
+
# One row per (event, consumer). A consumer is a named
|
|
17
19
|
# policy or process manager that would react to the event — resolved
|
|
18
|
-
# at
|
|
19
|
-
#
|
|
20
|
+
# at enqueue time from the registry (`Fanout`), so the outbox records
|
|
21
|
+
# who was owed what, not just that an event happened. Rows move
|
|
20
22
|
# `pending → claimed → delivered | failed`:
|
|
21
23
|
#
|
|
22
|
-
# pending written in the
|
|
24
|
+
# pending written in the same adapter transaction as the
|
|
23
25
|
# aggregate save (`Interpreting#run_dispatch_order`
|
|
24
26
|
# wraps `save` + `emit` + enqueue in `repository.
|
|
25
27
|
# transaction`), so a row exists iff the state change
|
|
26
28
|
# it reacts to committed — never one without the other.
|
|
27
|
-
# claimed the relay is about to run this consumer. Set
|
|
29
|
+
# claimed the relay is about to run this consumer. Set before
|
|
28
30
|
# the reaction (a policy's `reenter`, a saga leg's
|
|
29
31
|
# dispatch, an adapter call) runs.
|
|
30
32
|
# delivered the consumer ran to completion — including the
|
|
@@ -33,31 +35,37 @@ module Hecks
|
|
|
33
35
|
# tracks delivery, not the domain's answer.
|
|
34
36
|
# failed the consumer raised a defect (non-refusal error).
|
|
35
37
|
#
|
|
36
|
-
#
|
|
38
|
+
# ## Delivery is inline by default
|
|
39
|
+
#
|
|
40
|
+
# The dispatcher drains the rows it
|
|
37
41
|
# just wrote, in the same call, in the order C10.2 fixes (per event
|
|
38
42
|
# in `emits` order: that event's policy rows, then its saga rows —
|
|
39
43
|
# the emitting domain's own policies before other domains'). Nothing about the
|
|
40
44
|
# happy path is deferred or asynchronous; a caller still sees every
|
|
41
45
|
# reaction settled when `dispatch` returns. What changes is the
|
|
42
|
-
# crash window: a process that dies between
|
|
43
|
-
#
|
|
44
|
-
# `Relay#redrive!` — run at boot by `Loader.run_boot_gates!` —
|
|
46
|
+
# crash window: without a durable row, a process that dies between
|
|
47
|
+
# commit and reaction loses the reaction silently. The row survives,
|
|
48
|
+
# and `Relay#redrive!` — run at boot by `Loader.run_boot_gates!` —
|
|
45
49
|
# finds it.
|
|
46
50
|
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
51
|
+
# ## What redrive does, and deliberately doesn't
|
|
52
|
+
#
|
|
53
|
+
# A `pending` row is
|
|
54
|
+
# redriven: its consumer provably never started (claiming is the
|
|
49
55
|
# first thing delivery does), so running it now is exactly-once by
|
|
50
|
-
# construction. A `claimed` row is
|
|
56
|
+
# construction. A `claimed` row is not auto-redriven: the consumer
|
|
51
57
|
# started and the crash hid its outcome — the same reasoning
|
|
52
58
|
# `saga_pending_dispatch.rb` gives (a stalled transfer is a better
|
|
53
59
|
# defect than a double-credited one). It is surfaced loudly
|
|
54
60
|
# (`warn`, and a `stalled: true` entry in `Relay#log`) and left for
|
|
55
61
|
# `Relay#redrive!(claimed: true)` — an explicit operator decision,
|
|
56
62
|
# never a boot-time default. `delivery_id` (event uid + consumer) is
|
|
57
|
-
#
|
|
63
|
+
# unique per store, so a re-enqueue of the same fact to the same
|
|
58
64
|
# consumer is a no-op rather than a second row.
|
|
59
65
|
#
|
|
60
|
-
#
|
|
66
|
+
# ## Which adapters
|
|
67
|
+
#
|
|
68
|
+
# Memory (in-process rows — visible to specs,
|
|
61
69
|
# gone with the process, exactly like everything else Memory holds),
|
|
62
70
|
# Sqlite and Postgres (a `hecks_outbox` table in the aggregate's own
|
|
63
71
|
# database — the only way the enqueue can share the save's
|
|
@@ -71,13 +79,30 @@ module Hecks
|
|
|
71
79
|
|
|
72
80
|
Row = Struct.new(:id, :delivery_id, :event_uid, :aggregate, :domain, :kind, :consumer, :event,
|
|
73
81
|
:status, :attempts, :error, keyword_init: true) do
|
|
82
|
+
# Reports whether this row is still waiting to be claimed.
|
|
83
|
+
#
|
|
84
|
+
# @return [Boolean] true if this row's status is `"pending"`
|
|
74
85
|
def pending? = status == "pending"
|
|
86
|
+
|
|
87
|
+
# Reports whether this row's consumer is currently running.
|
|
88
|
+
#
|
|
89
|
+
# @return [Boolean] true if this row's status is `"claimed"`
|
|
75
90
|
def claimed? = status == "claimed"
|
|
91
|
+
|
|
92
|
+
# Reports whether this row's consumer ran to completion.
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean] true if this row's status is `"delivered"`
|
|
76
95
|
def delivered? = status == "delivered"
|
|
96
|
+
|
|
97
|
+
# Reports whether this row's consumer raised a defect.
|
|
98
|
+
#
|
|
99
|
+
# @return [Boolean] true if this row's status is `"failed"`
|
|
77
100
|
def failed? = status == "failed"
|
|
78
101
|
|
|
79
102
|
# Wire-shaped — what an adapter persists. `event` is the event's
|
|
80
103
|
# own `to_h` plus correlation; `Row.event_from` reverses it.
|
|
104
|
+
#
|
|
105
|
+
# @return [Hash{Symbol => Object}] this row's own fields, keyed by name
|
|
81
106
|
def to_h
|
|
82
107
|
{ id: id, delivery_id: delivery_id, event_uid: event_uid, aggregate: aggregate, domain: domain,
|
|
83
108
|
kind: kind, consumer: consumer, event: event, status: status, attempts: attempts, error: error }
|
|
@@ -89,18 +114,34 @@ module Hecks
|
|
|
89
114
|
|
|
90
115
|
module_function
|
|
91
116
|
|
|
117
|
+
# Renders an event as the wire-shaped Hash an outbox row's own `event`
|
|
118
|
+
# field stores.
|
|
119
|
+
#
|
|
120
|
+
# @param event [Runtime::Event] the event to serialize
|
|
121
|
+
# @return [Hash{Symbol => Object}] `event`'s own `to_h`, with `correlation`
|
|
122
|
+
# merged in
|
|
92
123
|
def serialize_event(event)
|
|
93
124
|
event.to_h.merge(correlation: event.correlation)
|
|
94
125
|
end
|
|
95
126
|
|
|
96
|
-
#
|
|
127
|
+
# The emitting domain's own bluebook first, then the rest in load
|
|
97
128
|
# order (C10.2) — the one policy ordering both `PolicyInterpreter#
|
|
98
129
|
# policies_for` and `Fanout.policies` read.
|
|
130
|
+
#
|
|
131
|
+
# @param registry [Runtime::Registry] the booted registry whose loaded
|
|
132
|
+
# bluebooks are ordered
|
|
133
|
+
# @param domain [String, Symbol] the emitting domain, sorted first
|
|
134
|
+
# @return [Array<Bluebook::Chapter>] every loaded chapter, `domain`'s own first
|
|
99
135
|
def bluebooks_home_first(registry, domain)
|
|
100
136
|
home, others = registry.bluebooks.each_value.partition { |bluebook| bluebook.name == domain }
|
|
101
137
|
home + others
|
|
102
138
|
end
|
|
103
139
|
|
|
140
|
+
# Rebuilds a frozen event from an outbox row's own stored `event` field.
|
|
141
|
+
#
|
|
142
|
+
# @param hash [Hash{String, Symbol => Object}] the wire-shaped event Hash,
|
|
143
|
+
# as `serialize_event` built it (String or Symbol keys either way)
|
|
144
|
+
# @return [Runtime::Event] the rebuilt, frozen event
|
|
104
145
|
def event_from(hash)
|
|
105
146
|
hash = hash.transform_keys(&:to_sym)
|
|
106
147
|
Event.new(
|
|
@@ -113,6 +154,12 @@ module Hecks
|
|
|
113
154
|
).emit!
|
|
114
155
|
end
|
|
115
156
|
|
|
157
|
+
# Recursively symbolizes every Hash key reachable from `value`.
|
|
158
|
+
#
|
|
159
|
+
# @param value [Object] the value to symbolize; typically a Hash or Array,
|
|
160
|
+
# possibly nested
|
|
161
|
+
# @return [Object] `value` with every Hash key (at any depth) turned into a
|
|
162
|
+
# Symbol; a non-Hash, non-Array value passes through unchanged
|
|
116
163
|
def deep_symbolize(value)
|
|
117
164
|
case value
|
|
118
165
|
when Hash then value.to_h { |k, v| [k.to_sym, deep_symbolize(v)] }
|
|
@@ -121,7 +168,7 @@ module Hecks
|
|
|
121
168
|
end
|
|
122
169
|
end
|
|
123
170
|
|
|
124
|
-
#
|
|
171
|
+
# **Who is owed what** — the same selection `PolicyInterpreter#policies_for`
|
|
125
172
|
# and `SagaInterpreter#advance` make at delivery time, made once at
|
|
126
173
|
# enqueue time so the row names its consumer. Policy rows first,
|
|
127
174
|
# then saga rows, event order preserved within each: exactly the
|
|
@@ -129,14 +176,20 @@ module Hecks
|
|
|
129
176
|
module Fanout
|
|
130
177
|
module_function
|
|
131
178
|
|
|
132
|
-
#
|
|
179
|
+
# One UID per event for this enqueue — the Event struct is
|
|
133
180
|
# frozen after `emit!`, so the uid lives on the rows rather than
|
|
134
181
|
# on it (and stays off `Event#to_h`, whose shape the golden and
|
|
135
182
|
# parity specs pin). Policy and saga rows for the same event
|
|
136
183
|
# share it, which is what makes `delivery_id` mean "this fact,
|
|
137
184
|
# this consumer".
|
|
138
|
-
#
|
|
185
|
+
# Row order is delivery order (C10.2): per event, in `emits`
|
|
139
186
|
# order — that event's policy rows, then its saga rows.
|
|
187
|
+
#
|
|
188
|
+
# @param registry [Runtime::Registry] the booted registry every candidate
|
|
189
|
+
# consumer is resolved against
|
|
190
|
+
# @param events [Array<Runtime::Event>] the just-emitted events to build rows for
|
|
191
|
+
# @param domain [String, Symbol] the emitting domain
|
|
192
|
+
# @return [Array<Runtime::Outbox::Row>] one pending row per (event, consumer)
|
|
140
193
|
def rows_for(registry, events, domain)
|
|
141
194
|
uids = events.to_h { |event| [event, SecureRandom.uuid] }
|
|
142
195
|
events.flat_map do |event|
|
|
@@ -144,6 +197,16 @@ module Hecks
|
|
|
144
197
|
end
|
|
145
198
|
end
|
|
146
199
|
|
|
200
|
+
# Builds one pending row per policy `event` triggers.
|
|
201
|
+
#
|
|
202
|
+
# @param registry [Runtime::Registry] the booted registry policies are
|
|
203
|
+
# resolved against
|
|
204
|
+
# @param event [Runtime::Event] the just-emitted event
|
|
205
|
+
# @param domain [String, Symbol] the emitting domain
|
|
206
|
+
# @param uid [String] this event's own enqueue-time UID, shared by every row
|
|
207
|
+
# built for it
|
|
208
|
+
# @return [Array<Runtime::Outbox::Row>] one pending row per matching policy,
|
|
209
|
+
# emitting domain's own bluebook first
|
|
147
210
|
def policies(registry, event, domain, uid)
|
|
148
211
|
emitting = Naming.demodulise(event.aggregate)
|
|
149
212
|
Outbox.bluebooks_home_first(registry, domain).flat_map do |bluebook|
|
|
@@ -159,6 +222,18 @@ module Hecks
|
|
|
159
222
|
end
|
|
160
223
|
end
|
|
161
224
|
|
|
225
|
+
# Builds one pending row per process manager `event` advances, in `domain`
|
|
226
|
+
# only (a saga never reacts across domains).
|
|
227
|
+
#
|
|
228
|
+
# @param registry [Runtime::Registry] the booted registry process managers
|
|
229
|
+
# are resolved against
|
|
230
|
+
# @param event [Runtime::Event] the just-emitted event
|
|
231
|
+
# @param domain [String, Symbol] the domain whose declared process managers
|
|
232
|
+
# are checked
|
|
233
|
+
# @param uid [String] this event's own enqueue-time UID, shared by every row
|
|
234
|
+
# built for it
|
|
235
|
+
# @return [Array<Runtime::Outbox::Row>] one pending row per process manager
|
|
236
|
+
# `event` starts, ends, or advances
|
|
162
237
|
def sagas(registry, event, domain, uid)
|
|
163
238
|
bluebook = registry.bluebook(domain)
|
|
164
239
|
return [] unless bluebook
|
|
@@ -170,6 +245,13 @@ module Hecks
|
|
|
170
245
|
end
|
|
171
246
|
end
|
|
172
247
|
|
|
248
|
+
# Reports whether `event` starts, ends, or advances `process_manager`.
|
|
249
|
+
#
|
|
250
|
+
# @param process_manager [Bluebook::ProcessManager] the declared process
|
|
251
|
+
# manager to check
|
|
252
|
+
# @param event [Runtime::Event] the just-emitted event
|
|
253
|
+
# @return [Boolean] true if `event` names `process_manager`'s own
|
|
254
|
+
# `starts_on`, `ends_on`, or a declared handler
|
|
173
255
|
def listens?(process_manager, event)
|
|
174
256
|
process_manager.starts_on == event.name || process_manager.ends_on == event.name ||
|
|
175
257
|
!process_manager.handler_for(event.name).nil?
|
|
@@ -179,6 +261,14 @@ module Hecks
|
|
|
179
261
|
# operation — the row is the durable record that an external
|
|
180
262
|
# call was owed, claimed right before the adapter is asked and
|
|
181
263
|
# settled right after. Everything else is a plain "reaction".
|
|
264
|
+
#
|
|
265
|
+
# @param registry [Runtime::Registry] the booted registry the trigger's own
|
|
266
|
+
# aggregate/port are resolved against
|
|
267
|
+
# @param policy [Bluebook::Policy] the policy whose trigger is classified
|
|
268
|
+
# @param home_domain [String, Symbol] the domain `policy` is declared in,
|
|
269
|
+
# used when `policy` declares no `target_domain`
|
|
270
|
+
# @return [String] `"effect"` when the trigger resolves to an outbound port
|
|
271
|
+
# operation, `"reaction"` otherwise
|
|
182
272
|
def kind_for(registry, policy, home_domain)
|
|
183
273
|
target = "#{policy.target_domain || home_domain}::#{policy.trigger_command}"
|
|
184
274
|
parsed = Naming.split_verb(target)
|
|
@@ -194,42 +284,65 @@ module Hecks
|
|
|
194
284
|
end
|
|
195
285
|
end
|
|
196
286
|
|
|
197
|
-
#
|
|
287
|
+
# **The relay** — one per `Dispatcher`. Enqueues into a repository's
|
|
198
288
|
# store, drains rows inline, and redrives what a previous process
|
|
199
289
|
# left behind.
|
|
200
290
|
class Relay
|
|
201
291
|
attr_reader :registry, :log
|
|
202
292
|
|
|
203
|
-
#
|
|
293
|
+
# Not `saga_log`/`reaction_log` — those are ported byte-for-byte
|
|
204
294
|
# by the Rust kernel (`spec/rust_conformance_spec.rb`); this is
|
|
205
295
|
# an additive, Ruby-only log, the same rule `saga_dispatch_log`
|
|
206
296
|
# and `policy_dispatch_log` already follow.
|
|
297
|
+
#
|
|
298
|
+
# @param registry [Runtime::Registry] the booted registry this relay drains
|
|
299
|
+
# rows for
|
|
207
300
|
def initialize(registry)
|
|
208
301
|
@registry = registry
|
|
209
302
|
@log = []
|
|
210
303
|
end
|
|
211
304
|
|
|
305
|
+
# Attaches the interpreters a delivered row's own consumer runs through.
|
|
306
|
+
#
|
|
212
307
|
# A Dispatcher hands over the interpreters a consumer runs
|
|
213
308
|
# through (`Dispatcher#initialize`). Until then this relay can
|
|
214
309
|
# enqueue (that needs only the registry) but not deliver — and
|
|
215
310
|
# nothing can dispatch without a dispatcher, so nothing asks it
|
|
216
|
-
# to. The registry holds
|
|
311
|
+
# to. The registry holds one relay for its lifetime; a second
|
|
217
312
|
# dispatcher fronting the same registry re-attaches, which is
|
|
218
313
|
# fine because both dispatchers share every log and store.
|
|
314
|
+
#
|
|
315
|
+
# @param policies [Runtime::PolicyInterpreter] the interpreter a `"policy:"`
|
|
316
|
+
# consumer reacts through
|
|
317
|
+
# @param sagas [Runtime::SagaInterpreter] the interpreter a `"saga:"` consumer
|
|
318
|
+
# advances through
|
|
319
|
+
# @return [Runtime::Outbox::Relay] self
|
|
219
320
|
def attach(policies:, sagas:)
|
|
220
321
|
@policies = policies
|
|
221
322
|
@sagas = sagas
|
|
222
323
|
self
|
|
223
324
|
end
|
|
224
325
|
|
|
326
|
+
# Reports whether a dispatcher has attached its interpreters.
|
|
327
|
+
#
|
|
328
|
+
# @return [Boolean] true once `attach` has run
|
|
225
329
|
def attached? = !@policies.nil?
|
|
226
330
|
|
|
227
|
-
#
|
|
331
|
+
# Writes one pending row per (event, consumer) `events` owes a reaction to.
|
|
332
|
+
#
|
|
333
|
+
# Called inside the save transaction by `Interpreting` for the
|
|
228
334
|
# command/entity paths, and outside one by `Dispatcher` for port
|
|
229
335
|
# operations (which save nothing, so there is no transaction to
|
|
230
336
|
# share). Returns the rows as stored (ids assigned), or nil when
|
|
231
337
|
# the repository has no outbox — the dispatcher then reacts
|
|
232
338
|
# directly, exactly as before.
|
|
339
|
+
#
|
|
340
|
+
# @param repository [Persistence::AppendOnly] the repository whose store the
|
|
341
|
+
# rows are enqueued into; a no-op unless it has an outbox
|
|
342
|
+
# @param events [Array<Runtime::Event>] the events this dispatch just emitted
|
|
343
|
+
# @param domain [String, Symbol] the emitting domain
|
|
344
|
+
# @return [Array<Runtime::Outbox::Row>, nil] the stored rows, `id` assigned;
|
|
345
|
+
# `nil` when `repository` has no outbox; `[]` when `events` is empty
|
|
233
346
|
def enqueue(repository, events, domain)
|
|
234
347
|
return nil unless repository.outbox?
|
|
235
348
|
return [] if events.empty?
|
|
@@ -241,9 +354,18 @@ module Hecks
|
|
|
241
354
|
|
|
242
355
|
# Drain the rows a dispatch just committed. `rows` nil means "no
|
|
243
356
|
# outbox here" — react directly, the pre-outbox path.
|
|
357
|
+
#
|
|
358
|
+
# @param rows [Array<Runtime::Outbox::Row>, nil] the just-enqueued rows to
|
|
359
|
+
# deliver; nil to react directly instead (no outbox on this repository)
|
|
360
|
+
# @param events [Array<Runtime::Event>] the events this dispatch just emitted,
|
|
361
|
+
# read when `rows` is nil
|
|
362
|
+
# @param domain [String, Symbol] the emitting domain
|
|
363
|
+
# @param repository [Persistence::AppendOnly] the repository `rows` were
|
|
364
|
+
# enqueued into
|
|
365
|
+
# @return [void]
|
|
244
366
|
def deliver(rows, events, domain, repository)
|
|
245
367
|
if rows.nil?
|
|
246
|
-
#
|
|
368
|
+
# Per event, in `emits` order — its policies, then its sagas
|
|
247
369
|
# (C10.2, docs/semantics/bluebook-semantics.md); the same
|
|
248
370
|
# order `Fanout.rows_for` lays the outbox rows in.
|
|
249
371
|
events.each do |event|
|
|
@@ -258,6 +380,11 @@ module Hecks
|
|
|
258
380
|
|
|
259
381
|
# One row: claim, run its consumer, settle. A claim that fails
|
|
260
382
|
# means another relay (or this one, re-entrantly) already has it.
|
|
383
|
+
#
|
|
384
|
+
# @param row [Runtime::Outbox::Row] the row to claim and deliver
|
|
385
|
+
# @param repository [Persistence::AppendOnly] the repository `row` is stored in
|
|
386
|
+
# @return [Boolean] true when this call claimed and delivered `row`; false
|
|
387
|
+
# when the claim failed, or the consumer raised a defect (recorded on `log`)
|
|
261
388
|
def deliver_row(row, repository)
|
|
262
389
|
return false unless repository.outbox_claim(row.id)
|
|
263
390
|
|
|
@@ -283,13 +410,24 @@ module Hecks
|
|
|
283
410
|
end
|
|
284
411
|
|
|
285
412
|
# Every row in every bound store, newest last. `status:` narrows.
|
|
413
|
+
#
|
|
414
|
+
# @param status [String, Symbol, nil] keep only rows with this status; nil
|
|
415
|
+
# for every row
|
|
416
|
+
# @return [Array<Runtime::Outbox::Row>] copies of the matching rows, across
|
|
417
|
+
# every store with an outbox
|
|
286
418
|
def rows(status: nil)
|
|
287
419
|
stores.flat_map { |repository| repository.outbox_rows(status: status) }
|
|
288
420
|
end
|
|
289
421
|
|
|
290
|
-
#
|
|
422
|
+
# Runs the boot-time reconciliation over every bound store.
|
|
423
|
+
#
|
|
424
|
+
# **Boot-time reconciliation**. Redrives `pending` rows (never
|
|
291
425
|
# claimed — safe by construction); surfaces `claimed` rows and
|
|
292
|
-
# redrives them
|
|
426
|
+
# redrives them only when told to (`claimed: true`).
|
|
427
|
+
#
|
|
428
|
+
# @param claimed [Boolean] whether to also redrive `claimed` rows (an
|
|
429
|
+
# explicit operator decision); false leaves them surfaced and untouched
|
|
430
|
+
# @return [Array<Runtime::Outbox::Row>] every row this call actually delivered
|
|
293
431
|
def redrive!(claimed: false)
|
|
294
432
|
redriven = []
|
|
295
433
|
stores.each do |repository|
|