hecks 0.2.0 → 1.0.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 +427 -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 +101 -0
- data/lib/hecks/adapters/driven/heki/journal.rb +56 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +99 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +65 -0
- data/lib/hecks/adapters/driven/heki.adapter +4 -0
- data/lib/hecks/adapters/driven/heki.rb +179 -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 +145 -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 +88 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +207 -0
- data/lib/hecks/adapters/driven/postgres.adapter +5 -0
- data/lib/hecks/adapters/driven/postgres.rb +438 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +17 -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 +80 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +172 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +192 -0
- data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
- data/lib/hecks/adapters/driven/sqlite.rb +306 -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 +54 -0
- data/lib/hecks/adapters.rb +6 -0
- data/lib/hecks/behaviors/dsl.rb +125 -0
- data/lib/hecks/behaviors/expectations.rb +340 -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 +438 -0
- data/lib/hecks/bluebook/assembly/marks.rb +228 -0
- data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
- data/lib/hecks/bluebook/assembly.rb +91 -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 +68 -0
- data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
- data/lib/hecks/bluebook/behaviour/process_manager.rb +51 -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 +78 -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 +1018 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +348 -0
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1087 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +714 -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 +430 -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 +135 -0
- data/lib/hecks/bluebook/dsl/port_builder.rb +39 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +306 -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 +173 -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 +228 -0
- data/lib/hecks/bluebook/dsl/world_builder.rb +117 -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 +123 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +304 -0
- data/lib/hecks/bluebook/expression/projection.json +218 -0
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
- data/lib/hecks/bluebook/expression/resolver.rb +781 -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 +621 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +51 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +360 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +351 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +266 -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 +542 -0
- data/lib/hecks/bluebook/model_check.rb +445 -0
- data/lib/hecks/bluebook/pattern_subset.rb +184 -0
- data/lib/hecks/bluebook/policy.rb +41 -0
- data/lib/hecks/bluebook/process_manager.rb +128 -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 +66 -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 +410 -0
- data/lib/hecks/embryonaut_bluebook.rb +75 -0
- data/lib/hecks/facade/cli_door.rb +119 -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 +166 -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 +341 -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 +177 -0
- data/lib/hecks/forms/field_shape.rb +232 -0
- data/lib/hecks/forms/html.rb +84 -0
- data/lib/hecks/forms/index_renderer.rb +35 -0
- data/lib/hecks/forms/page.rb +157 -0
- data/lib/hecks/forms/params.rb +161 -0
- data/lib/hecks/forms/port_argument.rb +46 -0
- data/lib/hecks/forms/query_form_renderer.rb +114 -0
- data/lib/hecks/forms/record_renderer.rb +119 -0
- data/lib/hecks/forms/record_table.rb +68 -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 +145 -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/bounded_exhaustive_expressions.rb +527 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +286 -0
- data/lib/hecks/fuzzing/properties.rb +1192 -0
- data/lib/hecks/fuzzing/replay.rb +668 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +80 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +250 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +131 -0
- data/lib/hecks/fuzzing/value_generator.rb +200 -0
- data/lib/hecks/fuzzing.rb +12 -0
- data/lib/hecks/grammar/evolve.rb +324 -0
- data/lib/hecks/grammar/expression.bluebook +420 -0
- data/lib/hecks/grammar/expression_operators.json +1648 -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 +471 -0
- data/lib/hecks/language/bluebook/entity.bluebook +392 -0
- data/lib/hecks/language/bluebook/policy.bluebook +189 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +381 -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 +448 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +379 -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 +333 -0
- data/lib/hecks/language/port.bluebook +120 -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 +174 -0
- data/lib/hecks/ports/access_control.port +9 -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 +8 -0
- data/lib/hecks/ports/agent.rb +167 -0
- data/lib/hecks/ports/authentication.port +6 -0
- data/lib/hecks/ports/authentication.rb +50 -0
- data/lib/hecks/ports/authorization.port +7 -0
- data/lib/hecks/ports/authorization.rb +62 -0
- data/lib/hecks/ports/clock.port +5 -0
- data/lib/hecks/ports/clock.rb +62 -0
- data/lib/hecks/ports/extraction.port +5 -0
- data/lib/hecks/ports/extraction.rb +37 -0
- data/lib/hecks/ports/identity_assignment.port +5 -0
- data/lib/hecks/ports/identity_assignment.rb +45 -0
- data/lib/hecks/ports/identity_generation.port +5 -0
- data/lib/hecks/ports/identity_generation.rb +49 -0
- data/lib/hecks/ports/identity_resolution.port +5 -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 +138 -0
- data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
- data/lib/hecks/ports/persistence/execution.rb +23 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
- data/lib/hecks/ports/persistence/plugin.rb +54 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +169 -0
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +128 -0
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +161 -0
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +61 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +304 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +171 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +190 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +478 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +166 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +314 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +168 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +170 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +134 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +137 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +89 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +85 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +132 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +758 -0
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +31 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +46 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +102 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +46 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +70 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +72 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +183 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +41 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +28 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +30 -0
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +11 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +48 -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 +96 -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 +642 -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 +44 -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 +446 -0
- data/lib/hecks/projector/docs_projector.rb +321 -0
- data/lib/hecks/projector/exporter.rb +158 -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 +411 -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 +92 -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 +107 -0
- data/lib/hecks/query_specification/hop_path.rb +132 -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/aggregate_lock.rb +45 -0
- data/lib/hecks/runtime/boot_gates.rb +41 -0
- data/lib/hecks/runtime/caller.rb +66 -0
- data/lib/hecks/runtime/capability_graph.rb +44 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +135 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +260 -0
- data/lib/hecks/runtime/command_interpreter.rb +497 -0
- data/lib/hecks/runtime/command_rules/admissibility.rb +357 -0
- data/lib/hecks/runtime/command_rules/arithmetic.rb +260 -0
- data/lib/hecks/runtime/command_rules/authorization.rb +65 -0
- data/lib/hecks/runtime/command_rules/emission.rb +34 -0
- data/lib/hecks/runtime/command_rules/references.rb +189 -0
- data/lib/hecks/runtime/command_rules.rb +28 -0
- data/lib/hecks/runtime/dependency_planning.rb +245 -0
- data/lib/hecks/runtime/dispatcher.rb +301 -0
- data/lib/hecks/runtime/entity_element.rb +253 -0
- data/lib/hecks/runtime/entity_interpreter.rb +299 -0
- data/lib/hecks/runtime/errors.rb +122 -0
- data/lib/hecks/runtime/event.rb +51 -0
- data/lib/hecks/runtime/identity.rb +156 -0
- data/lib/hecks/runtime/instance.rb +175 -0
- data/lib/hecks/runtime/interpreting.rb +90 -0
- data/lib/hecks/runtime/loader.rb +184 -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 +286 -0
- data/lib/hecks/runtime/reaction_invocation.rb +253 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +341 -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 +126 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +142 -0
- data/lib/hecks/runtime/registry/verification.rb +246 -0
- data/lib/hecks/runtime/registry.rb +279 -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 +503 -0
- data/lib/hecks/runtime/saga_pending_dispatch.rb +45 -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 +130 -0
- data/lib/hecks/runtime/value/coercion.rb +565 -0
- data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
- data/lib/hecks/runtime/value.rb +125 -0
- data/lib/hecks/runtime.rb +107 -0
- data/lib/hecks/storehouse.rb +632 -0
- data/lib/hecks/version.rb +16 -0
- data/lib/hecks/vocabulary.rb +218 -0
- data/lib/hecks.rb +123 -6
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +90 -0
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +128 -0
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +160 -0
- metadata +412 -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,286 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "tmpdir"
|
|
3
|
+
require "securerandom"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Fuzzing
|
|
7
|
+
# A FRESH, IN-PROCESS ADAPTER FOR EVERY EPHEMERAL BOOT.
|
|
8
|
+
#
|
|
9
|
+
# Fuzzing/replay copies a domain to a tmpdir and boots from there
|
|
10
|
+
# specifically to get zero-history state — `rm_rf`ing the copy's own
|
|
11
|
+
# `data/` achieves that for a file-based adapter (Memory,
|
|
12
|
+
# SqlitePersistence, Heki), because copying the DIRECTORY copies the
|
|
13
|
+
# store. It achieves nothing for an adapter that lives outside the
|
|
14
|
+
# copied directory entirely — Postgres, named by a fixed connection
|
|
15
|
+
# string in `.world` (examples/pizzas/bluebook/pizzas.world, for
|
|
16
|
+
# instance). Copying the directory does not copy or isolate the
|
|
17
|
+
# DATABASE, so a "fresh" boot against a Postgres-bound domain would
|
|
18
|
+
# still see every record any other run, ever, wrote to it.
|
|
19
|
+
#
|
|
20
|
+
# So every `.hecksagon` in the copy gets its persistence binding
|
|
21
|
+
# rewritten to Memory before booting, and any `projected_by` bind
|
|
22
|
+
# dropped outright (optional — `Registry#read_repository` already
|
|
23
|
+
# falls back to the authoritative repository when none exists). The
|
|
24
|
+
# domain's own rules and shape are untouched ; only WHICH adapter this
|
|
25
|
+
# one ephemeral copy answers through changes. What the domain is
|
|
26
|
+
# bound to for real deployment is never touched — only this tmp copy.
|
|
27
|
+
#
|
|
28
|
+
# `adapter:` (PRD 02) — Memory is the default and the only mode every
|
|
29
|
+
# existing caller still gets with no change. `:sqlite` rebinds to the
|
|
30
|
+
# REAL SQLite adapter instead of the in-memory one, for exactly the
|
|
31
|
+
# same reason PRD 02 exists: 15 declared properties (properties.rb)
|
|
32
|
+
# and every fuzz/replay run has only ever been checked against
|
|
33
|
+
# Memory's own hand-written repository, never against a real,
|
|
34
|
+
# persisted, SQL-backed one — and `spec/adapters/query_agreement_spec
|
|
35
|
+
# .rb` already found 4 shipped query bugs from exactly that
|
|
36
|
+
# comparison, on a fixed corpus far smaller than what the fuzzer
|
|
37
|
+
# generates. `:sqlite` rewrites to `"SqlitePersistence"` — the name
|
|
38
|
+
# `lib/hecks/adapters/driven/sqlite.adapter` actually registers under
|
|
39
|
+
# (`Sqlite` is the class; `SqlitePersistence` is a thin subclass
|
|
40
|
+
# that's the one real port binding names) — and needs no `.world`
|
|
41
|
+
# settings at all, the same reason Memory needs none:
|
|
42
|
+
# `Sqlite#resolve_path` already defaults an
|
|
43
|
+
# unbound `database` setting to `"data/<table>.db"` relative to
|
|
44
|
+
# `root:`, which `Hecks.boot(copy)` passes as this ephemeral copy's
|
|
45
|
+
# own directory — a fresh, empty `data/` per run, exactly like
|
|
46
|
+
# Memory's own zero-history guarantee, just backed by a real SQLite
|
|
47
|
+
# file instead of a Hash. Postgres/PostgresEra are deliberately NOT
|
|
48
|
+
# added here: a real Postgres run needs a live server and shared
|
|
49
|
+
# connection settings this in-process, no-adapter-config path has no
|
|
50
|
+
# place to source safely — that stays `io: true`-gated, direct-adapter
|
|
51
|
+
# coverage (`spec/adapters/driven/postgres_*_spec.rb`), not this.
|
|
52
|
+
module IsolatedBoot
|
|
53
|
+
module_function
|
|
54
|
+
|
|
55
|
+
# PRD 02 (docs/future-features.md) — `adapter:` picks WHICH real
|
|
56
|
+
# persistence this one ephemeral boot answers through, not just
|
|
57
|
+
# Memory. `:memory` is the original, zero-config behavior (every
|
|
58
|
+
# other caller in this codebase that doesn't pass `adapter:` gets
|
|
59
|
+
# exactly what it always got). `:sqlite` is nearly as cheap —
|
|
60
|
+
# `Adapters::Sqlite#resolve_path` already defaults to
|
|
61
|
+
# `data/<table>.db` under the copy's own root with no settings at
|
|
62
|
+
# all, the same "needs nothing declared" property Memory has, so a
|
|
63
|
+
# real on-disk B-tree gets exercised for free. `:postgres` is the
|
|
64
|
+
# expensive one — a real server, a real round trip per dispatch —
|
|
65
|
+
# so `bin/fuzz --adapter postgres` is meant to run with smaller
|
|
66
|
+
# seed/step counts than the Memory default, not as a like-for-like
|
|
67
|
+
# swap; see that flag's own comment.
|
|
68
|
+
def call(domain_path, adapter: :memory)
|
|
69
|
+
Dir.mktmpdir("hecks-fuzz") do |tmp|
|
|
70
|
+
copy = File.join(tmp, File.basename(domain_path))
|
|
71
|
+
copy_dereferencing(domain_path, copy)
|
|
72
|
+
FileUtils.rm_rf(File.join(copy, "data"))
|
|
73
|
+
case adapter
|
|
74
|
+
when :memory then rebind_to_memory!(copy)
|
|
75
|
+
when :sqlite then rebind_to_sqlite!(copy)
|
|
76
|
+
when :postgres then rebind_to_postgres!(copy)
|
|
77
|
+
else raise ArgumentError, "unknown fuzz adapter #{adapter.inspect} — :memory, :sqlite, or :postgres"
|
|
78
|
+
end
|
|
79
|
+
yield copy
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# SYMLINKS ARE FOLLOWED, NOT COPIED. `FileUtils.cp_r` reproduces a
|
|
84
|
+
# symlink AS a symlink, and a RELATIVE one then points at nothing
|
|
85
|
+
# from a tmpdir — `lib/hecks/framework/bluebook/compliance
|
|
86
|
+
# .bluebook` is exactly that, a link to
|
|
87
|
+
# `examples/compliance/bluebook/compliance.bluebook`, so the whole
|
|
88
|
+
# framework domain failed to boot here with a LoadError naming a
|
|
89
|
+
# path under /var/folders that had never existed. Nothing about the
|
|
90
|
+
# domain was wrong; the copy was.
|
|
91
|
+
#
|
|
92
|
+
# `FileUtils.cp` follows a symlink and copies its CONTENT, which is
|
|
93
|
+
# what an isolated boot wants: the copy has to stand alone, since
|
|
94
|
+
# rebind! rewrites files in it and must not reach back through a
|
|
95
|
+
# link into the real tree.
|
|
96
|
+
def copy_dereferencing(source, destination)
|
|
97
|
+
FileUtils.mkdir_p(destination)
|
|
98
|
+
Dir.glob(File.join(source, "**", "*"), File::FNM_DOTMATCH).each do |path|
|
|
99
|
+
next if [".", ".."].include?(File.basename(path))
|
|
100
|
+
|
|
101
|
+
target = File.join(destination, path.delete_prefix("#{source}/"))
|
|
102
|
+
if File.directory?(path)
|
|
103
|
+
FileUtils.mkdir_p(target)
|
|
104
|
+
else
|
|
105
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
106
|
+
FileUtils.cp(path, target)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def rebind_to_memory!(copy)
|
|
112
|
+
rewrite_bindings!(copy, "Memory")
|
|
113
|
+
|
|
114
|
+
# THE SETTINGS, NOT JUST THE BIND — `WorldBuilder#method_missing`
|
|
115
|
+
# stores a settings block under BOTH "verb:adapter" and the bare
|
|
116
|
+
# "verb" (world_builder.rb:32-33), so a bind rewritten to Memory
|
|
117
|
+
# still falls back to whatever adapter's settings were declared
|
|
118
|
+
# bare — Postgres's `database:`, which Memory does not take and
|
|
119
|
+
# WiringError refuses on sight. Both Memory and Sqlite need no
|
|
120
|
+
# settings at all (`Sqlite#resolve_path` defaults `database` to
|
|
121
|
+
# `data/<table>.db` under `root:` when unset — the same
|
|
122
|
+
# zero-config default Memory gets from having no `.world` at
|
|
123
|
+
# all), so the simplest correct fix for either target is
|
|
124
|
+
# dropping `.world` from the copy entirely.
|
|
125
|
+
Dir.glob(File.join(copy, "**", "*.world")).each { |path| File.delete(path) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# SAME DANCE AS MEMORY, ONE ADAPTER OVER — `Adapters::Sqlite#
|
|
129
|
+
# resolve_path` (adapters/driven/sqlite.rb) defaults to
|
|
130
|
+
# `data/<table>.db` under the boot's own root when no `database`
|
|
131
|
+
# setting is declared, which `data/` already being cleared makes a
|
|
132
|
+
# fresh on-disk store with zero configuration, the same "no .world
|
|
133
|
+
# needed" property Memory has. `data/` itself is left for Sqlite to
|
|
134
|
+
# recreate on first write, same as it always was for Memory/Heki —
|
|
135
|
+
# nothing here creates it up front.
|
|
136
|
+
def rebind_to_sqlite!(copy)
|
|
137
|
+
rewrite_bindings!(copy, "SqlitePersistence")
|
|
138
|
+
Dir.glob(File.join(copy, "**", "*.world")).each { |path| File.delete(path) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# THE EXPENSIVE ONE — Postgres has no zero-config default the way
|
|
142
|
+
# Sqlite/Memory do (`Adapters::Postgres.connect_for` refuses outright
|
|
143
|
+
# with no `database` setting), so dropping `.world` the way the
|
|
144
|
+
# other two do would just move the WiringError from "wrong adapter"
|
|
145
|
+
# to "no adapter." Every domain name this copy declares gets a
|
|
146
|
+
# FRESH `.world` written for it instead — not a rewrite of whatever
|
|
147
|
+
# was there, a replacement, same reasoning `rewrite_bindings!`
|
|
148
|
+
# already applies to `.hecksagon`: this ephemeral boot owns every
|
|
149
|
+
# binding decision, nothing about a real deployment's own settings
|
|
150
|
+
# is relevant or safe to half-preserve here.
|
|
151
|
+
#
|
|
152
|
+
# ONE SHARED SCHEMA, DROPPED AND RECREATED BEFORE EVERY BOOT — not a
|
|
153
|
+
# fresh randomly-named one per call. `bin/fuzz` drives every
|
|
154
|
+
# ephemeral boot sequentially (one `IsolatedBoot.call` fully exits
|
|
155
|
+
# before the next begins — see that file's own single-threaded
|
|
156
|
+
# `while` loop), so nothing is ever concurrent here ; a fresh name
|
|
157
|
+
# every time would just leak schemas in `FUZZ_POSTGRES_DATABASE`
|
|
158
|
+
# forever with nothing to ever drop them. If a caller ever DOES
|
|
159
|
+
# start running fuzz adapters concurrently, this needs to move to a
|
|
160
|
+
# process-unique schema name (`SecureRandom.hex` is already
|
|
161
|
+
# `require`d here for exactly that day) — flagged, not solved,
|
|
162
|
+
# since nothing today calls this from more than one thread.
|
|
163
|
+
FUZZ_POSTGRES_DATABASE = "hecks_fuzz"
|
|
164
|
+
FUZZ_POSTGRES_SCHEMA = "hecks_fuzz"
|
|
165
|
+
|
|
166
|
+
def rebind_to_postgres!(copy)
|
|
167
|
+
require "pg"
|
|
168
|
+
rewrite_bindings!(copy, "Postgres")
|
|
169
|
+
ensure_fuzz_schema!
|
|
170
|
+
|
|
171
|
+
# ONE `.world` PER DIRECTORY A `.hecksagon` ACTUALLY LIVES IN, not
|
|
172
|
+
# one at `copy`'s own root — `Folder#load_domain` resolves a
|
|
173
|
+
# SINGLE `bluebook_directory` and globs `*.world` there, non-
|
|
174
|
+
# recursively (`Folder#load_each`); a domain can hold several
|
|
175
|
+
# `Hecks.hecksagon "<Name>" do ... end` SIBLING blocks in that one
|
|
176
|
+
# file (banking.hecksagon declares "Banking", "Governance", and
|
|
177
|
+
# "Identity" together), so every name found in one `.hecksagon`
|
|
178
|
+
# file gets bundled into one `.world` written beside it, not
|
|
179
|
+
# scattered by name.
|
|
180
|
+
Dir.glob(File.join(copy, "**", "*.hecksagon")).each do |hecksagon_path|
|
|
181
|
+
names = File.read(hecksagon_path).scan(/Hecks\.hecksagon\s+"([^"]+)"/).flatten.uniq
|
|
182
|
+
next if names.empty?
|
|
183
|
+
|
|
184
|
+
world_path = File.join(File.dirname(hecksagon_path), "hecks_fuzz_postgres.world")
|
|
185
|
+
File.write(world_path, names.map { |name|
|
|
186
|
+
<<~WORLD
|
|
187
|
+
Hecks.world "#{name}" do
|
|
188
|
+
persisted_by("Postgres") do
|
|
189
|
+
database "#{FUZZ_POSTGRES_DATABASE}"
|
|
190
|
+
schema "#{FUZZ_POSTGRES_SCHEMA}"
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
WORLD
|
|
194
|
+
}.join("\n"))
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Any PRE-EXISTING `.world` this copy shipped with (a real
|
|
198
|
+
# deployment's own connection string) is now redundant with — and
|
|
199
|
+
# would conflict with, `Registry#add_world`'s own header on
|
|
200
|
+
# loading the same domain name twice — the fresh one just
|
|
201
|
+
# written above, so it goes the same way `rebind_to_memory!`
|
|
202
|
+
# already sends every `.world` in a Memory-mode boot.
|
|
203
|
+
Dir.glob(File.join(copy, "**", "*.world")).each do |path|
|
|
204
|
+
File.delete(path) unless File.basename(path) == "hecks_fuzz_postgres.world"
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# ADMIN CONNECTION LIVES OUTSIDE THE TMP COPY ENTIRELY — same as
|
|
209
|
+
# every other real-Postgres spec in this repo (`support/
|
|
210
|
+
# postgres_probe.rb`'s own header). Database created once per
|
|
211
|
+
# process and remembered (`@fuzz_database_ready` on this module's
|
|
212
|
+
# own singleton, the same memoization shape `PostgresProbe
|
|
213
|
+
# .available?` already uses) ; the schema inside it is dropped and
|
|
214
|
+
# recreated on EVERY call, which is what actually isolates one
|
|
215
|
+
# ephemeral boot's data from the next.
|
|
216
|
+
def ensure_fuzz_schema!
|
|
217
|
+
# `Adapters::Postgres#initialize` opens ONE real `PG::Connection`
|
|
218
|
+
# PER AGGREGATE and never explicitly closes it — fine for a
|
|
219
|
+
# process that boots once and runs, exactly what every other
|
|
220
|
+
# caller of this adapter is. A fuzz run boots dozens to hundreds
|
|
221
|
+
# of EPHEMERAL times in one process (every seed does at least a
|
|
222
|
+
# generate + a replay, `replay_is_deterministic` doubles that,
|
|
223
|
+
# shrinking multiplies it further), and `PG::Connection` only
|
|
224
|
+
# actually closes its socket when Ruby's GC finalizes the
|
|
225
|
+
# (by-then-unreferenced) object — which, under a tight loop like
|
|
226
|
+
# this, does not reliably keep pace with how fast new
|
|
227
|
+
# connections open. Discovered live: `bin/fuzz --adapter
|
|
228
|
+
# postgres` against `examples/banking` hit a real local
|
|
229
|
+
# Postgres's own `max_connections` after roughly a dozen
|
|
230
|
+
# ephemeral boots, `PG::ConnectionBad: ... "too many clients
|
|
231
|
+
# already"`. A `GC.start` here — right before the next ephemeral
|
|
232
|
+
# boot's connections open, not on some timer — reclaims every
|
|
233
|
+
# connection the PREVIOUS boot's now-unreferenced adapters held,
|
|
234
|
+
# keeping the live count bounded regardless of run length. This
|
|
235
|
+
# is a real constraint on running Postgres in a loop, not
|
|
236
|
+
# something to route around by connecting less carefully.
|
|
237
|
+
GC.start
|
|
238
|
+
|
|
239
|
+
unless @fuzz_database_ready
|
|
240
|
+
admin = PG.connect(dbname: "postgres")
|
|
241
|
+
exists = admin.exec_params(
|
|
242
|
+
"SELECT 1 FROM pg_database WHERE datname = $1", [FUZZ_POSTGRES_DATABASE]
|
|
243
|
+
).ntuples.positive?
|
|
244
|
+
admin.exec(%(CREATE DATABASE "#{FUZZ_POSTGRES_DATABASE}")) unless exists
|
|
245
|
+
admin.close
|
|
246
|
+
@fuzz_database_ready = true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
db = PG.connect(dbname: FUZZ_POSTGRES_DATABASE)
|
|
250
|
+
# QUIET ON PURPOSE — same as `Adapters::Postgres.connect_for`'s
|
|
251
|
+
# own `SET client_min_messages`: a `DROP SCHEMA ... CASCADE` that
|
|
252
|
+
# actually has something to drop (every boot after the first)
|
|
253
|
+
# NOTICEs once per dropped object, which is the ordinary case
|
|
254
|
+
# here, not news, and would otherwise bury `bin/fuzz`'s own
|
|
255
|
+
# output under a wall of "drop cascades to table ..." on every
|
|
256
|
+
# single ephemeral boot.
|
|
257
|
+
db.exec("SET client_min_messages = warning")
|
|
258
|
+
quoted = db.quote_ident(FUZZ_POSTGRES_SCHEMA)
|
|
259
|
+
db.exec("DROP SCHEMA IF EXISTS #{quoted} CASCADE")
|
|
260
|
+
db.exec("CREATE SCHEMA #{quoted}")
|
|
261
|
+
db.close
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# THE SHARED REWRITE — factored out of `rebind_to_memory!` when
|
|
265
|
+
# Sqlite/Postgres modes needed the identical `.hecksagon` surgery
|
|
266
|
+
# with only the target adapter name differing. `persisted_by`/
|
|
267
|
+
# `projected_by` can be spelled two ways: aggregate-scoped
|
|
268
|
+
# (`Banking::Customer.persisted_by("Heki")`, always parenthesised)
|
|
269
|
+
# and, since §0's domain-level default binds, a bare call at the
|
|
270
|
+
# hecksagon's own root (`persisted_by "Heki"`, no parens, no
|
|
271
|
+
# receiver). Both must be caught here or a domain that only
|
|
272
|
+
# declares the bare form keeps its real adapter under an
|
|
273
|
+
# "isolated" fuzz boot. `projected_by` is dropped outright rather
|
|
274
|
+
# than rebound, for every target adapter — `Registry
|
|
275
|
+
# #read_repository` already falls back to the authoritative
|
|
276
|
+
# repository when none exists, so a read model this ephemeral copy
|
|
277
|
+
# never wires is simply unread, not broken.
|
|
278
|
+
def rewrite_bindings!(copy, adapter_name)
|
|
279
|
+
Dir.glob(File.join(copy, "**", "*.hecksagon")).each do |path|
|
|
280
|
+
lines = File.readlines(path).reject { |line| line.match?(/\bprojected_by\s*\(?\s*"/) }
|
|
281
|
+
File.write(path, lines.join.gsub(/persisted_by\s*\(?\s*"[^"]+"\s*\)?/, "persisted_by(\"#{adapter_name}\")"))
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|