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,364 @@
|
|
|
1
|
+
Hecks.bluebook "Bluebook" do
|
|
2
|
+
aggregate "Vocabulary" do
|
|
3
|
+
# These are DECLARATIONS, not runtime state — a language's admitted sets are
|
|
4
|
+
# fixed when the language is defined, which is what one_of means. They carry
|
|
5
|
+
# no commands on purpose : nothing dispatches a vocabulary, the conformance
|
|
6
|
+
# check READS them from the IR and holds the runtime's hand-typed tables to them.
|
|
7
|
+
#
|
|
8
|
+
# Every one of these is a set the runtime must agree with, and every one has
|
|
9
|
+
# already drifted or leaked at least once :
|
|
10
|
+
# Comparison went disjoint from the grammar chapter's operator table
|
|
11
|
+
# NormalisationStrategy is the third, unchecked copy of the canonical-form table
|
|
12
|
+
# Primitive is what "primitives live in value objects only" is ABOUT
|
|
13
|
+
# DomainRefusal is the boundary three raw Ruby TypeErrors crossed tonight
|
|
14
|
+
description "The closed sets the language admits — the whole of what any runtime may accept, declared once."
|
|
15
|
+
|
|
16
|
+
# ITS NAME, and nothing else. A vocabulary hangs under no other thing — the
|
|
17
|
+
# closed sets are the language's own, declared once — so one path is the whole
|
|
18
|
+
# identity.
|
|
19
|
+
identified_by VocabularyName, as: :name
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
value_object "VocabularyName" do
|
|
23
|
+
attribute :value, String
|
|
24
|
+
invariant("a vocabulary is named") { !value.to_s.empty? }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Expression::Evaluator::COMPARISONS — six operators, all reduced by the
|
|
28
|
+
# evaluator to two primitives (less_than, equal) combined with a small boolean
|
|
29
|
+
# algebra: compares_less_than and compares_equal choose which primitive(s) OR
|
|
30
|
+
# together, negated inverts the result. `compare` reads this table instead of
|
|
31
|
+
# hardcoding a six-way case statement — see Evaluator::COMPARISONS.
|
|
32
|
+
value_object "Comparison" do
|
|
33
|
+
attribute :symbol, String
|
|
34
|
+
attribute :compares_less_than, String
|
|
35
|
+
attribute :compares_equal, String
|
|
36
|
+
attribute :negated, String
|
|
37
|
+
|
|
38
|
+
member symbol: ">=", compares_less_than: "true", compares_equal: "false", negated: "true"
|
|
39
|
+
member symbol: "<=", compares_less_than: "true", compares_equal: "true", negated: "false"
|
|
40
|
+
member symbol: "<", compares_less_than: "true", compares_equal: "false", negated: "false"
|
|
41
|
+
member symbol: ">", compares_less_than: "true", compares_equal: "true", negated: "true"
|
|
42
|
+
member symbol: "==", compares_less_than: "false", compares_equal: "true", negated: "false"
|
|
43
|
+
member symbol: "!=", compares_less_than: "false", compares_equal: "true", negated: "true"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Expression::Resolver::SIGN_TESTS
|
|
47
|
+
# Each sign test is comparing against the literal 0, using an operator
|
|
48
|
+
# Comparison already declares — compares_via names which one, so a sign
|
|
49
|
+
# test is sugar for an existing operator rather than a second algebra
|
|
50
|
+
# beside it. `positive?` = value > 0, `negative?` = value < 0, `zero?` =
|
|
51
|
+
# value == 0.
|
|
52
|
+
value_object "SignTest" do
|
|
53
|
+
attribute :name, String
|
|
54
|
+
attribute :compares_via, String
|
|
55
|
+
|
|
56
|
+
member name: "positive?", compares_via: ">"
|
|
57
|
+
member name: "negative?", compares_via: "<"
|
|
58
|
+
member name: "zero?", compares_via: "=="
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# `.include?`'s haystack type decides its behaviour : Array does
|
|
62
|
+
# membership (the same equal? primitive Comparison's == uses), String
|
|
63
|
+
# does an exact substring match and refuses a non-String needle. Anything
|
|
64
|
+
# else is always false — not declared here, since it is the fallback
|
|
65
|
+
# every OTHER haystack type shares, not a case of its own.
|
|
66
|
+
value_object "IncludeHaystack" do
|
|
67
|
+
attribute :type, String
|
|
68
|
+
attribute :strategy, String
|
|
69
|
+
|
|
70
|
+
member type: "Array", strategy: "membership"
|
|
71
|
+
member type: "String", strategy: "substring"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# `.to_s` admits exactly these scalar types, and every one of them uses
|
|
75
|
+
# the SAME rule (Ruby's own to_s — nil renders "", a bool its name, a
|
|
76
|
+
# number its digits, a string itself) — a closed set to admit into, not a
|
|
77
|
+
# table of different rules per type.
|
|
78
|
+
value_object "ToStringType" do
|
|
79
|
+
attribute :type, String, one_of: ["String", "Integer", "Float", "TrueClass", "FalseClass", "NilClass"]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# `.size` and `.empty?` admit exactly the same closed set — a list, a
|
|
83
|
+
# string, or an open map — and each just calls the one Ruby method
|
|
84
|
+
# already named for it. One declaration for both, since the set itself is
|
|
85
|
+
# the only thing either needed to say.
|
|
86
|
+
value_object "SizedType" do
|
|
87
|
+
attribute :type, String, one_of: ["Array", "String", "Hash"]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Attribute::PRIMITIVES — the scalars a value object may bottom out in
|
|
91
|
+
value_object "Primitive" do
|
|
92
|
+
attribute :name, String, one_of: ["String", "Integer", "Float", "TrueClass", "FalseClass"]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Expression::CanonicalForm::STRATEGIES
|
|
96
|
+
value_object "NormalisationStrategy" do
|
|
97
|
+
attribute :name, String, one_of: ["collapse_whitespace", "replace"]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# the ops Runtime::CommandInterpreter applies. `sign` is the arithmetic
|
|
101
|
+
# delta increment/decrement share one primitive by — CommandRules#arithmetic
|
|
102
|
+
# applies `current + sign *
|
|
103
|
+
# amount`, differing only in which sign. set and append do no arithmetic,
|
|
104
|
+
# so they carry no sign — ABSENT IS NOT EMPTY, same reading as elsewhere in
|
|
105
|
+
# this file.
|
|
106
|
+
value_object "MutationOp" do
|
|
107
|
+
attribute :name, String
|
|
108
|
+
attribute :sign, String
|
|
109
|
+
|
|
110
|
+
member name: "set", sign: ""
|
|
111
|
+
member name: "append", sign: ""
|
|
112
|
+
member name: "increment", sign: "1"
|
|
113
|
+
member name: "decrement", sign: "-1"
|
|
114
|
+
# Vendored addition, not (yet) upstream hecks (migration plan
|
|
115
|
+
# task 4, i106 in-DSL math — CommandRules::Arithmetic#multiply/
|
|
116
|
+
# #clamp): multiply scales (`current * amount`), clamp bounds
|
|
117
|
+
# (`current.clamp(min, max)`) — neither is an add/subtract, so
|
|
118
|
+
# neither carries a sign, same reading as set/append above.
|
|
119
|
+
member name: "multiply", sign: ""
|
|
120
|
+
member name: "clamp", sign: ""
|
|
121
|
+
# Vendored addition, not (yet) upstream hecks (migration plan
|
|
122
|
+
# task 4): remove — the list-removal counterpart to append,
|
|
123
|
+
# matching an element by value. No sign, same reading as append.
|
|
124
|
+
member name: "remove", sign: ""
|
|
125
|
+
# Vendored addition, not (yet) upstream hecks — CommandBuilder
|
|
126
|
+
# #delegates_to's own comment gives the full reasoning: an
|
|
127
|
+
# aggregate-level command's synchronous, single-dispatch handoff
|
|
128
|
+
# into one nested entity command, rather than a policy/saga's own
|
|
129
|
+
# commit-then-react reentry. Rides the SAME multi-binding wire
|
|
130
|
+
# shape append does (`with: {...}` is a field map, same as
|
|
131
|
+
# append's own `fields:`), so it carries no sign, same reading.
|
|
132
|
+
member name: "delegate", sign: ""
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# QuerySpecification::Common::Comparators::COMPARATORS — a where-clause's
|
|
136
|
+
# admitted operators. Unlike Comparison, these do not reduce to one shared
|
|
137
|
+
# boolean algebra (eq/ne compare values, gt/gte/lt/lte order them, in/contains
|
|
138
|
+
# test membership in opposite directions), so this stays a flat closed set —
|
|
139
|
+
# the same shape MutationOp had before it grew a sign.
|
|
140
|
+
# `none_in_state` (the last member) is a vendored addition, not (yet)
|
|
141
|
+
# upstream hecks (migration plan task 4) — see
|
|
142
|
+
# query_specification/common/comparators.rb's own comment on
|
|
143
|
+
# none_in_state. Both closed sets (the Ruby COMPARATORS constant and
|
|
144
|
+
# this self-hosted grammar entry) must agree, the same two-places-
|
|
145
|
+
# must-agree discipline MutationOp/multiply/clamp already required
|
|
146
|
+
# earlier this pass.
|
|
147
|
+
value_object "QueryComparator" do
|
|
148
|
+
attribute :name, String, one_of: ["eq", "ne", "gt", "gte", "lt", "lte", "in", "contains", "none_in_state"]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Adapters::Driven::Folder::DOMAIN_ORDER — declarations load in this order
|
|
152
|
+
value_object "LoadOrder" do
|
|
153
|
+
attribute :glob, String,
|
|
154
|
+
one_of: ["*.port", "*.adapter", "*.bluebook", "translations/*.bluebook", "*.hecksagon", "*.world"]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# CommandInterpreter#call — an aggregate command's
|
|
158
|
+
# own interpretation, ending at the events it emits. Reaction (policies,
|
|
159
|
+
# sagas) is a structurally separate phase and is not part
|
|
160
|
+
# of this : CommandInterpreter#call returns before it runs, in a
|
|
161
|
+
# different class — reaction is
|
|
162
|
+
# what a command's OWN emitted events cause, not what interpreting
|
|
163
|
+
# the command does. Two conditional steps — assign_creation_attributes only
|
|
164
|
+
# fires for a creating command, advance_lifecycle only when a transition
|
|
165
|
+
# applies — so this is the order a command that does both follows,
|
|
166
|
+
# confirmed by tracing a real dispatch, not read off the source.
|
|
167
|
+
value_object "AggregateDispatchOrder" do
|
|
168
|
+
attribute :step, String,
|
|
169
|
+
one_of: ["refuse_unknown_arguments", "refuse_absent_arguments", "normalize_args",
|
|
170
|
+
"refuse_role_mismatch", "resolve_references", "hydrate", "enforce_givens",
|
|
171
|
+
"admissible_transition", "assign_creation_attributes", "apply_mutations",
|
|
172
|
+
"advance_lifecycle", "delegate_to_entity", "enforce_ensures", "enforce_invariants",
|
|
173
|
+
"save", "emit"]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# EntityInterpreter#call — the same shape
|
|
177
|
+
# one level down, on a piece an aggregate holds rather than the aggregate
|
|
178
|
+
# itself. Shorter than AggregateDispatchOrder because an entity is never
|
|
179
|
+
# CREATED through this path (no assign_creation_attributes) and inherits
|
|
180
|
+
# its aggregate's own argument gate rather than running one of its own (no
|
|
181
|
+
# refuse_unknown_arguments) — hydrating the parent and locating the
|
|
182
|
+
# element replace a single hydrate. resolve_references stayed, though —
|
|
183
|
+
# an entity command can declare a reference-typed attribute the same way
|
|
184
|
+
# an aggregate command can (CommandRules#resolve_references is shared by
|
|
185
|
+
# both interpreters), even though nothing in the real corpus does yet.
|
|
186
|
+
value_object "EntityDispatchOrder" do
|
|
187
|
+
attribute :step, String,
|
|
188
|
+
one_of: ["normalize_args", "refuse_role_mismatch", "resolve_references", "hydrate_parent",
|
|
189
|
+
"locate_element", "enforce_givens", "admissible_transition", "apply_mutations",
|
|
190
|
+
"advance_lifecycle", "enforce_ensures", "enforce_invariants", "save", "emit"]
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Runtime::Errors::DOMAIN_REFUSALS — what counts as the domain judging,
|
|
194
|
+
# as opposed to the runtime breaking. Anything outside this set that reaches
|
|
195
|
+
# a refusal list is a bug wearing a refusal's clothes.
|
|
196
|
+
value_object "DomainRefusal" do
|
|
197
|
+
attribute :name, String,
|
|
198
|
+
one_of: ["AbsentArgument", "AlreadyExists", "AttributeAbsent", "EnsuresNotMet", "GivenNotMet",
|
|
199
|
+
"InvariantViolation", "LifecycleRefused", "NotFound", "ProjectionAbsent", "RemoteRefusal",
|
|
200
|
+
"TypeMismatch", "Unauthorized", "UnknownArgument", "UnknownVerb"]
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# THE WORDING ITSELF, for every DomainRefusal site that is not already
|
|
204
|
+
# data — `given`/`ensures`/a declared `invariant` already carry their own
|
|
205
|
+
# description, read at dispatch time off the command or value object that
|
|
206
|
+
# declared them. Everything here is different in kind: a LANGUAGE-LEVEL
|
|
207
|
+
# refusal, the same wording for every domain, not authored per-bluebook —
|
|
208
|
+
# closer to Comparison/SignTest beside it than to a given. So it follows
|
|
209
|
+
# THEIR pattern, not given's: declared here for a human to read and a
|
|
210
|
+
# conformance spec to hold equal, and a hand-typed table
|
|
211
|
+
# (RefusalWording) is what a dispatch
|
|
212
|
+
# actually reads — the same reason Evaluator::SIGN_TEST_OPERATORS is
|
|
213
|
+
# hand-typed rather than read live off this very chapter at every call.
|
|
214
|
+
#
|
|
215
|
+
# `{name}` markers are placeholders — plain text substitution, not
|
|
216
|
+
# expression syntax ; a template is read, never evaluated. Two call
|
|
217
|
+
# sites that happen to raise the same sentence share one `site` row
|
|
218
|
+
# (entity_interpreter.rb and command_interpreter.rb's own "not found"
|
|
219
|
+
# messages, for instance) rather than being declared as two facts that
|
|
220
|
+
# would have to be kept identical by hand.
|
|
221
|
+
value_object "RefusalTemplate" do
|
|
222
|
+
attribute :refusal, String, admits: "Vocabulary::DomainRefusal"
|
|
223
|
+
attribute :site, String
|
|
224
|
+
attribute :template, String
|
|
225
|
+
|
|
226
|
+
member refusal: "NotFound", site: "creating_no_identity",
|
|
227
|
+
template: "{command} creates a {aggregate} — pass {identity}:"
|
|
228
|
+
member refusal: "AlreadyExists", site: "creating_duplicate",
|
|
229
|
+
template: "{command} creates a {aggregate} that already exists — {identity} {offered}"
|
|
230
|
+
member refusal: "AlreadyExists", site: "entity_duplicate",
|
|
231
|
+
template: "a {entity} already exists on {aggregate} — {identity} {offered}"
|
|
232
|
+
member refusal: "NotFound", site: "acting_no_identity",
|
|
233
|
+
template: "{command} acts on an existing {aggregate} — pass {identity}:"
|
|
234
|
+
member refusal: "NotFound", site: "record_missing",
|
|
235
|
+
template: "no {aggregate} with {identity} {offered}"
|
|
236
|
+
member refusal: "NotFound", site: "entity_parent_no_identity",
|
|
237
|
+
template: "{command} acts on a {aggregate}'s {entity} — pass {identity}:"
|
|
238
|
+
member refusal: "UnknownVerb", site: "entity_unknown",
|
|
239
|
+
template: "{aggregate} has no entity {entity}"
|
|
240
|
+
member refusal: "NotFound", site: "entity_element_no_identity",
|
|
241
|
+
template: "{command} acts on one {entity} — pass {identity}:"
|
|
242
|
+
member refusal: "NotFound", site: "entity_element_missing",
|
|
243
|
+
template: "no {entity} with {identity} {wants} on {aggregate} {parent_id}"
|
|
244
|
+
member refusal: "NotFound", site: "reference_target_missing",
|
|
245
|
+
template: "no {target} with {heads} {key}"
|
|
246
|
+
member refusal: "NotFound", site: "read_model_reference_missing",
|
|
247
|
+
template: "no {aggregate} with reference {offered}"
|
|
248
|
+
member refusal: "TypeMismatch", site: "read_model_object_reference",
|
|
249
|
+
template: "{query} refused — a reference is an id, and {field} arrived as an object"
|
|
250
|
+
member refusal: "UnknownVerb", site: "no_query",
|
|
251
|
+
template: "{aggregate} has no query {query}"
|
|
252
|
+
member refusal: "UnknownVerb", site: "entity_query_missing",
|
|
253
|
+
template: "{entity} has no query {query}"
|
|
254
|
+
member refusal: "UnknownVerb", site: "entity_holds_no_list",
|
|
255
|
+
template: "{aggregate} holds no list of {entity}"
|
|
256
|
+
member refusal: "UnknownVerb", site: "entity_no_command",
|
|
257
|
+
template: "{entity} has no command {command}"
|
|
258
|
+
member refusal: "UnknownVerb", site: "aggregate_no_command",
|
|
259
|
+
template: "{aggregate} has no command {command}"
|
|
260
|
+
member refusal: "UnknownVerb", site: "port_no_operation",
|
|
261
|
+
template: "{port} has no operation {operation}"
|
|
262
|
+
member refusal: "UnknownVerb", site: "no_domain",
|
|
263
|
+
template: "no domain {domain} loaded (verb {verb})"
|
|
264
|
+
member refusal: "UnknownVerb", site: "no_read_model",
|
|
265
|
+
template: "{domain} has no read model {query}"
|
|
266
|
+
member refusal: "UnknownVerb", site: "not_fully_qualified",
|
|
267
|
+
template: "{verb} is not a fully-qualified verb (Domain::Aggregate.Command)"
|
|
268
|
+
member refusal: "UnknownVerb", site: "no_aggregate",
|
|
269
|
+
template: "{domain} has no aggregate {aggregate}"
|
|
270
|
+
member refusal: "LifecycleRefused", site: "transition_blocked",
|
|
271
|
+
template: "{command} refused — {field} is {current}, and {command} moves it only from {allowed}"
|
|
272
|
+
member refusal: "TypeMismatch", site: "value_object_shape",
|
|
273
|
+
template: "{name} is a {type} — pass its fields as an object, not {offered}"
|
|
274
|
+
member refusal: "TypeMismatch", site: "reference_as_object",
|
|
275
|
+
template: "{command} refused — a reference is an id, and {attribute} arrived as an object{known_by}"
|
|
276
|
+
member refusal: "TypeMismatch", site: "multi_field_scalar",
|
|
277
|
+
template: "{type} has multiple fields and cannot stand in for a scalar"
|
|
278
|
+
member refusal: "TypeMismatch", site: "composite_identity",
|
|
279
|
+
template: "{type} is a composite identity — an identity must have exactly one field"
|
|
280
|
+
member refusal: "TypeMismatch", site: "numeric_field",
|
|
281
|
+
template: "{type}.{field} expects {expected}, got {offered}"
|
|
282
|
+
member refusal: "TypeMismatch", site: "pattern_mismatch",
|
|
283
|
+
template: "{type}.{field} must match {pattern}, got {offered}"
|
|
284
|
+
member refusal: "TypeMismatch", site: "arithmetic_amount",
|
|
285
|
+
template: "{op} of {target} needs an Integer, got {offered}"
|
|
286
|
+
member refusal: "TypeMismatch", site: "arithmetic_current",
|
|
287
|
+
template: "{op} of {target} needs an Integer {target}, got {offered}"
|
|
288
|
+
member refusal: "TypeMismatch", site: "arithmetic_shared_field",
|
|
289
|
+
template: "{op} of {target} needs a value object with one shared Integer field"
|
|
290
|
+
member refusal: "UnknownArgument", site: "unknown_args",
|
|
291
|
+
template: "{command} does not declare {unknown} — it takes {declared}"
|
|
292
|
+
member refusal: "AbsentArgument", site: "absent_args",
|
|
293
|
+
template: "{command} was not given {absent} — it takes {declared}"
|
|
294
|
+
member refusal: "InvariantViolation", site: "closed_set_member",
|
|
295
|
+
template: "{type} admits {admitted} — got {offered}"
|
|
296
|
+
member refusal: "InvariantViolation", site: "value_object_invariant",
|
|
297
|
+
template: "{name} invariant violated — {description} (given {offered})"
|
|
298
|
+
member refusal: "InvariantViolation", site: "admits_declared_set",
|
|
299
|
+
template: "{name} admits {admits} — {admitted} — got {offered}"
|
|
300
|
+
member refusal: "InvariantViolation", site: "undeclared_set",
|
|
301
|
+
template: "{name} admits {admits}, which this chapter does not declare — a closed set is named " \
|
|
302
|
+
"Aggregate::SetName, and it must be one the bluebook actually holds"
|
|
303
|
+
member refusal: "Unauthorized", site: "tenant_required",
|
|
304
|
+
template: "{query} declares authorize with tenant: {field} — pass {field}: to name which " \
|
|
305
|
+
"{field} this ask is scoped to"
|
|
306
|
+
member refusal: "Unauthorized", site: "role_mismatch",
|
|
307
|
+
template: "{command} refused — role: {role}, and the caller stated {caller_role}"
|
|
308
|
+
member refusal: "AttributeAbsent", site: "absent_read",
|
|
309
|
+
template: "{aggregate} {field} is absent on this record — declared, not optional, and " \
|
|
310
|
+
"added since it was written. Backfill it in a translation (backfill :{field}, " \
|
|
311
|
+
"default: ...), or declare it optional: true"
|
|
312
|
+
# S12, ADR 0025 — the same silent-wrong-answer class AttributeAbsent
|
|
313
|
+
# above refuses, one line up: a `projects` field this record predates,
|
|
314
|
+
# or that no rebuild sweep has populated yet, read by a rule as
|
|
315
|
+
# though it were a real value rather than one nobody has copied over.
|
|
316
|
+
member refusal: "ProjectionAbsent", site: "absent_read",
|
|
317
|
+
template: "{aggregate} {field} is not yet projected on this record — declared via " \
|
|
318
|
+
"projects :{field}, but no rebuild sweep has populated it. Run the sweep, " \
|
|
319
|
+
"or read {reference}.{remote_field} directly if this rule cannot wait"
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# SagaInterpreter::REFUSED.
|
|
323
|
+
#
|
|
324
|
+
# A leg answers an EVENT — `on "AccountDebited"` — or it answers one of these,
|
|
325
|
+
# which are not events at all: no aggregate announces that a leg the procedure
|
|
326
|
+
# dispatched was declined. `on :refused` is the compensating leg, and without
|
|
327
|
+
# this declaration the word lived only as a magic string in the interpreter,
|
|
328
|
+
# and a reader of the language could not discover the
|
|
329
|
+
# trigger existed.
|
|
330
|
+
value_object "Trigger" do
|
|
331
|
+
attribute :name, String, one_of: ["refused"]
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Hecks::Forms::FieldShape's own EMAIL_HINT/URL_HINT/
|
|
335
|
+
# TEL_HINT/TEXTAREA_HINT (lib/hecks/forms/field_shape.rb)
|
|
336
|
+
# — the regexes `text_field` matches a text attribute's own NAME
|
|
337
|
+
# against (case-insensitively) to guess an HTML input type or a
|
|
338
|
+
# textarea kind, when nothing more specific (a `pattern:`, an
|
|
339
|
+
# `admits:`, a closed set) already answered the question. Declared
|
|
340
|
+
# here for the same reason RefusalTemplate is: a LANGUAGE-LEVEL
|
|
341
|
+
# rendering convention, the same guess for every domain, not
|
|
342
|
+
# authored per-bluebook — closer to Comparison/SignTest than to a
|
|
343
|
+
# given. `pattern` is the regex SOURCE, no delimiters or flags
|
|
344
|
+
# (Ruby's own `Regexp#source`) — spec/field_hint_conformance_spec.rb
|
|
345
|
+
# holds FieldShape's four hand-typed constants equal to this, both
|
|
346
|
+
# directions, the same conformance shape refusal_wording_
|
|
347
|
+
# conformance_spec.rb already holds RefusalTemplate to.
|
|
348
|
+
#
|
|
349
|
+
# `resolves_to` names WHICH Field attribute a match sets — `html_type`
|
|
350
|
+
# for email/url/tel (three candidates, only one wins, checked in that
|
|
351
|
+
# order), `kind` for textarea (checked separately, and only once
|
|
352
|
+
# html_type has already fallen through to "text").
|
|
353
|
+
value_object "FieldHint" do
|
|
354
|
+
attribute :name, String
|
|
355
|
+
attribute :pattern, String
|
|
356
|
+
attribute :resolves_to, String
|
|
357
|
+
|
|
358
|
+
member name: "email", pattern: 'email', resolves_to: "html_type"
|
|
359
|
+
member name: "url", pattern: '\b(url|uri|website|link)\b', resolves_to: "html_type"
|
|
360
|
+
member name: "tel", pattern: 'phone|\btel(ephone)?\b', resolves_to: "html_type"
|
|
361
|
+
member name: "textarea", pattern: '\b(text|body|note|notes|description|message|comment)\b', resolves_to: "kind"
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Hecks.bluebook "Hecksagon" do
|
|
2
|
+
aggregate "AdapterBinding" do
|
|
3
|
+
description "One aggregate-to-adapter binding inside a hecksagon — the verb it answers, the adapter it names. Its own root because a hecksagon's binds are an open set of verbs (one per declared port), which no value object can hold — the same reasoning Wiring carries for a world's settings."
|
|
4
|
+
|
|
5
|
+
# The retained parent edge is structural state. `hecksagon` below is
|
|
6
|
+
# separately the text component of this binding's own compound identity,
|
|
7
|
+
# so the relationship keeps the same explicit `_ref` distinction World::
|
|
8
|
+
# Wiring uses for its parent edge.
|
|
9
|
+
belongs_to Hecksagon, as: :hecksagon_ref
|
|
10
|
+
|
|
11
|
+
# THE HECKSAGON IT IS IN, THE AGGREGATE IT NAMES, THE VERB IT ANSWERS.
|
|
12
|
+
# One hecksagon binds one adapter per (aggregate, verb) pair — that is
|
|
13
|
+
# what a binding IS — so the triple identifies it.
|
|
14
|
+
identified_by :hecksagon, :aggregate, :verb
|
|
15
|
+
|
|
16
|
+
attribute :hecksagon, BindingText
|
|
17
|
+
attribute :aggregate, BindingText
|
|
18
|
+
attribute :verb, BindingText
|
|
19
|
+
attribute :adapter, BindingText
|
|
20
|
+
attribute :role, BindingText, optional: true
|
|
21
|
+
|
|
22
|
+
value_object "BindingText" do
|
|
23
|
+
attribute :value, String
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
command "Bind" do
|
|
27
|
+
role "Deployment"
|
|
28
|
+
goal "Name the adapter one aggregate answers one verb through"
|
|
29
|
+
|
|
30
|
+
# A creating command receives the parent's identity as an ordinary
|
|
31
|
+
# value fact. It does not declare a behavioral relationship or use the
|
|
32
|
+
# parent as a hidden receiver.
|
|
33
|
+
attribute :hecksagon_ref, HecksagonName
|
|
34
|
+
attribute :aggregate, BindingText
|
|
35
|
+
attribute :verb, BindingText
|
|
36
|
+
attribute :adapter, BindingText
|
|
37
|
+
attribute :role, BindingText, optional: true
|
|
38
|
+
|
|
39
|
+
given("a binding names its verb") { !verb.value.to_s.empty? }
|
|
40
|
+
|
|
41
|
+
sets :hecksagon_ref
|
|
42
|
+
sets :hecksagon
|
|
43
|
+
sets :aggregate
|
|
44
|
+
sets :verb
|
|
45
|
+
sets :adapter
|
|
46
|
+
sets :role
|
|
47
|
+
|
|
48
|
+
emits "Bound"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Hecks.bluebook "Hecksagon" do
|
|
2
|
+
aggregate "DomainPort" do
|
|
3
|
+
description "A primary port — the boundary between a domain and its adapters, in hexagonal terms, is exactly what a hecksagon already IS for every other port. Root-level (belongs to the chapter) or aggregate-scoped (reached the same way persisted_by is, through the open Const.verb(...) door). One of two shapes, never both: a list of operations translating an inbound fact into this domain's own events, or a bare verb naming a swappable resource port (the same Hecks.port a project's own .port file declares, reached from inside the hecksagon instead)."
|
|
4
|
+
|
|
5
|
+
identified_by PortName, as: :name
|
|
6
|
+
|
|
7
|
+
attribute :verb, PortVerb, optional: true
|
|
8
|
+
|
|
9
|
+
value_object "PortName" do
|
|
10
|
+
attribute :value, String
|
|
11
|
+
invariant("a port is named") { !value.to_s.empty? }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
value_object "PortVerb" do
|
|
15
|
+
attribute :value, String
|
|
16
|
+
invariant("a verb is named") { !value.to_s.empty? }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# HOW DOMAINPORT IS SPELLED. These rows live with the concept
|
|
20
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
21
|
+
# Contexts represented here: DomainPort.
|
|
22
|
+
value_object "KeywordSeed" do
|
|
23
|
+
attribute :word, String
|
|
24
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
25
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
26
|
+
attribute :inner, String
|
|
27
|
+
attribute :opens, String
|
|
28
|
+
attribute :fills, String
|
|
29
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
30
|
+
attribute :was, String
|
|
31
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
32
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
33
|
+
|
|
34
|
+
member word: "operation", context: "DomainPort", body: "keywords", inner: "PortOperation", opens: "PortOperation", fills: "", calls: "tells_impl"
|
|
35
|
+
member word: "tells", context: "DomainPort", body: "keywords", inner: "PortOperation", opens: "PortOperation", fills: "", calls: "tells_impl"
|
|
36
|
+
member word: "asks", context: "DomainPort", body: "keywords", inner: "PortOperation", opens: "PortOperation", fills: "", calls: "asks_impl"
|
|
37
|
+
member word: "verb", context: "DomainPort", body: "none", inner: "", opens: "", fills: "verb"
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
value_object "ArgumentSeed" do
|
|
42
|
+
attribute :keyword, String
|
|
43
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
44
|
+
attribute :at, String
|
|
45
|
+
attribute :named, String
|
|
46
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
47
|
+
attribute :required, String
|
|
48
|
+
attribute :fills, String
|
|
49
|
+
attribute :selects, String
|
|
50
|
+
attribute :pair_key_fills, String
|
|
51
|
+
attribute :pair_value_fills, String
|
|
52
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
53
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
54
|
+
attribute :variadic, String
|
|
55
|
+
attribute :coerce, String
|
|
56
|
+
attribute :blank_message, String
|
|
57
|
+
|
|
58
|
+
member keyword: "operation", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
59
|
+
member keyword: "tells", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
60
|
+
member keyword: "asks", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
61
|
+
member keyword: "verb", context: "DomainPort", at: "1", named: "", kind: "text", required: "true", fills: "verb"
|
|
62
|
+
|
|
63
|
+
# THE RECEIVING AGGREGATE — PortOperationBuilder's own `reference_to`
|
|
64
|
+
# (inside the block) is refused (#335); this is the sanctioned
|
|
65
|
+
# replacement, named directly on the word that opens the block
|
|
66
|
+
# rather than a statement inside it. `kind: "constant"`, matching
|
|
67
|
+
# `reference_to`'s own first positional argument
|
|
68
|
+
# (port_operation.bluebook) — same bareword-constant resolution,
|
|
69
|
+
# just moved.
|
|
70
|
+
member keyword: "operation", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
|
|
71
|
+
member keyword: "tells", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
|
|
72
|
+
member keyword: "asks", context: "DomainPort", at: "", named: "to", kind: "constant", required: "false", fills: "to"
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Hecks.bluebook "Hecksagon" do
|
|
2
|
+
aggregate "Hecksagon" do
|
|
3
|
+
description "One .hecksagon — the events a domain subscribes to, and the root every binding hangs off. A sibling artifact to the bluebook, not part of it."
|
|
4
|
+
|
|
5
|
+
identified_by HecksagonName, as: :domain
|
|
6
|
+
|
|
7
|
+
attribute :subscriptions, list_of(Subscription)
|
|
8
|
+
attribute :framework_members, list_of(FrameworkMember)
|
|
9
|
+
attribute :vendored_bluebooks, list_of(VendoredBluebook)
|
|
10
|
+
|
|
11
|
+
value_object "HecksagonName" do
|
|
12
|
+
attribute :value, String
|
|
13
|
+
invariant("a hecksagon names its domain") { !value.to_s.empty? }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
value_object "Subscription" do
|
|
17
|
+
attribute :value, String
|
|
18
|
+
invariant("a subscription names an event") { !value.to_s.empty? }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# A `framework/bluebook/` member this hecksagon attaches — Governance,
|
|
22
|
+
# Identity, whatever else lands beside them. Same shape as
|
|
23
|
+
# `Subscription` beside it, one word over.
|
|
24
|
+
value_object "FrameworkMember" do
|
|
25
|
+
attribute :value, String
|
|
26
|
+
invariant("a framework member is named") { !value.to_s.empty? }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# A vendored, external bluebook this hecksagon attaches — one level
|
|
30
|
+
# further out than `FrameworkMember`: not a member shipped inside
|
|
31
|
+
# hecks's own lib/, but a separate package vendored into the
|
|
32
|
+
# consuming project's own checkout. Same shape as `FrameworkMember`
|
|
33
|
+
# beside it, one word over — see EmbryonautBluebook's own header.
|
|
34
|
+
value_object "VendoredBluebook" do
|
|
35
|
+
attribute :value, String
|
|
36
|
+
invariant("a vendored bluebook is named") { !value.to_s.empty? }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
command "Declare" do
|
|
40
|
+
role "Deployment"
|
|
41
|
+
goal "Open a hecksagon for a domain"
|
|
42
|
+
|
|
43
|
+
attribute :domain, HecksagonName
|
|
44
|
+
|
|
45
|
+
sets :domain
|
|
46
|
+
|
|
47
|
+
emits "HecksagonDeclared"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
command "Subscribe" do
|
|
51
|
+
role "Deployment"
|
|
52
|
+
goal "Take a hecksagon's own event, from outside the domain's own bluebook"
|
|
53
|
+
|
|
54
|
+
attribute :event, Subscription
|
|
55
|
+
|
|
56
|
+
sets :subscriptions, append: { value: :event }
|
|
57
|
+
|
|
58
|
+
emits "SubscriptionAdded"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
command "UsesFramework" do
|
|
62
|
+
role "Deployment"
|
|
63
|
+
goal "Attach a framework/bluebook/ member to this hecksagon"
|
|
64
|
+
|
|
65
|
+
attribute :member, FrameworkMember
|
|
66
|
+
|
|
67
|
+
sets :framework_members, append: { value: :member }
|
|
68
|
+
|
|
69
|
+
emits "FrameworkMemberAttached"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
command "UsesEmbryonautBluebook" do
|
|
73
|
+
role "Deployment"
|
|
74
|
+
goal "Attach a vendored, external bluebook to this hecksagon"
|
|
75
|
+
|
|
76
|
+
attribute :package, VendoredBluebook
|
|
77
|
+
|
|
78
|
+
sets :vendored_bluebooks, append: { value: :package }
|
|
79
|
+
|
|
80
|
+
emits "VendoredBluebookAttached"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# HOW HECKSAGON IS SPELLED. These rows live with the concept
|
|
84
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
85
|
+
# Contexts represented here: File, Hecksagon.
|
|
86
|
+
value_object "KeywordSeed" do
|
|
87
|
+
attribute :word, String
|
|
88
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
89
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
90
|
+
attribute :inner, String
|
|
91
|
+
attribute :opens, String
|
|
92
|
+
attribute :fills, String
|
|
93
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
94
|
+
attribute :was, String
|
|
95
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
96
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
97
|
+
|
|
98
|
+
member word: "hecksagon", context: "File", body: "keywords", inner: "Hecksagon", opens: "Hecksagon", fills: ""
|
|
99
|
+
member word: "subscribe", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "subscriptions"
|
|
100
|
+
member word: "uses_framework", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "framework_members"
|
|
101
|
+
member word: "uses_embryonaut_bluebook", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "vendored_bluebooks"
|
|
102
|
+
member word: "port", context: "Hecksagon", body: "keywords", inner: "DomainPort", opens: "DomainPort", fills: "", calls: "port_impl"
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
value_object "ArgumentSeed" do
|
|
107
|
+
attribute :keyword, String
|
|
108
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
109
|
+
attribute :at, String
|
|
110
|
+
attribute :named, String
|
|
111
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
112
|
+
attribute :required, String
|
|
113
|
+
attribute :fills, String
|
|
114
|
+
attribute :selects, String
|
|
115
|
+
attribute :pair_key_fills, String
|
|
116
|
+
attribute :pair_value_fills, String
|
|
117
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
118
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
119
|
+
attribute :variadic, String
|
|
120
|
+
attribute :coerce, String
|
|
121
|
+
attribute :blank_message, String
|
|
122
|
+
|
|
123
|
+
member keyword: "hecksagon", context: "File", at: "1", named: "", kind: "text", required: "true", fills: "domain"
|
|
124
|
+
member keyword: "subscribe", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "subscriptions"
|
|
125
|
+
member keyword: "uses_framework", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "framework_members"
|
|
126
|
+
member keyword: "uses_embryonaut_bluebook", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "vendored_bluebooks"
|
|
127
|
+
member keyword: "port", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|