hecks 2.8.0 → 3.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 +4 -4
- data/exe/hecks +50 -7
- 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 +32 -100
- 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 +10 -32
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +149 -136
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +48 -38
- 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 +76 -62
- 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 +32 -142
- 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/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- 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 +56 -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 +39 -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 +11 -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 +16 -50
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +49 -67
- 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 +96 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
- 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 +42 -89
- 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 +148 -197
- 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 +38 -43
- 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 +46 -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 +39 -661
- data/lib/hecks/bluebook/hexagon.rb +18 -33
- 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 +25 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +87 -352
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +122 -596
- data/lib/hecks/bluebook/pattern_subset.rb +49 -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 +27 -51
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +9 -99
- 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/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +5 -23
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +4 -6
- data/lib/hecks/cli/mcp.rb +5 -6
- data/lib/hecks/cli/model_check.rb +24 -88
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +223 -64
- data/lib/hecks/cli/project_diagrams.rb +4 -10
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +15 -61
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +7 -19
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -6
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +216 -73
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +14 -34
- data/lib/hecks/doors/handle.rb +206 -0
- data/lib/hecks/doors/json_door.rb +132 -0
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
- data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
- data/lib/hecks/doors/ruby_door.rb +77 -0
- data/lib/hecks/doors.rb +61 -0
- 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 +5 -72
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +23 -51
- data/lib/hecks/forms/app.rb +21 -76
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- 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 +31 -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/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- 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/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/kernel_capabilities.rb +194 -0
- 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 +26 -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 +19 -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 +83 -198
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -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_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- 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 +44 -144
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
- 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 +19 -76
- 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 +43 -127
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- 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 +50 -47
- 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/translation.rb +1 -0
- 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 +47 -108
- 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/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +12 -44
- 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 +40 -207
- data/lib/hecks/projections/deploy/lambda.rb +191 -708
- 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/preview.sh.erb +1 -1
- 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 +3 -59
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +48 -147
- 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 +22 -584
- 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 +16 -43
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +13 -32
- data/lib/hecks/projections/reference.rb +4 -18
- data/lib/hecks/projections/rust_vocabulary.rb +13 -251
- 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 +154 -400
- 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/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- 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 +5 -8
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +15 -9
- data/lib/hecks/release/runner/npm_publisher.rb +9 -53
- data/lib/hecks/release/runner/preflight.rb +29 -20
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +31 -23
- data/lib/hecks/release/runner.rb +60 -38
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +15 -39
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- 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 +27 -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 +50 -104
- data/lib/hecks/runtime/dispatcher.rb +134 -243
- 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 +14 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +109 -194
- data/lib/hecks/runtime/outbox.rb +39 -262
- data/lib/hecks/runtime/policy_interpreter.rb +43 -202
- data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
- data/lib/hecks/runtime/query_interpreter.rb +122 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- 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 +28 -87
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +213 -227
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +156 -247
- data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
- 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 +162 -760
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +15 -84
- data/lib/hecks/runtime.rb +35 -69
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +155 -582
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- 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 +52 -90
- 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
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +478 -12
- data/lib/hecks/facade/cli_door.rb +0 -178
- data/lib/hecks/facade/cli_runner.rb +0 -271
- data/lib/hecks/facade/handle.rb +0 -293
- data/lib/hecks/facade/json_door.rb +0 -247
- data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
- data/lib/hecks/facade/surface/chapter.rb +0 -116
- data/lib/hecks/facade/surface.rb +0 -61
- data/lib/hecks/mcp_door_scope.rb +0 -176
data/lib/hecks/ports/agent.rb
CHANGED
|
@@ -2,103 +2,28 @@ require_relative "../runtime/registry"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
|
-
# The interviewer
|
|
6
|
-
#
|
|
7
|
-
# rather than structure, or suggests a name.
|
|
8
|
-
#
|
|
9
|
-
# ## Why a singleton port
|
|
10
|
-
#
|
|
11
|
-
# Resolved the same zero/one/many way every other port here is
|
|
12
|
-
# (`Ports::IdentityGeneration`'s own singleton adapter — one
|
|
13
|
-
# interviewer per process, never per-aggregate), because a second
|
|
14
|
-
# adapter answering this port is exactly as unchoosable as a second
|
|
15
|
-
# one minting identities.
|
|
16
|
-
#
|
|
17
|
-
# ## Why this exists
|
|
18
|
-
#
|
|
19
|
-
# Built last, on purpose, and still optional. `.claude/skills/
|
|
20
|
-
# interview/SKILL.md` conducts a whole session with none of this —
|
|
21
|
-
# Claude Code reads `bin/interview state` itself, asks the human
|
|
22
|
-
# directly with real conversation context, and calls `bin/interview
|
|
23
|
-
# ask`/`propose`/`accept` itself. This port exists for what that
|
|
24
|
-
# cannot reach: a headless run (`bin/interview suggest`, no model in
|
|
25
|
-
# the room otherwise), a batch `critique` over an already-written
|
|
26
|
-
# chapter, and — the actual point of building it at all — a
|
|
27
|
-
# scripted double (`spec/fixtures/scripted_agent.rb`) that makes the
|
|
28
|
-
# whole loop testable with no real model involved.
|
|
29
|
-
#
|
|
30
|
-
# ## What this port is not
|
|
31
|
-
#
|
|
32
|
-
# It does not judge whether a declaration is well-formed — that is
|
|
33
|
-
# the meta-domain's own job, answered by a real dispatch refusing or
|
|
34
|
-
# not (`Interview::Session#offer`). This port only ever produces
|
|
35
|
-
# shape: a question, a proposed declaration, a judgement about
|
|
36
|
-
# taste, a name. A proposal naming a category the language does not
|
|
37
|
-
# declare is an adapter fault, refused here, in `Answers`; a
|
|
38
|
-
# proposal naming a real category but describing the wrong domain
|
|
39
|
-
# fact is dispatched anyway, so the language gets to say why. That
|
|
40
|
-
# line is the whole design.
|
|
41
|
-
#
|
|
42
|
-
# ## Where parsing happens
|
|
43
|
-
#
|
|
44
|
-
# Parsing belongs to this file, not the adapter. An adapter answers
|
|
45
|
-
# with a plain, already-JSON-shaped Hash (a real model's parsed
|
|
46
|
-
# reply, or a spec double's own hand-built one) — never a Struct —
|
|
47
|
-
# so every adapter is validated identically here rather than trusting
|
|
48
|
-
# each one to refuse the same way. Two adapters that parsed
|
|
49
|
-
# differently would mean the same malformed answer passing through
|
|
50
|
-
# one and refusing through the other.
|
|
5
|
+
# The interviewer: asks questions, reads prose into proposed declarations, critiques a
|
|
6
|
+
# model on taste, and suggests names. One adapter per process.
|
|
51
7
|
module Agent
|
|
52
8
|
NAME = "agent".freeze
|
|
53
9
|
|
|
54
|
-
# The answer
|
|
55
|
-
# category the language does not declare, a severity outside the
|
|
56
|
-
# two that exist. A foreign failure (JSON::ParserError, a missing
|
|
57
|
-
# key) wrapped into something this port owns, the same shape
|
|
58
|
-
# `Ports::Authentication::ValidationError` already is, so no
|
|
59
|
-
# caller ever rescues a raw parser error leaking out of an
|
|
60
|
-
# adapter.
|
|
10
|
+
# The adapter's answer arrived but was unusable; retrying the same prompt will not help.
|
|
61
11
|
class ValidationError < StandardError
|
|
62
12
|
end
|
|
63
13
|
|
|
64
|
-
# Nothing answered
|
|
65
|
-
# died, the call timed out. Separate from ValidationError on
|
|
66
|
-
# purpose: unavailable means retry or fall back to asking the
|
|
67
|
-
# human directly; malformed means the prompt is wrong, not the
|
|
68
|
-
# transport, and retrying identically will not fix it.
|
|
14
|
+
# Nothing answered (missing binary, dead subprocess, timeout); retry or ask the human.
|
|
69
15
|
class Unavailable < StandardError
|
|
70
16
|
end
|
|
71
17
|
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
#
|
|
75
|
-
# already is one: a `keyword_init` Struct raises on a key nobody
|
|
76
|
-
# declared, which turns "the model invented a field" into a
|
|
77
|
-
# failure at the boundary rather than a nil three calls in.
|
|
78
|
-
|
|
79
|
-
# One question. `because` is the reasoning quoted back so a human
|
|
80
|
-
# can see it, not decoration — the same "show your work" the
|
|
81
|
-
# language's own refusal messages already practice.
|
|
18
|
+
# keyword_init Structs raise on an undeclared key, so an invented field fails at the edge.
|
|
19
|
+
|
|
20
|
+
# One question; `because` is the reasoning shown to the human.
|
|
82
21
|
Question = Struct.new(:text, :because, keyword_init: true)
|
|
83
22
|
|
|
84
|
-
#
|
|
85
|
-
# `Interview::Proposal`'s own `Argument` rows — `{name:, field:,
|
|
86
|
-
# value:}`, the exact triple `bin/interview propose --arg
|
|
87
|
-
# name:field:value` already takes and `Interview::Lowering`
|
|
88
|
-
# already knows how to lower. Nothing here decides how to address
|
|
89
|
-
# a record or whether a value is bare or wrapped — that was
|
|
90
|
-
# already the proposal-writer's job in `interview.bluebook`'s own
|
|
91
|
-
# design (see `Argument`'s own comment there); this only adds the
|
|
92
|
-
# prose reasoning a human typed does not carry on its own.
|
|
23
|
+
# `arguments` are `{name:, field:, value:}` rows, as `bin/interview propose --arg` takes.
|
|
93
24
|
Proposal = Struct.new(:verb, :arguments, :rationale, keyword_init: true)
|
|
94
25
|
|
|
95
|
-
#
|
|
96
|
-
# same fields, same severities, so a mechanical finding
|
|
97
|
-
# (`Session#gaps`) and a judgement (this) print in one list and
|
|
98
|
-
# sort together. The kind vocabulary is not shared — ModelCheck's
|
|
99
|
-
# eleven kinds are structural facts about a graph; these are
|
|
100
|
-
# opinions about a model, closed here on purpose (an open kind
|
|
101
|
-
# field is an open prompt, and an open prompt drifts).
|
|
26
|
+
# Kinds are closed: an open kind is an open prompt, and an open prompt drifts.
|
|
102
27
|
CRITIQUE_KINDS = %i[
|
|
103
28
|
anemic_aggregate wrong_boundary crud_verb leaky_value_object
|
|
104
29
|
missing_lifecycle missing_invariant ubiquitous_language
|
|
@@ -106,132 +31,82 @@ module Hecks
|
|
|
106
31
|
].freeze
|
|
107
32
|
SEVERITIES = %i[error warning].freeze
|
|
108
33
|
|
|
34
|
+
# Same shape as `Bluebook::ModelCheck::Finding`, so gaps and critiques sort together.
|
|
109
35
|
Finding = Struct.new(:kind, :severity, :subject, :message, keyword_init: true) do
|
|
110
36
|
def to_s = "#{severity.to_s.upcase.ljust(7)} #{kind.to_s.ljust(20)} #{subject} — #{message}"
|
|
111
37
|
end
|
|
112
38
|
|
|
113
|
-
#
|
|
114
|
-
# they were passed over — free at the point the model is choosing
|
|
115
|
-
# anyway, and the part a human actually learns from.
|
|
39
|
+
# `rejected` holds the near-misses and why each was passed over.
|
|
116
40
|
Suggestion = Struct.new(:name, :because, :rejected, keyword_init: true)
|
|
117
41
|
|
|
42
|
+
# Adapters return plain Hashes; validating here makes every adapter refuse the same way.
|
|
118
43
|
module_function
|
|
119
44
|
|
|
120
|
-
# Asks the adapter for the next
|
|
121
|
-
#
|
|
122
|
-
# `state` is the whole picture — normally
|
|
123
|
-
# `Interview::Session#declaration` plus `#gaps`, so an adapter
|
|
124
|
-
# needs no memory of its own between calls; that is what lets a
|
|
125
|
-
# headless run be a series of one-shot processes, same as
|
|
126
|
-
# `bin/interview` itself already is.
|
|
45
|
+
# Asks the adapter for the next question.
|
|
127
46
|
#
|
|
128
47
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
129
|
-
# @param state [Hash]
|
|
130
|
-
#
|
|
131
|
-
# @
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# @raise [
|
|
136
|
-
# `"questions"` array whose rows each carry a non-blank `"text"` and `"because"`
|
|
137
|
-
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer at all (missing
|
|
138
|
-
# binary, failed subprocess, timeout, or an exhausted scripted queue)
|
|
139
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
140
|
-
# (see `adapter`)
|
|
48
|
+
# @param state [Hash] declaration plus gaps; adapters keep no memory between calls
|
|
49
|
+
# @param asked [Array<Object>] questions already asked, so the adapter does not repeat one
|
|
50
|
+
# @return [Array<Ports::Agent::Question>]
|
|
51
|
+
# @raise [Ports::Agent::ValidationError] unless the answer is a Hash whose `"questions"`
|
|
52
|
+
# rows each carry a non-blank `"text"` and `"because"`
|
|
53
|
+
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer
|
|
54
|
+
# @raise [Runtime::WiringError] unless exactly one adapter implements the port
|
|
141
55
|
def ask(registry, state:, asked: [])
|
|
142
56
|
Answers.questions(adapter(registry).ask(state: state, asked: asked))
|
|
143
57
|
end
|
|
144
58
|
|
|
145
|
-
# Turns a
|
|
146
|
-
#
|
|
147
|
-
# Returns `[]` when the sentence
|
|
148
|
-
# carried no declaration at all (a clarifying question back from
|
|
149
|
-
# the human, say) — a legitimate answer, not a failure.
|
|
59
|
+
# Turns a sentence into proposed declarations; `[]` when it named none.
|
|
150
60
|
#
|
|
151
61
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
152
62
|
# @param prose [String] a human's plain-English sentence
|
|
153
|
-
# @param state [Hash]
|
|
154
|
-
#
|
|
155
|
-
# @
|
|
156
|
-
#
|
|
157
|
-
# @raise [Ports::Agent::
|
|
158
|
-
#
|
|
159
|
-
# `"rationale"` is blank, or one of its argument rows has no `"name"`
|
|
160
|
-
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer at all (missing
|
|
161
|
-
# binary, failed subprocess, timeout, or an exhausted scripted queue)
|
|
162
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
163
|
-
# (see `adapter`)
|
|
63
|
+
# @param state [Hash] declaration plus gaps
|
|
64
|
+
# @return [Array<Ports::Agent::Proposal>]
|
|
65
|
+
# @raise [Ports::Agent::ValidationError] unless the answer is a Hash whose `"proposals"`
|
|
66
|
+
# rows have a `Chapter::Aggregate.Command` verb, a rationale and named arguments
|
|
67
|
+
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer
|
|
68
|
+
# @raise [Runtime::WiringError] unless exactly one adapter implements the port
|
|
164
69
|
def interpret(registry, prose:, state:)
|
|
165
70
|
Answers.proposals(adapter(registry).interpret(prose: prose, state: state))
|
|
166
71
|
end
|
|
167
72
|
|
|
168
|
-
# Asks the adapter to judge a declared model on taste
|
|
169
|
-
#
|
|
170
|
-
# What is wrong with this as a model — handed everything already
|
|
171
|
-
# known (the language's own refusals, `Session#gaps`'s mechanical
|
|
172
|
-
# findings) so it spends its judgement on what neither of those
|
|
173
|
-
# can see, rather than restating them.
|
|
73
|
+
# Asks the adapter to judge a declared model on taste.
|
|
174
74
|
#
|
|
175
75
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
176
|
-
# @param declared [Hash] the chapter as declared so far
|
|
177
|
-
#
|
|
178
|
-
# @param
|
|
179
|
-
#
|
|
180
|
-
# @
|
|
181
|
-
#
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
# @raise [Ports::Agent::ValidationError] if the answer is not a Hash holding a
|
|
185
|
-
# `"findings"` array, a row's `"kind"` is outside `CRITIQUE_KINDS`, its `"severity"`
|
|
186
|
-
# is outside `SEVERITIES`, or its `"subject"` or `"message"` is blank
|
|
187
|
-
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer at all (missing
|
|
188
|
-
# binary, failed subprocess, timeout, or an exhausted scripted queue)
|
|
189
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
190
|
-
# (see `adapter`)
|
|
76
|
+
# @param declared [Hash] the chapter as declared so far
|
|
77
|
+
# @param refusals [Array<Object>] refusals the language already raised
|
|
78
|
+
# @param findings [Array<Object>] `Session#gaps` findings; both are passed so the
|
|
79
|
+
# adapter spends its judgement on what neither can see
|
|
80
|
+
# @return [Array<Ports::Agent::Finding>]
|
|
81
|
+
# @raise [Ports::Agent::ValidationError] if a kind is outside `CRITIQUE_KINDS` or a
|
|
82
|
+
# severity outside `SEVERITIES`
|
|
83
|
+
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer
|
|
191
84
|
def critique(registry, declared:, refusals: [], findings: [])
|
|
192
85
|
Answers.findings(adapter(registry).critique(declared: declared, refusals: refusals, findings: findings))
|
|
193
86
|
end
|
|
194
87
|
|
|
195
|
-
#
|
|
196
|
-
#
|
|
197
|
-
# Vocabulary help. `near` is what the chapter already calls
|
|
198
|
-
# things, so a suggestion cannot collide with a name in use.
|
|
88
|
+
# Suggests names for a construct.
|
|
199
89
|
#
|
|
200
|
-
#
|
|
201
|
-
# operation, but `Module#name` already exists and is load-bearing
|
|
202
|
-
# everywhere (backtraces, RSpec's own description building,
|
|
203
|
-
# `inspect`): a module-function called `name` shadows it the
|
|
204
|
-
# instant it's defined, and `SomeModule.name` (no args) then
|
|
205
|
-
# raises `ArgumentError: missing keywords` the next time anything
|
|
206
|
-
# — not this file, something else entirely — asks the module its
|
|
207
|
-
# own name. Measured, not theoretical: this exact collision broke
|
|
208
|
-
# RSpec's own failure-message formatting the first time it was
|
|
209
|
-
# named `name` here.
|
|
90
|
+
# Not called `name`: a module function of that name shadows `Module#name`.
|
|
210
91
|
#
|
|
211
92
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
212
93
|
# @param meaning [String] what the new name needs to mean
|
|
213
|
-
# @param kind [String] the
|
|
214
|
-
#
|
|
215
|
-
# @
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
# @raise [Ports::Agent::ValidationError] if the answer is not a Hash holding a
|
|
220
|
-
# `"names"` array whose rows each carry a non-blank `"name"` and `"because"`
|
|
221
|
-
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer at all (missing
|
|
222
|
-
# binary, failed subprocess, timeout, or an exhausted scripted queue)
|
|
223
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
224
|
-
# (see `adapter`)
|
|
94
|
+
# @param kind [String] the construct being named, such as `"event"`
|
|
95
|
+
# @param near [Array<String>] names already in use; a suggestion must not collide
|
|
96
|
+
# @return [Array<Ports::Agent::Suggestion>]
|
|
97
|
+
# @raise [Ports::Agent::ValidationError] unless the answer is a Hash whose `"names"`
|
|
98
|
+
# rows each carry a non-blank `"name"` and `"because"`
|
|
99
|
+
# @raise [Ports::Agent::Unavailable] if the adapter cannot answer
|
|
225
100
|
def suggest_name(registry, meaning:, kind:, near: [])
|
|
226
101
|
Answers.suggestions(adapter(registry).suggest_name(meaning: meaning, kind: kind, near: near))
|
|
227
102
|
end
|
|
228
103
|
|
|
229
|
-
# Finds the single adapter bound to this port
|
|
104
|
+
# Finds the single adapter bound to this port.
|
|
230
105
|
#
|
|
231
106
|
# @param registry [Runtime::Registry] the booted registry to search
|
|
232
107
|
# @return [Module] the adapter module or class implementing this port
|
|
233
|
-
# @raise [Runtime::WiringError] if
|
|
234
|
-
#
|
|
108
|
+
# @raise [Runtime::WiringError] if none, or more than one, implements the port, or the
|
|
109
|
+
# one that does has no Ruby implementation under `Hecks::Adapters`
|
|
235
110
|
def adapter(registry)
|
|
236
111
|
implementations = registry.adapters.values.select { |a| a.port == NAME }
|
|
237
112
|
|
|
@@ -2,27 +2,12 @@ require_relative "../runtime/registry"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
|
-
# The OIDC handshake
|
|
6
|
-
#
|
|
7
|
-
# claims (`issuer`, `subject`, `email`, `email_verified`). Resolved the same way every
|
|
8
|
-
# other port here resolves its adapter: one adapter registry-wide
|
|
9
|
-
# answers this, not a per-aggregate binding, since a domain has no
|
|
10
|
-
# reason to want a different sign-in provider per aggregate.
|
|
11
|
-
#
|
|
12
|
-
# The other half of "who is this" — what a verified pair means to
|
|
13
|
-
# this app, whether it resolves to an existing Identity — is
|
|
14
|
-
# `Ports::IdentityResolution`'s job, not this one's. This port only
|
|
15
|
-
# ever talks to the external provider; it never touches the
|
|
16
|
-
# registry's own Identity/Governance data (it takes `registry`
|
|
17
|
-
# purely to resolve which adapter answers it, same as every port
|
|
18
|
-
# here already does).
|
|
5
|
+
# The OIDC handshake: builds the provider URL and turns the returned code into verified claims.
|
|
6
|
+
# One adapter registry-wide answers it; it never touches the registry's Identity data.
|
|
19
7
|
module Authentication
|
|
20
8
|
NAME = "authentication".freeze
|
|
21
9
|
|
|
22
|
-
# A sign-in that could not be verified
|
|
23
|
-
# exchange, a missing or invalid ID token. An adapter wraps its own
|
|
24
|
-
# libraries' errors into this, so a caller rescues one class whichever
|
|
25
|
-
# provider answers the port.
|
|
10
|
+
# A sign-in that could not be verified (state mismatch, failed code exchange, bad ID token).
|
|
26
11
|
class ValidationError < StandardError
|
|
27
12
|
end
|
|
28
13
|
|
|
@@ -30,17 +15,13 @@ module Hecks
|
|
|
30
15
|
|
|
31
16
|
# Builds the provider URL that starts a sign-in, with the CSRF state minted for it.
|
|
32
17
|
#
|
|
33
|
-
# The caller keeps the state
|
|
34
|
-
# as `expected_state`.
|
|
18
|
+
# The caller keeps the state and hands it back to `verify` as `expected_state`.
|
|
35
19
|
#
|
|
36
20
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
37
21
|
# @return [Array(String, String)] the URL to send the browser to, then the fresh
|
|
38
22
|
# `state` value embedded in it
|
|
39
23
|
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
40
|
-
# (see `adapter`)
|
|
41
24
|
# @raise [KeyError] if the adapter's required configuration is unset
|
|
42
|
-
# (`GoogleAuthentication` reads `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` and
|
|
43
|
-
# `GOOGLE_REDIRECT_URI` with no defaults)
|
|
44
25
|
def authorization_url(registry)
|
|
45
26
|
adapter(registry).authorization_url
|
|
46
27
|
end
|
|
@@ -50,28 +31,20 @@ module Hecks
|
|
|
50
31
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
51
32
|
# @param code [String] the authorization code the provider sent back
|
|
52
33
|
# @param state [String, nil] the state parameter the provider returned; nil is refused
|
|
53
|
-
# @param expected_state [String, nil] the state `authorization_url`
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
# @raise [Ports::Authentication::ValidationError] if either state is nil or the two
|
|
59
|
-
# differ, the code exchange fails, the response has no ID token, or the ID token
|
|
60
|
-
# does not verify
|
|
34
|
+
# @param expected_state [String, nil] the state `authorization_url` returned; nil is refused
|
|
35
|
+
# @return [Hash{Symbol => Object}] the verified claims: `issuer:`, `subject:`, `email:`
|
|
36
|
+
# (nil if the token carries none) and `email_verified:` -- never the raw token
|
|
37
|
+
# @raise [Ports::Authentication::ValidationError] if a state is nil or they differ, the
|
|
38
|
+
# code exchange fails, or the ID token is missing or does not verify
|
|
61
39
|
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
62
|
-
#
|
|
63
|
-
# @raise [KeyError] if the adapter's required configuration is unset, or a verified
|
|
64
|
-
# token lacks an `iss` or `sub` claim
|
|
40
|
+
# @raise [KeyError] if required configuration is unset, or the token lacks `iss`/`sub`
|
|
65
41
|
def verify(registry, code:, state:, expected_state:)
|
|
66
42
|
adapter(registry).verify(code: code, state: state, expected_state: expected_state)
|
|
67
43
|
end
|
|
68
44
|
|
|
69
|
-
# Finds the single adapter bound to this port
|
|
45
|
+
# Finds the single adapter bound to this port.
|
|
70
46
|
#
|
|
71
|
-
# @
|
|
72
|
-
# @return [Module] the adapter module or class implementing this port
|
|
73
|
-
# @raise [Runtime::WiringError] if no adapter, or more than one, implements this port,
|
|
74
|
-
# or the one that does has no Ruby implementation under `Hecks::Adapters`
|
|
47
|
+
# @raise [Runtime::WiringError] if none, or more than one, implements this port
|
|
75
48
|
def adapter(registry)
|
|
76
49
|
implementations = registry.adapters.values.select { |a| a.port == NAME }
|
|
77
50
|
|
|
@@ -2,28 +2,8 @@ require_relative "../runtime/registry"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# resolves its own adapter: one adapter registry-wide answers this
|
|
8
|
-
# port, not a per-aggregate binding, since a domain has no reason to
|
|
9
|
-
# want a different authorization source per aggregate. What answers
|
|
10
|
-
# it is deliberately not named here — the governance-backed adapter
|
|
11
|
-
# is one implementation, not the only possible one, the same way
|
|
12
|
-
# `SequentialIdentity` and `SecureRandomIdentity` are two
|
|
13
|
-
# implementations of `identity_generation`.
|
|
14
|
-
#
|
|
15
|
-
# A caller decides what to do with the answer — dispatch under that
|
|
16
|
-
# role, refuse, log, prefer it over some other fallback value — this
|
|
17
|
-
# only answers the question asked. Nothing here binds a
|
|
18
|
-
# `Runtime::Caller`.
|
|
19
|
-
#
|
|
20
|
-
# `CommandRules::Authorization#refuse_role_mismatch` calls `holds_role?`
|
|
21
|
-
# directly, once a caller binds an `actor_id` and the command's domain
|
|
22
|
-
# has Governance attached (see that rule's own header). `spec/
|
|
23
|
-
# act_as_spec.rb` remains the precedent for the other shape — two
|
|
24
|
-
# separate registries, queried directly by name — for whenever
|
|
25
|
-
# Governance is not in the same boot as the caller; this port is the
|
|
26
|
-
# same questions asked through one adapter when it is.
|
|
5
|
+
# Role questions an application asks before binding a caller. One adapter registry-wide
|
|
6
|
+
# answers them; it only answers, and never binds a `Runtime::Caller`.
|
|
27
7
|
module Authorization
|
|
28
8
|
NAME = "authorization".freeze
|
|
29
9
|
|
|
@@ -35,15 +15,11 @@ module Hecks
|
|
|
35
15
|
# @param actor_id [String] the actor whose grants are checked
|
|
36
16
|
# @param role [String, Symbol] the role name to look for, compared as a String
|
|
37
17
|
# @param as_of [Integer, nil] Unix epoch seconds (from `Ports::Clock.now`); a grant whose
|
|
38
|
-
# `starts_at` is later, or does not parse as a time, does not count. nil skips the
|
|
39
|
-
#
|
|
40
|
-
# @
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# `as_of` and `scope` checks
|
|
44
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
45
|
-
# (see `adapter`), or the governance-backed adapter finds no single loaded chapter
|
|
46
|
-
# providing `"authorization"`
|
|
18
|
+
# `starts_at` is later, or does not parse as a time, does not count. nil skips the check
|
|
19
|
+
# @param scope [String, nil] only a grant made for this scope counts; nil counts any scope
|
|
20
|
+
# @return [Boolean] true if at least one live grant of `role` to `actor_id` passes
|
|
21
|
+
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter,
|
|
22
|
+
# or the governance-backed adapter finds no single chapter providing `"authorization"`
|
|
47
23
|
def holds_role?(registry, actor_id:, role:, as_of: nil, scope: nil)
|
|
48
24
|
adapter(registry).holds_role?(registry, actor_id: actor_id, role: role, as_of: as_of, scope: scope)
|
|
49
25
|
end
|
|
@@ -56,32 +32,29 @@ module Hecks
|
|
|
56
32
|
# String
|
|
57
33
|
# @return [Boolean] true if a live (not ended) allowance lets `from_role` act as
|
|
58
34
|
# `to_role`
|
|
59
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
60
|
-
#
|
|
61
|
-
#
|
|
35
|
+
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter,
|
|
36
|
+
# or the governance-backed adapter finds no single loaded chapter providing
|
|
37
|
+
# `"authorization"`
|
|
62
38
|
def authorized_as?(registry, from_role:, to_role:)
|
|
63
39
|
adapter(registry).authorized_as?(registry, from_role: from_role, to_role: to_role)
|
|
64
40
|
end
|
|
65
41
|
|
|
66
|
-
# Looks up the role an actor holds right now
|
|
42
|
+
# Looks up the role an actor holds right now.
|
|
67
43
|
#
|
|
68
44
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
69
45
|
# @param actor_id [String] the actor to look up
|
|
70
46
|
# @return [String, nil] the role name of the actor's first live (not ended) grant, or
|
|
71
47
|
# nil if it has none; the caller supplies any fallback
|
|
72
|
-
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
73
|
-
#
|
|
74
|
-
#
|
|
48
|
+
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter,
|
|
49
|
+
# or the governance-backed adapter finds no single loaded chapter providing
|
|
50
|
+
# `"authorization"`
|
|
75
51
|
def live_role_for(registry, actor_id:)
|
|
76
52
|
adapter(registry).live_role_for(registry, actor_id: actor_id)
|
|
77
53
|
end
|
|
78
54
|
|
|
79
|
-
# Finds the single adapter bound to this port
|
|
55
|
+
# Finds the single adapter bound to this port.
|
|
80
56
|
#
|
|
81
|
-
# @
|
|
82
|
-
# @return [Module] the adapter module or class implementing this port
|
|
83
|
-
# @raise [Runtime::WiringError] if no adapter, or more than one, implements this port,
|
|
84
|
-
# or the one that does has no Ruby implementation under `Hecks::Adapters`
|
|
57
|
+
# @raise [Runtime::WiringError] if none, or more than one, implements this port
|
|
85
58
|
def adapter(registry)
|
|
86
59
|
implementations = registry.adapters.values.select { |a| a.port == NAME }
|
|
87
60
|
|
data/lib/hecks/ports/clock.rb
CHANGED
|
@@ -2,42 +2,8 @@ require_relative "../runtime/registry"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
|
-
# What time it is
|
|
6
|
-
#
|
|
7
|
-
# Resolved exactly the way `Ports::IdentityGeneration` resolves its own
|
|
8
|
-
# adapter: one adapter registry-wide implements this, not a per-aggregate
|
|
9
|
-
# binding, because two aggregates in one running app have no real reason to
|
|
10
|
-
# disagree about the time.
|
|
11
|
-
#
|
|
12
|
-
# ## Why a port and not `Time.now`
|
|
13
|
-
#
|
|
14
|
-
# A staleness rule — "another agent may take this claim after fifteen
|
|
15
|
-
# minutes" — is untestable against the real clock: a spec for it would
|
|
16
|
-
# either sleep for fifteen minutes or never run at all. Bound to a fixed
|
|
17
|
-
# adapter, the same rule is three lines. That is the whole argument, and
|
|
18
|
-
# it is the same one `SequentialIdentity` makes next door.
|
|
19
|
-
#
|
|
20
|
-
# ## Why a predicate still can't ask the time
|
|
21
|
-
#
|
|
22
|
-
# The expression sublanguage has no clock and should not: a `given` that
|
|
23
|
-
# read the time would evaluate differently on two runs over the same
|
|
24
|
-
# record, and every replay, audit and fuzz oracle in this repository
|
|
25
|
-
# assumes it does not. So `now` remains an argument the predicate merely
|
|
26
|
-
# reads, and this port is what lets a caller stop typing it — the door
|
|
27
|
-
# fills it in, the value is baked into the dispatch, and the recorded
|
|
28
|
-
# step carries the concrete number forever after.
|
|
29
|
-
#
|
|
30
|
-
# ## Why the runtime never calls this directly
|
|
31
|
-
#
|
|
32
|
-
# `IdentityGeneration`'s own note works through the replay question for
|
|
33
|
-
# a minted uuid and lands on "the value gets baked into the caller's
|
|
34
|
-
# args at the first live dispatch". A clock consulted inside the
|
|
35
|
-
# interpreter would not have that property: a recorded corpus step
|
|
36
|
-
# replayed tomorrow would silently get tomorrow's time, and the
|
|
37
|
-
# fuzzer's oracle and the adapter-agreement gate both compare runs of
|
|
38
|
-
# exactly that shape. So the filling happens at the door, where a
|
|
39
|
-
# human or an agent is typing, and never on the dispatch path a replay
|
|
40
|
-
# uses.
|
|
5
|
+
# What time it is, as one registry-wide adapter answers it.
|
|
6
|
+
# Predicates cannot read the clock (replays must be deterministic), so the door fills `now`.
|
|
41
7
|
module Clock
|
|
42
8
|
NAME = "clock".freeze
|
|
43
9
|
|
|
@@ -45,23 +11,17 @@ module Hecks
|
|
|
45
11
|
|
|
46
12
|
# Reads the current time from the bound clock adapter.
|
|
47
13
|
#
|
|
48
|
-
#
|
|
49
|
-
# arithmetic on. `claimed_at.value + window.value <= now.value` is
|
|
50
|
-
# addition and comparison — the only two things it has — and a Time
|
|
14
|
+
# Integer seconds, because the expression sublanguage can add and compare but a Time
|
|
51
15
|
# object supports neither.
|
|
52
16
|
#
|
|
53
17
|
# @param registry [Runtime::Registry] the booted registry to resolve the adapter against
|
|
54
18
|
# @return [Integer] the current time, in Unix epoch seconds
|
|
55
19
|
# @raise [Runtime::WiringError] if this port does not resolve to exactly one adapter
|
|
56
|
-
# (see `adapter`)
|
|
57
20
|
def now(registry) = adapter(registry).now
|
|
58
21
|
|
|
59
|
-
# Finds the single adapter bound to this port
|
|
22
|
+
# Finds the single adapter bound to this port.
|
|
60
23
|
#
|
|
61
|
-
# @
|
|
62
|
-
# @return [Module] the adapter module or class implementing this port
|
|
63
|
-
# @raise [Runtime::WiringError] if no adapter, or more than one, implements this port,
|
|
64
|
-
# or the one that does has no Ruby implementation under `Hecks::Adapters`
|
|
24
|
+
# @raise [Runtime::WiringError] if none, or more than one, implements this port
|
|
65
25
|
def adapter(registry)
|
|
66
26
|
implementations = registry.adapters.values.select { |a| a.port == NAME }
|
|
67
27
|
|
|
@@ -2,10 +2,8 @@ require_relative "../runtime/registry"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# directly rather than taking a registry argument, since extraction only
|
|
8
|
-
# ever happens while a bluebook is loading, never after boot.
|
|
5
|
+
# Resolves the adapter that recovers a predicate's own source (`canonical`).
|
|
6
|
+
# Reads `Hecks.current_registry`, since extraction only happens while a bluebook loads.
|
|
9
7
|
module Extraction
|
|
10
8
|
NAME = "extraction".freeze
|
|
11
9
|
|
|
@@ -16,19 +14,16 @@ module Hecks
|
|
|
16
14
|
# @param block [Proc] a block written in a bluebook file, such as a `given` predicate
|
|
17
15
|
# or an `identified_by` path
|
|
18
16
|
# @return [String, nil] the block body's source, normalised by
|
|
19
|
-
# `Bluebook::Expression::CanonicalForm
|
|
20
|
-
#
|
|
21
|
-
# the block has an empty body
|
|
17
|
+
# `Bluebook::Expression::CanonicalForm`; nil if the block's file cannot be read, no
|
|
18
|
+
# block starts on its line, or the block has an empty body
|
|
22
19
|
# @raise [Runtime::WiringError] if called outside a boot, or this port does not resolve
|
|
23
|
-
# to exactly one adapter
|
|
20
|
+
# to exactly one adapter
|
|
24
21
|
def canonical(block) = adapter.canonical(block)
|
|
25
22
|
|
|
26
23
|
# Finds the single adapter bound to this port in the registry currently booting.
|
|
27
24
|
#
|
|
28
|
-
# @
|
|
29
|
-
#
|
|
30
|
-
# boot), if no adapter, or more than one, implements this port, or if the one that
|
|
31
|
-
# does has no Ruby implementation under `Hecks::Adapters`
|
|
25
|
+
# @raise [Runtime::WiringError] if called outside a boot, or none, or more than one,
|
|
26
|
+
# implements this port
|
|
32
27
|
def adapter
|
|
33
28
|
registry = Hecks.current_registry
|
|
34
29
|
unless registry
|