hecks 0.2.0 → 0.3.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 +5 -5
- data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
- data/lib/hecks/adapters/driven/claude_code.rb +127 -0
- data/lib/hecks/adapters/driven/d1.adapter +12 -0
- data/lib/hecks/adapters/driven/d1.rb +403 -0
- data/lib/hecks/adapters/driven/folder.adapter +3 -0
- data/lib/hecks/adapters/driven/folder.rb +199 -0
- data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
- data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
- data/lib/hecks/adapters/driven/governance_authorization.rb +62 -0
- data/lib/hecks/adapters/driven/heki/journal.rb +51 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +0 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +38 -0
- data/lib/hecks/adapters/driven/heki.adapter +4 -0
- data/lib/hecks/adapters/driven/heki.rb +148 -0
- data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
- data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
- data/lib/hecks/adapters/driven/lambda.adapter +4 -0
- data/lib/hecks/adapters/driven/lambda.rb +131 -0
- data/lib/hecks/adapters/driven/memory.adapter +3 -0
- data/lib/hecks/adapters/driven/memory.rb +103 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
- data/lib/hecks/adapters/driven/postgres/codec.rb +80 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +168 -0
- data/lib/hecks/adapters/driven/postgres.adapter +5 -0
- data/lib/hecks/adapters/driven/postgres.rb +391 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +171 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/field_cache.rb +190 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/head_compiler.rb +429 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +166 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +286 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/resumable_backfill.rb +168 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/tail_merge.rb +163 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/transform_installer.rb +114 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage.rb +137 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +89 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +82 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +132 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +74 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +6 -0
- data/lib/hecks/adapters/driven/postgres_era.rb +671 -0
- data/lib/hecks/adapters/driven/prism.adapter +3 -0
- data/lib/hecks/adapters/driven/prism.rb +80 -0
- data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
- data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
- data/lib/hecks/adapters/driven/sqlite/codec.rb +63 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +105 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +180 -0
- data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
- data/lib/hecks/adapters/driven/sqlite.rb +285 -0
- data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
- data/lib/hecks/adapters/driven/system_clock.rb +14 -0
- data/lib/hecks/adapters/driven.rb +36 -0
- data/lib/hecks/adapters.rb +6 -0
- data/lib/hecks/behaviors/dsl.rb +96 -0
- data/lib/hecks/behaviors/expectations.rb +280 -0
- data/lib/hecks/behaviors/ir.rb +31 -0
- data/lib/hecks/behaviors/rspec.rb +42 -0
- data/lib/hecks/behaviors/runner.rb +96 -0
- data/lib/hecks/behaviors.rb +25 -0
- data/lib/hecks/bluebook/aggregate.rb +108 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
- data/lib/hecks/bluebook/assembly/build.rb +48 -0
- data/lib/hecks/bluebook/assembly/contract.rb +112 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +409 -0
- data/lib/hecks/bluebook/assembly/marks.rb +227 -0
- data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
- data/lib/hecks/bluebook/assembly.rb +78 -0
- data/lib/hecks/bluebook/attribute.rb +96 -0
- data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
- data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
- data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
- data/lib/hecks/bluebook/behaviour/command.rb +116 -0
- data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
- data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
- data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +51 -0
- data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
- data/lib/hecks/bluebook/behaviour/process_manager.rb +38 -0
- data/lib/hecks/bluebook/behaviour/query.rb +10 -0
- data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
- data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
- data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
- data/lib/hecks/bluebook/chapter.rb +68 -0
- data/lib/hecks/bluebook/command.rb +124 -0
- data/lib/hecks/bluebook/domain_port.rb +102 -0
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +906 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +327 -0
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1018 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +626 -0
- data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
- data/lib/hecks/bluebook/dsl/entity_builder.rb +305 -0
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
- data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
- data/lib/hecks/bluebook/dsl/policy_builder.rb +120 -0
- data/lib/hecks/bluebook/dsl/port_builder.rb +30 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +207 -0
- data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
- data/lib/hecks/bluebook/dsl/rule_reference.rb +172 -0
- data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
- data/lib/hecks/bluebook/dsl/word_gate.rb +221 -0
- data/lib/hecks/bluebook/dsl/world_builder.rb +77 -0
- data/lib/hecks/bluebook/dsl.rb +45 -0
- data/lib/hecks/bluebook/entity.rb +103 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +55 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +261 -0
- data/lib/hecks/bluebook/expression/projection.json +170 -0
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
- data/lib/hecks/bluebook/expression/resolver.rb +630 -0
- data/lib/hecks/bluebook/expression.rb +13 -0
- data/lib/hecks/bluebook/hexagon.rb +60 -0
- data/lib/hecks/bluebook/lifecycle.rb +42 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +559 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +47 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +350 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +312 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
- data/lib/hecks/bluebook/meta_validator.rb +452 -0
- data/lib/hecks/bluebook/model_check.rb +318 -0
- data/lib/hecks/bluebook/pattern_subset.rb +120 -0
- data/lib/hecks/bluebook/policy.rb +41 -0
- data/lib/hecks/bluebook/process_manager.rb +86 -0
- data/lib/hecks/bluebook/project_discovery.rb +30 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +82 -0
- data/lib/hecks/bluebook/query.rb +61 -0
- data/lib/hecks/bluebook/read_model.rb +109 -0
- data/lib/hecks/bluebook/reference.rb +74 -0
- data/lib/hecks/bluebook/smoke_test.rb +166 -0
- data/lib/hecks/bluebook/synthesizer.rb +95 -0
- data/lib/hecks/bluebook/translation.rb +92 -0
- data/lib/hecks/bluebook/value_object.rb +58 -0
- data/lib/hecks/bluebook.rb +74 -0
- data/lib/hecks/codemod.rb +342 -0
- data/lib/hecks/construct.rb +71 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
- data/lib/hecks/deploy/oidc.json +18 -0
- data/lib/hecks/doc/reference.rb +389 -0
- data/lib/hecks/embryonaut_bluebook.rb +75 -0
- data/lib/hecks/facade/cli_door.rb +116 -0
- data/lib/hecks/facade/cli_runner.rb +190 -0
- data/lib/hecks/facade/command_request.rb +105 -0
- data/lib/hecks/facade/handle.rb +173 -0
- data/lib/hecks/facade/json_door.rb +154 -0
- data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
- data/lib/hecks/facade/surface/chapter.rb +107 -0
- data/lib/hecks/facade/surface.rb +48 -0
- data/lib/hecks/facade.rb +44 -0
- data/lib/hecks/forms/app.rb +300 -0
- data/lib/hecks/forms/command_form_renderer.rb +113 -0
- data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
- data/lib/hecks/forms/field_renderer.rb +170 -0
- data/lib/hecks/forms/field_shape.rb +232 -0
- data/lib/hecks/forms/html.rb +53 -0
- data/lib/hecks/forms/index_renderer.rb +35 -0
- data/lib/hecks/forms/page.rb +157 -0
- data/lib/hecks/forms/params.rb +132 -0
- data/lib/hecks/forms/query_form_renderer.rb +114 -0
- data/lib/hecks/forms/record_renderer.rb +115 -0
- data/lib/hecks/forms/record_table.rb +63 -0
- data/lib/hecks/forms/reference_options.rb +30 -0
- data/lib/hecks/forms/value_object_shape.rb +46 -0
- data/lib/hecks/forms.rb +54 -0
- data/lib/hecks/fqn.rb +94 -0
- data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
- data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
- data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
- data/lib/hecks/framework/bluebook/governance.bluebook +130 -0
- data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
- data/lib/hecks/framework/oidc.json +39 -0
- data/lib/hecks/framework.rb +90 -0
- data/lib/hecks/freezer.rb +67 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +92 -0
- data/lib/hecks/fuzzing/properties.rb +1146 -0
- data/lib/hecks/fuzzing/replay.rb +635 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +54 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +185 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +130 -0
- data/lib/hecks/fuzzing/value_generator.rb +177 -0
- data/lib/hecks/fuzzing.rb +12 -0
- data/lib/hecks/grammar/evolve.rb +291 -0
- data/lib/hecks/grammar/expression.bluebook +417 -0
- data/lib/hecks/grammar/expression_operators.json +1152 -0
- data/lib/hecks/grammar/grammar.hecksagon +20 -0
- data/lib/hecks/grammar/oidc.json +69 -0
- data/lib/hecks/grammar/translation.bluebook +203 -0
- data/lib/hecks/grammar.rb +178 -0
- data/lib/hecks/ir.rb +126 -0
- data/lib/hecks/language/adapter.bluebook +116 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
- data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
- data/lib/hecks/language/bluebook/command.bluebook +437 -0
- data/lib/hecks/language/bluebook/entity.bluebook +316 -0
- data/lib/hecks/language/bluebook/policy.bluebook +172 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +264 -0
- data/lib/hecks/language/bluebook/projection.bluebook +267 -0
- data/lib/hecks/language/bluebook/query.bluebook +245 -0
- data/lib/hecks/language/bluebook/shape.bluebook +292 -0
- data/lib/hecks/language/bluebook/syntax.bluebook +447 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +364 -0
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
- data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
- data/lib/hecks/language/oidc.json +313 -0
- data/lib/hecks/language/port.bluebook +92 -0
- data/lib/hecks/language/translation/translation.bluebook +110 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
- data/lib/hecks/language/world/wiring.bluebook +62 -0
- data/lib/hecks/language/world/world.bluebook +84 -0
- data/lib/hecks/literal.rb +125 -0
- data/lib/hecks/naming.rb +121 -0
- data/lib/hecks/ports/access_control.port +4 -0
- data/lib/hecks/ports/access_control.rb +62 -0
- data/lib/hecks/ports/agent/answers.rb +104 -0
- data/lib/hecks/ports/agent.port +4 -0
- data/lib/hecks/ports/agent.rb +167 -0
- data/lib/hecks/ports/authentication.port +4 -0
- data/lib/hecks/ports/authentication.rb +50 -0
- data/lib/hecks/ports/authorization.port +4 -0
- data/lib/hecks/ports/authorization.rb +59 -0
- data/lib/hecks/ports/clock.port +4 -0
- data/lib/hecks/ports/clock.rb +62 -0
- data/lib/hecks/ports/extraction.port +4 -0
- data/lib/hecks/ports/extraction.rb +37 -0
- data/lib/hecks/ports/identity_assignment.port +4 -0
- data/lib/hecks/ports/identity_assignment.rb +45 -0
- data/lib/hecks/ports/identity_generation.port +4 -0
- data/lib/hecks/ports/identity_generation.rb +49 -0
- data/lib/hecks/ports/identity_resolution.port +4 -0
- data/lib/hecks/ports/identity_resolution.rb +40 -0
- data/lib/hecks/ports/loading.port +4 -0
- data/lib/hecks/ports/loading.rb +13 -0
- data/lib/hecks/ports/persistence/append_only.rb +102 -0
- data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
- data/lib/hecks/ports/persistence/execution.rb +18 -0
- data/lib/hecks/ports/persistence/lineage.rb +277 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
- data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
- data/lib/hecks/ports/persistence.port +4 -0
- data/lib/hecks/ports/persistence.rb +39 -0
- data/lib/hecks/ports/projection.port +4 -0
- data/lib/hecks/ports/projection.rb +76 -0
- data/lib/hecks/ports/query/in_memory.rb +60 -0
- data/lib/hecks/ports/query/ordering.rb +41 -0
- data/lib/hecks/ports/query.rb +36 -0
- data/lib/hecks/ports.rb +27 -0
- data/lib/hecks/projections/diagrams.rb +413 -0
- data/lib/hecks/projections/ir.rb +18 -0
- data/lib/hecks/projections/model/deviations.rb +98 -0
- data/lib/hecks/projections/model.rb +145 -0
- data/lib/hecks/projections/oidc.rb +110 -0
- data/lib/hecks/projections/parser_table.rb +159 -0
- data/lib/hecks/projections/reference.rb +38 -0
- data/lib/hecks/projections/shape.rb +31 -0
- data/lib/hecks/projections/statements.rb +110 -0
- data/lib/hecks/projections/vocabulary.rb +100 -0
- data/lib/hecks/projections.rb +32 -0
- data/lib/hecks/projector/cli_projector.rb +437 -0
- data/lib/hecks/projector/docs_projector.rb +321 -0
- data/lib/hecks/projector/exporter.rb +141 -0
- data/lib/hecks/projector/ir_projector.rb +18 -0
- data/lib/hecks/projector/narrate_projector.rb +243 -0
- data/lib/hecks/projector/target.rb +97 -0
- data/lib/hecks/projector.rb +186 -0
- data/lib/hecks/query_ir.rb +392 -0
- data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
- data/lib/hecks/query_specification/common/comparators.rb +25 -0
- data/lib/hecks/query_specification/common/comparison.rb +174 -0
- data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
- data/lib/hecks/query_specification/common/dsl.rb +58 -0
- data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
- data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
- data/lib/hecks/query_specification/common/null_policy.rb +80 -0
- data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
- data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
- data/lib/hecks/query_specification/common/options.rb +32 -0
- data/lib/hecks/query_specification/common/order_by.rb +9 -0
- data/lib/hecks/query_specification/common/specification.rb +10 -0
- data/lib/hecks/query_specification/common/where_clause.rb +9 -0
- data/lib/hecks/query_specification/field_path.rb +89 -0
- data/lib/hecks/query_specification/hop_path.rb +130 -0
- data/lib/hecks/query_specification/read_model/specification.rb +18 -0
- data/lib/hecks/query_specification.rb +14 -0
- data/lib/hecks/rendering.rb +48 -0
- data/lib/hecks/router/namespace_installer.rb +157 -0
- data/lib/hecks/router.rb +70 -0
- data/lib/hecks/runtime/caller.rb +50 -0
- data/lib/hecks/runtime/capability_graph.rb +44 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +248 -0
- data/lib/hecks/runtime/command_interpreter.rb +413 -0
- data/lib/hecks/runtime/command_rules/admissibility.rb +307 -0
- data/lib/hecks/runtime/command_rules/arithmetic.rb +254 -0
- data/lib/hecks/runtime/command_rules/authorization.rb +64 -0
- data/lib/hecks/runtime/command_rules/emission.rb +34 -0
- data/lib/hecks/runtime/command_rules/references.rb +181 -0
- data/lib/hecks/runtime/command_rules.rb +28 -0
- data/lib/hecks/runtime/dependency_planning.rb +231 -0
- data/lib/hecks/runtime/dispatcher.rb +286 -0
- data/lib/hecks/runtime/entity_element.rb +253 -0
- data/lib/hecks/runtime/entity_interpreter.rb +228 -0
- data/lib/hecks/runtime/era_check.rb +136 -0
- data/lib/hecks/runtime/era_guard/shape_diff.rb +128 -0
- data/lib/hecks/runtime/era_guard.rb +193 -0
- data/lib/hecks/runtime/era_tamper.rb +61 -0
- data/lib/hecks/runtime/errors.rb +100 -0
- data/lib/hecks/runtime/event.rb +51 -0
- data/lib/hecks/runtime/identity.rb +128 -0
- data/lib/hecks/runtime/instance.rb +120 -0
- data/lib/hecks/runtime/interpreting.rb +69 -0
- data/lib/hecks/runtime/loader.rb +143 -0
- data/lib/hecks/runtime/policy_interpreter.rb +366 -0
- data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
- data/lib/hecks/runtime/query_interpreter.rb +254 -0
- data/lib/hecks/runtime/reaction_invocation.rb +245 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +266 -0
- data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
- data/lib/hecks/runtime/reference_hop.rb +99 -0
- data/lib/hecks/runtime/refusal_wording.rb +124 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +70 -0
- data/lib/hecks/runtime/registry/verification.rb +158 -0
- data/lib/hecks/runtime/registry.rb +218 -0
- data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
- data/lib/hecks/runtime/routing.rb +96 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
- data/lib/hecks/runtime/saga_interpreter.rb +301 -0
- data/lib/hecks/runtime/storage_shape.rb +120 -0
- data/lib/hecks/runtime/tenant_check.rb +84 -0
- data/lib/hecks/runtime/tenant_scope.rb +55 -0
- data/lib/hecks/runtime/value/admission.rb +112 -0
- data/lib/hecks/runtime/value/coercion.rb +500 -0
- data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
- data/lib/hecks/runtime/value.rb +125 -0
- data/lib/hecks/runtime.rb +95 -0
- data/lib/hecks/translation/audit/approval_digest.rb +31 -0
- data/lib/hecks/translation/audit/layer_one.rb +37 -0
- data/lib/hecks/translation/audit/layer_two.rb +77 -0
- data/lib/hecks/translation/audit/unfed_report.rb +42 -0
- data/lib/hecks/translation/audit.rb +70 -0
- data/lib/hecks/translation/reattest.rb +72 -0
- data/lib/hecks/translation/rule_compiler.rb +120 -0
- data/lib/hecks/translation/scaffold/differ.rb +183 -0
- data/lib/hecks/translation/scaffold/renderer.rb +41 -0
- data/lib/hecks/translation/scaffold/writer.rb +28 -0
- data/lib/hecks/translation/scaffold.rb +30 -0
- data/lib/hecks/translation.rb +11 -0
- data/lib/hecks/version.rb +16 -0
- data/lib/hecks/vocabulary.rb +213 -0
- data/lib/hecks.rb +118 -6
- metadata +401 -222
- data/bin/hecks +0 -7
- data/bin/hecks-package +0 -65
- data/bin/hecks_console +0 -12
- data/bin/hecks_serverless +0 -6
- data/lib/cli/build.rb +0 -14
- data/lib/cli/command_runner.rb +0 -28
- data/lib/cli/console.rb +0 -10
- data/lib/cli/generate.rb +0 -37
- data/lib/cli/hecks-cli.rb +0 -27
- data/lib/cli/test.rb +0 -57
- data/lib/console/commands.rb +0 -8
- data/lib/console/hecks-console.rb +0 -1
- data/lib/packager/README.md +0 -0
- data/lib/packager/app_runner.rb +0 -21
- data/lib/packager/args.rb +0 -26
- data/lib/packager/compatibility/fixnum.rb +0 -6
- data/lib/packager/hecks.rb +0 -39
- data/lib/packager/query_runner.rb +0 -21
- data/lib/packager/resources/Dockerfile +0 -11
- data/lib/packager/resources/app_binary +0 -7
- data/lib/packager/resources/bundle_config +0 -3
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
- data/lib/serverless/Domain +0 -32
- data/lib/serverless/cli.rb +0 -75
- data/lib/serverless/resources/command_name.js +0 -5
- data/lib/serverless/resources/environment.js +0 -7
- data/lib/serverless/resources/handler.js.tt +0 -28
- data/lib/serverless/resources/run_binary.js +0 -22
- data/lib/serverless/resources/serverless.yml +0 -20
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module MetaValidator
|
|
4
|
+
# What the language says about ITSELF, read back as something walkable.
|
|
5
|
+
#
|
|
6
|
+
# The judge used to carry one hand-written branch per category, and the
|
|
7
|
+
# reason given for keeping it that way was that "which append command
|
|
8
|
+
# belongs to which list is not derivable from a name". True — and beside
|
|
9
|
+
# the point. It is derivable from the language's own IR, because every
|
|
10
|
+
# append command DECLARES its target:
|
|
11
|
+
#
|
|
12
|
+
# command "Argument" do
|
|
13
|
+
# reference_to Command
|
|
14
|
+
# then_set :arguments, append: { name: :name, type: :type, ... }
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# That one line says both things a walk needs: `Command.Argument` is the
|
|
18
|
+
# appender for the `arguments` list, and the map binds each value-object
|
|
19
|
+
# field to the command argument that fills it. Nothing is matched by name.
|
|
20
|
+
#
|
|
21
|
+
# The same reading recovers the containment tree. A command with NO
|
|
22
|
+
# self-reference is the creating one, and the `*_id` argument it carries
|
|
23
|
+
# names the parent — so Bluebook -> Aggregate -> Command / ValueObject /
|
|
24
|
+
# Query / Entity, ValueObject -> Member, ProcessManager -> Handler ->
|
|
25
|
+
# Dispatch all fall out of the declarations rather than being restated here.
|
|
26
|
+
#
|
|
27
|
+
# Usage:
|
|
28
|
+
#
|
|
29
|
+
# plan = Plan.for(MetaValidator.grammar_registry)
|
|
30
|
+
# plan.category("Command").parent # => "Aggregate"
|
|
31
|
+
# plan.category("Command").appends["rules"] # => Append(verb: "Rule", map: {...})
|
|
32
|
+
# plan.verbs # every Bluebook:: verb declared
|
|
33
|
+
#
|
|
34
|
+
# This reads the language. It does not read a bluebook and it dispatches
|
|
35
|
+
# nothing — that is the judge's job.
|
|
36
|
+
class Plan
|
|
37
|
+
# One append command: the verb, and the value-object-field -> argument map.
|
|
38
|
+
Append = Struct.new(:verb, :map, keyword_init: true)
|
|
39
|
+
|
|
40
|
+
# One setting command. `targets` is target -> argument ; Lifecycle sets two
|
|
41
|
+
# fields in a single command, so it is a map rather than a pair.
|
|
42
|
+
Setter = Struct.new(:verb, :targets, keyword_init: true)
|
|
43
|
+
|
|
44
|
+
Category = Struct.new(:name, :declare, :parent, :parent_key, :fields,
|
|
45
|
+
:appends, :alternates, :setters, :sealers, :references,
|
|
46
|
+
:identity_paths, :entity_owned,
|
|
47
|
+
keyword_init: true) do
|
|
48
|
+
# Every verb this category declares, in declaration order. `alternates`
|
|
49
|
+
# matters here: two commands can append to one list, and a verb missing
|
|
50
|
+
# from this is a verb the coverage gate stops watching.
|
|
51
|
+
def verbs
|
|
52
|
+
[declare, *setters.map(&:verb), *appends.values.map(&:verb),
|
|
53
|
+
*alternates.map(&:verb), *sealers].compact
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# DOES THIS ARGUMENT CARRY AN ID? A reference is the id of a head, and
|
|
57
|
+
# an id is a scalar — so the judge offers it bare, where every other
|
|
58
|
+
# field goes as a one-field value object. The language answers this
|
|
59
|
+
# about itself, so declaring a new reference needs no change here.
|
|
60
|
+
def references?(verb, argument)
|
|
61
|
+
Array(references[verb.to_s]).include?(argument.to_s)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def root? = parent.nil?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.for(registry)
|
|
68
|
+
new(registry.bluebook("Bluebook"))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
attr_reader :categories
|
|
72
|
+
|
|
73
|
+
def initialize(meta)
|
|
74
|
+
@categories = {}
|
|
75
|
+
meta.aggregates.each do |aggregate|
|
|
76
|
+
# Vocabulary declares no commands — it is static declaration read from
|
|
77
|
+
# the IR by spec/vocabulary_conformance_spec, never dispatched. It needs
|
|
78
|
+
# no special case: a category with nothing to offer contributes nothing.
|
|
79
|
+
next if aggregate.commands.empty?
|
|
80
|
+
|
|
81
|
+
@categories[aggregate.hecks_name] = read(aggregate)
|
|
82
|
+
|
|
83
|
+
# S17, ADR 0026 — Member/Handler/Dispatch are ENTITIES now
|
|
84
|
+
# (`entity "Member" do ... end`, nested under `ValueObject`/
|
|
85
|
+
# `ProcessManager`/`Handler`), not their own top-level
|
|
86
|
+
# aggregates — so `meta.aggregates` alone no longer finds
|
|
87
|
+
# them the way it always found a standalone `aggregate
|
|
88
|
+
# "Member"`. Each STILL needs its own named category here:
|
|
89
|
+
# `Assembly::Contracts` keeps a bespoke entry for each
|
|
90
|
+
# (Member's own open-map `pairs`, Dispatch's own open-map
|
|
91
|
+
# `with_spec`), distinct from the single generic "Entity"
|
|
92
|
+
# category every ORDINARY real-corpus entity (LedgerEntry,
|
|
93
|
+
# Withdrawal, ...) is described through instead. Safe to
|
|
94
|
+
# walk EVERY meta-domain aggregate's own `.entities`
|
|
95
|
+
# unconditionally — `Plan` only ever reads the META-
|
|
96
|
+
# DOMAIN'S OWN self-description (`Plan.for(MetaValidator.
|
|
97
|
+
# grammar_registry)`), which never declares a generic,
|
|
98
|
+
# nameless entity of its own the way a REAL domain's
|
|
99
|
+
# `LedgerEntry` is; the only entities the meta-domain
|
|
100
|
+
# itself ever declares are exactly the three this ADR
|
|
101
|
+
# names. `entity_owned: true` records WHY this is a
|
|
102
|
+
# category at all — the real runtime has no top-level
|
|
103
|
+
# aggregate named "Member" to dispatch a BARE verb into
|
|
104
|
+
# any more, so the judge has to build a DOTTED one instead
|
|
105
|
+
# (see `Judge#verb_for`).
|
|
106
|
+
#
|
|
107
|
+
# RECURSES — `Dispatch` nests inside `Handler`, which nests
|
|
108
|
+
# inside `ProcessManager`, two levels deep, not one. Each
|
|
109
|
+
# nested entity's own `parent` names the DIRECT owner it was
|
|
110
|
+
# actually found under (Dispatch's is "Handler", not
|
|
111
|
+
# "ProcessManager") — `read`'s own `owner:` argument already
|
|
112
|
+
# takes whichever name is passed, so walking one level deeper
|
|
113
|
+
# each recursive call is the whole change; nothing about
|
|
114
|
+
# `read` itself needed to know how deep it was called from.
|
|
115
|
+
add_nested_entities(aggregate)
|
|
116
|
+
end
|
|
117
|
+
@categories.freeze
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def category(name) = @categories[name.to_s]
|
|
121
|
+
def names = @categories.keys
|
|
122
|
+
|
|
123
|
+
# Every verb the language declares, spelled as the judge would
|
|
124
|
+
# dispatch it. S17, ADR 0026 — an ENTITY-OWNED category (its
|
|
125
|
+
# own `entity_owned` flag) has no real top-level aggregate the
|
|
126
|
+
# runtime can route a BARE verb into any more, so it is
|
|
127
|
+
# spelled DOTTED here too — `Bluebook::ValueObject.Member.
|
|
128
|
+
# Declare`, `Bluebook::ProcessManager.Handler.Dispatch.Bind` —
|
|
129
|
+
# matching `Judge#verb_for`/`#dotted_prefix`'s own build
|
|
130
|
+
# exactly (recursing the same way, for the same reason: an
|
|
131
|
+
# entity-owned category's own parent may itself be entity-
|
|
132
|
+
# owned), so this stays what it already is: the judge's own
|
|
133
|
+
# coverage promise, not a second guess at it.
|
|
134
|
+
def verbs
|
|
135
|
+
@categories.flat_map do |name, category|
|
|
136
|
+
category.verbs.map { |verb| "Bluebook::#{dotted_prefix(name)}.#{verb}" }
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
# Walks one construct's own `.entities`, recursing into each
|
|
143
|
+
# found entity's own `.entities` in turn — S17, ADR 0026's
|
|
144
|
+
# two-level chain (`Dispatch`, inside `Handler`, inside
|
|
145
|
+
# `ProcessManager`). `owner` is passed down explicitly rather
|
|
146
|
+
# than re-derived, because it names whichever construct THIS
|
|
147
|
+
# call actually found the entity under — the DIRECT parent, not
|
|
148
|
+
# the root.
|
|
149
|
+
def add_nested_entities(owner)
|
|
150
|
+
owner.entities.each do |entity|
|
|
151
|
+
next if entity.commands.empty?
|
|
152
|
+
|
|
153
|
+
@categories[entity.hecks_name] = read(entity, owner: owner.hecks_name, entity_owned: true)
|
|
154
|
+
add_nested_entities(entity)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# THE FULL DOTTED PREFIX a category's own verbs hang off —
|
|
159
|
+
# mirrors `Judge#dotted_prefix` exactly (S17, ADR 0026): the
|
|
160
|
+
# plain name for an ordinary category, or its PARENT's own
|
|
161
|
+
# prefix with this category's name appended, for an entity-
|
|
162
|
+
# owned one, recursing because the parent may itself be
|
|
163
|
+
# entity-owned.
|
|
164
|
+
def dotted_prefix(name)
|
|
165
|
+
found = category(name)
|
|
166
|
+
return name unless found&.entity_owned
|
|
167
|
+
|
|
168
|
+
"#{dotted_prefix(found.parent)}.#{name}"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# `owner:`/`entity_owned:` — S17, ADR 0026. An AGGREGATE-level
|
|
172
|
+
# creating command carries its own parent as a `reference_to`
|
|
173
|
+
# argument (read via `parent_reference_of` below), the same
|
|
174
|
+
# way it always has. An ENTITY-level one never does — `entity
|
|
175
|
+
# "Member" do ... end`'s own creating command reaches its
|
|
176
|
+
# parent through the DOTTED CALL itself (`ValueObject.Member.
|
|
177
|
+
# Declare`), the same reason an ordinary entity's own commands
|
|
178
|
+
# never declare `reference_to` either (entity.md's own
|
|
179
|
+
# reference page states this). So the OWNING aggregate's name
|
|
180
|
+
# is passed in directly here, by the caller who already knows
|
|
181
|
+
# it (the same `.entities` walk that found this node), rather
|
|
182
|
+
# than derived from an argument that was never going to be
|
|
183
|
+
# there.
|
|
184
|
+
def read(aggregate, owner: nil, entity_owned: false)
|
|
185
|
+
# An ENTITY-OWNED category has no creating command of its own to find.
|
|
186
|
+
# `creating_command` tests `command.references.nil?` — the same test
|
|
187
|
+
# a REAL entity's own commands pass too, since `entity "Member" do
|
|
188
|
+
# command "Pair" ... end end` never writes `reference_to` (an
|
|
189
|
+
# entity's commands never do — banking's own LedgerEntry.Amend
|
|
190
|
+
# doesn't either). Calling it here would have it seize on Member's
|
|
191
|
+
# own "Pair" and call THAT the creating command, which it is not:
|
|
192
|
+
# a Member is created by `ValueObject.Member`, its OWNER's own bare
|
|
193
|
+
# append command, the same way a real LedgerEntry is created by
|
|
194
|
+
# `Account.LogEntry`, never by a dotted verb of its own.
|
|
195
|
+
declare = entity_owned ? nil : declaration_command(aggregate)
|
|
196
|
+
parent = parent_relationship_of(aggregate)
|
|
197
|
+
parent_key = owner ? "aggregate" : parent&.name&.to_s
|
|
198
|
+
rest = aggregate.commands - [declare].compact
|
|
199
|
+
|
|
200
|
+
Category.new(
|
|
201
|
+
name: aggregate.hecks_name,
|
|
202
|
+
declare: declare&.hecks_name,
|
|
203
|
+
parent: owner || parent&.type&.target_name,
|
|
204
|
+
parent_key: parent_key,
|
|
205
|
+
fields: declared_fields(declare),
|
|
206
|
+
appends: appends_in(rest),
|
|
207
|
+
alternates: alternates_in(rest),
|
|
208
|
+
setters: setters_in(rest),
|
|
209
|
+
sealers: sealers_in(rest),
|
|
210
|
+
# EVERY command, not `rest` — the creating command carries the parent
|
|
211
|
+
# link, which is the most common reference of all.
|
|
212
|
+
references: references_in(aggregate.commands),
|
|
213
|
+
# HOW THE CATEGORY NAMES ITS RECORDS, read from the language rather
|
|
214
|
+
# than restated. The judge has to know a record's id BEFORE it
|
|
215
|
+
# dispatches, because the children it walks next carry it as their
|
|
216
|
+
# parent — so it derives the same join the runtime will, off the same
|
|
217
|
+
# declaration. It used to be a branch per category, and a branch that
|
|
218
|
+
# disagreed with the runtime by one separator was a broken reference.
|
|
219
|
+
identity_paths: aggregate.identity_paths,
|
|
220
|
+
entity_owned: entity_owned
|
|
221
|
+
)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Which arguments of which verbs carry an ID rather than a value, read
|
|
225
|
+
# straight from the language's own IR.
|
|
226
|
+
def references_in(commands)
|
|
227
|
+
commands.each_with_object({}) do |command, found|
|
|
228
|
+
named = command.attributes.select(&:reference?).map { |attribute| attribute.name.to_s }
|
|
229
|
+
found[command.hecks_name] = named unless named.empty?
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# The declaration command establishes the record's declared identity.
|
|
234
|
+
# Receiver references never carried that meaning; entity-owned categories
|
|
235
|
+
# prove it because every one of their commands lacks such a marker. The
|
|
236
|
+
# identity-write rule is structural and remains true after routing moves
|
|
237
|
+
# entirely into `to:`. `owner_id` is traversal context rather than stored
|
|
238
|
+
# state, so the declaration establishes every remaining identity head.
|
|
239
|
+
def declaration_command(aggregate)
|
|
240
|
+
required = aggregate.identity_heads.map(&:to_sym) - [:owner_id]
|
|
241
|
+
candidates = aggregate.commands.select do |command|
|
|
242
|
+
targets = Array(command.mutations).map { |mutation| mutation.target.to_sym }
|
|
243
|
+
required.all? { |field| targets.include?(field) }
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
return candidates.first if candidates.one?
|
|
247
|
+
|
|
248
|
+
raise DSL::Malformed,
|
|
249
|
+
"#{aggregate.hecks_name} must declare exactly one command that establishes " \
|
|
250
|
+
"its identity fields #{required.join(', ')} — found #{candidates.map(&:hecks_name).join(', ')}"
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Containment belongs to stored aggregate structure. The first declared
|
|
254
|
+
# structural relationship is the traversal parent; command arguments may
|
|
255
|
+
# carry its identity as an ordinary value object, but do not define it.
|
|
256
|
+
def parent_relationship_of(aggregate)
|
|
257
|
+
aggregate.attributes.find(&:reference?)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# What the creating command sets directly. EVERY reference
|
|
261
|
+
# argument is dropped, not just the parent link: a reference is
|
|
262
|
+
# not a field. Command.Declare carries `entity_id` as well as
|
|
263
|
+
# the parent `aggregate` reference, because an entity declares
|
|
264
|
+
# commands too, and offering either as a field would have the
|
|
265
|
+
# walk hand it a name instead of a head.
|
|
266
|
+
def declared_fields(declare)
|
|
267
|
+
return [] unless declare
|
|
268
|
+
|
|
269
|
+
declare.attributes.reject(&:reference?).map { |attribute| attribute.name.to_s }
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# list attribute -> the command that appends to it, and how its arguments map.
|
|
273
|
+
def appends_in(commands)
|
|
274
|
+
commands.each_with_object({}) do |command, found|
|
|
275
|
+
Array(command.mutations).each do |mutation|
|
|
276
|
+
next unless mutation.op == :append
|
|
277
|
+
|
|
278
|
+
# FIRST wins, not last. Two commands can append to the same list —
|
|
279
|
+
# Aggregate.Attribute and Aggregate.Reference both extend `attributes`,
|
|
280
|
+
# because a reference's type is not a value object and cannot go
|
|
281
|
+
# through the same verb. Overwriting would have let the one declared
|
|
282
|
+
# later silently displace the other, and the walk would have offered
|
|
283
|
+
# every ordinary attribute as a reference.
|
|
284
|
+
found[mutation.target.to_s] ||= Append.new(verb: command.hecks_name, map: mutation.source)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# The appenders DISPLACED by first-wins — Aggregate.Reference behind
|
|
290
|
+
# Aggregate.Attribute. The walk reaches them by reading the row, not the
|
|
291
|
+
# plan, but they are still verbs the language declares and the coverage
|
|
292
|
+
# gate has to see them.
|
|
293
|
+
def alternates_in(commands)
|
|
294
|
+
claimed = {}
|
|
295
|
+
commands.flat_map do |command|
|
|
296
|
+
Array(command.mutations).filter_map do |mutation|
|
|
297
|
+
next unless mutation.op == :append
|
|
298
|
+
|
|
299
|
+
target = mutation.target.to_s
|
|
300
|
+
if claimed[target]
|
|
301
|
+
Append.new(verb: command.hecks_name, map: mutation.source)
|
|
302
|
+
else
|
|
303
|
+
claimed[target] = true
|
|
304
|
+
nil
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Commands that SET rather than append. Lifecycle sets two targets at once,
|
|
311
|
+
# so a setter is keyed by its verb and carries every target it writes.
|
|
312
|
+
def setters_in(commands)
|
|
313
|
+
commands.filter_map do |command|
|
|
314
|
+
targets = Array(command.mutations)
|
|
315
|
+
.select { |mutation| mutation.op == :set }
|
|
316
|
+
.to_h { |mutation| [mutation.target.to_s, mutation.source.to_s] }
|
|
317
|
+
next if targets.empty?
|
|
318
|
+
|
|
319
|
+
Setter.new(verb: command.hecks_name, targets: targets)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Commands that change nothing — they exist to be REFUSED. Aggregate.Seal is
|
|
324
|
+
# the whole-document check: dispatched once everything is declared, carrying
|
|
325
|
+
# only givens. A category with no sealer simply has no such rule.
|
|
326
|
+
def sealers_in(commands)
|
|
327
|
+
commands.select { |command| Array(command.mutations).empty? }.map(&:hecks_name)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module MetaValidator
|
|
4
|
+
# Offers a built .port to the language that describes ports.
|
|
5
|
+
#
|
|
6
|
+
# A port is a SIBLING of a bluebook, the same shape WorldJudge already
|
|
7
|
+
# is one level over — its own file, its own door, judged through its
|
|
8
|
+
# own self-hosted language (port.bluebook) rather than left as a plain
|
|
9
|
+
# Ruby struct nothing checks. Whole-project table-unification survey,
|
|
10
|
+
# item #13's remaining builders.
|
|
11
|
+
class PortJudge
|
|
12
|
+
attr_reader :refusals
|
|
13
|
+
|
|
14
|
+
def initialize(port)
|
|
15
|
+
@port = port
|
|
16
|
+
@refusals = []
|
|
17
|
+
@runtime = MetaValidator.fresh_runtime
|
|
18
|
+
judge!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def v(text) = text.nil? ? nil : { value: text.to_s }
|
|
24
|
+
|
|
25
|
+
def args(pairs) = pairs.compact
|
|
26
|
+
|
|
27
|
+
def offer(label)
|
|
28
|
+
yield
|
|
29
|
+
rescue Runtime::GivenNotMet, Runtime::InvariantViolation,
|
|
30
|
+
Runtime::TypeMismatch, Runtime::NotFound => e
|
|
31
|
+
@refusals << "#{label}: #{e.message}"
|
|
32
|
+
rescue Runtime::UnknownVerb
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def send_to(verb, label, **payload)
|
|
37
|
+
offer(label) { @runtime.dispatch(verb, **args(payload)) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def judge!
|
|
41
|
+
send_to("Port::Port.Declare", @port.name, name: v(@port.name),
|
|
42
|
+
verb: v(@port.verb), signal: v(@port.signal))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|