hecks 1.3.0 → 1.4.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/lib/hecks/adapters/driven/claude_code.rb +7 -7
- data/lib/hecks/adapters/driven/d1.rb +187 -23
- data/lib/hecks/adapters/driven/folder.rb +10 -10
- data/lib/hecks/adapters/driven/google_authentication.rb +8 -8
- data/lib/hecks/adapters/driven/governance_authorization.rb +31 -13
- data/lib/hecks/adapters/driven/heki/journal.rb +5 -4
- data/lib/hecks/adapters/driven/heki/saga_store.rb +5 -5
- data/lib/hecks/adapters/driven/heki.rb +13 -7
- data/lib/hecks/adapters/driven/identity_registry.rb +2 -2
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +3 -3
- data/lib/hecks/adapters/driven/lambda/client.rb +34 -9
- data/lib/hecks/adapters/driven/lambda.rb +39 -33
- data/lib/hecks/adapters/driven/local_storage.rb +17 -10
- data/lib/hecks/adapters/driven/memory.rb +205 -9
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +1 -1
- data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
- data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
- data/lib/hecks/adapters/driven/postgres.rb +175 -28
- data/lib/hecks/adapters/driven/prism.rb +4 -4
- data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
- data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
- data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
- data/lib/hecks/adapters/driven/sqlite.rb +181 -21
- data/lib/hecks/adapters/driven.rb +4 -4
- data/lib/hecks/adapters/driving/github_webhook.rb +18 -18
- data/lib/hecks/behaviors/dsl.rb +2 -2
- data/lib/hecks/behaviors/expectations.rb +23 -23
- data/lib/hecks/behaviors/ir.rb +1 -1
- data/lib/hecks/behaviors/rspec.rb +1 -1
- data/lib/hecks/behaviors/runner.rb +2 -2
- data/lib/hecks/behaviors.rb +1 -1
- data/lib/hecks/bluebook/aggregate.rb +13 -13
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +10 -10
- data/lib/hecks/bluebook/assembly/build.rb +1 -1
- data/lib/hecks/bluebook/assembly/contract.rb +39 -16
- data/lib/hecks/bluebook/assembly/contracts.rb +40 -38
- data/lib/hecks/bluebook/assembly/marks.rb +18 -18
- data/lib/hecks/bluebook/assembly/specializer.rb +19 -21
- data/lib/hecks/bluebook/assembly.rb +9 -9
- data/lib/hecks/bluebook/attribute.rb +9 -9
- data/lib/hecks/bluebook/behaviour/aggregate.rb +11 -11
- data/lib/hecks/bluebook/behaviour/attribute.rb +5 -5
- data/lib/hecks/bluebook/behaviour/chapter.rb +23 -5
- data/lib/hecks/bluebook/behaviour/command.rb +23 -23
- data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -7
- data/lib/hecks/bluebook/behaviour/entity.rb +8 -8
- data/lib/hecks/bluebook/behaviour/hexagon.rb +4 -4
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +5 -5
- data/lib/hecks/bluebook/behaviour/policy.rb +12 -12
- data/lib/hecks/bluebook/behaviour/process_manager.rb +7 -7
- data/lib/hecks/bluebook/behaviour/query.rb +1 -1
- data/lib/hecks/bluebook/behaviour/read_model.rb +8 -8
- data/lib/hecks/bluebook/behaviour/traits.rb +12 -12
- data/lib/hecks/bluebook/behaviour/value_object.rb +6 -6
- data/lib/hecks/bluebook/capabilities.rb +27 -0
- data/lib/hecks/bluebook/chapter.rb +28 -9
- data/lib/hecks/bluebook/command.rb +12 -12
- data/lib/hecks/bluebook/domain_port.rb +9 -9
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +96 -96
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +41 -41
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +22 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +111 -74
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +48 -30
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +103 -103
- data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
- data/lib/hecks/bluebook/dsl/entity_builder.rb +56 -56
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +89 -30
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +17 -17
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
- data/lib/hecks/bluebook/dsl/policy_builder.rb +30 -21
- data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +35 -35
- data/lib/hecks/bluebook/dsl/query_builder.rb +5 -5
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +34 -34
- data/lib/hecks/bluebook/dsl/rule_reference.rb +41 -39
- data/lib/hecks/bluebook/dsl/translation_builder.rb +9 -9
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +16 -16
- data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
- data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
- data/lib/hecks/bluebook/entity.rb +11 -11
- data/lib/hecks/bluebook/expression/ast_json.rb +20 -20
- data/lib/hecks/bluebook/expression/ast_reader.rb +3 -3
- data/lib/hecks/bluebook/expression/canonical_form.rb +9 -9
- data/lib/hecks/bluebook/expression/evaluator.rb +18 -18
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +18 -18
- data/lib/hecks/bluebook/expression/resolver.rb +60 -62
- data/lib/hecks/bluebook/hexagon.rb +1 -1
- data/lib/hecks/bluebook/lifecycle.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/judge.rb +101 -87
- data/lib/hecks/bluebook/meta_validator/plan.rb +39 -39
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -2
- data/lib/hecks/bluebook/meta_validator/readings.rb +43 -43
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +44 -37
- data/lib/hecks/bluebook/meta_validator/shapes.rb +25 -21
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +145 -31
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +6 -6
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +5 -5
- data/lib/hecks/bluebook/meta_validator.rb +70 -70
- data/lib/hecks/bluebook/model_check.rb +170 -84
- data/lib/hecks/bluebook/pattern_subset.rb +9 -9
- data/lib/hecks/bluebook/policy.rb +15 -13
- data/lib/hecks/bluebook/process_manager.rb +14 -14
- data/lib/hecks/bluebook/project_register.rb +6 -6
- data/lib/hecks/bluebook/query.rb +4 -4
- data/lib/hecks/bluebook/read_model.rb +14 -14
- data/lib/hecks/bluebook/reference.rb +8 -8
- data/lib/hecks/bluebook/smoke_test.rb +19 -19
- data/lib/hecks/bluebook/synthesizer.rb +12 -12
- data/lib/hecks/bluebook/translation.rb +4 -4
- data/lib/hecks/bluebook/value_object.rb +6 -6
- data/lib/hecks/bluebook.rb +2 -2
- data/lib/hecks/codemod/legacy_dispatch_args.rb +299 -0
- data/lib/hecks/codemod/legacy_dispatch_recorder.rb +186 -0
- data/lib/hecks/codemod.rb +36 -35
- data/lib/hecks/construct.rb +6 -6
- data/lib/hecks/corpus.rb +317 -0
- data/lib/hecks/deprecation.rb +95 -0
- data/lib/hecks/doc/reference.rb +19 -19
- data/lib/hecks/embryonaut_bluebook.rb +11 -11
- data/lib/hecks/facade/cli_door.rb +69 -10
- data/lib/hecks/facade/cli_runner.rb +105 -24
- data/lib/hecks/facade/command_request.rb +23 -0
- data/lib/hecks/facade/handle.rb +79 -32
- data/lib/hecks/facade/json_door.rb +106 -25
- data/lib/hecks/facade/surface/aggregate_door.rb +42 -27
- data/lib/hecks/facade/surface/chapter.rb +26 -17
- data/lib/hecks/facade/surface.rb +16 -3
- data/lib/hecks/facade.rb +15 -4
- data/lib/hecks/forms/app.rb +46 -30
- data/lib/hecks/forms/command_form_renderer.rb +70 -9
- data/lib/hecks/forms/field_renderer.rb +142 -6
- data/lib/hecks/forms/field_shape.rb +180 -19
- data/lib/hecks/forms/html.rb +51 -7
- data/lib/hecks/forms/index_renderer.rb +14 -2
- data/lib/hecks/forms/params.rb +120 -23
- data/lib/hecks/forms/port_argument.rb +2 -2
- data/lib/hecks/forms/query_form_renderer.rb +2 -2
- data/lib/hecks/forms/record_renderer.rb +2 -2
- data/lib/hecks/forms/record_table.rb +1 -1
- data/lib/hecks/forms/value_object_shape.rb +3 -3
- data/lib/hecks/forms.rb +24 -4
- data/lib/hecks/fqn.rb +1 -1
- data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
- data/lib/hecks/framework.rb +48 -17
- data/lib/hecks/freezer.rb +11 -11
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +90 -90
- data/lib/hecks/fuzzing/combination_miner.rb +119 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +140 -45
- data/lib/hecks/fuzzing/coverage_campaign.rb +118 -0
- data/lib/hecks/fuzzing/differential.rb +158 -0
- data/lib/hecks/fuzzing/domain_generator.rb +694 -0
- data/lib/hecks/fuzzing/era_boundary.rb +37 -18
- data/lib/hecks/fuzzing/form_census.rb +35 -20
- data/lib/hecks/fuzzing/generated_domain_check.rb +95 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +6 -6
- data/lib/hecks/fuzzing/isolated_boot.rb +62 -62
- data/lib/hecks/fuzzing/nondeterministic.rb +67 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +19 -21
- data/lib/hecks/fuzzing/properties/corrections.rb +9 -9
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +154 -49
- data/lib/hecks/fuzzing/properties/guards.rb +42 -42
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +32 -32
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +22 -35
- data/lib/hecks/fuzzing/properties/outbox.rb +24 -24
- data/lib/hecks/fuzzing/properties/querying.rb +17 -17
- data/lib/hecks/fuzzing/properties.rb +64 -40
- data/lib/hecks/fuzzing/qa_settings.rb +152 -0
- data/lib/hecks/fuzzing/replay.rb +114 -114
- data/lib/hecks/fuzzing/rotation_priority.rb +10 -10
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +113 -0
- data/lib/hecks/fuzzing/self_consistency.rb +141 -112
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +35 -35
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +58 -31
- data/lib/hecks/fuzzing/sequence_generator.rb +111 -23
- data/lib/hecks/fuzzing/shrinker.rb +197 -0
- data/lib/hecks/fuzzing/structural_skips.rb +23 -130
- data/lib/hecks/fuzzing/sweep_depth.rb +4 -4
- data/lib/hecks/fuzzing/target_capabilities.rb +49 -18
- data/lib/hecks/fuzzing/value_generator.rb +14 -14
- data/lib/hecks/fuzzing.rb +5 -0
- data/lib/hecks/grammar/evolve.rb +10 -10
- data/lib/hecks/grammar.rb +7 -7
- data/lib/hecks/ir.rb +13 -13
- data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
- data/lib/hecks/language/bluebook/policy.bluebook +11 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
- data/lib/hecks/language/oidc.json +5 -0
- data/lib/hecks/literal.rb +9 -9
- data/lib/hecks/naming.rb +25 -25
- data/lib/hecks/ports/access_control.rb +58 -2
- data/lib/hecks/ports/agent/answers.rb +83 -6
- data/lib/hecks/ports/agent.rb +119 -35
- data/lib/hecks/ports/authentication.rb +44 -4
- data/lib/hecks/ports/authorization.rb +53 -11
- data/lib/hecks/ports/clock.rb +42 -23
- data/lib/hecks/ports/extraction.rb +16 -0
- data/lib/hecks/ports/identity_assignment.rb +24 -2
- data/lib/hecks/ports/identity_generation.rb +17 -3
- data/lib/hecks/ports/identity_resolution.rb +18 -1
- data/lib/hecks/ports/loading.rb +4 -0
- data/lib/hecks/ports/persistence/append_only.rb +172 -8
- data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
- data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
- data/lib/hecks/ports/persistence/execution.rb +4 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
- data/lib/hecks/ports/persistence/plugin.rb +42 -4
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +28 -5
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +57 -4
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +42 -8
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -19
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +5 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
- data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
- data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
- data/lib/hecks/ports/persistence/state_codec.rb +319 -0
- data/lib/hecks/ports/persistence.rb +36 -1
- data/lib/hecks/ports/projection.rb +61 -7
- data/lib/hecks/ports/query/in_memory.rb +3 -3
- data/lib/hecks/ports/query/ordering.rb +6 -6
- data/lib/hecks/ports/query.rb +35 -0
- data/lib/hecks/projections/bootstrap_table.rb +112 -0
- data/lib/hecks/projections/diagrams.rb +75 -75
- data/lib/hecks/projections/glossary/html.rb +3 -3
- data/lib/hecks/projections/glossary/markdown.rb +3 -3
- data/lib/hecks/projections/glossary/mermaid.rb +1 -1
- data/lib/hecks/projections/glossary/sections.rb +1 -1
- data/lib/hecks/projections/glossary/sentences.rb +5 -5
- data/lib/hecks/projections/glossary.rb +15 -15
- data/lib/hecks/projections/ir.rb +1 -1
- data/lib/hecks/projections/model/deviations.rb +18 -17
- data/lib/hecks/projections/model.rb +25 -21
- data/lib/hecks/projections/oidc.rb +7 -7
- data/lib/hecks/projections/parser_table.rb +5 -5
- data/lib/hecks/projections/reference.rb +3 -3
- data/lib/hecks/projections/rust_vocabulary.rb +443 -0
- data/lib/hecks/projections/shape.rb +2 -2
- data/lib/hecks/projections/statements.rb +11 -11
- data/lib/hecks/projections/vocabulary.rb +9 -9
- data/lib/hecks/projections.rb +5 -3
- data/lib/hecks/projector/cli_projector.rb +29 -29
- data/lib/hecks/projector/docs_projector.rb +13 -13
- data/lib/hecks/projector/exporter.rb +42 -21
- data/lib/hecks/projector/ir_projector.rb +1 -1
- data/lib/hecks/projector/narrate_projector.rb +11 -11
- data/lib/hecks/projector/target.rb +13 -13
- data/lib/hecks/projector.rb +15 -15
- data/lib/hecks/query_ir.rb +47 -47
- data/lib/hecks/query_specification/common/comparators.rb +19 -3
- data/lib/hecks/query_specification/common/comparison.rb +109 -27
- data/lib/hecks/query_specification/common/dsl.rb +65 -9
- data/lib/hecks/query_specification/common/null_policy.rb +57 -13
- data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
- data/lib/hecks/query_specification/common/options.rb +25 -0
- data/lib/hecks/query_specification/field_path.rb +69 -15
- data/lib/hecks/query_specification/hop_path.rb +57 -20
- data/lib/hecks/query_specification/read_model/specification.rb +4 -0
- data/lib/hecks/rendering.rb +3 -3
- data/lib/hecks/router/namespace_installer.rb +3 -3
- data/lib/hecks/router.rb +1 -1
- data/lib/hecks/runtime/aggregate_lock.rb +11 -11
- data/lib/hecks/runtime/boot_gates.rb +3 -3
- data/lib/hecks/runtime/caller.rb +8 -8
- data/lib/hecks/runtime/capability_graph.rb +2 -2
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +22 -25
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +42 -63
- data/lib/hecks/runtime/command_interpreter.rb +159 -102
- data/lib/hecks/runtime/command_rules/admissibility.rb +69 -69
- data/lib/hecks/runtime/command_rules/arithmetic.rb +137 -91
- data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
- data/lib/hecks/runtime/command_rules/emission.rb +18 -1
- data/lib/hecks/runtime/command_rules/references.rb +35 -35
- data/lib/hecks/runtime/command_rules.rb +3 -0
- data/lib/hecks/runtime/dependency_planning.rb +11 -11
- data/lib/hecks/runtime/dispatcher.rb +283 -90
- data/lib/hecks/runtime/entity_element.rb +151 -67
- data/lib/hecks/runtime/entity_interpreter.rb +108 -82
- data/lib/hecks/runtime/errors.rb +19 -19
- data/lib/hecks/runtime/event.rb +6 -6
- data/lib/hecks/runtime/identity.rb +22 -22
- data/lib/hecks/runtime/instance.rb +39 -14
- data/lib/hecks/runtime/interpreting.rb +12 -12
- data/lib/hecks/runtime/invocation.rb +276 -0
- data/lib/hecks/runtime/loader.rb +14 -14
- data/lib/hecks/runtime/outbox.rb +23 -23
- data/lib/hecks/runtime/policy_interpreter.rb +54 -54
- data/lib/hecks/runtime/port_operation_interpreter.rb +22 -19
- data/lib/hecks/runtime/query_interpreter.rb +55 -64
- data/lib/hecks/runtime/reaction_invocation.rb +20 -20
- data/lib/hecks/runtime/read_model_interpreter.rb +40 -40
- data/lib/hecks/runtime/rebuild_sweep.rb +4 -4
- data/lib/hecks/runtime/reference_hop.rb +6 -6
- data/lib/hecks/runtime/refusal_wording.rb +92 -115
- data/lib/hecks/runtime/registry/saga_persistence.rb +21 -21
- data/lib/hecks/runtime/registry/verification.rb +36 -26
- data/lib/hecks/runtime/registry.rb +45 -28
- data/lib/hecks/runtime/remote_dispatcher.rb +38 -23
- data/lib/hecks/runtime/routing.rb +10 -153
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +17 -17
- data/lib/hecks/runtime/saga_interpreter.rb +64 -64
- data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
- data/lib/hecks/runtime/tenant_check.rb +9 -9
- data/lib/hecks/runtime/tenant_scope.rb +5 -5
- data/lib/hecks/runtime/value/admission.rb +75 -30
- data/lib/hecks/runtime/value/coercion.rb +318 -127
- data/lib/hecks/runtime/value/entity_list_coercion.rb +34 -34
- data/lib/hecks/runtime/value.rb +21 -21
- data/lib/hecks/runtime.rb +7 -7
- data/lib/hecks/storehouse.rb +64 -64
- data/lib/hecks/version.rb +3 -3
- data/lib/hecks/vocabulary.rb +205 -4
- data/lib/hecks.rb +13 -11
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +11 -11
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +14 -12
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +11 -11
- metadata +22 -2
|
@@ -3,14 +3,14 @@ require_relative "../../forms/html"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
5
|
module Glossary
|
|
6
|
-
#
|
|
6
|
+
# **The page, rendered from the markdown** — `html/index.html` is
|
|
7
7
|
# `glossary.md` read back and dressed: a navigation rail built from
|
|
8
8
|
# its `##` headings, each `###` a term entry, every ```mermaid fence
|
|
9
9
|
# a diagram, every `[x](#y)` an in-page link. Nothing here reads
|
|
10
10
|
# the bluebook; if the page shows it, the Markdown says it, so the
|
|
11
11
|
# two cannot drift.
|
|
12
12
|
#
|
|
13
|
-
# A
|
|
13
|
+
# A subset renderer, not a markdown library — the projector emits
|
|
14
14
|
# a fixed handful of constructs (`Markdown`'s own header lists
|
|
15
15
|
# them), and this reads exactly those. The Gemfile keeps every
|
|
16
16
|
# dependency justified in its own comment; a full Markdown engine
|
|
@@ -89,7 +89,7 @@ module Hecks
|
|
|
89
89
|
# The same slugs GitHub would give these headings, in the same
|
|
90
90
|
# order — so the links the Markdown carries land here too.
|
|
91
91
|
#
|
|
92
|
-
#
|
|
92
|
+
# Keyed by the block itself, not its value — a Struct compares by
|
|
93
93
|
# members, so two "### Open" headings in different sections would
|
|
94
94
|
# otherwise be one key, and the first would answer with the
|
|
95
95
|
# second's "-1" slug, leaving `#open` with nothing to land on.
|
|
@@ -6,7 +6,7 @@ require_relative "../statements"
|
|
|
6
6
|
module Hecks
|
|
7
7
|
module Projections
|
|
8
8
|
module Glossary
|
|
9
|
-
#
|
|
9
|
+
# **The document itself** — `glossary.md`, the one source the page is
|
|
10
10
|
# rendered from. Written in the handful of Markdown constructs
|
|
11
11
|
# GitHub renders as-is (headings, blockquotes, ```mermaid fences,
|
|
12
12
|
# lists, in-page links), so the file is a complete, readable
|
|
@@ -62,7 +62,7 @@ module Hecks
|
|
|
62
62
|
parts.join("\n\n")
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
# What an aggregate
|
|
65
|
+
# What an aggregate is, what it can be, how it fits and moves,
|
|
66
66
|
# and what is always true of it — before a single term.
|
|
67
67
|
def opening(aggregate, bluebook)
|
|
68
68
|
parts = []
|
|
@@ -75,7 +75,7 @@ module Hecks
|
|
|
75
75
|
parts
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
#
|
|
78
|
+
# The statements projection's own sentences, spoken. An invariant
|
|
79
79
|
# is the author's words and stays exactly so. A relationship
|
|
80
80
|
# sentence is built mechanically from construct names ("An
|
|
81
81
|
# ATMCard references an Account."), and a construct name is the
|
|
@@ -3,7 +3,7 @@ require_relative "../../naming"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
5
|
module Glossary
|
|
6
|
-
#
|
|
6
|
+
# The three pictures the glossary draws, each kept to the handful of
|
|
7
7
|
# things that matter — Evans' "three to five objects central to the
|
|
8
8
|
# issue at hand", never the whole model at once.
|
|
9
9
|
#
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Projections
|
|
3
3
|
module Glossary
|
|
4
|
-
#
|
|
4
|
+
# The three sections nothing homes to one aggregate. In their own
|
|
5
5
|
# file because `Markdown` reads them and loads before the
|
|
6
6
|
# projector's own body does.
|
|
7
7
|
ROLES = "Roles".freeze
|
|
@@ -4,7 +4,7 @@ require_relative "../statements"
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module Projections
|
|
6
6
|
module Glossary
|
|
7
|
-
#
|
|
7
|
+
# Every sentence the glossary says, and the rule each one obeys.
|
|
8
8
|
#
|
|
9
9
|
# Authored text is verbatim: an aggregate's `description`, a
|
|
10
10
|
# command's `goal`, a query's `description`, an invariant's own
|
|
@@ -65,7 +65,7 @@ module Hecks
|
|
|
65
65
|
[value_object_sentence(value_object, index, within), rules_line(rules)].compact
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
# A one-field object whose field is just "value"
|
|
68
|
+
# A one-field object whose field is just "value" is its type —
|
|
69
69
|
# "Text.", "A whole number." — the field name would add nothing.
|
|
70
70
|
def value_object_sentence(value_object, index, within)
|
|
71
71
|
return closed_set_sentence(value_object.members) if value_object.closed_set?
|
|
@@ -92,7 +92,7 @@ module Hecks
|
|
|
92
92
|
field.list? ? "a list of #{inner}" : inner
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
# A
|
|
95
|
+
# A closed set's rows — a one-field set is its values; a set
|
|
96
96
|
# whose rows carry more (StatementFrequency's cadence plus a
|
|
97
97
|
# retention and a fee) leads with the first field and keeps the
|
|
98
98
|
# rest beside it, so no row loses what makes it distinct.
|
|
@@ -162,7 +162,7 @@ module Hecks
|
|
|
162
162
|
sentence
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
# A
|
|
165
|
+
# A noun list, deliberately — "Responsible for Credit and Debit",
|
|
166
166
|
# never "Can credit and debit": banking's System role raises
|
|
167
167
|
# `Debited` and `Credited`, and "can … debited" is a wrong
|
|
168
168
|
# sentence. The headwords are already what people say.
|
|
@@ -170,7 +170,7 @@ module Hecks
|
|
|
170
170
|
"Responsible for #{Naming.to_sentence_list(command_links(issues, index))}."
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
#
|
|
173
|
+
# The same word for two different things gets its holder beside it
|
|
174
174
|
# — a role responsible for CardPayment's Reverse and Transfer's
|
|
175
175
|
# Reverse is responsible for "Reverse (card payment)" and
|
|
176
176
|
# "Reverse (transfer)", not for "Reverse" twice.
|
|
@@ -9,15 +9,15 @@ require_relative "glossary/html"
|
|
|
9
9
|
|
|
10
10
|
module Hecks
|
|
11
11
|
module Projections
|
|
12
|
-
# A
|
|
13
|
-
# whole team, in the sense Evans meant (DDD ch. 2):
|
|
12
|
+
# A chapter, projected as its ubiquitous language — a glossary for the
|
|
13
|
+
# whole team, in the sense Evans meant (DDD ch. 2): one language,
|
|
14
14
|
# shared by domain experts and developers, written the same way in
|
|
15
15
|
# conversation, diagrams, documents and code, so that a subject-matter
|
|
16
16
|
# expert can read the model and say "yes, that's how it works" or
|
|
17
17
|
# "no, that's wrong". A banker, a support rep, the CEO and an engineer
|
|
18
18
|
# read the same page.
|
|
19
19
|
#
|
|
20
|
-
#
|
|
20
|
+
# **Three things follow from that audience**. First, no type jargon: a
|
|
21
21
|
# term is a term, not "an Aggregate" or "a Value Object", and every
|
|
22
22
|
# identifier is spelled as a person says it (`Naming.words`: `ATMCard`
|
|
23
23
|
# is "ATM card"). Second, nothing invented: every sentence is either
|
|
@@ -29,7 +29,7 @@ module Hecks
|
|
|
29
29
|
# reader thinks "what does Account mean" before "what starts with A",
|
|
30
30
|
# and once there reads the way a dictionary reads.
|
|
31
31
|
#
|
|
32
|
-
#
|
|
32
|
+
# **Two files from one source**. `glossary.md` is the document — every
|
|
33
33
|
# construct in it renders on GitHub as-is (headings, blockquotes,
|
|
34
34
|
# ```mermaid fences, lists, in-page links). `html/index.html` is that
|
|
35
35
|
# exact Markdown string rendered into a page with a navigation rail;
|
|
@@ -72,7 +72,7 @@ module Hecks
|
|
|
72
72
|
Document.new(bluebook: bluebook, sections: sections, index: Index.new(sections))
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
#
|
|
75
|
+
# Aggregates first, a to Z by their spoken name ("Account" before
|
|
76
76
|
# "ATM card"), then the three groups nothing homes to one aggregate.
|
|
77
77
|
def sections(bluebook, entries)
|
|
78
78
|
grouped = entries.group_by(&:section)
|
|
@@ -87,7 +87,7 @@ module Hecks
|
|
|
87
87
|
list
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
# A HEADWORD
|
|
90
|
+
# A HEADWORD is qualified only when it would repeat within its own
|
|
91
91
|
# section — "Open" the action and "Open (the list)" the question;
|
|
92
92
|
# "Return (key issuance)" beside another Return — never numbered
|
|
93
93
|
# (Chicago 18.9, MDN's disambiguation pages: qualify the headword).
|
|
@@ -111,14 +111,14 @@ module Hecks
|
|
|
111
111
|
|
|
112
112
|
# ── gathering ────────────────────────────────────────────────────
|
|
113
113
|
|
|
114
|
-
#
|
|
114
|
+
# An entity can carry its own commands and queries too — walked the
|
|
115
115
|
# same one level down `DocsProjector` and `Projections::Diagrams`
|
|
116
116
|
# already walk it.
|
|
117
117
|
def holders(bluebook)
|
|
118
118
|
bluebook.aggregates.flat_map { |aggregate| [aggregate, *aggregate.entities] }
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
#
|
|
121
|
+
# Every holder's own aggregate, one hop or zero — an aggregate maps
|
|
122
122
|
# to itself, an entity to whichever aggregate declared it. The one
|
|
123
123
|
# fact the grouping is built on.
|
|
124
124
|
def holder_aggregate(bluebook)
|
|
@@ -128,8 +128,8 @@ module Hecks
|
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
#
|
|
132
|
-
# so its home is whichever aggregate the
|
|
131
|
+
# Every event's raisers — an event is never declared, only emitted,
|
|
132
|
+
# so its home is whichever aggregate the first command that raises
|
|
133
133
|
# it belongs to; a policy or saga reacting to it inherits that home.
|
|
134
134
|
def event_raisers(bluebook)
|
|
135
135
|
holders(bluebook).each_with_object(Hash.new { |hash, key| hash[key] = [] }) do |holder, map|
|
|
@@ -165,7 +165,7 @@ module Hecks
|
|
|
165
165
|
end
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
-
#
|
|
168
|
+
# Aggregates only — an entity declares no value objects of its own
|
|
169
169
|
# (`Bluebook::Entity` deliberately does not answer `value_objects`).
|
|
170
170
|
def value_object_entries(bluebook)
|
|
171
171
|
bluebook.aggregates.flat_map do |aggregate|
|
|
@@ -213,7 +213,7 @@ module Hecks
|
|
|
213
213
|
end
|
|
214
214
|
end
|
|
215
215
|
|
|
216
|
-
#
|
|
216
|
+
# Cross-cutting by nature — `System` and `Customer` issue commands
|
|
217
217
|
# across half the aggregates here — so a role belongs to no single
|
|
218
218
|
# one and gets its own section.
|
|
219
219
|
def role_entries(bluebook)
|
|
@@ -236,7 +236,7 @@ module Hecks
|
|
|
236
236
|
|
|
237
237
|
# ── anchors ──────────────────────────────────────────────────────
|
|
238
238
|
|
|
239
|
-
#
|
|
239
|
+
# **GitHub's own heading slugs, reproduced** — lowercase, punctuation
|
|
240
240
|
# dropped, spaces to hyphens, a repeat gets "-1", "-2" in document
|
|
241
241
|
# order. Computed here, once, in the order the headings will appear,
|
|
242
242
|
# so a link written into the Markdown lands on the same heading
|
|
@@ -261,8 +261,8 @@ module Hecks
|
|
|
261
261
|
end
|
|
262
262
|
end
|
|
263
263
|
|
|
264
|
-
#
|
|
265
|
-
# by its holder
|
|
264
|
+
# **Where a declared reference points** — keyed structurally (a command
|
|
265
|
+
# by its holder and name, an event by its bare name), never by
|
|
266
266
|
# searching prose for a matching word. Anything not declared here
|
|
267
267
|
# (a cross-domain command like `Notifications.Send`) answers nil,
|
|
268
268
|
# and the sentence says it in words with no link.
|
data/lib/hecks/projections/ir.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Hecks
|
|
|
7
7
|
# The canonical IR, as a constant. The implementation already existed
|
|
8
8
|
# and is already golden-tested (`Projector::IRProjector`, registered
|
|
9
9
|
# as `:ir`) — this only gives it the constant spelling every other
|
|
10
|
-
# target has, by re-registering the
|
|
10
|
+
# target has, by re-registering the same module under the same key.
|
|
11
11
|
#
|
|
12
12
|
# Deliberately not a new implementation: two things named `IR` that
|
|
13
13
|
# each rendered IR their own way is exactly the drift this namespace
|
|
@@ -1,32 +1,19 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Projections
|
|
3
3
|
module Model
|
|
4
|
-
#
|
|
4
|
+
# How the model's shape differs from the language's, and why.
|
|
5
5
|
#
|
|
6
6
|
# Every construct's `emits_ir` restates what the grammar declares —
|
|
7
7
|
# and the two legitimately differ, in seven ways. These lived only
|
|
8
8
|
# as prose in Ruby comments until spec/model_shape_conformance_spec
|
|
9
|
-
# made them checkable; they live
|
|
9
|
+
# made them checkable; they live here so the generator and the gate
|
|
10
10
|
# read one source rather than two that must agree.
|
|
11
11
|
#
|
|
12
12
|
# A reason is carried beside each entry because the generated file
|
|
13
|
-
# will
|
|
13
|
+
# will carry it: a deviation is exactly the kind of thing whose
|
|
14
14
|
# explanation must survive regeneration, and the only way it can is
|
|
15
15
|
# to be emitted rather than typed into the output.
|
|
16
16
|
module Deviations
|
|
17
|
-
# The grammar is relational — a Command points UP at its
|
|
18
|
-
# Aggregate — where the model composes. An explicit `as:` still
|
|
19
|
-
# keeps its `_id` (Command's own `entity_id`, kept as data); the
|
|
20
|
-
# parent link itself mints bare now (ADR 0025) — `aggregate` or
|
|
21
|
-
# `bluebook`, whichever this category's creating command declares
|
|
22
|
-
# first — so both spellings are checked. Entity spells its own
|
|
23
|
-
# (separate, non-colliding) text twin of the parent link `owner`.
|
|
24
|
-
PARENT_REF = ->(field) { field.to_s.match?(/_id\z/) || %i[owner aggregate bluebook].include?(field) }
|
|
25
|
-
|
|
26
|
-
# The judge's own field, never the model's — contracts.rb already
|
|
27
|
-
# says so with `derived: { position: :walk }`.
|
|
28
|
-
JUDGE_ONLY = %i[position].freeze
|
|
29
|
-
|
|
30
17
|
# What the model holds that the grammar declares elsewhere: the
|
|
31
18
|
# containment edges, stated in syntax.bluebook's Keyword rows as
|
|
32
19
|
# `context` -> `opens`.
|
|
@@ -64,7 +51,7 @@ module Hecks
|
|
|
64
51
|
"Policy" => { where_ast: "the structured form of `where`, derived from the same text at emission" }
|
|
65
52
|
}.freeze
|
|
66
53
|
|
|
67
|
-
#
|
|
54
|
+
# **Declared, and deliberately not emitted**. The category that had no
|
|
68
55
|
# home anywhere before — each of these was a comment and nothing
|
|
69
56
|
# more.
|
|
70
57
|
OFF_THE_WIRE = {
|
|
@@ -85,6 +72,20 @@ module Hecks
|
|
|
85
72
|
|
|
86
73
|
module_function
|
|
87
74
|
|
|
75
|
+
# The grammar is relational — a Command points up at its
|
|
76
|
+
# Aggregate — where the model composes. An explicit `as:` still
|
|
77
|
+
# keeps its `_id` (Command's own `entity_id`, kept as data); the
|
|
78
|
+
# parent link itself mints bare now (ADR 0025) — `aggregate` or
|
|
79
|
+
# `bluebook`, whichever this category's creating command declares
|
|
80
|
+
# first. Entity spells its own (separate, non-colliding) text twin
|
|
81
|
+
# of the parent link `owner`. Not restated here: the one list is
|
|
82
|
+
# `Assembly::PARENT_POINTERS`, which the assembly gate reads too.
|
|
83
|
+
def parent_ref?(field) = Hecks::Bluebook::Assembly.parent_pointer?(field)
|
|
84
|
+
|
|
85
|
+
# The judge's own fields, never the model's — read off the
|
|
86
|
+
# category's contract (`derived: { position: :walk }`), not restated.
|
|
87
|
+
def judge_only(name) = Hecks::Bluebook::Assembly.contract(name).walked
|
|
88
|
+
|
|
88
89
|
# The tables that carry a reason answer with names only when the
|
|
89
90
|
# caller wants the set rather than the explanations.
|
|
90
91
|
def off_the_wire(name) = OFF_THE_WIRE.fetch(name, {}).keys
|
|
@@ -3,22 +3,22 @@ require_relative "../projector"
|
|
|
3
3
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module Projections
|
|
6
|
-
#
|
|
6
|
+
# The model classes, projected from the language that declares them.
|
|
7
7
|
#
|
|
8
|
-
# A construct's
|
|
8
|
+
# A construct's holding half — its readers, its emission, a
|
|
9
9
|
# constructor that assigns declared fields and hands off — restates
|
|
10
10
|
# what `bluebook.bluebook` already says, three times over in Ruby.
|
|
11
11
|
# This renders it instead.
|
|
12
12
|
#
|
|
13
|
-
#
|
|
13
|
+
# **Only the holding half**. `Behaviour::X` is hand-written and permanent,
|
|
14
14
|
# and `settle` is the seam: everything a declaration cannot state
|
|
15
15
|
# lives behind it, so regenerating can never be lossy. That property
|
|
16
16
|
# was established construct by construct before any of this was
|
|
17
17
|
# written — the chapter looked generatable and was not, until its
|
|
18
18
|
# `@hecks_root`, ports table and child stamping moved behind `settle`.
|
|
19
19
|
#
|
|
20
|
-
#
|
|
21
|
-
# it does not state which constructs are Ruby
|
|
20
|
+
# The HOST manifest is the honest part. The grammar states the fields;
|
|
21
|
+
# it does not state which constructs are Ruby classes rather than
|
|
22
22
|
# instances, what a constructor's defaults are, or how a value is
|
|
23
23
|
# coerced on the way in. Those are facts about Ruby, not about
|
|
24
24
|
# bluebooks, so they are declared here rather than pretended into the
|
|
@@ -29,7 +29,7 @@ module Hecks
|
|
|
29
29
|
|
|
30
30
|
projects_as :model, declares: "Bluebook", emits: :files
|
|
31
31
|
|
|
32
|
-
#
|
|
32
|
+
# **Per-construct Ruby facts**. `coerce` is the only fiddly column: a
|
|
33
33
|
# declared field arrives as whatever the builder handed over, and
|
|
34
34
|
# each construct has always normalised its own on the way in.
|
|
35
35
|
HOST = {
|
|
@@ -37,21 +37,25 @@ module Hecks
|
|
|
37
37
|
construct: "Policy",
|
|
38
38
|
file: "policy.rb",
|
|
39
39
|
behaviour: "Behaviour::Policy",
|
|
40
|
-
readers: %i[name on_event trigger_command target_domain where for_each with_spec],
|
|
40
|
+
readers: %i[name on_event trigger_command target_domain expect_undelivered where for_each with_spec],
|
|
41
41
|
accessors: %i[aggregate],
|
|
42
42
|
defaults: { name: nil, on_event: "nil", trigger_command: "nil",
|
|
43
|
-
target_domain: "nil", where: "nil", for_each: "nil",
|
|
43
|
+
target_domain: "nil", expect_undelivered: "false", where: "nil", for_each: "nil",
|
|
44
44
|
with_spec: "[]", aggregate: "nil" },
|
|
45
|
-
|
|
46
|
-
#
|
|
45
|
+
# A flag on the wire is a boolean — the language holds it as
|
|
46
|
+
# text ("true"), the builder hands over `true`, and a
|
|
47
|
+
# reconstruction hands back whichever it read; all three land
|
|
48
|
+
# as the same `true`/`false`.
|
|
49
|
+
coerce: { name: ".to_s", aggregate: "&.to_s", expect_undelivered: ".to_s == \"true\"" },
|
|
50
|
+
# A list of bindings is not a scalar on the wire. Every other
|
|
47
51
|
# field emits as itself; this one has to render the way
|
|
48
52
|
# `DispatchSpec`'s own `with_spec` does — keys to strings, and
|
|
49
|
-
# `render_value`
|
|
53
|
+
# `render_value` keeping the leading colon on a Symbol, because
|
|
50
54
|
# a binding that reads an event field and one that supplies a
|
|
51
55
|
# literal string are otherwise indistinguishable once written
|
|
52
56
|
# down (see `MetaValidator::Readings`' own note on exactly that).
|
|
53
57
|
renders: { with_spec: "-> { with_spec.map { |key, value| [key.to_s, Bluebook.render_value(value)] } }",
|
|
54
|
-
#
|
|
58
|
+
# Computed (Deviations::COMPUTED["Policy"]): the structured
|
|
55
59
|
# form of `where`, a pure function of that text, the same
|
|
56
60
|
# `ast` every rule row carries beside its `canonical`.
|
|
57
61
|
where_ast: "-> { where_ast }" },
|
|
@@ -67,8 +71,8 @@ module Hecks
|
|
|
67
71
|
|
|
68
72
|
def render(bluebook, name, host)
|
|
69
73
|
<<~RUBY
|
|
70
|
-
#
|
|
71
|
-
#
|
|
74
|
+
# Generated — projected from the language's own #{name} aggregate.
|
|
75
|
+
# Do not edit: the holding half is rendered, and #{host.fetch(:behaviour)}
|
|
72
76
|
# is where anything hand-written belongs.
|
|
73
77
|
require_relative "behaviour/#{File.basename(host.fetch(:file), '.rb')}"
|
|
74
78
|
|
|
@@ -91,9 +95,9 @@ module Hecks
|
|
|
91
95
|
|
|
92
96
|
# The emission, keyed as the model spells it and sourced as the
|
|
93
97
|
# language declares it.
|
|
94
|
-
# A
|
|
98
|
+
# A computed field (Deviations::COMPUTED) is emitted too — it is
|
|
95
99
|
# model-only by definition, so it rides after the declared fields
|
|
96
|
-
# and
|
|
100
|
+
# and must have a `renders` entry, there being nothing to `send`.
|
|
97
101
|
def emits(bluebook, name)
|
|
98
102
|
fields = emitted_fields(bluebook, name) + Deviations.computed(name)
|
|
99
103
|
renders = HOST.fetch(name).fetch(:renders, {})
|
|
@@ -102,14 +106,14 @@ module Hecks
|
|
|
102
106
|
"emits_ir(\n#{fields.map { |f| " #{"#{f}:".ljust(width + 1)} #{renders.fetch(f, ":#{f}")}" }.join(",\n")}\n)"
|
|
103
107
|
end
|
|
104
108
|
|
|
105
|
-
#
|
|
109
|
+
# What the construct emits: what the language declares, less every
|
|
106
110
|
# deviation the tables account for. The generator and
|
|
107
111
|
# spec/model_shape_conformance_spec compute this the same way, from
|
|
108
112
|
# the same tables, which is the point of the tables being in lib.
|
|
109
113
|
def emitted_fields(bluebook, name)
|
|
110
114
|
bluebook.aggregate(name).attributes.map(&:name)
|
|
111
|
-
.reject { |f| Deviations
|
|
112
|
-
Deviations
|
|
115
|
+
.reject { |f| Deviations.parent_ref?(f) } -
|
|
116
|
+
Deviations.judge_only(name) -
|
|
113
117
|
Deviations.off_the_wire(name) -
|
|
114
118
|
Deviations.dynamic_tail(name) -
|
|
115
119
|
Deviations.folded(name).values.flatten -
|
|
@@ -122,13 +126,13 @@ module Hecks
|
|
|
122
126
|
return lines.join("\n") if accessors.empty?
|
|
123
127
|
|
|
124
128
|
# A declared field the model deliberately does not emit still
|
|
125
|
-
# needs a reader, and the
|
|
129
|
+
# needs a reader, and the reason it is off the wire is carried
|
|
126
130
|
# here rather than typed in — a comment that survives
|
|
127
131
|
# regeneration is one the generator writes.
|
|
128
132
|
reasons = Deviations::OFF_THE_WIRE.fetch(host.fetch(:construct, ""), {})
|
|
129
133
|
(lines + accessors.map do |a|
|
|
130
134
|
why = reasons[a]
|
|
131
|
-
(why ? "\n# #{a.
|
|
135
|
+
(why ? "\n# #{a.to_s.capitalize}, declared and deliberately off the wire\n# #{wrap(why)}\n" : "") +
|
|
132
136
|
"attr_accessor :#{a}"
|
|
133
137
|
end).join("\n")
|
|
134
138
|
end
|
|
@@ -3,16 +3,16 @@ require_relative "../projector"
|
|
|
3
3
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module Projections
|
|
6
|
-
#
|
|
6
|
+
# An OIDC client/scope manifest derived from a domain's own IR: what
|
|
7
7
|
# an identity provider has to know about this domain before it can
|
|
8
8
|
# issue a token that means anything here.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
# `spec/oidc_projection_spec.rb` covers the
|
|
10
|
+
# The artifact half of something already half-built.
|
|
11
|
+
# `spec/oidc_projection_spec.rb` covers the integration half — verified
|
|
12
12
|
# claims in, `IdentityResolution.resolve` → `Authorization.holds_role?`
|
|
13
13
|
# → a dispatch scoped by `Hecks.as_caller(role:)`. That half enforces
|
|
14
14
|
# a role per command. It just had no way to say, up front and as data,
|
|
15
|
-
#
|
|
15
|
+
# which role each command wants — every answer came from asking the
|
|
16
16
|
# live runtime one dispatch at a time.
|
|
17
17
|
#
|
|
18
18
|
# This is that catalogue, and the two are checked against each other
|
|
@@ -24,12 +24,12 @@ module Hecks
|
|
|
24
24
|
# `Ports::Authorization.holds_role?` compares against a real
|
|
25
25
|
# `Governance::RoleAssignment`.
|
|
26
26
|
#
|
|
27
|
-
#
|
|
27
|
+
# Roles come from the commands, not from governance. A command's own
|
|
28
28
|
# `role "Compliance officer"` is in the bluebook IR
|
|
29
29
|
# (`Command#role`), whereas `uses_framework "Governance"` is
|
|
30
30
|
# declared in the `.hecksagon` — which `call(bluebook:, options:)`
|
|
31
31
|
# cannot see at all. Reading the commands is both the only thing
|
|
32
|
-
# available here
|
|
32
|
+
# available here and the more accurate source: it says what each
|
|
33
33
|
# command actually demands, not merely which role vocabulary the
|
|
34
34
|
# application happened to mount.
|
|
35
35
|
#
|
|
@@ -93,7 +93,7 @@ module Hecks
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
# `banking:account.open` — the shape an OIDC scope is conventionally
|
|
96
|
-
# spelled in, and snake_cased through the
|
|
96
|
+
# spelled in, and snake_cased through the same `Naming.snake` the
|
|
97
97
|
# facade uses to name a command's own door method, so a scope and
|
|
98
98
|
# the Ruby call that satisfies it cannot drift apart.
|
|
99
99
|
def command_scopes(commands, verb_prefix, scope_prefix)
|
|
@@ -2,12 +2,12 @@ require_relative "../projector"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
|
-
#
|
|
6
|
-
# Syntax aggregate — "the parser's grammar knowledge is
|
|
5
|
+
# The Rust parser's keyword table, projected from the chapter's own
|
|
6
|
+
# Syntax aggregate — "the parser's grammar knowledge is derived from
|
|
7
7
|
# hecks's self-description, not hand-typed a second time", which
|
|
8
8
|
# is the anti-drift idea the whole Rust-parser plan rests on.
|
|
9
9
|
#
|
|
10
|
-
# A
|
|
10
|
+
# A registered target now, rather than a module living inside its own
|
|
11
11
|
# bin/ script. It was already a projection in everything but call
|
|
12
12
|
# shape; this only stops it being a fifth way of spelling one.
|
|
13
13
|
module ParserTable
|
|
@@ -20,7 +20,7 @@ module Hecks
|
|
|
20
20
|
|
|
21
21
|
module_function
|
|
22
22
|
|
|
23
|
-
#
|
|
23
|
+
# The chapter is handed over, not reached for. This used to open the
|
|
24
24
|
# grammar registry itself, which meant the projection could only ever
|
|
25
25
|
# project one chapter — the language's own. Taking it as an argument is
|
|
26
26
|
# what the projector protocol asks for, and it costs nothing.
|
|
@@ -64,7 +64,7 @@ module Hecks
|
|
|
64
64
|
|
|
65
65
|
# S14, ADR 0026 — Keyword/Argument are genuine entities of Syntax
|
|
66
66
|
# now, dispatched (not merely declared) so their own `status`
|
|
67
|
-
# really is a lifecycle. `SyntaxBoot.call` reads the
|
|
67
|
+
# really is a lifecycle. `SyntaxBoot.call` reads the still-static
|
|
68
68
|
# seed rows (`KeywordSeed`/`ArgumentSeed`), dispatches each one
|
|
69
69
|
# through the real admission/lifecycle door, and hands back the
|
|
70
70
|
# exact same shape `rows` used to read straight off the closed set
|
|
@@ -3,18 +3,18 @@ require_relative "../projector"
|
|
|
3
3
|
|
|
4
4
|
module Hecks
|
|
5
5
|
module Projections
|
|
6
|
-
#
|
|
6
|
+
# The DSL reference pages, projected from the chapter's own Syntax
|
|
7
7
|
# aggregate — the tables come from the declaration, the prose is
|
|
8
8
|
# preserved from whatever is already committed.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
10
|
+
# The first projection that emits a tree. `emits: :files` says so,
|
|
11
11
|
# and the framework writes the map rather than inferring one: a Hash
|
|
12
12
|
# of path => contents and a Hash that merely holds strings are the
|
|
13
13
|
# same object to Ruby, so only the projection can know which it
|
|
14
14
|
# meant. This is the case the output contract was designed for and
|
|
15
15
|
# deliberately left unimplemented until something real needed it.
|
|
16
16
|
#
|
|
17
|
-
#
|
|
17
|
+
# Not pure, and it cannot be. `Doc::Reference.pages` reads the
|
|
18
18
|
# committed pages to harvest their prose, so the existing directory
|
|
19
19
|
# is an input — passed as `from:` rather than assumed, so the
|
|
20
20
|
# projection never reaches for a path of its own choosing.
|