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
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
require_relative "../runtime/errors"
|
|
2
|
-
|
|
3
|
-
module Hecks
|
|
4
|
-
module Facade
|
|
5
|
-
# **The CLI door** — where Facade meets a caller holding flat strings.
|
|
6
|
-
#
|
|
7
|
-
# `JsonDoor` beside this one translates for a caller holding parsed JSON:
|
|
8
|
-
# String keys, already-nested objects, real Integers. A command line has
|
|
9
|
-
# neither of those. It has `sequence.value=99` — one flat string, with the
|
|
10
|
-
# nesting spelled as a path and the type not spelled at all.
|
|
11
|
-
#
|
|
12
|
-
# So this does the two things that turns into: rebuild the nesting, and
|
|
13
|
-
# give every leaf the type the chapter declared for it.
|
|
14
|
-
#
|
|
15
|
-
# The type comes from the projection, never from the value. A door that
|
|
16
|
-
# guessed — "99 looks like a number" — would send the Integer 99 for a
|
|
17
|
-
# version string of "99", and be wrong in a way nothing downstream could
|
|
18
|
-
# detect, because both are perfectly good arguments. `Projector::CliProjector`
|
|
19
|
-
# already read the declared field type out of the value object; this only
|
|
20
|
-
# applies it.
|
|
21
|
-
module CliDoor
|
|
22
|
-
module_function
|
|
23
|
-
|
|
24
|
-
# Builds a verb's nested, typed argument Hash out of the `name=value` words on a
|
|
25
|
-
# command line.
|
|
26
|
-
#
|
|
27
|
-
# `["reference.value=BUG#1", "sequence.value=99"]` against a projected
|
|
28
|
-
# verb spec -> `{ reference: { value: "BUG#1" }, sequence: { value: 99 } }`
|
|
29
|
-
#
|
|
30
|
-
# @param spec [Hash{Symbol => Object}] one verb's entry from `Projector::CliProjector`;
|
|
31
|
-
# read for `:arguments` and the optional `:legacy_arguments`, each an Array of
|
|
32
|
-
# option Hashes with `:path`, `:type` and, for a list, `:list`
|
|
33
|
-
# @param pairs [Array<String>] the words after the verb, each `path=value`; a path
|
|
34
|
-
# may be the short form of a single-field value object (`reference` for
|
|
35
|
-
# `reference.value`)
|
|
36
|
-
# @return [Hash{Symbol => Object}] the arguments nested by path, each leaf cast to
|
|
37
|
-
# its declared type and each list option collected into an Array; `{}` for no pairs
|
|
38
|
-
# @raise [Runtime::NotFound] if a pair has no `=`, or names a path the verb does
|
|
39
|
-
# not take
|
|
40
|
-
# @raise [Runtime::TypeMismatch] if a value cannot be read as the declared Integer
|
|
41
|
-
# or Float
|
|
42
|
-
def arguments(spec, pairs)
|
|
43
|
-
# Legacy options are accepted but not printed in help. This lets an
|
|
44
|
-
# existing id=... aggregate invocation cross the new receiver boundary
|
|
45
|
-
# while the projected surface teaches to=... exclusively.
|
|
46
|
-
options = (spec[:arguments] + Array(spec[:legacy_arguments])).to_h do |argument|
|
|
47
|
-
[argument[:path], argument]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
pairs.each_with_object({}) do |pair, args|
|
|
51
|
-
path, value = split(pair)
|
|
52
|
-
# key? first, never `||` — full names whichever spelling (the
|
|
53
|
-
# bare path, or its one-argument expansion) actually declares
|
|
54
|
-
# this option, and the lookup below must hold to that same
|
|
55
|
-
# decision rather than re-guessing which one exists.
|
|
56
|
-
full = options.key?(path) ? path : expand(path, options)
|
|
57
|
-
argument = options.key?(full) ? options[full] : raise(Runtime::NotFound, unknown(path, options.keys))
|
|
58
|
-
|
|
59
|
-
next append(args, full.split("."), cast(value, argument[:type])) if argument[:list]
|
|
60
|
-
|
|
61
|
-
bury(args, full.split("."), cast(value, argument[:type]))
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Cuts one command-line word at its first `=`, so a value may itself contain `=`.
|
|
66
|
-
#
|
|
67
|
-
# @param pair [String] one word, such as `"reference.value=BUG#1"`
|
|
68
|
-
# @return [Array(String, String)] the path and the value; the value is `""` for
|
|
69
|
-
# `"name="`
|
|
70
|
-
# @raise [Runtime::NotFound] if the word contains no `=`
|
|
71
|
-
def split(pair)
|
|
72
|
-
name, value = pair.split("=", 2)
|
|
73
|
-
raise Runtime::NotFound, "#{pair.inspect} is not name=value" if value.nil?
|
|
74
|
-
|
|
75
|
-
[name, value]
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Expands a bare value-object name into the full path of its only field.
|
|
79
|
-
#
|
|
80
|
-
# The short form, for the common case. Almost every value object in this
|
|
81
|
-
# corpus has exactly one field, so `reference=BUG#1` is unambiguous and
|
|
82
|
-
# is what anybody types. Expanded only when precisely one option starts
|
|
83
|
-
# with that prefix — two would be a guess, and a guess about which field
|
|
84
|
-
# a caller meant is worse than asking them to say.
|
|
85
|
-
#
|
|
86
|
-
# @param path [String] the path as typed, such as `"reference"`
|
|
87
|
-
# @param options [Hash{String => Hash}] the verb's options keyed by full path
|
|
88
|
-
# @return [String] the one full path beginning `"#{path}."`, or `path` unchanged when
|
|
89
|
-
# none or several do
|
|
90
|
-
def expand(path, options)
|
|
91
|
-
candidates = options.keys.select { |key| key.start_with?("#{path}.") }
|
|
92
|
-
candidates.length == 1 ? candidates.first : path
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Converts one command-line value to the type the chapter declares for its field.
|
|
96
|
-
#
|
|
97
|
-
# @param value [String] the text after the `=`
|
|
98
|
-
# @param type [String] the declared type name; `"Integer"`, `"Float"` and
|
|
99
|
-
# `"Boolean"` are converted, anything else leaves the value a String
|
|
100
|
-
# @return [Integer, Float, Boolean, String] the typed value; a Boolean is true only
|
|
101
|
-
# for `true`, `yes` or `1` in any letter case, and false for every other text
|
|
102
|
-
# @raise [Runtime::TypeMismatch] if the text does not parse as the declared Integer
|
|
103
|
-
# or Float
|
|
104
|
-
def cast(value, type)
|
|
105
|
-
case type
|
|
106
|
-
when "Integer" then Integer(value)
|
|
107
|
-
when "Float" then Float(value)
|
|
108
|
-
when "Boolean" then %w[true yes 1].include?(value.downcase)
|
|
109
|
-
else value
|
|
110
|
-
end
|
|
111
|
-
rescue ArgumentError
|
|
112
|
-
raise Runtime::TypeMismatch, "#{value.inspect} is not #{type} — the chapter declares this field as #{type}"
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Adds one element to a list argument, creating the list on first use.
|
|
116
|
-
#
|
|
117
|
-
# A list grows rather than overwrites, and getting this wrong is silent.
|
|
118
|
-
#
|
|
119
|
-
# `tags.value=framework tags.value=model-checker` sent through `bury`
|
|
120
|
-
# twice would store the second one alone — no refusal, no warning, one tag
|
|
121
|
-
# simply gone. That is the failure the interview named first: not the
|
|
122
|
-
# loud kind, the kind where a value is forgotten and the caller has no
|
|
123
|
-
# way to notice.
|
|
124
|
-
#
|
|
125
|
-
# A list of one is still a list. `tags.value=flaky` produces
|
|
126
|
-
# `[{ value: "flaky" }]`, not `{ value: "flaky" }`, because the chapter
|
|
127
|
-
# declared a collection and a caller who sent one element did not
|
|
128
|
-
# thereby declare a different shape. A bare object must never reach a
|
|
129
|
-
# `list_of` attribute: everything downstream that walks
|
|
130
|
-
# it — a query's `contains`, a projection, the Postgres adapter's own
|
|
131
|
-
# array handling — is entitled to assume it can iterate.
|
|
132
|
-
#
|
|
133
|
-
# Multi-field elements are not supported here, deliberately. A flat
|
|
134
|
-
# command line has no way to say which `a.x=` goes with which `a.y=`,
|
|
135
|
-
# and inventing an index syntax would be a language nobody asked for.
|
|
136
|
-
# Every list in this corpus is a list of single-field value objects; a
|
|
137
|
-
# richer one is a job for `JsonDoor`, which has real nesting.
|
|
138
|
-
#
|
|
139
|
-
# @param hash [Hash{Symbol => Object}] the arguments built so far; mutated in place
|
|
140
|
-
# @param path [Array<String>] the option's path segments, at least two: the last
|
|
141
|
-
# names the element's field, the one before it names the list
|
|
142
|
-
# @param value [Integer, Float, Boolean, String] the cast value for the new element
|
|
143
|
-
# @return [Hash{Symbol => Object}] `hash`, with `{ leaf => value }` appended to the
|
|
144
|
-
# Array at the list's key
|
|
145
|
-
def append(hash, path, value)
|
|
146
|
-
*branches, leaf = path.map(&:to_sym)
|
|
147
|
-
holder = branches[0..-2].reduce(hash) { |node, key| node[key] ||= {} }
|
|
148
|
-
list = holder[branches.last] ||= []
|
|
149
|
-
|
|
150
|
-
list << { leaf => value }
|
|
151
|
-
hash
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# Sets one value at a nested path, creating each intermediate Hash on the way and
|
|
155
|
-
# overwriting whatever the leaf already held.
|
|
156
|
-
#
|
|
157
|
-
# @param hash [Hash{Symbol => Object}] the arguments built so far; mutated in place
|
|
158
|
-
# @param path [Array<String>] the option's path segments, outermost first
|
|
159
|
-
# @param value [Integer, Float, Boolean, String] the cast value to store at the leaf
|
|
160
|
-
# @return [Hash{Symbol => Object}] `hash`, with the value set under Symbol keys
|
|
161
|
-
def bury(hash, path, value)
|
|
162
|
-
*branches, leaf = path.map(&:to_sym)
|
|
163
|
-
target = branches.reduce(hash) { |node, key| node[key] ||= {} }
|
|
164
|
-
target[leaf] = value
|
|
165
|
-
hash
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Words the refusal for an argument the verb does not take, listing what it does.
|
|
169
|
-
#
|
|
170
|
-
# @param path [String] the path as the caller typed it
|
|
171
|
-
# @param known [Array<String>] every path the verb accepts, in any order
|
|
172
|
-
# @return [String] a one-line message naming `path` and the sorted accepted paths
|
|
173
|
-
def unknown(path, known)
|
|
174
|
-
"no argument #{path.inspect} — this verb takes #{known.sort.join(', ')}"
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
end
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
require_relative "cli_door"
|
|
3
|
-
require_relative "command_request"
|
|
4
|
-
require_relative "json_door"
|
|
5
|
-
require_relative "../projector"
|
|
6
|
-
require_relative "../ports/clock"
|
|
7
|
-
|
|
8
|
-
module Hecks
|
|
9
|
-
module Facade
|
|
10
|
-
# The runner behind a projected CLI.
|
|
11
|
-
#
|
|
12
|
-
# `Projector::CliProjector` answers what a domain's command line looks
|
|
13
|
-
# like; this is the twenty lines that parse against it and dispatch. It
|
|
14
|
-
# lives in `lib/` rather than in a `bin/` because more than one front door
|
|
15
|
-
# wants it — `bin/run` for whichever domain you are standing in, `bin/qc`
|
|
16
|
-
# pinned to the QA ledger — and a second copy of the parse-and-dispatch
|
|
17
|
-
# would be the exact duplication the projection exists to avoid.
|
|
18
|
-
#
|
|
19
|
-
# No IO. It answers `[text, status]` and never prints or exits, so a spec
|
|
20
|
-
# can call it without capturing streams or trapping SystemExit. The `bin/`
|
|
21
|
-
# scripts do the printing, the same division `Router` and `JsonDoor`
|
|
22
|
-
# already keep against HTTP.
|
|
23
|
-
module CliRunner
|
|
24
|
-
module_function
|
|
25
|
-
|
|
26
|
-
# Runs one command line against a booted domain: resolves the verb or question,
|
|
27
|
-
# parses its `name=value` arguments, dispatches or queries, and answers with the text
|
|
28
|
-
# to print.
|
|
29
|
-
#
|
|
30
|
-
# `[text, status]` — status 0 answered, 1 refused or misused.
|
|
31
|
-
#
|
|
32
|
-
# Only the first bluebook in the registry (the booted domain's own) is projected
|
|
33
|
-
# into verbs. `--help`, `-h`, `help` or an empty `argv` answers the usage text; a
|
|
34
|
-
# verb followed by `--help` answers that verb's help.
|
|
35
|
-
#
|
|
36
|
-
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain,
|
|
37
|
-
# as `Hecks.boot` returns it
|
|
38
|
-
# @param argv [Array<String>] the words after the program name: an optional `ask`,
|
|
39
|
-
# the verb or question name (bare or aggregate-qualified), then `path=value` pairs
|
|
40
|
-
# @param program [String] how the caller was invoked, echoed in usage and hints
|
|
41
|
-
# @return [Array(String, Integer)] the text to print and the exit status: 0 with
|
|
42
|
-
# usage, help, or pretty-printed JSON of the outcome; 1 with a message when the
|
|
43
|
-
# verb is unknown, an argument is wrong, a record is missing, or the domain refuses
|
|
44
|
-
# @raise [Runtime::WiringError] if a repository, or the clock adapter a `now`
|
|
45
|
-
# argument needs, cannot be resolved
|
|
46
|
-
# @raise [Runtime::StaleWrite] if concurrent writers beat the command through every
|
|
47
|
-
# retry
|
|
48
|
-
def call(runtime:, argv:, program: "bin/run")
|
|
49
|
-
bluebook = runtime.registry.bluebooks.values.first
|
|
50
|
-
cli = Projector.call(:cli, bluebook: bluebook, options: { program: program })
|
|
51
|
-
|
|
52
|
-
name = argv.first
|
|
53
|
-
return [cli[:usage], 0] if name.nil? || %w[--help -h help].include?(name)
|
|
54
|
-
|
|
55
|
-
# `ask` puts a question in its own namespace — a chapter may declare a
|
|
56
|
-
# command and a query of one name, and banking does.
|
|
57
|
-
asking = name == "ask"
|
|
58
|
-
argv = argv[1..] if asking
|
|
59
|
-
name = argv.first
|
|
60
|
-
return [cli[:usage], 1] if name.nil?
|
|
61
|
-
|
|
62
|
-
# Resolved through the alias map, so `pizzas create_pizza` and
|
|
63
|
-
# `pizzas order.create_pizza` reach the same verb — the aggregate is
|
|
64
|
-
# worth typing only when two of them declare the same word.
|
|
65
|
-
pool = asking ? cli[:questions] : cli[:verbs]
|
|
66
|
-
key = cli[:names][asking ? :question : :command][name]
|
|
67
|
-
spec = pool[key]
|
|
68
|
-
return [unknown(cli, name, asking, program), 1] unless spec
|
|
69
|
-
|
|
70
|
-
rest = argv[1..]
|
|
71
|
-
if rest.include?("--help")
|
|
72
|
-
help = Projector.call(:cli, bluebook: bluebook,
|
|
73
|
-
options: { program: program, verb: name, ask: asking })[:usage]
|
|
74
|
-
return [help, 0]
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
dispatch(runtime, spec, name, rest, program, asking)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Parses one resolved verb's arguments, runs it as a query or a command, and turns
|
|
81
|
-
# the outcome, or the domain's refusal, into printable text.
|
|
82
|
-
#
|
|
83
|
-
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
|
|
84
|
-
# @param spec [Hash{Symbol => Object}] the verb's entry from `Projector::CliProjector`;
|
|
85
|
-
# read for `:kind`, `:verb`, `:arguments`, `:receiver` and `:legacy_receiver`
|
|
86
|
-
# @param name [String] the verb as the caller typed it, echoed in the `--help` hint
|
|
87
|
-
# @param rest [Array<String>] the `path=value` words after the verb
|
|
88
|
-
# @param program [String] how the caller was invoked, echoed in the `--help` hint
|
|
89
|
-
# @param asking [Boolean] whether the verb was reached through `ask`, which only
|
|
90
|
-
# changes the wording of the hint
|
|
91
|
-
# @return [Array(String, Integer)] status 0 with pretty-printed JSON: the materialized
|
|
92
|
-
# rows for a query; `id`, `state` and event names for a command; `id` and events
|
|
93
|
-
# with payloads for a port operation. Status 1 with the message of a
|
|
94
|
-
# `Runtime::DOMAIN_REFUSALS` error, followed by a `--help` hint when it is a
|
|
95
|
-
# `Runtime::NotFound` or `Runtime::TypeMismatch`
|
|
96
|
-
# @raise [Runtime::WiringError] if a repository, or the clock adapter a `now`
|
|
97
|
-
# argument needs, cannot be resolved
|
|
98
|
-
# @raise [Runtime::StaleWrite] if concurrent writers beat the command through every
|
|
99
|
-
# retry
|
|
100
|
-
def dispatch(runtime, spec, name, rest, program, asking)
|
|
101
|
-
args = stamp_time(runtime, spec, CliDoor.arguments(spec, rest))
|
|
102
|
-
|
|
103
|
-
if spec[:kind] == :query
|
|
104
|
-
rows = runtime.query(spec[:verb], **args)
|
|
105
|
-
return [JSON.pretty_generate(rows.map { |row| JsonDoor.materialize(row) }), 0]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# The answer is scoped to what was asked. `bin/run`'s step-list form
|
|
109
|
-
# reports the whole store because a corpus run is judged on all of it;
|
|
110
|
-
# somebody who issued one verb wants that verb's outcome, and against a
|
|
111
|
-
# Postgres-backed domain the full dump is every record there has been.
|
|
112
|
-
request = CommandRequest.normalize(args, receiver: spec[:receiver],
|
|
113
|
-
legacy_receiver: spec[:legacy_receiver])
|
|
114
|
-
handle = runtime.dispatch_flat(spec[:verb], request)
|
|
115
|
-
return [JSON.pretty_generate(answered(handle)), 0] if handle.state.nil?
|
|
116
|
-
|
|
117
|
-
[JSON.pretty_generate(id: handle.id,
|
|
118
|
-
state: JsonDoor.materialize(handle.state),
|
|
119
|
-
events: handle.events.map(&:name)), 0]
|
|
120
|
-
rescue Runtime::NotFound, Runtime::TypeMismatch => e
|
|
121
|
-
# A bad argument and a missing record both land here, and both want the
|
|
122
|
-
# same next step: read what the verb actually takes.
|
|
123
|
-
["#{e.message}\n\n #{program} #{'ask ' if asking}#{name} --help", 1]
|
|
124
|
-
rescue *Runtime::DOMAIN_REFUSALS => e
|
|
125
|
-
# **The refusal is the product** — the chapter's own sentence, verbatim.
|
|
126
|
-
[e.message, 1]
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# Supplies the current time for a verb that takes a `now` argument the caller left out.
|
|
130
|
-
#
|
|
131
|
-
# The clock, filled in at the door.
|
|
132
|
-
#
|
|
133
|
-
# A staleness rule needs the time, and the sublanguage cannot ask for it
|
|
134
|
-
# — a `given` that read the clock would judge the same record differently
|
|
135
|
-
# on two runs, and every replay, audit and fuzz oracle here assumes it
|
|
136
|
-
# does not. So `now` stays an argument the predicate merely reads, and
|
|
137
|
-
# the question becomes who types it. Left to the caller, that is:
|
|
138
|
-
#
|
|
139
|
-
# qa/quality_control target.claim id=QC held_by.value=me \
|
|
140
|
-
# now.value=$(date +%s) window.value=900
|
|
141
|
-
#
|
|
142
|
-
# which is a shell incantation in front of every claim, and one an agent
|
|
143
|
-
# gets wrong by pasting a stale number.
|
|
144
|
-
#
|
|
145
|
-
# At the door, not in the runtime, and the distinction is load-bearing.
|
|
146
|
-
# `Ports::IdentityGeneration` reasons the same question through for a
|
|
147
|
-
# minted uuid and lands on "the value is baked into the caller's args at
|
|
148
|
-
# the first live dispatch". A clock consulted inside the interpreter
|
|
149
|
-
# would not have that property — a recorded corpus step replayed
|
|
150
|
-
# tomorrow would quietly get tomorrow's time, and the fuzzer's oracle and
|
|
151
|
-
# the adapter-agreement gate both compare runs of exactly that shape. Here
|
|
152
|
-
# it fills only what a person or an agent is typing, and `runtime.dispatch`
|
|
153
|
-
# is left alone.
|
|
154
|
-
#
|
|
155
|
-
# An explicit value always wins, so a spec or a caller reproducing a
|
|
156
|
-
# moment says so and is believed. This only supplies what was omitted.
|
|
157
|
-
#
|
|
158
|
-
# By name, which is the one uncomfortable part. `now` is a plausible
|
|
159
|
-
# domain word and nothing declares that it means the clock. It is
|
|
160
|
-
# tolerable because this is a convenience layer rather than semantics —
|
|
161
|
-
# the verb's own help says the argument exists, dispatch is unchanged,
|
|
162
|
-
# and passing it explicitly is always available. The honest version is a
|
|
163
|
-
# declaration in the chapter (`attribute :now, Instant, from: :clock`),
|
|
164
|
-
# which is a language change: DSL, IR, the self-hosted grammar and its
|
|
165
|
-
# goldens. Worth doing; not worth smuggling in here.
|
|
166
|
-
#
|
|
167
|
-
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain,
|
|
168
|
-
# whose registry names the clock adapter
|
|
169
|
-
# @param spec [Hash{Symbol => Object}] the verb's projected entry; only an option whose
|
|
170
|
-
# `:path` starts `"now."` makes this method act
|
|
171
|
-
# @param args [Hash{Symbol => Object}] the parsed arguments; not mutated
|
|
172
|
-
# @return [Hash{Symbol => Object}] `args` itself when the verb takes no `now` or the
|
|
173
|
-
# caller gave one; otherwise a copy with `now: { value: seconds }`, the clock port's
|
|
174
|
-
# current time in whole seconds
|
|
175
|
-
# @raise [Runtime::WiringError] if the time is needed and zero or several adapters
|
|
176
|
-
# implement the clock port
|
|
177
|
-
def stamp_time(runtime, spec, args)
|
|
178
|
-
return args unless spec[:arguments].any? { |argument| argument[:path].start_with?("now.") }
|
|
179
|
-
return args if args.key?(:now)
|
|
180
|
-
|
|
181
|
-
args.merge(now: { value: Ports::Clock.now(runtime.registry) })
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# Shapes a port operation's outcome for printing: the record asked about, and each
|
|
185
|
-
# event with its full payload.
|
|
186
|
-
#
|
|
187
|
-
# A port operation has no state, and its payload is the entire point.
|
|
188
|
-
#
|
|
189
|
-
# A command answers with the record it changed, so naming the events is
|
|
190
|
-
# enough — the interesting part is in `state`. A port operation changes
|
|
191
|
-
# no record: it asked something outside and came back with what was
|
|
192
|
-
# said, and that lives only in the event payload. Reporting names alone
|
|
193
|
-
# would print `SpecsCompleted` and drop the spec output on the floor.
|
|
194
|
-
#
|
|
195
|
-
# This is what makes a projected CLI usable as somebody's only door. An
|
|
196
|
-
# agent that may not shell out cannot run `rspec` and read the terminal;
|
|
197
|
-
# it asks the port and reads the answer, and if the answer is a bare
|
|
198
|
-
# event name then the door leads nowhere and it needs a shell after all.
|
|
199
|
-
#
|
|
200
|
-
# Both endings come back the same way, and the status stays 0 for both.
|
|
201
|
-
# A refusal here is not a misuse — `IssueStillOpen` and `SuiteFailed`
|
|
202
|
-
# are answers the caller asked for, correctly delivered. Exit 1 is for
|
|
203
|
-
# "you typed something wrong", and conflating the two would have a
|
|
204
|
-
# scripted agent treat a healthy no as a broken call.
|
|
205
|
-
#
|
|
206
|
-
# @param handle [Runtime::Dispatcher::Result, Runtime::RemoteDispatcher::Result] the
|
|
207
|
-
# dispatch result, which for a port operation has a nil `state`
|
|
208
|
-
# @return [Hash{Symbol => Object}] `:id`, the result's id or else the first event's
|
|
209
|
-
# (nil when there is neither), and `:events`, an Array of `{ name:, payload: }`
|
|
210
|
-
# Hashes with each payload materialized to plain data
|
|
211
|
-
def answered(handle)
|
|
212
|
-
# The ID comes off the event, because a port operation hydrates no
|
|
213
|
-
# instance and the handle's own `id` is nil by design. The event knows
|
|
214
|
-
# which record was asked about — it was stamped with it — and printing
|
|
215
|
-
# `null` beside a payload that plainly says `SW-TOOL` would read as a
|
|
216
|
-
# bug in something.
|
|
217
|
-
{ id: handle.id || handle.events.first&.id,
|
|
218
|
-
events: handle.events.map do |event|
|
|
219
|
-
{ name: event.name, payload: JsonDoor.materialize(event.payload) }
|
|
220
|
-
end }
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# Words the answer to a verb or question that does not exist, suggesting up to five
|
|
224
|
-
# names that start the same way.
|
|
225
|
-
#
|
|
226
|
-
# A near miss is worth more than a list. Somebody who typed
|
|
227
|
-
# `bug.discovr` wants one line, not eighty-seven of them.
|
|
228
|
-
#
|
|
229
|
-
# Ranked by shared prefix, not by substring. Substring matching finds
|
|
230
|
-
# nothing for the commonest typo of all — a dropped
|
|
231
|
-
# letter, `order.create_piza`, which is a substring of nothing. Prefix
|
|
232
|
-
# length survives an error anywhere after it, which is where errors are.
|
|
233
|
-
#
|
|
234
|
-
# @param cli [Hash{Symbol => Object}] the `Projector::CliProjector` projection; read
|
|
235
|
-
# for `cli[:names]`, the alias maps under `:command` and `:question`
|
|
236
|
-
# @param name [String] what the caller typed
|
|
237
|
-
# @param asking [Boolean] whether it was typed after `ask`, which picks the question
|
|
238
|
-
# names and the wording
|
|
239
|
-
# @param program [String] how the caller was invoked, echoed in the closing hint
|
|
240
|
-
# @return [String] a multi-line message; candidates must share a prefix of at least
|
|
241
|
-
# half of `name`'s length, and never fewer than three characters
|
|
242
|
-
def unknown(cli, name, asking, program)
|
|
243
|
-
# **Both spellings are candidates**. A caller who typed the qualified
|
|
244
|
-
# form with a typo — `order.create_piza` — shares no prefix with the
|
|
245
|
-
# short name `create_pizza`, so pooling only one of them suggests
|
|
246
|
-
# nothing for half the mistakes anybody makes.
|
|
247
|
-
pool = cli[:names][asking ? :question : :command].keys
|
|
248
|
-
near = pool.map { |candidate| [shared_prefix(candidate, name), candidate] }
|
|
249
|
-
.select { |shared, _| shared >= [name.length / 2, 3].max }
|
|
250
|
-
.sort_by { |shared, candidate| [-shared, candidate] }
|
|
251
|
-
.map(&:last)
|
|
252
|
-
|
|
253
|
-
lines = ["no such #{asking ? 'question' : 'verb'}: #{name}"]
|
|
254
|
-
lines += ["", "did you mean:", *near.first(5).map { |candidate| " #{candidate}" }] unless near.empty?
|
|
255
|
-
lines += ["", " #{program}#{' ask' if asking} for the full list"]
|
|
256
|
-
lines.join("\n")
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
# Counts how many leading characters two names have in common.
|
|
260
|
-
#
|
|
261
|
-
# @param one [String] a candidate name
|
|
262
|
-
# @param other [String] the name to compare it with
|
|
263
|
-
# @return [Integer] the length of the common prefix, from 0 up to the shorter
|
|
264
|
-
# name's length
|
|
265
|
-
def shared_prefix(one, other)
|
|
266
|
-
length = [one.length, other.length].min
|
|
267
|
-
(0...length).find { |index| one[index] != other[index] } || length
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
end
|