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,245 @@
|
|
|
1
|
+
Hecks.bluebook "Bluebook" do
|
|
2
|
+
aggregate "Query" do
|
|
3
|
+
description "One query declared on an aggregate — what it filters on, how it orders, and how many it returns."
|
|
4
|
+
|
|
5
|
+
reference_to Aggregate
|
|
6
|
+
|
|
7
|
+
# Which piece declared it — see Command's entity_id.
|
|
8
|
+
reference_to Entity, as: :entity_id, optional: true
|
|
9
|
+
|
|
10
|
+
# THE IMMEDIATE OWNER, AND ITS NAME — the same derivation Command takes
|
|
11
|
+
# (see the note there), because an ask sits exactly where a verb does and
|
|
12
|
+
# an entity's asks are its own the same way its verbs are.
|
|
13
|
+
identified_by :owner_id, :name
|
|
14
|
+
|
|
15
|
+
attribute :name, QueryName
|
|
16
|
+
attribute :description, QueryText
|
|
17
|
+
attribute :order_field, QueryText
|
|
18
|
+
attribute :order_way, QueryText
|
|
19
|
+
attribute :limit, QueryText
|
|
20
|
+
attribute :wheres, list_of(Filter)
|
|
21
|
+
attribute :attributes, list_of(AskArgument)
|
|
22
|
+
# EVERY OTHER OPTION A QUERY CAN CARRY, as an open map rather than a field
|
|
23
|
+
# each. `offset`, `cursor`, `nulls`, `authorize`, `consistency`, `freshness`,
|
|
24
|
+
# `inspect_query` and `use_index` are eight more specifications, several of them
|
|
25
|
+
# compound — authorize names a policy AND a tenant, freshness a mode AND a max
|
|
26
|
+
# age. Eleven more fields would have to be added here one at a time, and the
|
|
27
|
+
# ninth option would need a twelfth.
|
|
28
|
+
#
|
|
29
|
+
# So they ride as rows: the option's NAME, the KEY within it, and the value. The
|
|
30
|
+
# language already models an open map exactly this way twice — a member's pairs
|
|
31
|
+
# and a world's settings — and both are their own root for the same reason, that
|
|
32
|
+
# no value object can hold a map. Held here as a list because an option belongs
|
|
33
|
+
# to the ask rather than standing alone.
|
|
34
|
+
attribute :options, list_of(AskOption)
|
|
35
|
+
|
|
36
|
+
value_object "QueryName" do
|
|
37
|
+
attribute :value, String
|
|
38
|
+
invariant("a query is named") { !value.to_s.empty? }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
value_object "QueryText" do
|
|
42
|
+
attribute :value, String
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
value_object "Filter" do
|
|
46
|
+
attribute :field, String
|
|
47
|
+
# THE FIRST USE OF THE WORD. The runtime maps these eight strings
|
|
48
|
+
# through a hand-typed comparator table ; the set it is mapping to is
|
|
49
|
+
# one the language DECLARES, and until the link between them was
|
|
50
|
+
# declared, typing it downstream
|
|
51
|
+
# would have been a guess. This declares it.
|
|
52
|
+
attribute :op, String, admits: "Vocabulary::QueryComparator"
|
|
53
|
+
attribute :value, String
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
value_object "AskArgument" do
|
|
57
|
+
attribute :name, String
|
|
58
|
+
attribute :type, String
|
|
59
|
+
attribute :list, String
|
|
60
|
+
attribute :optional, String, optional: true
|
|
61
|
+
attribute :pattern, String, optional: true
|
|
62
|
+
attribute :default, String
|
|
63
|
+
# The closed set this value must belong to — see Aggregate::Field.
|
|
64
|
+
attribute :admits, String, optional: true
|
|
65
|
+
attribute :relationship, String, optional: true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# One entry of one option. `option` names which specification it belongs to
|
|
69
|
+
# (offset, freshness, authorization), `key` the part within it (value, mode,
|
|
70
|
+
# max_age, policy, tenant), and `value` what was declared. A single-valued
|
|
71
|
+
# option is one row ; a compound is one row per part ; a repeated one — an index
|
|
72
|
+
# hint — is one row per occurrence, told apart by `at`.
|
|
73
|
+
value_object "AskOption" do
|
|
74
|
+
attribute :option, String
|
|
75
|
+
attribute :key, String
|
|
76
|
+
attribute :value, String
|
|
77
|
+
attribute :at, String
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The way back: everything DECLARED IN the aggregate above. The parent
|
|
81
|
+
# reference IS the query.
|
|
82
|
+
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
83
|
+
# SOURCE — the IR is a contract read straight from this file,
|
|
84
|
+
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
85
|
+
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
86
|
+
# does not say how it is ordered is answered in identity order, which is
|
|
87
|
+
# right for every other ask and fatal for the one that is the SOURCE.
|
|
88
|
+
value_object "Position" do
|
|
89
|
+
attribute :value, Integer
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
attribute :position, Position
|
|
93
|
+
|
|
94
|
+
query "DeclaredIn" do
|
|
95
|
+
attribute :aggregate, QueryText
|
|
96
|
+
where(aggregate: :aggregate)
|
|
97
|
+
order_by :position
|
|
98
|
+
end
|
|
99
|
+
command "Declare" do
|
|
100
|
+
role "Language"
|
|
101
|
+
goal "Open a query on an aggregate"
|
|
102
|
+
|
|
103
|
+
reference_to Aggregate
|
|
104
|
+
# Declared on an aggregate or on one of its entities — see Command.Declare.
|
|
105
|
+
reference_to Entity, as: :entity_id, optional: true
|
|
106
|
+
attribute :name, QueryName
|
|
107
|
+
attribute :description, QueryText, optional: true
|
|
108
|
+
attribute :order_field, QueryText, optional: true
|
|
109
|
+
attribute :order_way, QueryText, optional: true
|
|
110
|
+
attribute :limit, QueryText, optional: true
|
|
111
|
+
|
|
112
|
+
attribute :position, Position, optional: true
|
|
113
|
+
sets :aggregate
|
|
114
|
+
sets :entity_id
|
|
115
|
+
sets :name
|
|
116
|
+
sets :description
|
|
117
|
+
sets :order_field
|
|
118
|
+
sets :order_way
|
|
119
|
+
sets :limit
|
|
120
|
+
sets :position
|
|
121
|
+
emits "AskDeclared"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
command "Filter" do
|
|
125
|
+
role "Language"
|
|
126
|
+
goal "Attach one where-clause to the query"
|
|
127
|
+
|
|
128
|
+
attribute :field, QueryText
|
|
129
|
+
# The same word at the same door — see Command.Change.op.
|
|
130
|
+
attribute :op, QueryText, admits: "Vocabulary::QueryComparator"
|
|
131
|
+
attribute :value, QueryText
|
|
132
|
+
|
|
133
|
+
sets :wheres, append: { field: :field, op: :op, value: :value }
|
|
134
|
+
|
|
135
|
+
emits "FilterAttached"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
command "Option" do
|
|
139
|
+
role "Language"
|
|
140
|
+
goal "Attach one part of one specification option to the query"
|
|
141
|
+
|
|
142
|
+
attribute :option, QueryText
|
|
143
|
+
attribute :key, QueryText
|
|
144
|
+
# AN OPTION MAY HAVE NO VALUE. `consistency :snapshot` with no timeout is a
|
|
145
|
+
# complete declaration, and an option is judged one key at a time — so the
|
|
146
|
+
# `timeout` row arrives carrying nothing. Requiring a value here made every
|
|
147
|
+
# such declaration unbuildable, which is a rule about the LANGUAGE, not
|
|
148
|
+
# about the one spec that noticed.
|
|
149
|
+
attribute :value, QueryText, optional: true
|
|
150
|
+
attribute :at, QueryText, optional: true
|
|
151
|
+
|
|
152
|
+
given("an option is named") { !option.value.to_s.empty? }
|
|
153
|
+
|
|
154
|
+
sets :options, append: { option: :option, key: :key, value: :value, at: :at }
|
|
155
|
+
|
|
156
|
+
emits "OptionAttached"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
command "Argument" do
|
|
160
|
+
role "Language"
|
|
161
|
+
goal "Attach one parameter to the query"
|
|
162
|
+
|
|
163
|
+
attribute :name, QueryText
|
|
164
|
+
attribute :type, QueryText
|
|
165
|
+
attribute :list, QueryText
|
|
166
|
+
attribute :optional, QueryText, optional: true
|
|
167
|
+
attribute :pattern, QueryText, optional: true
|
|
168
|
+
attribute :default, QueryText, optional: true
|
|
169
|
+
attribute :admits, QueryText, optional: true
|
|
170
|
+
# See Command.Argument's own :relationship (command.bluebook) — the
|
|
171
|
+
# same field, the same reason: an argument minted verbatim from the
|
|
172
|
+
# owner's own reference-typed attribute must carry that fact through
|
|
173
|
+
# the self-hosted round trip too, or the language cannot say it about
|
|
174
|
+
# itself.
|
|
175
|
+
attribute :relationship, QueryText, optional: true
|
|
176
|
+
|
|
177
|
+
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
178
|
+
|
|
179
|
+
emits "AskArgumentAttached"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# HOW QUERY IS SPELLED. These rows live with the concept
|
|
184
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
185
|
+
# Contexts represented here: Query.
|
|
186
|
+
value_object "KeywordSeed" do
|
|
187
|
+
attribute :word, String
|
|
188
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
189
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
190
|
+
attribute :inner, String
|
|
191
|
+
attribute :opens, String
|
|
192
|
+
attribute :fills, String
|
|
193
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
194
|
+
attribute :was, String
|
|
195
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
196
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
197
|
+
|
|
198
|
+
member word: "description", context: "Query", body: "none", inner: "", opens: "", fills: "description"
|
|
199
|
+
member word: "attribute", context: "Query", body: "none", inner: "", opens: "", fills: "attributes", calls: "attribute_impl"
|
|
200
|
+
member word: "reference_to", context: "Query", body: "none", inner: "", opens: "", fills: "attributes", calls: "reference_to_impl"
|
|
201
|
+
member word: "where", context: "Query", body: "none", inner: "", opens: "", fills: "wheres", calls: "where_impl"
|
|
202
|
+
member word: "order_by", context: "Query", body: "none", inner: "", opens: "", fills: "order_field", calls: "order_by_impl"
|
|
203
|
+
member word: "authorize", context: "Query", body: "none", inner: "", opens: "", fills: "options", calls: "authorize_impl"
|
|
204
|
+
member word: "inspect_query", context: "Query", body: "none", inner: "", opens: "", fills: "options"
|
|
205
|
+
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
value_object "ArgumentSeed" do
|
|
209
|
+
attribute :keyword, String
|
|
210
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
211
|
+
attribute :at, String
|
|
212
|
+
attribute :named, String
|
|
213
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
214
|
+
attribute :required, String
|
|
215
|
+
attribute :fills, String
|
|
216
|
+
attribute :selects, String
|
|
217
|
+
attribute :pair_key_fills, String
|
|
218
|
+
attribute :pair_value_fills, String
|
|
219
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
220
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
221
|
+
attribute :variadic, String
|
|
222
|
+
attribute :coerce, String
|
|
223
|
+
attribute :blank_message, String
|
|
224
|
+
|
|
225
|
+
member keyword: "description", context: "Query", at: "1", named: "", kind: "text", required: "true", fills: "description", coerce: "false"
|
|
226
|
+
member keyword: "attribute", context: "Query", at: "1", named: "", kind: "symbol", required: "true", fills: "name"
|
|
227
|
+
member keyword: "attribute", context: "Query", at: "2", named: "", kind: "constant", required: "true", fills: "type"
|
|
228
|
+
member keyword: "attribute", context: "Query", at: "", named: "default", kind: "literal", required: "false", fills: "default"
|
|
229
|
+
member keyword: "attribute", context: "Query", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
|
|
230
|
+
member keyword: "attribute", context: "Query", at: "", named: "pattern", kind: "text", required: "false", fills: "pattern"
|
|
231
|
+
member keyword: "attribute", context: "Query", at: "", named: "admits", kind: "text", required: "false", fills: "admits"
|
|
232
|
+
member keyword: "attribute", context: "Query", at: "", named: "one_of", kind: "list", required: "false", fills: "one_of"
|
|
233
|
+
member keyword: "reference_to", context: "Query", at: "1", named: "", kind: "constant", required: "true", fills: "type"
|
|
234
|
+
member keyword: "reference_to", context: "Query", at: "", named: "as", kind: "symbol", required: "false", fills: "name"
|
|
235
|
+
member keyword: "reference_to", context: "Query", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
|
|
236
|
+
member keyword: "where", context: "Query", at: "1", named: "", kind: "pairs", required: "true", fills: "wheres", pair_key_fills: "field", pair_value_fills: "value", pairs_shape: "elements"
|
|
237
|
+
member keyword: "order_by", context: "Query", at: "1", named: "", kind: "symbol", required: "true", fills: "order_field"
|
|
238
|
+
member keyword: "order_by", context: "Query", at: "2", named: "", kind: "symbol", required: "false", fills: "order_way"
|
|
239
|
+
member keyword: "authorize", context: "Query", at: "1", named: "", kind: "symbol", required: "true", fills: "policy"
|
|
240
|
+
member keyword: "authorize", context: "Query", at: "", named: "tenant", kind: "symbol", required: "false", fills: "tenant"
|
|
241
|
+
member keyword: "inspect_query", context: "Query", at: "1", named: "", kind: "symbol", required: "false", fills: "mode"
|
|
242
|
+
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
Hecks.bluebook "Bluebook" do
|
|
2
|
+
aggregate "ValueObject" do
|
|
3
|
+
description "One value object declared on an aggregate — its fields and the rules they must satisfy. Its own root because a value object holds nested lists, which no list element can."
|
|
4
|
+
|
|
5
|
+
reference_to Aggregate
|
|
6
|
+
|
|
7
|
+
# THE AGGREGATE IT BELONGS TO, AND ITS NAME. A value object belongs to one
|
|
8
|
+
# aggregate by rule, and `Name` or `Amount` is spelled in half the chapters
|
|
9
|
+
# there are.
|
|
10
|
+
identified_by :aggregate, :name
|
|
11
|
+
|
|
12
|
+
attribute :name, ValueObjectName
|
|
13
|
+
attribute :attributes, list_of(ShapeField)
|
|
14
|
+
attribute :invariants, list_of(Assertion)
|
|
15
|
+
attribute :rows, RowCount, optional: true
|
|
16
|
+
# S17, ADR 0026 — Member NESTED here, an entity rather than its own
|
|
17
|
+
# root aggregate (see `entity "Member"`, below). `list_of(Member)`
|
|
18
|
+
# forward-references it the same way banking's own `attribute :ledger,
|
|
19
|
+
# list_of(LedgerEntry)` names LedgerEntry before it is declared.
|
|
20
|
+
attribute :members, list_of(Member)
|
|
21
|
+
|
|
22
|
+
value_object "RowCount" do
|
|
23
|
+
attribute :value, Integer
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
value_object "ValueObjectName" do
|
|
27
|
+
attribute :value, String, pattern: '[^ \t\n\r]'
|
|
28
|
+
invariant("a value object is named") { !value.to_s.empty? }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
value_object "ShapeField" do
|
|
32
|
+
attribute :name, String, pattern: '[^ \t\n\r]'
|
|
33
|
+
attribute :type, String, pattern: '[^ \t\n\r]'
|
|
34
|
+
attribute :list, String, pattern: '[^ \t\n\r]'
|
|
35
|
+
attribute :optional, String, optional: true
|
|
36
|
+
attribute :pattern, String, optional: true
|
|
37
|
+
attribute :default, String
|
|
38
|
+
# The closed set this value must belong to — see Aggregate::Field.
|
|
39
|
+
attribute :admits, String, optional: true
|
|
40
|
+
attribute :relationship, String, optional: true
|
|
41
|
+
invariant("a field is named") { !name.to_s.empty? }
|
|
42
|
+
invariant("a field has a type") { !type.to_s.empty? }
|
|
43
|
+
invariant("a field's list mode is specified") { !list.to_s.empty? }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
value_object "Assertion" do
|
|
47
|
+
attribute :description, String, pattern: '[^ \t\n\r]'
|
|
48
|
+
attribute :canonical, String, pattern: '[^ \t\n\r]'
|
|
49
|
+
invariant("an assertion description is present") { !description.to_s.empty? }
|
|
50
|
+
invariant("an assertion canonical form is present") { !canonical.to_s.empty? }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# S17, ADR 0026 — MemberPosition/MemberText/Pair, hoisted up from the
|
|
54
|
+
# old standalone `aggregate "Member"`. An entity cannot declare its own
|
|
55
|
+
# `value_object` (EntityBuilder has no such method — a piece borrows its
|
|
56
|
+
# owning aggregate's, the same way LedgerEntry borrows Account's Money),
|
|
57
|
+
# so these live here now, one level up, where `entity "Member"` below
|
|
58
|
+
# can still reach them.
|
|
59
|
+
#
|
|
60
|
+
# Named MemberPosition rather than reusing ValueObject's own `Position`
|
|
61
|
+
# two lines above — that one orders value objects among an AGGREGATE's
|
|
62
|
+
# siblings ; this one orders admitted rows within ONE value object. Same
|
|
63
|
+
# shape, different fact, so a shared name would have let one silently
|
|
64
|
+
# answer for the other.
|
|
65
|
+
value_object "MemberPosition" do
|
|
66
|
+
attribute :value, Integer
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
value_object "MemberText" do
|
|
70
|
+
attribute :value, String
|
|
71
|
+
# MemberText is free-form serialized text from member definitions,
|
|
72
|
+
# which can include empty strings and numeric literals — not restricted
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
value_object "Pair" do
|
|
76
|
+
attribute :key, String, pattern: '[^ \t\n\r]'
|
|
77
|
+
attribute :value, String
|
|
78
|
+
# Pair keys must be named, but values can be empty strings or numeric literals
|
|
79
|
+
invariant("a pair key is present") { !key.to_s.empty? }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The way back: everything DECLARED IN the aggregate above. The parent
|
|
83
|
+
# reference IS the query.
|
|
84
|
+
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
85
|
+
# SOURCE — the IR is a contract read straight from this file,
|
|
86
|
+
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
87
|
+
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
88
|
+
# does not say how it is ordered is answered in identity order, which is
|
|
89
|
+
# right for every other ask and fatal for the one that is the SOURCE.
|
|
90
|
+
value_object "Position" do
|
|
91
|
+
attribute :value, Integer
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
attribute :position, Position
|
|
95
|
+
|
|
96
|
+
query "DeclaredIn" do
|
|
97
|
+
attribute :aggregate, ValueObjectText
|
|
98
|
+
where(aggregate: :aggregate)
|
|
99
|
+
order_by :position
|
|
100
|
+
end
|
|
101
|
+
command "Declare" do
|
|
102
|
+
role "Language"
|
|
103
|
+
goal "Open a value object on an aggregate"
|
|
104
|
+
|
|
105
|
+
reference_to Aggregate
|
|
106
|
+
attribute :name, ValueObjectName
|
|
107
|
+
|
|
108
|
+
attribute :position, Position, optional: true
|
|
109
|
+
sets :aggregate
|
|
110
|
+
sets :name
|
|
111
|
+
sets :position
|
|
112
|
+
emits "ShapeDeclared"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
command "Field" do
|
|
116
|
+
role "Language"
|
|
117
|
+
goal "Attach one field to the value object"
|
|
118
|
+
|
|
119
|
+
attribute :name, ValueObjectName
|
|
120
|
+
attribute :type, ValueObjectName
|
|
121
|
+
attribute :list, ValueObjectName
|
|
122
|
+
attribute :optional, ValueObjectName, optional: true
|
|
123
|
+
# FREE TEXT, like `default` beside it and like the pattern every other
|
|
124
|
+
# element builder takes. `ValueObjectName` carries the invariant "a value
|
|
125
|
+
# object is named", which is not a thing a regex has to be — it happened to
|
|
126
|
+
# admit banking's one pattern because that pattern is not empty, and it
|
|
127
|
+
# said the wrong thing about why.
|
|
128
|
+
attribute :pattern, ValueObjectText, optional: true
|
|
129
|
+
attribute :default, ValueObjectText, optional: true
|
|
130
|
+
attribute :admits, ValueObjectText, optional: true
|
|
131
|
+
# See Command.Argument's own :relationship (command.bluebook) — the
|
|
132
|
+
# same field, the same reason.
|
|
133
|
+
attribute :relationship, ValueObjectText, optional: true
|
|
134
|
+
|
|
135
|
+
sets :attributes, append: { name: :name, type: :type, list: :list, default: :default, optional: :optional, pattern: :pattern, admits: :admits, relationship: :relationship }
|
|
136
|
+
|
|
137
|
+
emits "ShapeFieldAttached"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
command "Close" do
|
|
141
|
+
role "Language"
|
|
142
|
+
goal "Declare that this value object admits a closed set of rows"
|
|
143
|
+
|
|
144
|
+
# Dispatched only when the bluebook declared a one_of — so an EMPTY closed
|
|
145
|
+
# set is visible where it used to be invisible : a shape that is closed
|
|
146
|
+
# and admits nothing. Members live in their own root (a row is a list of
|
|
147
|
+
# pairs inside a list of rows), so the count is offered rather than read.
|
|
148
|
+
|
|
149
|
+
given("a closed set admits a member") { rows.value > 0 }
|
|
150
|
+
|
|
151
|
+
sets :rows
|
|
152
|
+
|
|
153
|
+
emits "ShapeClosed"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
command "Assert" do
|
|
157
|
+
role "Language"
|
|
158
|
+
goal "Attach one invariant to the value object"
|
|
159
|
+
|
|
160
|
+
attribute :description, ValueObjectText, optional: true
|
|
161
|
+
attribute :canonical, ValueObjectText
|
|
162
|
+
|
|
163
|
+
given("a rule says what it means") { !description.value.to_s.empty? }
|
|
164
|
+
given("a rule survives extraction") { !canonical.value.to_s.empty? }
|
|
165
|
+
|
|
166
|
+
sets :invariants, append: { description: :description, canonical: :canonical }
|
|
167
|
+
|
|
168
|
+
emits "AssertionAttached"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
value_object "ValueObjectText" do
|
|
172
|
+
attribute :value, String
|
|
173
|
+
# ValueObjectText is free-form serialized text from member definitions,
|
|
174
|
+
# which can include empty strings and numeric literals — not restricted
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# THE MEMBER'S OWN CREATION. S17, ADR 0026 — Member is a genuine ENTITY
|
|
178
|
+
# now (`entity "Member"`, below), and an entity is never created through
|
|
179
|
+
# its own dotted verb — banking's own LedgerEntry is created by
|
|
180
|
+
# `Account.LogEntry`, an ordinary append on the OWNER, never by a
|
|
181
|
+
# `LedgerEntry.Declare` of its own (EntityInterpreter#element_of only
|
|
182
|
+
# LOCATES an element already on the list — see entity_interpreter.rb —
|
|
183
|
+
# it has no path that creates one). So Member's creation moved here,
|
|
184
|
+
# onto ValueObject, mirroring `Field`/`Close`/`Assert` beside it :
|
|
185
|
+
# a bare, aggregate-level append. What it creates is empty — pairs fill
|
|
186
|
+
# in afterward, one at a time, through the entity's own `Pair`.
|
|
187
|
+
command "Member" do
|
|
188
|
+
role "Language"
|
|
189
|
+
goal "Open one admitted row on a value object"
|
|
190
|
+
|
|
191
|
+
attribute :position, MemberPosition
|
|
192
|
+
|
|
193
|
+
sets :members, append: { position: :position }
|
|
194
|
+
|
|
195
|
+
emits "MemberDeclared"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# S17, ADR 0026 — ONE ADMITTED ROW, nested rather than its own root
|
|
199
|
+
# aggregate. A member has no other distinguishing fact : its pairs are
|
|
200
|
+
# an OPEN MAP, which is the whole reason it used to need a root of its
|
|
201
|
+
# own, and a map cannot be a path — but that was always a reason it
|
|
202
|
+
# could not be a VALUE OBJECT, never a reason it could not be an
|
|
203
|
+
# ENTITY, which is what it structurally always was: a nested, ordered,
|
|
204
|
+
# separately-mutated element of ValueObject's own list. `ValueObject.
|
|
205
|
+
# Member` (above) creates it ; `Pair` (below) fills it in, one field
|
|
206
|
+
# at a time, exactly the way `Command.Rule` fills in a precondition.
|
|
207
|
+
entity "Member" do
|
|
208
|
+
description "One admitted row of a value object's one_of — a whole combination of field values, not a per-field choice. Nested under the value object because a row is a list of pairs inside a list of rows."
|
|
209
|
+
|
|
210
|
+
# Position is not a mint — it is read straight out of the source
|
|
211
|
+
# file, the same fact the language already holds deliberately so
|
|
212
|
+
# that an ask ordered any other way cannot take declaration order
|
|
213
|
+
# away. `ValueObject.Member` mints it as the walk index at creation
|
|
214
|
+
# (the same way `declare`'s own `position` field always has), and
|
|
215
|
+
# every later `Pair` locates the element by it.
|
|
216
|
+
identified_by MemberPosition, as: :position
|
|
217
|
+
|
|
218
|
+
attribute :pairs, list_of(Pair)
|
|
219
|
+
|
|
220
|
+
command "Pair" do
|
|
221
|
+
role "Language"
|
|
222
|
+
goal "Bind one field of the admitted row"
|
|
223
|
+
|
|
224
|
+
attribute :key, MemberText
|
|
225
|
+
attribute :value, MemberText
|
|
226
|
+
|
|
227
|
+
given("an admitted row binds a named field") { !key.value.to_s.empty? }
|
|
228
|
+
|
|
229
|
+
sets :pairs, append: { key: :key, value: :value }
|
|
230
|
+
|
|
231
|
+
emits "PairBound"
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# HOW VALUEOBJECT IS SPELLED. These rows live with the concept
|
|
236
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
237
|
+
# Contexts represented here: ValueObject, OneOf, Type.
|
|
238
|
+
value_object "KeywordSeed" do
|
|
239
|
+
attribute :word, String
|
|
240
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
241
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
242
|
+
attribute :inner, String
|
|
243
|
+
attribute :opens, String
|
|
244
|
+
attribute :fills, String
|
|
245
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
246
|
+
attribute :was, String
|
|
247
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
248
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
249
|
+
|
|
250
|
+
member word: "attribute", context: "ValueObject", body: "none", inner: "", opens: "", fills: "attributes", calls: "attribute_impl"
|
|
251
|
+
member word: "one_of", context: "ValueObject", body: "rows", inner: "OneOf", opens: "", fills: "rows", calls: "one_of_impl"
|
|
252
|
+
member word: "invariant", context: "ValueObject", body: "source", inner: "", opens: "", fills: "invariants", resolves_via: "sibling_scan", calls: "invariant_impl"
|
|
253
|
+
member word: "member", context: "ValueObject", body: "none", inner: "", opens: "Member", fills: "", calls: "member_impl"
|
|
254
|
+
member word: "member", context: "OneOf", body: "none", inner: "", opens: "Member", fills: "", calls: "member_impl"
|
|
255
|
+
member word: "list_of", context: "Type", body: "none", inner: "", opens: "", fills: "", calls: "list_of_impl"
|
|
256
|
+
member word: "one_of", context: "Type", body: "none", inner: "", opens: "", fills: "", calls: "one_of_impl"
|
|
257
|
+
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
value_object "ArgumentSeed" do
|
|
261
|
+
attribute :keyword, String
|
|
262
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
263
|
+
attribute :at, String
|
|
264
|
+
attribute :named, String
|
|
265
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
266
|
+
attribute :required, String
|
|
267
|
+
attribute :fills, String
|
|
268
|
+
attribute :selects, String
|
|
269
|
+
attribute :pair_key_fills, String
|
|
270
|
+
attribute :pair_value_fills, String
|
|
271
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
272
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
273
|
+
attribute :variadic, String
|
|
274
|
+
attribute :coerce, String
|
|
275
|
+
attribute :blank_message, String
|
|
276
|
+
|
|
277
|
+
member keyword: "attribute", context: "ValueObject", at: "1", named: "", kind: "symbol", required: "true", fills: "name"
|
|
278
|
+
member keyword: "attribute", context: "ValueObject", at: "2", named: "", kind: "constant", required: "true", fills: "type"
|
|
279
|
+
member keyword: "attribute", context: "ValueObject", at: "", named: "default", kind: "literal", required: "false", fills: "default"
|
|
280
|
+
member keyword: "attribute", context: "ValueObject", at: "", named: "optional", kind: "flag", required: "false", fills: "optional"
|
|
281
|
+
member keyword: "attribute", context: "ValueObject", at: "", named: "pattern", kind: "text", required: "false", fills: "pattern"
|
|
282
|
+
member keyword: "attribute", context: "ValueObject", at: "", named: "admits", kind: "text", required: "false", fills: "admits"
|
|
283
|
+
member keyword: "attribute", context: "ValueObject", at: "", named: "one_of", kind: "list", required: "false", fills: "one_of"
|
|
284
|
+
member keyword: "invariant", context: "ValueObject", at: "1", named: "", kind: "text", required: "true", fills: "description"
|
|
285
|
+
member keyword: "member", context: "ValueObject", at: "1", named: "", kind: "pairs", required: "true", fills: "members", pairs_shape: "verbatim"
|
|
286
|
+
member keyword: "member", context: "OneOf", at: "1", named: "", kind: "pairs", required: "true", fills: "members", pairs_shape: "verbatim"
|
|
287
|
+
member keyword: "list_of", context: "Type", at: "1", named: "", kind: "constant", required: "true", fills: ""
|
|
288
|
+
member keyword: "one_of", context: "Type", at: "1", named: "", kind: "literal", required: "true", fills: ""
|
|
289
|
+
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|