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,366 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module DSL
|
|
4
|
+
# ITEM #13's FULL METAPROGRAMMED DISPATCH — slices 1-2 of 4, whole-
|
|
5
|
+
# project table-unification survey. WordGate (the first slice,
|
|
6
|
+
# already shipped) only CHECKS a word's admissibility; this module
|
|
7
|
+
# EXECUTES the safe, mechanical subset of what a word actually
|
|
8
|
+
# DOES, read live off the SAME self-hosted grammar table — so a
|
|
9
|
+
# builder method for one of these words no longer needs to be
|
|
10
|
+
# hand-written at all. Called from `WordGate#method_missing`'s own
|
|
11
|
+
# "admitted here, no builder method for it yet" branch, so it only
|
|
12
|
+
# ever sees a word whose (context, word) pair the grammar already
|
|
13
|
+
# admits.
|
|
14
|
+
#
|
|
15
|
+
# SCOPE, deliberately narrow and VERIFIED word-by-word — a full
|
|
16
|
+
# audit read every real Ruby builder method's own source before
|
|
17
|
+
# any of this was written, not inferred from the table's shape
|
|
18
|
+
# alone (which fooled a first pass: `ReadModelBuilder#group_by`/
|
|
19
|
+
# `#include` LOOK like plain fills from `kind`/`fills` alone, but
|
|
20
|
+
# actually wrap their arguments in a Hash/tuple). What's covered:
|
|
21
|
+
#
|
|
22
|
+
# - a SINGLE, non-variadic, positional Argument row whose value
|
|
23
|
+
# is stored with nothing beyond a uniform, kind-driven
|
|
24
|
+
# coercion (`COERCE_BY_KIND`) — or, for `kind: "text"`, no
|
|
25
|
+
# coercion at all when the row's own `coerce: "false"` says so
|
|
26
|
+
# (six real, audited exceptions: `.to_s` on an actual String
|
|
27
|
+
# is a same-object no-op for every real corpus use, but a
|
|
28
|
+
# genuine behavior change for a direct Ruby API call passing
|
|
29
|
+
# something else)
|
|
30
|
+
# - a scalar ASSIGN (`@ivar = value`) or list APPEND (`@ivar <<
|
|
31
|
+
# value`), chosen by whether the ivar `fills:` names is
|
|
32
|
+
# ALREADY an Array at call time (every candidate's own
|
|
33
|
+
# `initialize` pre-populates its accumulating ivars as `[]` —
|
|
34
|
+
# read live, not assumed)
|
|
35
|
+
# - a ZERO-ARGUMENT word, either (a) one of several sibling
|
|
36
|
+
# Keyword rows in the SAME context sharing the SAME `fills:`
|
|
37
|
+
# target — derives its own stored value from ITS OWN word
|
|
38
|
+
# name as a symbol (`core`/`generic`/`supporting` all fill
|
|
39
|
+
# `classification`), or (b) the ONLY Keyword row filling its
|
|
40
|
+
# own `fills:` target — a bare marker, stores literal `true`
|
|
41
|
+
# (`ReadModel#count`)
|
|
42
|
+
# - an OPENS_BLOCK word named in `SAFE_OPENS_BLOCK` below,
|
|
43
|
+
# verified to do NOTHING beyond "build the child, instance_
|
|
44
|
+
# eval the block against it, append the result" — see that
|
|
45
|
+
# constant's own comment
|
|
46
|
+
# - (slice 2) a single-fill word whose row also names a `blank_
|
|
47
|
+
# message:` — raises that EXACT Malformed text if the coerced
|
|
48
|
+
# value is blank, before storing it, matching a real hand-
|
|
49
|
+
# written guard exactly (`Translation#retired`/
|
|
50
|
+
# `TranslationAggregate#drop`, the only two words in the whole
|
|
51
|
+
# grammar with this precise shape — `required: "true"` alone
|
|
52
|
+
# only gates Ruby's own arity, never a present-but-blank
|
|
53
|
+
# value, and most `required: "true"` words do NOT raise on
|
|
54
|
+
# blank, so this needed a real per-row signal, not an
|
|
55
|
+
# assumption from `required:` alone)
|
|
56
|
+
#
|
|
57
|
+
# Explicitly OUT of this slice (found live, during the audit, not
|
|
58
|
+
# assumed) — stays hand-written, unaffected, until a later slice's
|
|
59
|
+
# own new table columns (`gated_by:`/`calls:`) can name
|
|
60
|
+
# what it really does: variadic accumulation with a real transform
|
|
61
|
+
# (`attaches_to`); source-block extraction (`ensures`, `where`);
|
|
62
|
+
# Struct/Hash-wrapping (`limit`, `group_by`, `rekey`); a guard
|
|
63
|
+
# clause NOT reducible to a plain blank-check (`role`'s own "raise
|
|
64
|
+
# if ALREADY set" uniqueness gate — a genuinely different shape
|
|
65
|
+
# from `retired`/`drop`'s own blank-check, needing its own
|
|
66
|
+
# design); a dynamically-BUILT refusal message rather than one
|
|
67
|
+
# fixed string (`TranslationAggregateBuilder#unresolved` — real
|
|
68
|
+
# branching logic choosing between several message shapes, not a
|
|
69
|
+
# simple "always refuses" flag; belongs with `calls:`, slice 4,
|
|
70
|
+
# where a table row can name the real Ruby helper that already
|
|
71
|
+
# builds it); a side effect beyond storage (`uses_framework`,
|
|
72
|
+
# `uses_embryonaut_bluebook`); an opens-block word threading extra
|
|
73
|
+
# constructor args to its child (`asks`/`tells`/`operation`,
|
|
74
|
+
# `Bluebook#aggregate`, `Translation#aggregate`) or doing anything
|
|
75
|
+
# beyond a bare fold after building (`Aggregate#policy`'s stamp,
|
|
76
|
+
# `Aggregate#value_object`'s flatten, `Hecksagon#port`'s resolver-
|
|
77
|
+
# swap-and-branch); the DEFERRED-build queue pattern (`Aggregate`/
|
|
78
|
+
# `Entity`'s own `command`/`entity`/`query`); the shadow_parsing?-
|
|
79
|
+
# gated words (`has_many`/`has_one`/`belongs_to`/`then_set`/
|
|
80
|
+
# `trigger`/`dispatch`/`one_of` — each delegates to its own
|
|
81
|
+
# `legacy_*` method under `MetaValidator.shadow_parsing?`, else
|
|
82
|
+
# refuses; a genuinely different two-branch shape per word, closer
|
|
83
|
+
# to `calls:`'s own territory than a simple fill); and every
|
|
84
|
+
# `File`-context word (routes through `Runtime.current_registry`,
|
|
85
|
+
# a side effect this module has no business performing).
|
|
86
|
+
#
|
|
87
|
+
# TWO FURTHER, DIFFERENT reasons a word can look table-safe and
|
|
88
|
+
# still be excluded, both found live rather than assumed:
|
|
89
|
+
# - BOOTSTRAP REACHABILITY. `WordGate`'s own gate steps aside
|
|
90
|
+
# entirely while `MetaValidator.bootstrapping?` (the meta-
|
|
91
|
+
# domain's own circularity — its grammar table doesn't exist
|
|
92
|
+
# yet to read), and `load_grammar_into` loads REAL `.port`/
|
|
93
|
+
# `.adapter` files, plus every core `.bluebook` chapter, DURING
|
|
94
|
+
# that exact window. Any word those files actually call (found
|
|
95
|
+
# to be nearly every common one — `vision`/`core`/`generic`/
|
|
96
|
+
# `supporting`/`description`/`goal`/`emits`/`role`/`identified_
|
|
97
|
+
# by` describe literally every self-hosted aggregate/command)
|
|
98
|
+
# has NO working method to fall back on if its hand-written
|
|
99
|
+
# `def` is removed — `super` from `WordGate#method_missing`
|
|
100
|
+
# just raises `NoMethodError`. `PortBuilder`/`AdapterBuilder`/
|
|
101
|
+
# `BluebookBuilder` turned out to be entirely off-limits to
|
|
102
|
+
# this slice for exactly this reason, confirmed by cold-
|
|
103
|
+
# booting `MetaValidator.grammar_registry` after each
|
|
104
|
+
# candidate removal, not assumed safe from reading the table
|
|
105
|
+
# alone.
|
|
106
|
+
# - A CONFLICTING HAND-WRITTEN `method_missing`. `WorldBuilder`
|
|
107
|
+
# and `HecksagonBuilder` each define their OWN `method_missing`
|
|
108
|
+
# directly on the class (for genuinely open-ended settings/
|
|
109
|
+
# collector verbs) — a method defined directly on a class always
|
|
110
|
+
# wins over one from an included module in Ruby's own method
|
|
111
|
+
# resolution, so `WordGate`'s (and this module's) own
|
|
112
|
+
# `method_missing` never runs for THEIR builders at all. Their
|
|
113
|
+
# own candidate words (`realm`/`latest`, `subscribe`) stay
|
|
114
|
+
# hand-written for this structural reason, independent of
|
|
115
|
+
# whether their own behavior would otherwise qualify.
|
|
116
|
+
module GenericDispatch
|
|
117
|
+
NOT_HANDLED = Object.new.freeze
|
|
118
|
+
|
|
119
|
+
COERCE_BY_KIND = { "text" => :to_s, "symbol" => :to_sym }.freeze
|
|
120
|
+
|
|
121
|
+
# (context, word) OPENS_BLOCK pairs verified, by reading every
|
|
122
|
+
# real Ruby method, to do NOTHING beyond building the child and
|
|
123
|
+
# appending it — see this file's own header for the full account
|
|
124
|
+
# of what was excluded and why. Value: the ivar the built child
|
|
125
|
+
# is appended into. NOT derivable from `fills:` — every one of
|
|
126
|
+
# these Keyword rows carries `fills: ""`; the append target is
|
|
127
|
+
# implicit in the hand-written code today, never named by the
|
|
128
|
+
# table at all, so this is the one place slice 1 hand-names a
|
|
129
|
+
# fact the table doesn't yet carry, rather than guessing a
|
|
130
|
+
# pluralization rule that would silently mismatch a future word.
|
|
131
|
+
SAFE_OPENS_BLOCK = {
|
|
132
|
+
%w[Bluebook policy] => :policies,
|
|
133
|
+
%w[Bluebook process_manager] => :process_managers,
|
|
134
|
+
%w[Bluebook read_model] => :read_models
|
|
135
|
+
}.freeze
|
|
136
|
+
|
|
137
|
+
# `WordGate#method_missing`'s OWN bootstrap-window fallback,
|
|
138
|
+
# consulted ONLY while `MetaValidator.bootstrapping?` (the real
|
|
139
|
+
# table doesn't exist yet to read `keyword[:calls]` from). Names
|
|
140
|
+
# the SAME (context, word) -> method pairs the real table's own
|
|
141
|
+
# `calls:` column carries for these rows — kept in sync by hand,
|
|
142
|
+
# the one place in this whole arc that was worth it: it
|
|
143
|
+
# duplicates a METHOD NAME, never the method's own logic, so
|
|
144
|
+
# there is nothing here that could drift into a WRONG ANSWER,
|
|
145
|
+
# only (if ever forgotten) into `attribute` staying unreachable
|
|
146
|
+
# during bootstrap, the same loud `NoMethodError` failure this
|
|
147
|
+
# whole mechanism already had before slice 3 existed.
|
|
148
|
+
BOOTSTRAP_CALLS_FALLBACK = {
|
|
149
|
+
%w[Aggregate attribute] => :attribute_impl,
|
|
150
|
+
%w[Entity attribute] => :attribute_impl,
|
|
151
|
+
%w[Command attribute] => :attribute_impl,
|
|
152
|
+
%w[ValueObject attribute] => :attribute_impl,
|
|
153
|
+
%w[Query attribute] => :attribute_impl,
|
|
154
|
+
%w[PortOperation attribute] => :attribute_impl,
|
|
155
|
+
%w[Command role] => :role_impl,
|
|
156
|
+
# given/invariant/reference_to — slice 4b. Each is a SEPARATE
|
|
157
|
+
# per-builder implementation (not a shared mixin like
|
|
158
|
+
# attribute_impl), so every (context, word) pair below names
|
|
159
|
+
# its OWN builder's own method, even where several share a
|
|
160
|
+
# name.
|
|
161
|
+
%w[Aggregate given] => :given_impl,
|
|
162
|
+
%w[Entity given] => :given_impl,
|
|
163
|
+
%w[Command given] => :given_impl,
|
|
164
|
+
%w[Aggregate invariant] => :invariant_impl,
|
|
165
|
+
%w[Entity invariant] => :invariant_impl,
|
|
166
|
+
%w[ValueObject invariant] => :invariant_impl,
|
|
167
|
+
%w[Aggregate reference_to] => :reference_to_impl,
|
|
168
|
+
%w[Entity reference_to] => :reference_to_impl,
|
|
169
|
+
%w[Command reference_to] => :reference_to_impl,
|
|
170
|
+
%w[Query reference_to] => :reference_to_impl,
|
|
171
|
+
%w[ReadModel reference_to] => :reference_to_impl,
|
|
172
|
+
%w[PortOperation reference_to] => :reference_to_impl,
|
|
173
|
+
# `belongs_to` — genuinely NEW bootstrap-reachability, post-dating
|
|
174
|
+
# the "not bootstrap-reachable" determination above: has_many/
|
|
175
|
+
# has_one/belongs_to were retired everywhere when that check was
|
|
176
|
+
# made, so nothing core/attached used one to describe itself.
|
|
177
|
+
# Wave 6 (identity-and-relationships arc) un-deprecates all three
|
|
178
|
+
# for real, and syntax.bluebook's own Bluebook.Declare relationship
|
|
179
|
+
# (`belongs_to Bluebook`) now uses one describing itself — checked
|
|
180
|
+
# directly (only `belongs_to`, not `has_many`/`has_one`, is
|
|
181
|
+
# actually used this way by any core/attached chapter today).
|
|
182
|
+
%w[Aggregate belongs_to] => :belongs_to_impl,
|
|
183
|
+
# slice 4c — the remaining hand-written words a fresh survey
|
|
184
|
+
# found still un-migrated across every builder. Each checked
|
|
185
|
+
# for bootstrap-reachability individually (grepped directly
|
|
186
|
+
# against every core/attached chapter, not assumed); only the
|
|
187
|
+
# ones below actually are.
|
|
188
|
+
%w[Bluebook aggregate] => :aggregate_impl,
|
|
189
|
+
%w[Aggregate provenance] => :provenance_impl,
|
|
190
|
+
%w[Aggregate identified_by] => :identified_by_impl,
|
|
191
|
+
%w[Aggregate lifecycle] => :lifecycle_impl,
|
|
192
|
+
%w[Aggregate entity] => :entity_impl,
|
|
193
|
+
%w[Aggregate query] => :query_impl,
|
|
194
|
+
%w[Aggregate policy] => :policy_impl,
|
|
195
|
+
%w[Aggregate command] => :command_impl,
|
|
196
|
+
%w[Aggregate projects] => :projects_impl,
|
|
197
|
+
%w[Entity identified_by] => :identified_by_impl,
|
|
198
|
+
%w[Entity command] => :command_impl,
|
|
199
|
+
%w[Entity query] => :query_impl,
|
|
200
|
+
%w[Entity lifecycle] => :lifecycle_impl,
|
|
201
|
+
%w[Command provenance] => :provenance_impl,
|
|
202
|
+
%w[Command sets] => :sets_impl,
|
|
203
|
+
%w[Lifecycle transition] => :transition_impl,
|
|
204
|
+
%w[ReadModel where] => :where_impl,
|
|
205
|
+
%w[ReadModel order_by] => :order_by_impl,
|
|
206
|
+
%w[ReadModel include] => :include_impl,
|
|
207
|
+
%w[Query where] => :where_impl,
|
|
208
|
+
%w[Query order_by] => :order_by_impl,
|
|
209
|
+
%w[Entity entity] => :entity_impl,
|
|
210
|
+
%w[ValueObject member] => :member_impl,
|
|
211
|
+
# slice 5. `port`/`realm`/`latest` — real, closed-set words
|
|
212
|
+
# that sat unreachable behind Hecksagon/World's own class-level
|
|
213
|
+
# `method_missing` (see WordGate#word_gate_dispatch's own
|
|
214
|
+
# header), not bootstrap circularity as such, but the SAME
|
|
215
|
+
# fallback table serves them: this hash is looked up before
|
|
216
|
+
# `word_gate_dispatch` even runs, keyed by whichever context
|
|
217
|
+
# the caller's own class reports.
|
|
218
|
+
%w[Hecksagon port] => :port_impl,
|
|
219
|
+
%w[World realm] => :realm_impl,
|
|
220
|
+
%w[World latest] => :latest_impl,
|
|
221
|
+
# `["Type", word]` — ONE entry each covers `list_of`/`one_of`
|
|
222
|
+
# for EVERY calling context (Aggregate/Entity/Command/Query/
|
|
223
|
+
# PortOperation/ValueObject all use them in an attribute's own
|
|
224
|
+
# type position, and `self.class::GRAMMAR_CONTEXT` can never
|
|
225
|
+
# actually equal "Type" — see `word_gate_dispatch`'s own
|
|
226
|
+
# header). The bootstrap branch checks this key directly, the
|
|
227
|
+
# same way the ordinary `word_gate_dispatch` path's own
|
|
228
|
+
# "Type"-context fallback does.
|
|
229
|
+
%w[Type list_of] => :list_of_impl,
|
|
230
|
+
%w[Type one_of] => :one_of_impl
|
|
231
|
+
}.freeze
|
|
232
|
+
|
|
233
|
+
module_function
|
|
234
|
+
|
|
235
|
+
# THE STATIC PREDICATE — does this (context, word) pair fall
|
|
236
|
+
# within this slice's own verified scope, WITHOUT executing
|
|
237
|
+
# anything? The same row-shape checks `try` itself runs before
|
|
238
|
+
# ever touching a real argument, shared so a conformance spec
|
|
239
|
+
# (which has no real call, no real builder instance) can ask the
|
|
240
|
+
# SAME question `method_missing` answers live.
|
|
241
|
+
def handles?(context, word, rows: MetaValidator::SyntaxBoot.call)
|
|
242
|
+
!shape_for(context, word, rows).nil?
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# `NOT_HANDLED` for anything outside this slice's own verified
|
|
246
|
+
# scope — the caller (`WordGate#method_missing`) falls through
|
|
247
|
+
# to its own existing "not yet implemented" refusal, UNCHANGED,
|
|
248
|
+
# the exact same message a word not yet migrated to any slice
|
|
249
|
+
# already gets today. A real `ArgumentError` — matching what a
|
|
250
|
+
# hand-written method of the same arity would raise — for a
|
|
251
|
+
# call whose SHAPE the grammar admits but whose actual argument
|
|
252
|
+
# count doesn't match; never a silent wrong answer.
|
|
253
|
+
def try(builder, context, word, args, kwargs, block, rows)
|
|
254
|
+
shape = shape_for(context, word, rows)
|
|
255
|
+
return NOT_HANDLED unless shape
|
|
256
|
+
|
|
257
|
+
case shape[:kind]
|
|
258
|
+
when :calls_through then try_calls_through(builder, shape[:calls], args, kwargs, block)
|
|
259
|
+
when :opens_block then try_opens_block(builder, shape[:keyword], args, kwargs, block)
|
|
260
|
+
when :zero_arg then try_zero_arg(builder, shape[:keyword], args)
|
|
261
|
+
when :single_fill then try_single_fill(builder, shape[:fills], shape[:argument], args, kwargs)
|
|
262
|
+
else
|
|
263
|
+
# `shape_for` names exactly four kinds and this case
|
|
264
|
+
# matches all four — a backstop against the day a fifth is
|
|
265
|
+
# added there without a matching arm here. Falling through
|
|
266
|
+
# silently would return bare `nil` from what the caller
|
|
267
|
+
# (`WordGate#method_missing`) reads as "handled" (anything
|
|
268
|
+
# other than NOT_HANDLED counts), so a self-hosted DSL word
|
|
269
|
+
# would silently execute as a no-op instead of raising the
|
|
270
|
+
# same "not yet implemented" refusal a genuinely unmigrated
|
|
271
|
+
# word already gets.
|
|
272
|
+
raise Runtime::WiringError, "no dispatcher handles shape #{shape[:kind].inspect} — add one before shape_for can produce it"
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# THE ONE PLACE ROW SHAPE IS JUDGED — returns a small Hash naming
|
|
277
|
+
# which of the four safe shapes (context, word) is, or `nil` if
|
|
278
|
+
# it falls outside this slice's own verified scope. No argument
|
|
279
|
+
# values are read here; this only ever looks at the table.
|
|
280
|
+
def shape_for(context, word, rows)
|
|
281
|
+
keyword = rows[:keywords].find { |k| k[:context] == context && k[:word] == word && k[:status] != "retired" }
|
|
282
|
+
return nil unless keyword
|
|
283
|
+
|
|
284
|
+
calls = keyword[:calls].to_s
|
|
285
|
+
return { kind: :calls_through, calls: calls } unless calls.empty?
|
|
286
|
+
|
|
287
|
+
return { kind: :opens_block, keyword: keyword } if SAFE_OPENS_BLOCK.key?([context, word])
|
|
288
|
+
|
|
289
|
+
fills = keyword[:fills].to_s
|
|
290
|
+
return nil if fills.empty?
|
|
291
|
+
|
|
292
|
+
arguments = rows[:arguments].select { |a| a[:context] == context && a[:keyword] == word && a[:status] != "retired" }
|
|
293
|
+
return { kind: :zero_arg, keyword: keyword } if arguments.empty?
|
|
294
|
+
|
|
295
|
+
return nil unless arguments.size == 1
|
|
296
|
+
|
|
297
|
+
arg = arguments.first
|
|
298
|
+
return nil if arg[:variadic] == "true" || arg[:at] != "1" || !arg[:named].to_s.empty?
|
|
299
|
+
return nil unless COERCE_BY_KIND.key?(arg[:kind])
|
|
300
|
+
|
|
301
|
+
{ kind: :single_fill, fills: fills, argument: arg }
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# `keyword[:calls]` names a real Ruby method whose whole call —
|
|
305
|
+
# every positional, every kwarg, the block, all of it — forwards
|
|
306
|
+
# here UNCHANGED. No argument-shape interpretation at all,
|
|
307
|
+
# deliberately: the target method (`AttributeCollector#
|
|
308
|
+
# attribute_impl`, etc.) already does its own, real, hand-
|
|
309
|
+
# written argument handling; this is a pure, transparent `send`,
|
|
310
|
+
# the lowest-risk possible shape for a word whose own logic is
|
|
311
|
+
# too complex to re-derive from the table (type-quoting refusal,
|
|
312
|
+
# closed-set synthesis, pattern validation, ...).
|
|
313
|
+
def try_calls_through(builder, calls, args, kwargs, block)
|
|
314
|
+
builder.send(calls, *args, **kwargs, &block)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def try_opens_block(builder, keyword, args, kwargs, block)
|
|
318
|
+
return NOT_HANDLED unless kwargs.empty?
|
|
319
|
+
|
|
320
|
+
target_ivar = SAFE_OPENS_BLOCK.fetch([keyword[:context], keyword[:word]])
|
|
321
|
+
child_class = DSL.const_get("#{keyword[:opens]}Builder")
|
|
322
|
+
|
|
323
|
+
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)" unless args.size == 1
|
|
324
|
+
|
|
325
|
+
child = child_class.build(args.first, &block)
|
|
326
|
+
|
|
327
|
+
ivar = :"@#{target_ivar}"
|
|
328
|
+
list = builder.instance_variable_get(ivar) || builder.instance_variable_set(ivar, [])
|
|
329
|
+
list << child
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def try_zero_arg(builder, keyword, args)
|
|
333
|
+
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0)" unless args.empty?
|
|
334
|
+
|
|
335
|
+
rows = MetaValidator::SyntaxBoot.call[:keywords]
|
|
336
|
+
siblings = rows.count { |k| k[:context] == keyword[:context] && k[:fills] == keyword[:fills] && k[:status] != "retired" }
|
|
337
|
+
value = siblings > 1 ? keyword[:word].to_sym : true
|
|
338
|
+
|
|
339
|
+
builder.instance_variable_set(:"@#{keyword[:fills]}", value)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def try_single_fill(builder, fills, arg, args, kwargs)
|
|
343
|
+
return NOT_HANDLED unless kwargs.empty?
|
|
344
|
+
|
|
345
|
+
coerce = COERCE_BY_KIND.fetch(arg[:kind])
|
|
346
|
+
|
|
347
|
+
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)" unless args.size == 1
|
|
348
|
+
|
|
349
|
+
value = arg[:coerce] == "false" ? args.first : args.first.public_send(coerce)
|
|
350
|
+
|
|
351
|
+
message = arg[:blank_message].to_s
|
|
352
|
+
raise Malformed, message if !message.empty? && value.to_s.empty?
|
|
353
|
+
|
|
354
|
+
ivar = :"@#{fills}"
|
|
355
|
+
current = builder.instance_variable_get(ivar)
|
|
356
|
+
|
|
357
|
+
if current.is_a?(Array)
|
|
358
|
+
current << value
|
|
359
|
+
else
|
|
360
|
+
builder.instance_variable_set(ivar, value)
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require_relative "word_gate"
|
|
2
|
+
module Hecks
|
|
3
|
+
module Bluebook
|
|
4
|
+
module DSL
|
|
5
|
+
class HecksagonBuilder
|
|
6
|
+
GRAMMAR_CONTEXT = "Hecksagon"
|
|
7
|
+
|
|
8
|
+
include WordGate
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
attr_accessor :collector
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :binds, :subscriptions, :framework_members, :vendored_bluebooks
|
|
15
|
+
|
|
16
|
+
def initialize(domain)
|
|
17
|
+
@domain = domain
|
|
18
|
+
@binds = []
|
|
19
|
+
@subscriptions = []
|
|
20
|
+
@framework_members = []
|
|
21
|
+
@vendored_bluebooks = []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# An event this hecksagon takes from OUTSIDE the domain's own
|
|
25
|
+
# bluebook.
|
|
26
|
+
def subscribe(event) = @subscriptions << event.to_s
|
|
27
|
+
|
|
28
|
+
# A framework/ member this domain wants attached —
|
|
29
|
+
# Governance, Identity, whatever else lands beside them.
|
|
30
|
+
# Attaching one is a WIRING decision, the same kind `persisted_by`/
|
|
31
|
+
# `projected_by` already are, so it lives here rather than as a
|
|
32
|
+
# fact stated in the domain's own bluebook. Recorded onto THIS
|
|
33
|
+
# hecksagon, the same way `subscribe` records onto its own
|
|
34
|
+
# `subscriptions` — and loads the member's bluebook then its own
|
|
35
|
+
# hecksagon into whatever registry this one is loading into, see
|
|
36
|
+
# `Framework.load!`.
|
|
37
|
+
def uses_framework(name)
|
|
38
|
+
@framework_members << name.to_s
|
|
39
|
+
Hecks::Framework.load!(name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# A VENDORED, EXTERNAL bluebook this domain wants attached — same
|
|
43
|
+
# wiring-decision shape `uses_framework` already is, one level
|
|
44
|
+
# further out: not a member shipped inside hecks's own lib/,
|
|
45
|
+
# but a separate package (embryonaut_bluebooks) vendored into THIS
|
|
46
|
+
# project's own checkout. See EmbryonautBluebook's own header for
|
|
47
|
+
# the full reasoning on why its ROOT can't be a fixed constant the
|
|
48
|
+
# way Framework::ROOT is, and for the recovery provenance.
|
|
49
|
+
#
|
|
50
|
+
# RECORDED ONTO @vendored_bluebooks, same shape `uses_framework`
|
|
51
|
+
# already gives @framework_members — a SEPARATE list on purpose:
|
|
52
|
+
# `framework_members` is load-bearing for `refuse_ungoverned_roles!`
|
|
53
|
+
# (below) and for Governance's own attachment check; conflating
|
|
54
|
+
# the two would make a vendored bluebook attachment satisfy a
|
|
55
|
+
# Governance check it has nothing to do with.
|
|
56
|
+
def uses_embryonaut_bluebook(name)
|
|
57
|
+
@vendored_bluebooks << name.to_s
|
|
58
|
+
Hecks::EmbryonautBluebook.load!(name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# THE PRIMARY PORT, BARE AT THE ROOT — belongs to the CHAPTER as a
|
|
62
|
+
# whole, not one aggregate. `BindingProxy#port` is the aggregate-
|
|
63
|
+
# scoped sibling (`Payments::Payment.port("Gateway") do ... end`);
|
|
64
|
+
# this is what's left when a port isn't about any one record. The
|
|
65
|
+
# bluebook must already be built and registered, since a hecksagon
|
|
66
|
+
# loads after its bluebook, and this attaches to that real, final
|
|
67
|
+
# object directly rather than building a second copy MetaValidator
|
|
68
|
+
# would have to know how to reconstruct.
|
|
69
|
+
# RENAMED FROM `port` — item #13's full metaprogrammed dispatch
|
|
70
|
+
# (slice 5). Not bootstrap-reachable (checked directly — no
|
|
71
|
+
# core/attached chapter declares a Hecksagon of its own). Reached
|
|
72
|
+
# through `WordGate#method_missing`'s new `word_gate_dispatch`,
|
|
73
|
+
# called explicitly below since `HecksagonBuilder`'s own
|
|
74
|
+
# class-level `method_missing` (the open-verb catch-all beneath
|
|
75
|
+
# this) always wins over the module's — see `word_gate.rb`'s own
|
|
76
|
+
# header for the full mechanism.
|
|
77
|
+
def port_impl(name, &block)
|
|
78
|
+
bluebook_ir = Hecks.current_registry.bluebook(@domain) or
|
|
79
|
+
raise Malformed, "#{@domain} declares no such bluebook — a port needs one to belong to"
|
|
80
|
+
|
|
81
|
+
# See BindingProxy#port's own comment on why this resolver swap is
|
|
82
|
+
# needed — ConstShim's active resolver is one global for the whole
|
|
83
|
+
# dynamic extent, currently this file's own BindingProxy-minting
|
|
84
|
+
# one, which would turn a bare constant inside an operation's
|
|
85
|
+
# `reference_to`/`attribute` into another BindingProxy instead of
|
|
86
|
+
# a name.
|
|
87
|
+
built = ConstShim.with(->(const) { const }) { DomainPortBuilder.build(name, &block) }
|
|
88
|
+
|
|
89
|
+
# See BindingProxy#port's own comment on the same branch — a
|
|
90
|
+
# `verb`-shaped port is a plain `Port`, registered the same
|
|
91
|
+
# way `Hecks.port`'s top-level method already does, not attached
|
|
92
|
+
# to this bluebook's own IR the way an operations-shaped
|
|
93
|
+
# `DomainPort` is.
|
|
94
|
+
return Hecks.current_registry.add_port(built) if built.is_a?(Port)
|
|
95
|
+
|
|
96
|
+
bluebook_ir.add_port(built)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# NO ungoverned-role check here anymore — see
|
|
100
|
+
# Registry::Verification#refuse_ungoverned_roles!. Moved out of
|
|
101
|
+
# per-block `build`, recovered alongside `environment:`
|
|
102
|
+
# (Runtime::Loader.boot's comment has the provenance): a domain
|
|
103
|
+
# split across multiple hecksagon blocks (base + an
|
|
104
|
+
# `environments/<name>.hecksagon` overlay) would have every
|
|
105
|
+
# block but the one declaring `uses_framework "Governance"`
|
|
106
|
+
# refused HERE, even though `Registry#add_hecksagon` merges them
|
|
107
|
+
# into one Hecksagon before anything ever dispatches against it.
|
|
108
|
+
# Checking the MERGED result once, at verify! time — after every
|
|
109
|
+
# file for this domain has loaded — is both more permissive (no
|
|
110
|
+
# need to repeat `uses_framework` in every file) and strictly
|
|
111
|
+
# more correct (a check against an incomplete, not-yet-merged
|
|
112
|
+
# hecksagon can never see the real final shape).
|
|
113
|
+
def build
|
|
114
|
+
Hecksagon.new(domain: @domain, binds: @binds, subscriptions: @subscriptions,
|
|
115
|
+
framework_members: @framework_members, vendored_bluebooks: @vendored_bluebooks)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# DOMAIN-LEVEL DEFAULT BINDS — `persisted_by "Heki"` bare, at the top
|
|
119
|
+
# of a hecksagon block, applies to every aggregate in this domain
|
|
120
|
+
# that doesn't declare its own override. Mirrors `BindingProxy`'s own
|
|
121
|
+
# `method_missing` one level down (`aggregate:` filled in there,
|
|
122
|
+
# `nil` here) — generic over verb name, not hardcoded to
|
|
123
|
+
# `persisted_by`/`projected_by` specifically, so any future verb
|
|
124
|
+
# gets a domain-level default for free too. See `Hecksagon#bind_for`
|
|
125
|
+
# for the fallback lookup this feeds.
|
|
126
|
+
def method_missing(verb, *args, **kwargs, &block)
|
|
127
|
+
# A closed-set grammar word (`port`, today) gets first refusal
|
|
128
|
+
# — item #13's full metaprogrammed dispatch (slice 5); see
|
|
129
|
+
# `WordGate#word_gate_dispatch`'s own header for why this class
|
|
130
|
+
# needs to call it explicitly rather than including it the
|
|
131
|
+
# ordinary way. Only once THAT says "not admitted" does the
|
|
132
|
+
# genuinely open-ended `persisted_by "Heki"`-style bind
|
|
133
|
+
# vocabulary below get a turn.
|
|
134
|
+
result = word_gate_dispatch(verb, args, kwargs, block)
|
|
135
|
+
return result unless result.equal?(WordGate::NOT_ADMITTED)
|
|
136
|
+
|
|
137
|
+
return super unless args.first
|
|
138
|
+
|
|
139
|
+
@binds << Bind.new(aggregate: nil, verb: verb.to_s, adapter: args.first.to_s, role: kwargs[:role]&.to_s)
|
|
140
|
+
block&.call
|
|
141
|
+
self
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def respond_to_missing?(_name, _include_private = false) = true
|
|
145
|
+
|
|
146
|
+
def self.build(domain, &block)
|
|
147
|
+
builder = new(domain)
|
|
148
|
+
resolver = ->(name) { BindingProxy.namespace(name, builder.binds) }
|
|
149
|
+
|
|
150
|
+
previous = collector
|
|
151
|
+
self.collector = builder.binds
|
|
152
|
+
begin
|
|
153
|
+
ConstShim.with(resolver) { builder.instance_eval(&block) } if block
|
|
154
|
+
ensure
|
|
155
|
+
self.collector = previous
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
builder.build
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|