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,221 @@
|
|
|
1
|
+
require_relative "generic_dispatch"
|
|
2
|
+
module Hecks
|
|
3
|
+
module Bluebook
|
|
4
|
+
module DSL
|
|
5
|
+
# THE RUBY-SIDE `word_gate` (`rust/parser/src/parse/mod.rs`'s own,
|
|
6
|
+
# read there first — this is the same job, one level up: Rust's own
|
|
7
|
+
# gate refuses a mistyped/inadmissible WORD directly, at the
|
|
8
|
+
# moment it reads a line of `.bluebook` SOURCE TEXT, before any
|
|
9
|
+
# per-construct parsing runs. Ruby never lexes source text — a
|
|
10
|
+
# `.bluebook` file IS Ruby, so `given("x")` is ALREADY a real
|
|
11
|
+
# method call by the time any of this code runs, and Ruby's own
|
|
12
|
+
# method dispatch already refuses an ARITY mismatch on an
|
|
13
|
+
# EXISTING method for free. What Ruby's own dispatch does NOT do
|
|
14
|
+
# is consult the self-hosted grammar table AT ALL — a mistyped
|
|
15
|
+
# word (`giv3n("x")`) or a word used in the wrong context
|
|
16
|
+
# (`identified_by` inside a `command` block) just raises Ruby's
|
|
17
|
+
# own generic `NoMethodError`, naming nothing about what the
|
|
18
|
+
# language actually admits. This module closes that gap.
|
|
19
|
+
#
|
|
20
|
+
# `method_missing`/`respond_to_missing?` ONLY — a word this
|
|
21
|
+
# builder class already answers with an ordinary `def` (or a
|
|
22
|
+
# shared mixin method like `AttributeCollector#attribute`) never
|
|
23
|
+
# reaches this module at all; Ruby's own method lookup finds it
|
|
24
|
+
# first, and item #13's later slices haven't removed every one of
|
|
25
|
+
# those yet. This WAS "zero behavior change for every currently-
|
|
26
|
+
# valid line in the entire corpus" in its own first slice — since
|
|
27
|
+
# item #13's full metaprogrammed dispatch (slice 1, whole-project
|
|
28
|
+
# table-unification survey) started REMOVING the hand-written
|
|
29
|
+
# methods this module's own admissibility check used to defer to,
|
|
30
|
+
# some words now execute for real here too, via `GenericDispatch`
|
|
31
|
+
# — see that module's own header for exactly which ones, and the
|
|
32
|
+
# full account of what was verified before each was migrated. A
|
|
33
|
+
# mistyped or wrongly-contexted word still gets the same real,
|
|
34
|
+
# helpful, table-driven refusal Rust's own `word_gate` already
|
|
35
|
+
# gives, instead of Ruby's own generic `NoMethodError` — that half
|
|
36
|
+
# is genuinely unchanged.
|
|
37
|
+
#
|
|
38
|
+
# `self.class::GRAMMAR_CONTEXT` — each including class names which
|
|
39
|
+
# row of the self-hosted `Context` closed set it corresponds to
|
|
40
|
+
# (`AggregateBuilder::GRAMMAR_CONTEXT = "Aggregate"`, etc.) — the
|
|
41
|
+
# SAME string `word_gate`'s own `context` parameter already is on
|
|
42
|
+
# the Rust side, read off the identical table.
|
|
43
|
+
#
|
|
44
|
+
# BOOTSTRAPPING GATED, the same reason `RuleReference#lookup`
|
|
45
|
+
# already is (`rule_reference.rb`'s own comment has the full
|
|
46
|
+
# story) — the meta-domain's own bootstrap calls dozens of
|
|
47
|
+
# keywords on itself before its own grammar table exists to
|
|
48
|
+
# check them against. For most words, this module steps aside
|
|
49
|
+
# entirely during bootstrap (`super`, Ruby's own ordinary
|
|
50
|
+
# `NoMethodError`) — the exact behavior every builder already had
|
|
51
|
+
# before this module existed, and (unlike `RuleReference`) there
|
|
52
|
+
# is deliberately no fallback covering the whole ~200-row table —
|
|
53
|
+
# that would defeat the entire point.
|
|
54
|
+
#
|
|
55
|
+
# ONE NARROW EXCEPTION, added in item #13's full metaprogrammed
|
|
56
|
+
# dispatch (slice 3, whole-project table-unification survey):
|
|
57
|
+
# `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`, a SMALL, EXPLICIT
|
|
58
|
+
# table naming the same (context, word) -> method pairs the real
|
|
59
|
+
# `calls:` column would say once it exists — used ONLY for words
|
|
60
|
+
# BOTH migrated to the `calls:` shape AND bootstrap-reachable
|
|
61
|
+
# (`attribute`, today). This is the one place in this whole arc a
|
|
62
|
+
# bootstrap fallback was worth building despite `RuleReference`'s
|
|
63
|
+
# own precedent against it: it duplicates NO logic, only a METHOD
|
|
64
|
+
# NAME — `attribute_impl`'s own real, hand-written body is called
|
|
65
|
+
# either way, bootstrap or not, so there is nothing here that can
|
|
66
|
+
# drift the way a full behavioral duplicate could.
|
|
67
|
+
#
|
|
68
|
+
# TWO FURTHER PIECES, both slice 5:
|
|
69
|
+
# - `word_gate_dispatch` is the same admission+dispatch logic
|
|
70
|
+
# `method_missing` below runs, factored out so a class with
|
|
71
|
+
# its OWN class-level `method_missing` (`HecksagonBuilder`'s/
|
|
72
|
+
# `WorldBuilder`'s genuinely open-ended verb vocabulary) can
|
|
73
|
+
# call it directly and fall back to its own open-verb handling
|
|
74
|
+
# only when this returns `NOT_ADMITTED` — a class-level `def`
|
|
75
|
+
# always wins over an included module's in Ruby's own method
|
|
76
|
+
# resolution, so their OWN `method_missing` is the only one
|
|
77
|
+
# that ever runs for them, and this is what lets a real,
|
|
78
|
+
# closed-set word (`port`/`realm`/`latest`) still reach
|
|
79
|
+
# `GenericDispatch` despite that.
|
|
80
|
+
# - the "Type"-position fallback inside `word_gate_dispatch`
|
|
81
|
+
# itself, for `one_of`/`list_of` — called inside an
|
|
82
|
+
# attribute's own type argument, with `self` as whatever
|
|
83
|
+
# builder is currently `instance_eval`ing, never a dedicated
|
|
84
|
+
# "Type" builder `self.class::GRAMMAR_CONTEXT` could ever
|
|
85
|
+
# name. See that method's own comment.
|
|
86
|
+
module WordGate
|
|
87
|
+
# A caller with its OWN class-level `method_missing`
|
|
88
|
+
# (`HecksagonBuilder`/`WorldBuilder` — see `word_gate_dispatch`'s
|
|
89
|
+
# own header) checks for this to tell "not a word the grammar
|
|
90
|
+
# admits at all" apart from every other outcome below (a real
|
|
91
|
+
# dispatch, or a raised refusal) — never raised itself, so a
|
|
92
|
+
# caller can fall through to its own open-ended handling instead.
|
|
93
|
+
NOT_ADMITTED = Object.new.freeze
|
|
94
|
+
|
|
95
|
+
# PRIVATE, matching Ruby's own convention for both (`Object`
|
|
96
|
+
# defines them private too) — and load-bearing here, not just
|
|
97
|
+
# style: `spec/syntax_conformance_spec.rb`'s "declares every
|
|
98
|
+
# word X answers" check walks `public_instance_methods`, and a
|
|
99
|
+
# public `method_missing`/`respond_to_missing?` would show up
|
|
100
|
+
# there as two more "answered words" no row of the grammar ever
|
|
101
|
+
# declares, on every builder this module touches.
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def method_missing(word, *args, **kwargs, &block)
|
|
106
|
+
if MetaValidator.bootstrapping?
|
|
107
|
+
fallback = GenericDispatch::BOOTSTRAP_CALLS_FALLBACK
|
|
108
|
+
# Own context first, "Type" second — the same order the
|
|
109
|
+
# ordinary (non-bootstrapping) `word_gate_dispatch` path
|
|
110
|
+
# below checks them in, for the same reason: `list_of`/
|
|
111
|
+
# `one_of` used in an attribute's own type position never
|
|
112
|
+
# arrive with `self.class::GRAMMAR_CONTEXT == "Type"`.
|
|
113
|
+
target = fallback[[self.class::GRAMMAR_CONTEXT, word.to_s]] || fallback[["Type", word.to_s]]
|
|
114
|
+
return send(target, *args, **kwargs, &block) if target
|
|
115
|
+
|
|
116
|
+
return super
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
result = word_gate_dispatch(word, args, kwargs, block)
|
|
120
|
+
return super if result.equal?(NOT_ADMITTED)
|
|
121
|
+
|
|
122
|
+
result
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# THE CORE ADMISSION+DISPATCH LOGIC, factored out of
|
|
126
|
+
# `method_missing` — item #13's full metaprogrammed dispatch
|
|
127
|
+
# (slice 5, whole-project table-unification survey) — so a
|
|
128
|
+
# class with its OWN class-level `method_missing`
|
|
129
|
+
# (`HecksagonBuilder`'s/`WorldBuilder`'s genuinely open-ended
|
|
130
|
+
# verb vocabulary, `persisted_by "Heki"`/`posted_by "Carrier"`,
|
|
131
|
+
# can never BE a closed table) can still route a word THE
|
|
132
|
+
# GRAMMAR ADMITS through here first, falling back to its own
|
|
133
|
+
# open-verb handling only for what this doesn't recognize at
|
|
134
|
+
# all — unblocking `Hecksagon#port`/`World#realm`/`World#latest`,
|
|
135
|
+
# each a real, closed-set word that happened to sit on a class
|
|
136
|
+
# whose own `method_missing` a class-level `def` always wins
|
|
137
|
+
# over Ruby's own module-inclusion order.
|
|
138
|
+
#
|
|
139
|
+
# NEVER RAISES "not admitted" — returns `NOT_ADMITTED` instead,
|
|
140
|
+
# so the caller (this module's own `method_missing`, or one of
|
|
141
|
+
# the two above) decides what that means for it. DOES still
|
|
142
|
+
# raise the richer, table-driven refusals below once a word is
|
|
143
|
+
# admitted-but-unimplemented, or admitted-somewhere-else-only —
|
|
144
|
+
# those are real, useful refusals regardless of which
|
|
145
|
+
# `method_missing` is asking.
|
|
146
|
+
def word_gate_dispatch(word, args, kwargs, block)
|
|
147
|
+
context = self.class::GRAMMAR_CONTEXT
|
|
148
|
+
rows = MetaValidator::SyntaxBoot.call
|
|
149
|
+
keywords = rows[:keywords]
|
|
150
|
+
admitted = keywords.select { |row| row[:context] == context && (row[:word] == word.to_s || row[:was] == word.to_s) }
|
|
151
|
+
|
|
152
|
+
# THE TYPE-POSITION FALLBACK — item #13's full metaprogrammed
|
|
153
|
+
# dispatch (slice 5). `one_of`/`list_of`, called inside an
|
|
154
|
+
# attribute's own type argument (`attribute :x,
|
|
155
|
+
# one_of("a","b")`), run with `self` as whatever builder is
|
|
156
|
+
# CURRENTLY instance_eval'ing — there is no dedicated "Type"
|
|
157
|
+
# builder of its own; every attribute()-taking builder answers
|
|
158
|
+
# these identically, through the shared `AttributeCollector`
|
|
159
|
+
# mixin. `self.class::GRAMMAR_CONTEXT` can never actually BE
|
|
160
|
+
# "Type", so a word admitted only there would otherwise look
|
|
161
|
+
# inadmissible everywhere. Checked only once THIS context has
|
|
162
|
+
# already come up empty, so a context with its own same-named
|
|
163
|
+
# row (`ValueObject`'s own `one_of`, the block-wrapper form)
|
|
164
|
+
# keeps using that instead, unaffected.
|
|
165
|
+
if admitted.empty?
|
|
166
|
+
type_admitted = keywords.select { |row| row[:context] == "Type" && row[:word] == word.to_s }
|
|
167
|
+
unless type_admitted.empty?
|
|
168
|
+
admitted = type_admitted
|
|
169
|
+
context = "Type"
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
return NOT_ADMITTED if admitted.empty? && !admitted_anywhere?(keywords, word)
|
|
174
|
+
|
|
175
|
+
if admitted.empty?
|
|
176
|
+
legal = keywords.select { |row| row[:context] == context }.map { |row| row[:word] }.uniq.sort
|
|
177
|
+
raise Malformed,
|
|
178
|
+
"'#{word}' is not a word #{context} admits — legal words here: #{legal.join(', ')}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# ITEM #13's FULL METAPROGRAMMED DISPATCH — the word IS
|
|
182
|
+
# admitted here, and this builder has no hand-written method
|
|
183
|
+
# left for it; before falling through to the "not yet
|
|
184
|
+
# implemented" refusal every word without one still gets,
|
|
185
|
+
# offer it to GenericDispatch — the SAFE, verified subset of
|
|
186
|
+
# words whose whole behavior is now executed off this same
|
|
187
|
+
# table, not just checked against it.
|
|
188
|
+
dispatched = GenericDispatch.try(self, context, word.to_s, args, kwargs, block, rows)
|
|
189
|
+
return dispatched unless dispatched.equal?(GenericDispatch::NOT_HANDLED)
|
|
190
|
+
|
|
191
|
+
raise Malformed,
|
|
192
|
+
"'#{word}' is admitted by #{context}'s own grammar, but #{self.class} has no " \
|
|
193
|
+
"builder method for it yet — not yet implemented"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def respond_to_missing?(word, include_private = false)
|
|
197
|
+
return super if MetaValidator.bootstrapping?
|
|
198
|
+
|
|
199
|
+
context = self.class::GRAMMAR_CONTEXT
|
|
200
|
+
keywords = MetaValidator::SyntaxBoot.call[:keywords]
|
|
201
|
+
keywords.any? { |row| row[:context] == context && (row[:word] == word.to_s || row[:was] == word.to_s) } ||
|
|
202
|
+
keywords.any? { |row| row[:context] == "Type" && row[:word] == word.to_s } ||
|
|
203
|
+
super
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# A word admitted SOMEWHERE, just not in THIS context, still
|
|
207
|
+
# falls through to Ruby's own `NoMethodError` rather than this
|
|
208
|
+
# module's own richer refusal — `method_missing` fires for
|
|
209
|
+
# every typo in the whole codebase (this class's own genuinely
|
|
210
|
+
# private helper methods included), not just DSL keyword calls;
|
|
211
|
+
# only raise the RICH, table-driven message when the word is at
|
|
212
|
+
# least SOMETHING the grammar knows about, anywhere, so an
|
|
213
|
+
# unrelated Ruby-level typo inside a builder's own private code
|
|
214
|
+
# keeps its own ordinary, unconfusing `NoMethodError`.
|
|
215
|
+
def admitted_anywhere?(rows, word)
|
|
216
|
+
rows.any? { |row| row[:word] == word.to_s || row[:was] == word.to_s }
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require_relative "word_gate"
|
|
2
|
+
module Hecks
|
|
3
|
+
module Bluebook
|
|
4
|
+
module DSL
|
|
5
|
+
class SettingsCollector
|
|
6
|
+
def initialize = @values = {}
|
|
7
|
+
|
|
8
|
+
def method_missing(key, *args, &_block)
|
|
9
|
+
@values[key.to_sym] = args.size == 1 ? args.first : args
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def respond_to_missing?(_name, _include_private = false) = true
|
|
13
|
+
|
|
14
|
+
def to_h = @values
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class WorldBuilder
|
|
18
|
+
GRAMMAR_CONTEXT = "World"
|
|
19
|
+
|
|
20
|
+
include WordGate
|
|
21
|
+
|
|
22
|
+
def initialize(domain)
|
|
23
|
+
@domain = domain
|
|
24
|
+
@settings = {}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# RENAMED FROM `realm`/`latest` — item #13's full metaprogrammed
|
|
28
|
+
# dispatch (slice 5). Neither bootstrap-reachable (checked
|
|
29
|
+
# directly). Reached through `WordGate#method_missing`'s new
|
|
30
|
+
# `word_gate_dispatch`, called explicitly below since
|
|
31
|
+
# `WorldBuilder`'s own class-level `method_missing` (the
|
|
32
|
+
# open-verb catch-all beneath this) always wins over the
|
|
33
|
+
# module's — see `word_gate.rb`'s own header for the full
|
|
34
|
+
# mechanism.
|
|
35
|
+
def realm_impl(value)
|
|
36
|
+
@realm = required(value, "realm")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def latest_impl(value)
|
|
40
|
+
@latest = required(value, "latest version")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def method_missing(verb, *args, **kwargs, &block)
|
|
44
|
+
result = word_gate_dispatch(verb, args, kwargs, block)
|
|
45
|
+
return result unless result.equal?(WordGate::NOT_ADMITTED)
|
|
46
|
+
|
|
47
|
+
collector = SettingsCollector.new
|
|
48
|
+
collector.instance_eval(&block) if block
|
|
49
|
+
value = { adapter: args.first.to_s }.merge(kwargs).merge(collector.to_h)
|
|
50
|
+
@settings[verb.to_s] = value
|
|
51
|
+
@settings["#{verb}:#{args.first.to_s.downcase}"] = value
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def respond_to_missing?(_name, _include_private = false) = true
|
|
55
|
+
|
|
56
|
+
def build
|
|
57
|
+
MetaValidator.call_world(
|
|
58
|
+
World.new(domain: @domain, realm: @realm, latest: @latest, settings: @settings)
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.build(domain, &block)
|
|
63
|
+
builder = new(domain)
|
|
64
|
+
builder.instance_eval(&block) if block
|
|
65
|
+
builder.build
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def required(value, label)
|
|
71
|
+
# moved to the language: Realm / Latest invariants, in world.bluebook
|
|
72
|
+
value.to_s
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
# The authoring surface — one builder per declaration kind, collecting
|
|
4
|
+
# what a .bluebook file says into the IR. Builders call the
|
|
5
|
+
# meta-validator at build time, not at load time, so their require
|
|
6
|
+
# order here is the readable one.
|
|
7
|
+
module DSL
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# The query/read-model builders reach QuerySpecification at class-body
|
|
13
|
+
# level and cannot say so themselves (contents frozen) — the namespace
|
|
14
|
+
# file says it for them. The builders also build IR, at build time.
|
|
15
|
+
require_relative "../construct"
|
|
16
|
+
require_relative "../query_specification"
|
|
17
|
+
# The model the builders construct — `bluebook.rb` requires the whole
|
|
18
|
+
# set; this names the one file that declares the chapter class itself,
|
|
19
|
+
# which every builder returns into.
|
|
20
|
+
require_relative "chapter"
|
|
21
|
+
|
|
22
|
+
require_relative "dsl/malformed"
|
|
23
|
+
require_relative "dsl/const_shim"
|
|
24
|
+
require_relative "dsl/attribute_collector"
|
|
25
|
+
require_relative "dsl/identity_declaration"
|
|
26
|
+
require_relative "dsl/rule_reference"
|
|
27
|
+
require_relative "dsl/word_gate"
|
|
28
|
+
require_relative "dsl/value_object_builder"
|
|
29
|
+
require_relative "dsl/command_builder"
|
|
30
|
+
require_relative "dsl/lifecycle_builder"
|
|
31
|
+
require_relative "dsl/query_builder"
|
|
32
|
+
require_relative "dsl/read_model_builder"
|
|
33
|
+
require_relative "dsl/entity_builder"
|
|
34
|
+
require_relative "dsl/policy_builder"
|
|
35
|
+
require_relative "dsl/process_manager_builder"
|
|
36
|
+
require_relative "dsl/port_operation_builder"
|
|
37
|
+
require_relative "dsl/domain_port_builder"
|
|
38
|
+
require_relative "dsl/aggregate_builder"
|
|
39
|
+
require_relative "dsl/bluebook_builder"
|
|
40
|
+
require_relative "dsl/binding_proxy"
|
|
41
|
+
require_relative "dsl/hecksagon_builder"
|
|
42
|
+
require_relative "dsl/port_builder"
|
|
43
|
+
require_relative "dsl/adapter_builder"
|
|
44
|
+
require_relative "dsl/world_builder"
|
|
45
|
+
require_relative "dsl/translation_builder"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require_relative "behaviour/entity"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Bluebook
|
|
5
|
+
# An entity, as a RUBY CLASS — a piece of an aggregate that has an identity
|
|
6
|
+
# of its own.
|
|
7
|
+
#
|
|
8
|
+
# Crossing over closes the OWNER CHAIN. An entity declares commands, and
|
|
9
|
+
# until now those commands had no owner that could state an identity: an
|
|
10
|
+
# entity was an IR object, not a construct, so `Construct#hecks_fqn` refused
|
|
11
|
+
# rather than answering "Deposit" and looking right. Four of banking's
|
|
12
|
+
# commands were in that state. They can say what they are now —
|
|
13
|
+
# `Banking::Account.Ledger.Deposit` — which is the id the judge already mints
|
|
14
|
+
# for them.
|
|
15
|
+
#
|
|
16
|
+
# NOT const_set, for the same reason a command is not: a name inside one
|
|
17
|
+
# aggregate can denote more than one kind of thing, so the constant tree
|
|
18
|
+
# cannot index it.
|
|
19
|
+
#
|
|
20
|
+
# It must stay STRUCTURALLY INTERCHANGEABLE with an aggregate — the runtime
|
|
21
|
+
# builds `Instance.new(aggregate: entity)` and `CommandRules` takes either as
|
|
22
|
+
# `declaring` — so it answers `hecks_name`, `attributes`, `attribute`,
|
|
23
|
+
# `identified_by` and `lifecycle` exactly as an aggregate does. And it must
|
|
24
|
+
# keep NOT answering `value_object`: `Value.for_attribute` sniffs for that
|
|
25
|
+
# method to tell a piece from a head.
|
|
26
|
+
class Entity
|
|
27
|
+
extend Construct
|
|
28
|
+
extend Hecks::IR
|
|
29
|
+
extend Behaviour::Entity
|
|
30
|
+
|
|
31
|
+
emits_ir(
|
|
32
|
+
name: :hecks_name,
|
|
33
|
+
description: :description,
|
|
34
|
+
identified_by: :identity_paths,
|
|
35
|
+
attributes: many(:attributes),
|
|
36
|
+
commands: many(:commands),
|
|
37
|
+
queries: many(:queries),
|
|
38
|
+
# S17, ADR 0026 — "That is what `entity` is for, and `entity` is
|
|
39
|
+
# declared by the language and used zero times in it" (the ADR's
|
|
40
|
+
# own words). Dispatch nests inside Handler, so an entity's own
|
|
41
|
+
# NESTED entities are part of its wire shape now, the same way
|
|
42
|
+
# an aggregate's always were — the field the ADR names as
|
|
43
|
+
# declared-but-unused until this slice.
|
|
44
|
+
entities: many(:entities),
|
|
45
|
+
# ADR 0028 — a piece's own `given`, the SAME shape
|
|
46
|
+
# `Aggregate#preconditions` already carries (its own `emits_ir`
|
|
47
|
+
# row, identical). A precondition shared across this piece's own
|
|
48
|
+
# commands, declared once — a command references it back by
|
|
49
|
+
# name; the resolved text still lands on EACH referencing
|
|
50
|
+
# command's own `givens` either way, so this field is read-only
|
|
51
|
+
# documentation of what the piece itself declared, the same
|
|
52
|
+
# relationship `Aggregate.preconditions` already has to its own
|
|
53
|
+
# commands.
|
|
54
|
+
preconditions: -> { preconditions.map { |rule| { description: rule.description, canonical: rule.canonical } } },
|
|
55
|
+
# A piece's OWN shape rule, checked against EVERY instance of
|
|
56
|
+
# this piece the aggregate holds (Admissibility#enforce_
|
|
57
|
+
# invariants' own recursive walk) — the SAME relationship
|
|
58
|
+
# `ValueObject#invariants` already has to its own instances,
|
|
59
|
+
# one level up the construct tree. Not a separate enforcement
|
|
60
|
+
# boundary; still checked at the SAME two points (after every
|
|
61
|
+
# mutation, before save) the aggregate's own invariants always
|
|
62
|
+
# were — see that method's own comment for why this does not
|
|
63
|
+
# contradict "there is no separate entity invariant."
|
|
64
|
+
invariants: -> { invariants.map { |rule| { description: rule.description, canonical: rule.canonical } } },
|
|
65
|
+
lifecycle: one(:lifecycle)
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
class << self
|
|
69
|
+
attr_reader :description, :identified_by, :identity_paths, :identity_heads,
|
|
70
|
+
:attributes, :commands, :queries, :entities, :preconditions, :invariants, :lifecycle
|
|
71
|
+
|
|
72
|
+
def declare(name:, description: nil, identified_by: nil, attributes: [],
|
|
73
|
+
commands: [], queries: [], entities: [], preconditions: [], invariants: [], lifecycle: nil)
|
|
74
|
+
piece = Class.new(self)
|
|
75
|
+
piece.hecks_name = name.to_s
|
|
76
|
+
piece.absorb(description: description, identified_by: identified_by,
|
|
77
|
+
attributes: attributes, commands: commands,
|
|
78
|
+
queries: queries, entities: entities, preconditions: preconditions,
|
|
79
|
+
invariants: invariants, lifecycle: lifecycle)
|
|
80
|
+
piece.stamp_children
|
|
81
|
+
piece
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Assigns what the language declares, then hands off to the
|
|
85
|
+
# behaviour's own `settle` — derived identity and the name
|
|
86
|
+
# indexes, neither of which the declaration states.
|
|
87
|
+
def absorb(description:, identified_by:, attributes:, commands:, queries:, entities:, preconditions:, invariants:, lifecycle:)
|
|
88
|
+
@description = description
|
|
89
|
+
@identified_by = identified_by
|
|
90
|
+
@attributes = attributes
|
|
91
|
+
@commands = commands
|
|
92
|
+
@queries = queries
|
|
93
|
+
@entities = entities
|
|
94
|
+
@preconditions = preconditions
|
|
95
|
+
@invariants = invariants
|
|
96
|
+
@lifecycle = lifecycle
|
|
97
|
+
|
|
98
|
+
settle
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "../../vocabulary"
|
|
3
|
+
|
|
4
|
+
module Hecks
|
|
5
|
+
module Bluebook
|
|
6
|
+
module Expression
|
|
7
|
+
module CanonicalForm
|
|
8
|
+
Rule = Struct.new(:strategy, :source_token, :replacement, :boundary, :position, keyword_init: true)
|
|
9
|
+
|
|
10
|
+
STRATEGIES = Hecks::Vocabulary.fetch("NormalisationStrategy")
|
|
11
|
+
|
|
12
|
+
# READ, NOT RESTATED — the admitted normalisation rules, projected
|
|
13
|
+
# from the grammar chapter by bin/expression_projection exactly as
|
|
14
|
+
# the evaluator's operator table is. See Evaluator::PROJECTION for
|
|
15
|
+
# why a projection rather than a boot.
|
|
16
|
+
RULES = JSON.parse(
|
|
17
|
+
File.read(File.join(__dir__, "projection.json")), symbolize_names: true
|
|
18
|
+
).fetch(:normalisations).map { |row| Rule.new(**row) }.freeze
|
|
19
|
+
|
|
20
|
+
module_function
|
|
21
|
+
|
|
22
|
+
def table
|
|
23
|
+
RULES.sort_by(&:position).map do |rule|
|
|
24
|
+
{
|
|
25
|
+
strategy: rule.strategy,
|
|
26
|
+
source_token: rule.source_token,
|
|
27
|
+
replacement: rule.replacement,
|
|
28
|
+
boundary: rule.boundary,
|
|
29
|
+
position: rule.position.to_s
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def apply(source)
|
|
35
|
+
RULES.sort_by(&:position).reduce(source.to_s) { |text, rule| step(text, rule) }.strip
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def step(text, rule)
|
|
39
|
+
case rule.strategy
|
|
40
|
+
when "collapse_whitespace" then text.gsub(/\s+/, " ")
|
|
41
|
+
when "replace" then replace(text, rule)
|
|
42
|
+
else
|
|
43
|
+
raise ArgumentError, "#{rule.strategy.inspect} is not a linked normalisation strategy"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def replace(text, rule)
|
|
48
|
+
return text.gsub(rule.source_token, rule.replacement) if rule.boundary == "none"
|
|
49
|
+
|
|
50
|
+
text.gsub(/#{Regexp.escape(rule.source_token)}(?![[:alnum:]_])/, rule.replacement)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|