hecks 2.8.0 → 2.9.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 +4 -4
- data/exe/hecks +4 -6
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +17 -98
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres.rb +145 -134
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +7 -30
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +5 -48
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +31 -141
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +10 -48
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +14 -63
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -194
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +19 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +37 -660
- data/lib/hecks/bluebook/hexagon.rb +5 -28
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +79 -349
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +100 -597
- data/lib/hecks/bluebook/pattern_subset.rb +11 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +9 -48
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +8 -98
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- data/lib/hecks/cli/document.rb +3 -21
- data/lib/hecks/cli/ir.rb +3 -5
- data/lib/hecks/cli/mcp.rb +2 -3
- data/lib/hecks/cli/mcp_door.rb +19 -114
- data/lib/hecks/cli/model_check.rb +18 -85
- data/lib/hecks/cli/project_cli.rb +7 -40
- data/lib/hecks/cli/project_diagrams.rb +0 -7
- data/lib/hecks/cli/run.rb +12 -58
- data/lib/hecks/cli/smoke_test.rb +2 -16
- data/lib/hecks/cli/stores.rb +1 -2
- data/lib/hecks/cli.rb +18 -24
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +4 -71
- data/lib/hecks/facade/cli_door.rb +24 -106
- data/lib/hecks/facade/cli_runner.rb +28 -172
- data/lib/hecks/facade/command_request.rb +13 -33
- data/lib/hecks/facade/handle.rb +34 -121
- data/lib/hecks/facade/json_door.rb +31 -146
- data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
- data/lib/hecks/facade/surface/chapter.rb +10 -54
- data/lib/hecks/facade/surface.rb +8 -23
- data/lib/hecks/facade.rb +10 -25
- data/lib/hecks/forms/app.rb +15 -70
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +30 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +12 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +82 -197
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_door_scope.rb +9 -90
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +23 -103
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projections/bootstrap_table.rb +11 -43
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +35 -202
- data/lib/hecks/projections/deploy/lambda.rb +150 -678
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +2 -58
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +47 -146
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +20 -582
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +15 -42
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +9 -28
- data/lib/hecks/projections/reference.rb +2 -15
- data/lib/hecks/projections/rust_vocabulary.rb +12 -250
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +60 -375
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +3 -6
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/gem_publisher.rb +2 -3
- data/lib/hecks/release/runner/npm_publisher.rb +6 -20
- data/lib/hecks/release/runner/preflight.rb +4 -19
- data/lib/hecks/release/runner/tagger.rb +2 -9
- data/lib/hecks/release/runner.rb +3 -32
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +12 -36
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +30 -102
- data/lib/hecks/runtime/dispatcher.rb +82 -241
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +11 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +48 -186
- data/lib/hecks/runtime/outbox.rb +38 -261
- data/lib/hecks/runtime/policy_interpreter.rb +38 -200
- data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
- data/lib/hecks/runtime/query_interpreter.rb +45 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +8 -89
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +52 -225
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +99 -244
- data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +155 -641
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value.rb +12 -84
- data/lib/hecks/runtime.rb +17 -65
- data/lib/hecks/storehouse.rb +141 -568
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +26 -81
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- metadata +3 -2
|
@@ -7,33 +7,17 @@ module Hecks
|
|
|
7
7
|
# command-line launcher beside each domain, named after its bluebook, so
|
|
8
8
|
# `Hecks.bluebook "QualityControl"` in `qa/` becomes `qa/quality_control`.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# `Facade::CliRunner`. The surface still comes from `Projector.call(:cli, …)` at
|
|
14
|
-
# the moment it runs, so editing a chapter changes the launcher's behaviour
|
|
15
|
-
# without regenerating anything. Re-run this when a domain is added or renamed.
|
|
16
|
-
#
|
|
17
|
-
# ## Beside the domain
|
|
18
|
-
#
|
|
19
|
-
# A domain's command line lives with the domain, so a folder is the whole unit.
|
|
20
|
-
# The launcher boots `__dir__`, and reaches `lib` by counting how deep the domain
|
|
21
|
-
# sits below the root, so no line knows where the checkout was cloned.
|
|
10
|
+
# Each launcher is a dozen lines pinning one directory and handing over to
|
|
11
|
+
# `Facade::CliRunner`; the surface itself is projected at the moment it runs,
|
|
12
|
+
# so editing a chapter changes behaviour without regenerating anything.
|
|
22
13
|
module ProjectCli
|
|
23
14
|
# Build output and other trees under a root that hold no domain a caller means.
|
|
24
15
|
IGNORED = %r{\A(rust|deploy|tmp|coverage)/}
|
|
25
16
|
|
|
26
17
|
module_function
|
|
27
18
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# @param argv [Array<String>] domain paths relative to `root`; empty for all of them
|
|
32
|
-
# @param program [String] the name the generated header credits
|
|
33
|
-
# @param root [String] the directory domains are found under and paths resolve against
|
|
34
|
-
# @param remove_stale_bin [Boolean] whether to delete `root/bin/<name>`, where a
|
|
35
|
-
# launcher for the same chapter would otherwise linger as a second front door
|
|
36
|
-
# @return [void]
|
|
19
|
+
# `remove_stale_bin` deletes `root/bin/<name>`, where a launcher for the same
|
|
20
|
+
# chapter would otherwise linger as a second front door.
|
|
37
21
|
def call(argv, program:, root:, remove_stale_bin: true)
|
|
38
22
|
wanted = argv.empty? ? domains(root) : argv.map { |path| path.delete_prefix("#{root}/").chomp("/") }
|
|
39
23
|
|
|
@@ -50,11 +34,6 @@ module Hecks
|
|
|
50
34
|
end
|
|
51
35
|
end
|
|
52
36
|
|
|
53
|
-
# Finds every domain under `root` a launcher can be written for.
|
|
54
|
-
#
|
|
55
|
-
# @param root [String] the directory to search under
|
|
56
|
-
# @return [Array<String>] domain directory paths relative to `root`,
|
|
57
|
-
# deduplicated and sorted
|
|
58
37
|
def domains(root)
|
|
59
38
|
folder = Adapters::Folder.new
|
|
60
39
|
Dir.glob(File.join(root, "**/*.hecksagon"))
|
|
@@ -65,14 +44,8 @@ module Hecks
|
|
|
65
44
|
.uniq.sort
|
|
66
45
|
end
|
|
67
46
|
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
# `formerly_known_as` gets a launcher under its new name.
|
|
71
|
-
#
|
|
72
|
-
# @param root [String] the directory `path` is relative to
|
|
73
|
-
# @param path [String] a domain directory path
|
|
74
|
-
# @return [String, nil] the domain's declared bluebook name, or nil after warning
|
|
75
|
-
# when it fails to boot
|
|
47
|
+
# Reads the name from `Hecks.bluebook "…"` rather than the directory, so a
|
|
48
|
+
# domain using `formerly_known_as` gets a launcher under its current name.
|
|
76
49
|
def bluebook_name(root, path)
|
|
77
50
|
Hecks.boot(File.join(root, path), install_facade: false).registry.bluebooks.keys.first
|
|
78
51
|
rescue StandardError => e
|
|
@@ -80,12 +53,6 @@ module Hecks
|
|
|
80
53
|
nil
|
|
81
54
|
end
|
|
82
55
|
|
|
83
|
-
# Renders one domain's launcher.
|
|
84
|
-
#
|
|
85
|
-
# @param path [String] the domain directory path, relative to the root
|
|
86
|
-
# @param name [String] the domain's declared bluebook name
|
|
87
|
-
# @param program [String] the name the generated header credits
|
|
88
|
-
# @return [String] the launcher script's full source
|
|
89
56
|
def launcher(path, name, program)
|
|
90
57
|
snake = Naming.snake(name)
|
|
91
58
|
up = "../" * path.count("/").succ
|
|
@@ -9,13 +9,6 @@ module Hecks
|
|
|
9
9
|
module ProjectDiagrams
|
|
10
10
|
module_function
|
|
11
11
|
|
|
12
|
-
# Projects and writes one chapter's diagrams, then lists what was written.
|
|
13
|
-
#
|
|
14
|
-
# @param argv [Array<String>] the domain path, then the chapter name
|
|
15
|
-
# @param program [String] the name the usage message calls this command by
|
|
16
|
-
# @param root [String] the directory `docs/generated/diagrams/` is written under
|
|
17
|
-
# @return [void]
|
|
18
|
-
# @raise [SystemExit] when either argument is missing
|
|
19
12
|
def call(argv, program:, root:)
|
|
20
13
|
usage = "usage: #{program} <domain-path> <ChapterName>"
|
|
21
14
|
domain_path = argv[0] or abort usage
|
data/lib/hecks/cli/run.rb
CHANGED
|
@@ -10,20 +10,12 @@ module Hecks
|
|
|
10
10
|
# command line, or executes a JSON step list and reports instances, events,
|
|
11
11
|
# refusals, reactions, sagas and query rows.
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# cannot go stale. The step-list form takes a script path, `-` for stdin, or the
|
|
20
|
-
# JSON itself, which is how the corpus scripts under `spec/corpus/` are run.
|
|
21
|
-
#
|
|
22
|
-
# ## Standing in a domain is enough
|
|
23
|
-
#
|
|
24
|
-
# `Adapters::Folder#domain_root` walks up for the nearest `.hecksagon`, so inside
|
|
25
|
-
# a domain the path can be left off. The first argument is a domain only when it
|
|
26
|
-
# is a directory.
|
|
13
|
+
# `run bug.discover reference=BUG#1 severity=high …` needs no JSON; the verb
|
|
14
|
+
# tree and its arguments are projected from the bluebook, so this knows nothing
|
|
15
|
+
# about any domain and its help cannot go stale. The step-list form takes a
|
|
16
|
+
# script path, `-` for stdin, or the JSON itself. The first argument is a
|
|
17
|
+
# domain only when it is a directory; otherwise the nearest enclosing one is
|
|
18
|
+
# used.
|
|
27
19
|
module Run
|
|
28
20
|
module_function
|
|
29
21
|
|
|
@@ -59,19 +51,9 @@ module Hecks
|
|
|
59
51
|
abort unmet.join("\n") unless unmet.empty?
|
|
60
52
|
end
|
|
61
53
|
|
|
62
|
-
#
|
|
63
|
-
# the
|
|
64
|
-
#
|
|
65
|
-
# **No fall-through**. This is reached only when the argument is not
|
|
66
|
-
# script-shaped, so a near miss deserves the runner's "did you mean" rather
|
|
67
|
-
# than the step-list form's "no such script".
|
|
68
|
-
#
|
|
69
|
-
# @param domain [String] the domain's directory path
|
|
70
|
-
# @param argv [Array<String>] the arguments after the domain, e.g.
|
|
71
|
-
# `["bug.discover", "reference=BUG#1"]`
|
|
72
|
-
# @param program [String] the name the runner's help calls this command by
|
|
73
|
-
# @return [void]
|
|
74
|
-
# @raise [SystemExit] always
|
|
54
|
+
# No fall-through: reached only when the argument is not script-shaped, so a
|
|
55
|
+
# near miss deserves the runner's "did you mean" rather than the step-list
|
|
56
|
+
# form's "no such script".
|
|
75
57
|
def cli_form(domain, argv, program)
|
|
76
58
|
runtime = Hecks.boot(domain, install_facade: false)
|
|
77
59
|
text, status = Facade::CliRunner.call(runtime: runtime, argv: argv, program: program)
|
|
@@ -79,20 +61,10 @@ module Hecks
|
|
|
79
61
|
exit 0
|
|
80
62
|
end
|
|
81
63
|
|
|
82
|
-
# Says whether `arg` is a step list rather than a verb: stdin, inline JSON, or
|
|
83
|
-
# a file that exists.
|
|
84
|
-
#
|
|
85
|
-
# @param arg [String] the first argument after the domain
|
|
86
|
-
# @return [Boolean] true when `arg` is script-shaped
|
|
87
64
|
def script_shaped?(arg) = arg == "-" || arg.match?(/\A\s*\{/) || File.file?(arg)
|
|
88
65
|
|
|
89
|
-
#
|
|
90
|
-
# decided by looking, because a script beginning with `{` is not a filename
|
|
66
|
+
# Decided by looking, because a script beginning with `{` is not a filename
|
|
91
67
|
# anybody meant.
|
|
92
|
-
#
|
|
93
|
-
# @param script [String] `-`, inline JSON, or a file path
|
|
94
|
-
# @return [String] the script's JSON text
|
|
95
|
-
# @raise [SystemExit] when `script` names no file
|
|
96
68
|
def read_source(script)
|
|
97
69
|
case script
|
|
98
70
|
when "-" then $stdin.read
|
|
@@ -102,25 +74,14 @@ module Hecks
|
|
|
102
74
|
end
|
|
103
75
|
end
|
|
104
76
|
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
# @param source [String] the script's JSON text
|
|
109
|
-
# @return [Hash{String => Object}] the parsed script
|
|
110
|
-
# @raise [SystemExit] when `source` is not JSON
|
|
77
|
+
# Parsed before anything boots, because booting opens a real store and a typo
|
|
78
|
+
# in the JSON should cost a sentence, not a connection.
|
|
111
79
|
def parse(source)
|
|
112
80
|
JSON.parse(source)
|
|
113
81
|
rescue JSON::ParserError => e
|
|
114
82
|
abort "that is not JSON: #{e.message.lines.first.strip}"
|
|
115
83
|
end
|
|
116
84
|
|
|
117
|
-
# Runs every step and gathers what the runtime holds afterwards.
|
|
118
|
-
#
|
|
119
|
-
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
|
|
120
|
-
# @param steps [Array<Hash{String => Object}>] the script's steps, each a
|
|
121
|
-
# `"verb"` or a `"query"` with optional `"args"`
|
|
122
|
-
# @return [Hash{Symbol => Object}] `:instances`, `:events`, `:refusals`,
|
|
123
|
-
# `:reactions`, `:sagas` and `:queries`, in the order they are printed
|
|
124
85
|
def execute(runtime, steps)
|
|
125
86
|
refusals = []
|
|
126
87
|
queries = []
|
|
@@ -171,13 +132,6 @@ module Hecks
|
|
|
171
132
|
end
|
|
172
133
|
end
|
|
173
134
|
|
|
174
|
-
# Checks the script's `"expectations"` against what the run produced.
|
|
175
|
-
#
|
|
176
|
-
# @param expectations [Hash{String => Object}] the script's `"event_names"`,
|
|
177
|
-
# `"refusals"` and `"instances"` expectations; `{}` when it declares none
|
|
178
|
-
# @param report [Hash{Symbol => Object}] what `execute` answered
|
|
179
|
-
# @return [Array<String>] one message per unmet expectation; empty when every
|
|
180
|
-
# one held
|
|
181
135
|
def unmet_expectations(expectations, report)
|
|
182
136
|
missing_events = Array(expectations["event_names"]) - report[:events].map { |event| event[:name] }
|
|
183
137
|
unmet = []
|
data/lib/hecks/cli/smoke_test.rb
CHANGED
|
@@ -7,22 +7,12 @@ module Hecks
|
|
|
7
7
|
# and dispatches one synthesized call per declared command and report
|
|
8
8
|
# (`Bluebook::SmokeTest`), printing every failure rather than the first.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# a value the synthesizer's naive choices (0, an empty list, "smoke-test") cannot
|
|
13
|
-
# satisfy; the message underneath says which. Smoke-testing proves nothing
|
|
10
|
+
# Needs a real `.hecksagon`; a failure may be a domain bug or a value the
|
|
11
|
+
# synthesizer's naive choices cannot satisfy — smoke-testing proves nothing
|
|
14
12
|
# crashes, not that an answer is right.
|
|
15
13
|
module SmokeTest
|
|
16
14
|
module_function
|
|
17
15
|
|
|
18
|
-
# Smoke-tests the domain `argv` names, or every wired domain under
|
|
19
|
-
# `root/examples/`, and exits with the verdict.
|
|
20
|
-
#
|
|
21
|
-
# @param argv [Array<String>] an optional domain directory
|
|
22
|
-
# @param root [String] the directory whose `examples/*` are tested when `argv`
|
|
23
|
-
# names no domain
|
|
24
|
-
# @return [void]
|
|
25
|
-
# @raise [SystemExit] always: 0 when clean, 1 with failures or no domain found
|
|
26
16
|
def call(argv, root:)
|
|
27
17
|
dir_arg = argv.first
|
|
28
18
|
targets = dir_arg ? [dir_arg] : Dir.glob("#{root}/examples/*/").map { |d| d.chomp("/") }.select { |d| wired?(d) }
|
|
@@ -35,10 +25,6 @@ module Hecks
|
|
|
35
25
|
exit(ok ? 0 : 1)
|
|
36
26
|
end
|
|
37
27
|
|
|
38
|
-
# Says whether `dir`, or something nested under it, is a bindable domain.
|
|
39
|
-
#
|
|
40
|
-
# @param dir [String] a directory to check
|
|
41
|
-
# @return [Boolean] true if `dir` contains at least one `.hecksagon` file
|
|
42
28
|
def wired?(dir) = !Dir.glob(File.join(dir, "**/*.hecksagon")).empty?
|
|
43
29
|
|
|
44
30
|
# @api private
|
data/lib/hecks/cli/stores.rb
CHANGED
|
@@ -4,8 +4,7 @@ require_relative "../../hecks"
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module CLI
|
|
6
6
|
# The command behind `bin/stores` and `hecks stores`: every aggregate's current
|
|
7
|
-
# records as JSON
|
|
8
|
-
# full write history).
|
|
7
|
+
# records as JSON (the head, not the journal — see `bin/history` for that).
|
|
9
8
|
module Stores
|
|
10
9
|
module_function
|
|
11
10
|
|
data/lib/hecks/cli.rb
CHANGED
|
@@ -1,27 +1,9 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
# The `hecks` command an installed gem puts on the path: one router over the
|
|
3
|
-
# domain-operator tools, each
|
|
3
|
+
# domain-operator tools, each also runnable from a checkout as `bin/<name>`.
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Every subcommand's logic lives in `lib/hecks/cli/`, and the matching `bin/`
|
|
8
|
-
# script is a thin wrapper over the same entry point, so `hecks run` and
|
|
9
|
-
# `bin/run` cannot drift apart. The domain-scoped verbs go through
|
|
10
|
-
# `Facade::CliRunner`, the same way `bin/run` does.
|
|
11
|
-
#
|
|
12
|
-
# ## What a checkout has and an install does not
|
|
13
|
-
#
|
|
14
|
-
# The `bin/` wrappers pass the repository root, which is where they look for
|
|
15
|
-
# `examples/`, `rust/` and `docs/generated/`. Here the root is the working
|
|
16
|
-
# directory, so a command that lists or writes files does it where the caller
|
|
17
|
-
# stands. `model_check` with no domain sweeps the repository's corpus, which an
|
|
18
|
-
# install does not carry, so here it needs at least one domain path.
|
|
19
|
-
#
|
|
20
|
-
# ## Loading
|
|
21
|
-
#
|
|
22
|
-
# Nothing here requires the framework. A subcommand loads it when it runs, and
|
|
23
|
-
# `mcp` checks its transport before anything else loads, as
|
|
24
|
-
# `McpStdioGuard.enforce_stdio!` requires.
|
|
5
|
+
# Every subcommand's logic lives under `cli/`, with `bin/<name>` a thin wrapper
|
|
6
|
+
# over the same entry point, so the two can't drift apart.
|
|
25
7
|
#
|
|
26
8
|
# See `docs/decisions/0066-the-gem-ships-a-hecks-executable-and-dev-tooling-stays-in-the-repo.md`.
|
|
27
9
|
module CLI
|
|
@@ -74,6 +56,18 @@ module Hecks
|
|
|
74
56
|
|
|
75
57
|
HELP_FLAGS = ["--help", "-h"].freeze
|
|
76
58
|
|
|
59
|
+
# Printed above the usage line by `overview`, on every path that reaches it
|
|
60
|
+
# (a bare `hecks`, `hecks --help`, and an unknown subcommand alike).
|
|
61
|
+
HERO = <<~BANNER.freeze
|
|
62
|
+
# # ##### #### # # ####
|
|
63
|
+
# # # # # # #
|
|
64
|
+
##### #### # ## ###
|
|
65
|
+
# # # # # # #
|
|
66
|
+
# # ##### #### # # ####
|
|
67
|
+
|
|
68
|
+
It's all about the specs
|
|
69
|
+
BANNER
|
|
70
|
+
|
|
77
71
|
# Exit status for a missing or unknown subcommand.
|
|
78
72
|
USAGE_STATUS = 2
|
|
79
73
|
|
|
@@ -81,9 +75,8 @@ module Hecks
|
|
|
81
75
|
|
|
82
76
|
# Routes `argv` to its subcommand and runs it.
|
|
83
77
|
#
|
|
84
|
-
# A subcommand followed by
|
|
85
|
-
#
|
|
86
|
-
# `hecks run order.place --help` still reaches the verb's own help.
|
|
78
|
+
# A subcommand followed only by `--help`/`-h` prints its usage without
|
|
79
|
+
# running it; other arguments still reach the verb itself.
|
|
87
80
|
#
|
|
88
81
|
# @param argv [Array<String>] the command line, subcommand first
|
|
89
82
|
# @param out [#puts] where help goes
|
|
@@ -148,6 +141,7 @@ module Hecks
|
|
|
148
141
|
|
|
149
142
|
# @api private
|
|
150
143
|
def overview(io)
|
|
144
|
+
io.puts HERO
|
|
151
145
|
io.puts "usage: hecks <command> [arguments]"
|
|
152
146
|
io.puts ""
|
|
153
147
|
width = COMMANDS.keys.map(&:length).max
|
data/lib/hecks/construct.rb
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
module Hecks
|
|
2
|
-
# The invisible
|
|
2
|
+
# The invisible identity a built construct carries: an owner chain under `hecks_`-prefixed
|
|
3
|
+
# fields, not an attribute and not a key in `to_h`.
|
|
3
4
|
#
|
|
4
|
-
#
|
|
5
|
+
# The fully-qualified name walks owners and matches the id `MetaValidator::Judge#identify` mints.
|
|
5
6
|
#
|
|
6
|
-
#
|
|
7
|
-
# owns its aggregates, an aggregate owns everything declared on it — and the
|
|
8
|
-
# bluebook identity is carried in its own field, under a `hecks_` prefix that
|
|
9
|
-
# no domain attribute can collide with. Invisible means exactly that: not an
|
|
10
|
-
# attribute, not a key in `to_h`, not a reader on instances. Framework
|
|
11
|
-
# metadata about the construct, not part of the domain it describes.
|
|
12
|
-
#
|
|
13
|
-
# The identity is computed by walking owners rather than stamped, so nothing
|
|
14
|
-
# has to be re-stamped when a chapter is assembled after its aggregates:
|
|
15
|
-
#
|
|
16
|
-
# Pizzas the chapter — no owner
|
|
7
|
+
# Pizzas the chapter, no owner
|
|
17
8
|
# Pizzas::Pizza an aggregate joins its chapter with ::
|
|
18
9
|
# Pizzas::Pizza.Price everything else joins its owner with .
|
|
19
|
-
#
|
|
20
|
-
# That spelling is not invented here. It is the id `MetaValidator::Judge`
|
|
21
|
-
# already mints in `#identify`, so a construct and the meta-domain's
|
|
22
|
-
# record of that construct carry the same identity, and there is no
|
|
23
|
-
# translation table between them to be quietly wrong in.
|
|
24
|
-
#
|
|
25
|
-
# ## Usage
|
|
26
|
-
#
|
|
27
10
|
# price = Class.new(ValueObject) # a declaration holder
|
|
28
11
|
# price.hecks_name = "Price"
|
|
29
12
|
# price.hecks_owner = pizza_ir # the Aggregate that declares it
|
|
@@ -32,15 +15,12 @@ module Hecks
|
|
|
32
15
|
# A construct asked for an identity it cannot compute.
|
|
33
16
|
class Unowned < StandardError; end
|
|
34
17
|
|
|
35
|
-
# What declares this
|
|
36
|
-
# above a value object. nil for a chapter, which is the top.
|
|
18
|
+
# What declares this construct; nil for a chapter, which is the top.
|
|
37
19
|
attr_accessor :hecks_owner
|
|
38
20
|
|
|
39
21
|
attr_writer :hecks_name
|
|
40
22
|
|
|
41
|
-
#
|
|
42
|
-
# else is declared in something, so a missing owner is an unstamped construct
|
|
43
|
-
# rather than a top — see hecks_fqn.
|
|
23
|
+
# Marks a chapter, the only construct that legitimately has no owner.
|
|
44
24
|
attr_writer :hecks_root
|
|
45
25
|
|
|
46
26
|
# Whether this construct is the top of its own owner chain.
|
|
@@ -53,18 +33,12 @@ module Hecks
|
|
|
53
33
|
# @return [String] the construct's own name, without any owner prefix
|
|
54
34
|
def hecks_name = @hecks_name
|
|
55
35
|
|
|
56
|
-
# How this construct joins its owner
|
|
57
|
-
# chapter's namespace (`::`) ; everything else is declared on its owner
|
|
58
|
-
# (`.`). Overridden by Aggregate, defaulted here for every other construct.
|
|
36
|
+
# How this construct joins its owner: `::` for an aggregate, `.` for everything else.
|
|
59
37
|
#
|
|
60
38
|
# @return [String] `"."`, the separator this construct uses in `hecks_fqn`
|
|
61
39
|
def hecks_separator = "."
|
|
62
40
|
|
|
63
|
-
# Refuses rather than
|
|
64
|
-
# chapter has simply not been stamped yet — entity commands are in that state
|
|
65
|
-
# while entities are still IR objects — and answering the bare name would be a
|
|
66
|
-
# plausible half-truth that no test would notice. That shape of falsehood is
|
|
67
|
-
# what this repo keeps finding, so it goes red instead.
|
|
41
|
+
# Refuses rather than answering a bare name for an unstamped construct.
|
|
68
42
|
#
|
|
69
43
|
# @return [String] the fully-qualified name, joining every owner from the
|
|
70
44
|
# chapter down to this construct
|