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
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
require_relative "../bluebook/expression/resolver"
|
|
2
|
+
require_relative "../bluebook/expression/evaluator"
|
|
3
|
+
|
|
4
|
+
module Hecks
|
|
5
|
+
module Fuzzing
|
|
6
|
+
# Generates every well-typed expression up to MAX_DEPTH and checks that
|
|
7
|
+
# `Expression::Evaluator` never raises anything but `EvaluationError` on them.
|
|
8
|
+
#
|
|
9
|
+
# Generation is type-directed: a sub-expression is only built where its parent
|
|
10
|
+
# accepts its type, with a small literal palette and a depth bound to stay tractable.
|
|
11
|
+
module BoundedExhaustiveExpressions
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# Integer and Float are one type: the resolver never distinguishes them.
|
|
15
|
+
TYPES = %i[numeric string boolean array nil_type].freeze
|
|
16
|
+
|
|
17
|
+
# A small literal palette; boundary values (Bignum, NaN, unicode) are covered elsewhere.
|
|
18
|
+
TYPE_LEAVES = {
|
|
19
|
+
numeric: ["0", "1", "-1"].freeze,
|
|
20
|
+
string: ['""', '"a"'].freeze,
|
|
21
|
+
boolean: %w[true false].freeze,
|
|
22
|
+
nil_type: %w[nil].freeze
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
# Names must not collide with BLOCK_PARAM: a block parameter shadows a same-named attribute.
|
|
26
|
+
SYNTHETIC_ATTRS = {
|
|
27
|
+
numeric: %w[num_a num_b].freeze,
|
|
28
|
+
string: %w[str_a str_b].freeze,
|
|
29
|
+
boolean: %w[bool_a bool_b].freeze,
|
|
30
|
+
array: %w[arr_num arr_str].freeze
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
# Element type per array attribute, so a block parameter gets the right leaf set.
|
|
34
|
+
ARRAY_ELEMENT_TYPE = { "arr_num" => :numeric, "arr_str" => :string }.freeze
|
|
35
|
+
|
|
36
|
+
BLOCK_PARAM = "el".freeze
|
|
37
|
+
|
|
38
|
+
MAX_DEPTH = 3
|
|
39
|
+
|
|
40
|
+
# Half the attributes are bare scalars, half wrapped in `SingleFieldVO`, so the
|
|
41
|
+
# value-object unwrap path in `Resolver#unwrap_scalar` is exercised.
|
|
42
|
+
#
|
|
43
|
+
# Not a plain Hash: `unwrap_scalar` leaves a Hash wrapped, so a `{value: X}` Hash
|
|
44
|
+
# would fail every scalar-typed operation.
|
|
45
|
+
SingleFieldVO = Struct.new(:value) do
|
|
46
|
+
def to_h = { value: value }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Builds the fixed state every generated predicate is interpreted against.
|
|
50
|
+
#
|
|
51
|
+
# @return [Hash{Symbol => Object}] symbol-keyed synthetic state
|
|
52
|
+
def synthetic_state
|
|
53
|
+
{
|
|
54
|
+
num_a: 3,
|
|
55
|
+
num_b: SingleFieldVO.new(5),
|
|
56
|
+
str_a: "hello",
|
|
57
|
+
str_b: SingleFieldVO.new("world"),
|
|
58
|
+
bool_a: true,
|
|
59
|
+
bool_b: SingleFieldVO.new(false),
|
|
60
|
+
arr_num: [1, SingleFieldVO.new(2), 3],
|
|
61
|
+
arr_str: ["x", SingleFieldVO.new("y"), "z"]
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# The `attrs` half of the interpret call; every name lives in `synthetic_state`.
|
|
66
|
+
#
|
|
67
|
+
# @return [Hash] always `{}`
|
|
68
|
+
def synthetic_attrs = {}
|
|
69
|
+
|
|
70
|
+
# Lists every terminal expression of `type`: literals, synthetic attribute names,
|
|
71
|
+
# and any bound block-parameter leaf.
|
|
72
|
+
#
|
|
73
|
+
# @param type [Symbol] one of `TYPES`
|
|
74
|
+
# @return [Array<String>] the terminal expressions for `type`
|
|
75
|
+
def leaves(type)
|
|
76
|
+
(TYPE_LEAVES[type] || []) + (SYNTHETIC_ATTRS[type] || []) + Array(bound_leaves[type])
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The per-type stack of bound block-parameter leaf names.
|
|
80
|
+
#
|
|
81
|
+
# A stack because nested block predicates push a second `BLOCK_PARAM`; the inner one
|
|
82
|
+
# shadows the outer, which the interpreter handles by rebinding per level.
|
|
83
|
+
#
|
|
84
|
+
# @return [Hash{Symbol => Array<String>}] each type's stack, usually `[]` or `["el"]`
|
|
85
|
+
def bound_leaves = @bound_leaves ||= Hash.new { |h, k| h[k] = [] }
|
|
86
|
+
|
|
87
|
+
# Runs the block with `BLOCK_PARAM` admitted as a leaf of `element_type`.
|
|
88
|
+
#
|
|
89
|
+
# @param element_type [Symbol] the type `BLOCK_PARAM` is bound to
|
|
90
|
+
# @yield runs with the leaf pushed and affected cache entries invalidated
|
|
91
|
+
# @return [Object] the block's result
|
|
92
|
+
def with_element_leaf(element_type)
|
|
93
|
+
bound_leaves[element_type] << BLOCK_PARAM
|
|
94
|
+
cache.delete_if { |(type, _depth), _| type == element_type }
|
|
95
|
+
yield
|
|
96
|
+
ensure
|
|
97
|
+
bound_leaves[element_type].pop
|
|
98
|
+
cache.delete_if { |(type, _depth), _| type == element_type }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Lists every expression of `type` reachable in at most `depth` steps, memoized
|
|
102
|
+
# so cost grows additively per level rather than multiplicatively.
|
|
103
|
+
#
|
|
104
|
+
# @param type [Symbol] one of `TYPES`
|
|
105
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
106
|
+
# @return [Array<String>] the deduplicated expressions; `leaves(type)` at depth 0
|
|
107
|
+
def productions(type, depth)
|
|
108
|
+
cache[[type, depth]] ||= begin
|
|
109
|
+
base = leaves(type)
|
|
110
|
+
depth <= 0 ? base : (base + recursive_productions(type, depth)).uniq
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# The `productions` memo, keyed by `[type, depth]`.
|
|
115
|
+
#
|
|
116
|
+
# @return [Hash{Array(Symbol, Integer) => Array<String>}] the cache
|
|
117
|
+
def cache = @cache ||= {}
|
|
118
|
+
|
|
119
|
+
# Dispatches to the recursive production rule for `type`.
|
|
120
|
+
#
|
|
121
|
+
# @param type [Symbol] one of `TYPES`
|
|
122
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
123
|
+
# @return [Array<String>] the non-leaf expressions; `[]` for `:nil_type`
|
|
124
|
+
# @raise [ArgumentError] if `type` is outside `TYPES`
|
|
125
|
+
def recursive_productions(type, depth)
|
|
126
|
+
case type
|
|
127
|
+
when :numeric then numeric_productions(depth)
|
|
128
|
+
when :string then string_productions(depth)
|
|
129
|
+
when :boolean then boolean_productions(depth)
|
|
130
|
+
when :array then array_productions(depth)
|
|
131
|
+
# nothing produces nil as source text; Find's "not found" is a runtime outcome
|
|
132
|
+
when :nil_type then []
|
|
133
|
+
else raise ArgumentError, "no production rule for type #{type.inspect}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Samples `productions(type, depth)` down to `SAMPLE_CAP` entries.
|
|
138
|
+
#
|
|
139
|
+
# Every internal sub-expression list goes through this: bounding the inputs (not the
|
|
140
|
+
# final output) is what keeps growth near-linear in depth instead of combinatorial.
|
|
141
|
+
#
|
|
142
|
+
# @param type [Symbol] one of `TYPES`
|
|
143
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
144
|
+
# @return [Array<String>] at most `SAMPLE_CAP` expressions
|
|
145
|
+
def bounded(type, depth) = sample(productions(type, depth))
|
|
146
|
+
|
|
147
|
+
# Numeric from Addition, Modulo, Size (string or array), and First/Last of a numeric array.
|
|
148
|
+
#
|
|
149
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
150
|
+
# @return [Array<String>] numeric expressions one construct deep
|
|
151
|
+
def numeric_productions(depth)
|
|
152
|
+
sub = bounded(:numeric, depth - 1)
|
|
153
|
+
# Modulo's receiver is restricted to `resolver_numeric_leaves`: `Resolver.parse` splits
|
|
154
|
+
# on `+` before the `.modulo` suffix, so "0 + 0.modulo(1)" parses as `0 + (0.modulo(1))`.
|
|
155
|
+
pairs(sub).map { |a, b| "#{a} + #{b}" } +
|
|
156
|
+
cross(resolver_numeric_leaves(depth - 1), sub).map { |a, b| "#{a}.modulo(#{b})" } +
|
|
157
|
+
bounded(:string, depth - 1).map { |s| "#{s}.size" } +
|
|
158
|
+
bounded(:array, depth - 1).map { |a| "#{a}.size" } +
|
|
159
|
+
sample(numeric_array_productions(depth - 1)).flat_map { |a| ["#{a}.first", "#{a}.last"] }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Booleans safe as the receiver of a Resolver-level suffix such as `.to_s` (a boolean-
|
|
163
|
+
# typed expression, is wanted). Found live, the same way the
|
|
164
|
+
# nested `.modulo` bug was: `Compare`, `Include`, `Or`, `And` and `Not` are boolean-
|
|
165
|
+
# typed at `interpret` time, but `Evaluator`-level syntax, not
|
|
166
|
+
# something `Resolver.parse` can take as a receiver, even parenthesized.
|
|
167
|
+
#
|
|
168
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
169
|
+
# @return [Array<String>] boolean expressions parsed by a Resolver suffix rule
|
|
170
|
+
def resolver_boolean_leaves(depth)
|
|
171
|
+
leaves(:boolean) +
|
|
172
|
+
resolver_numeric_leaves(depth).flat_map { |n| ["#{n}.positive?", "#{n}.negative?", "#{n}.zero?"] } +
|
|
173
|
+
bounded(:string, depth).flat_map do |s|
|
|
174
|
+
["#{s}.present?", "#{s}.blank?", "#{s}.match?(/a/)", "#{s}.start_with?(\"a\")", "#{s}.end_with?(\"a\")"]
|
|
175
|
+
end +
|
|
176
|
+
(sample(numeric_array_productions(depth)) + sample(string_array_productions(depth)) + bounded(:array, depth)).map do |x|
|
|
177
|
+
"#{x}.empty?"
|
|
178
|
+
end +
|
|
179
|
+
sample(block_predicate_productions(depth))
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Numerics safe to embed as the receiver of a Resolver-level suffix such as `.to_s`.
|
|
183
|
+
#
|
|
184
|
+
# A bare `Addition` is excluded: `Resolver.parse` splits on `+` before matching the
|
|
185
|
+
# suffix, so "0 + 0.to_s" parses as `0 + (0.to_s)`, not `(0 + 0).to_s`.
|
|
186
|
+
#
|
|
187
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
188
|
+
# @return [Array<String>] numeric expressions that are never a bare top-level `Addition`
|
|
189
|
+
def resolver_numeric_leaves(depth)
|
|
190
|
+
return leaves(:numeric) if depth <= 0
|
|
191
|
+
|
|
192
|
+
# Self-referential so Modulo's receiver stays restricted; its argument is unrestricted.
|
|
193
|
+
leaves(:numeric) +
|
|
194
|
+
cross(resolver_numeric_leaves(depth - 1), bounded(:numeric, depth - 1)).map { |a, b| "#{a}.modulo(#{b})" } +
|
|
195
|
+
bounded(:string, depth).map { |s| "#{s}.size" } +
|
|
196
|
+
bounded(:array, depth).map { |a| "#{a}.size" } +
|
|
197
|
+
sample(numeric_array_productions(depth)).flat_map { |a| ["#{a}.first", "#{a}.last"] }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# String from ToS of numeric, boolean, nil or string, and First/Last of a string array.
|
|
201
|
+
#
|
|
202
|
+
# `Split` is not listed: it produces an array, never a String.
|
|
203
|
+
#
|
|
204
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
205
|
+
# @return [Array<String>] string expressions one construct deep
|
|
206
|
+
def string_productions(depth)
|
|
207
|
+
sample(resolver_numeric_leaves(depth - 1)).map { |n| "#{n}.to_s" } +
|
|
208
|
+
sample(resolver_boolean_leaves(depth - 1)).map { |b| "#{b}.to_s" } +
|
|
209
|
+
bounded(:nil_type, depth - 1).map { |n| "#{n}.to_s" } +
|
|
210
|
+
bounded(:string, depth - 1).map { |s| "#{s}.to_s" } +
|
|
211
|
+
sample(string_array_productions(depth - 1)).flat_map { |a| ["#{a}.first", "#{a}.last"] }
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Array from Split and same-type array literals; array is mostly a receiver type, so
|
|
215
|
+
# few producers are needed.
|
|
216
|
+
#
|
|
217
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
218
|
+
# @return [Array<String>] array expressions one construct deep; `[]` at depth 0
|
|
219
|
+
def array_productions(depth)
|
|
220
|
+
return [] if depth <= 0
|
|
221
|
+
|
|
222
|
+
bounded(:string, depth - 1).map { |s| "#{s}.split(\",\")" } +
|
|
223
|
+
[numeric_array_literal(depth - 1), string_array_literal(depth - 1)]
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Builds a two-element numeric array literal at `depth`.
|
|
227
|
+
#
|
|
228
|
+
# @param depth [Integer] maximum recursive steps remaining for its elements
|
|
229
|
+
# @return [String] the literal's source text
|
|
230
|
+
def numeric_array_literal(depth) = "[#{bounded(:numeric, depth).first(2).join(', ')}]"
|
|
231
|
+
|
|
232
|
+
# Builds a two-element string array literal at `depth`.
|
|
233
|
+
#
|
|
234
|
+
# @param depth [Integer] maximum recursive steps remaining for its elements
|
|
235
|
+
# @return [String] the literal's source text
|
|
236
|
+
def string_array_literal(depth) = "[#{bounded(:string, depth).first(2).join(', ')}]"
|
|
237
|
+
|
|
238
|
+
# Arrays known by construction to hold numeric elements, so `.first`/`.last` and block
|
|
239
|
+
# predicates know the element type without a richer AST.
|
|
240
|
+
#
|
|
241
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
242
|
+
# @return [Array<String>] `"arr_num"` plus a numeric array literal at `depth`
|
|
243
|
+
def numeric_array_productions(depth)
|
|
244
|
+
["arr_num", numeric_array_literal(depth)]
|
|
245
|
+
# no Split entry: a Split of a string never yields numeric elements
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Arrays known by construction to hold string elements; the twin of
|
|
249
|
+
# `numeric_array_productions`.
|
|
250
|
+
#
|
|
251
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
252
|
+
# @return [Array<String>] `"arr_str"`, a string array literal, and every string `Split`
|
|
253
|
+
def string_array_productions(depth)
|
|
254
|
+
["arr_str", string_array_literal(depth)] + bounded(:string, depth).map { |s| "#{s}.split(\",\")" }
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Boolean from every comparison and predicate construct; a `given` body is boolean-
|
|
258
|
+
# typed at its own top level (`Evaluator.truthy?`), so this is also
|
|
259
|
+
# the set `all_predicates` draws from.
|
|
260
|
+
#
|
|
261
|
+
# One table rather than helper methods: each term's rationale sits beside it.
|
|
262
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
263
|
+
#
|
|
264
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
265
|
+
# @return [Array<String>] boolean expressions one construct deep
|
|
266
|
+
def boolean_productions(depth)
|
|
267
|
+
sub = bounded(:boolean, depth - 1)
|
|
268
|
+
num = bounded(:numeric, depth - 1)
|
|
269
|
+
str = bounded(:string, depth - 1)
|
|
270
|
+
|
|
271
|
+
pairs(num).map { |a, b| "#{a} == #{b}" } +
|
|
272
|
+
pairs(num).map { |a, b| "#{a} > #{b}" } +
|
|
273
|
+
pairs(str).map { |a, b| "#{a} == #{b}" } +
|
|
274
|
+
pairs(str).map { |a, b| "#{a} < #{b}" } +
|
|
275
|
+
# `resolver_numeric_leaves`, not `num`: a suffix match is a plain trailing strip, so
|
|
276
|
+
# an `Addition` would mis-split ("0 + 0.positive?" parses as `0 + (0.positive?)`).
|
|
277
|
+
resolver_numeric_leaves(depth - 1).flat_map { |n| ["#{n}.positive?", "#{n}.negative?", "#{n}.zero?"] } +
|
|
278
|
+
(str + sample(numeric_array_productions(depth - 1)) + sample(string_array_productions(depth - 1)) + bounded(:array,
|
|
279
|
+
depth - 1))
|
|
280
|
+
.map do |x|
|
|
281
|
+
"#{x}.empty?"
|
|
282
|
+
end +
|
|
283
|
+
str.map { |s| "#{s}.match?(/a/)" } +
|
|
284
|
+
str.flat_map { |s| ["#{s}.present?", "#{s}.blank?"] } +
|
|
285
|
+
str.flat_map { |s| ["#{s}.start_with?(\"a\")", "#{s}.end_with?(\"a\")"] } +
|
|
286
|
+
pairs(sub).flat_map { |a, b| ["#{a} && #{b}", "#{a} || #{b}"] } +
|
|
287
|
+
sub.map { |b| "!#{b}" } +
|
|
288
|
+
block_predicate_productions(depth - 1) +
|
|
289
|
+
include_productions(depth - 1)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# `.all?`/`.any?`/`.none?` over each known-element-typed array, with a predicate body
|
|
293
|
+
# bound to `BLOCK_PARAM`.
|
|
294
|
+
#
|
|
295
|
+
# The only construct where Resolver and Evaluator recurse into each other, and the
|
|
296
|
+
# only one that can nest into another block predicate.
|
|
297
|
+
#
|
|
298
|
+
# @param depth [Integer] maximum recursive steps remaining for the predicate body
|
|
299
|
+
# @return [Array<String>] `.all?`/`.any?`/`.none?` calls over each
|
|
300
|
+
# known-element-typed array source, one per predicate body `predicate_bodies`
|
|
301
|
+
# produces; `[]` if `depth` is negative
|
|
302
|
+
def block_predicate_productions(depth)
|
|
303
|
+
return [] if depth.negative?
|
|
304
|
+
|
|
305
|
+
[
|
|
306
|
+
["arr_num", :numeric], [numeric_array_literal(depth), :numeric],
|
|
307
|
+
["arr_str", :string], [string_array_literal(depth), :string]
|
|
308
|
+
].flat_map do |array_text, element_type|
|
|
309
|
+
predicate_bodies(element_type, depth).flat_map do |body|
|
|
310
|
+
%w[all? any? none?].map { |mode| "#{array_text}.#{mode} { |#{BLOCK_PARAM}| #{body} }" }
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# The predicate body a block gets: `boolean_productions` with `BLOCK_PARAM` also a leaf.
|
|
316
|
+
# Sampled because each body is multiplied by three modes and four array sources.
|
|
317
|
+
#
|
|
318
|
+
# @param element_type [Symbol] the type `BLOCK_PARAM` is bound to inside the block
|
|
319
|
+
# @param depth [Integer] maximum recursive steps remaining for the body
|
|
320
|
+
# @return [Array<String>] a sampled set of boolean expressions
|
|
321
|
+
def predicate_bodies(element_type, depth)
|
|
322
|
+
sample(with_element_leaf(element_type) { boolean_productions(depth) })
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# `haystack.include?(needle)`: a String haystack needs a String needle, an Array
|
|
326
|
+
# haystack admits any needle type.
|
|
327
|
+
#
|
|
328
|
+
# @param depth [Integer] maximum recursive steps remaining
|
|
329
|
+
# @return [Array<String>] `include?` expressions for string and array haystacks
|
|
330
|
+
def include_productions(depth)
|
|
331
|
+
str = bounded(:string, depth)
|
|
332
|
+
pairs(str).map { |haystack, needle| "#{haystack}.include?(#{needle})" } +
|
|
333
|
+
sample(numeric_array_productions(depth)).product(bounded(:numeric, depth)).map do |arr, needle|
|
|
334
|
+
"#{arr}.include?(#{needle})"
|
|
335
|
+
end +
|
|
336
|
+
sample(string_array_productions(depth)).product(bounded(:string, depth)).map do |arr, needle|
|
|
337
|
+
"#{arr}.include?(#{needle})"
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Cap on any sampled list. A full cross product explodes to tens of millions of cases,
|
|
342
|
+
# and `Or`/`And`/`Not` do no type-dependent work, so sampled operands cover them.
|
|
343
|
+
SAMPLE_CAP = 14
|
|
344
|
+
|
|
345
|
+
# Evenly samples `list` down to at most `SAMPLE_CAP` entries.
|
|
346
|
+
#
|
|
347
|
+
# @param list [Array<String>] the list to sample
|
|
348
|
+
# @return [Array<String>] `list` if short enough, else every n-th entry, evenly spaced
|
|
349
|
+
def sample(list) = list.size <= SAMPLE_CAP ? list : list.each_slice(list.size.fdiv(SAMPLE_CAP).ceil).map(&:first)
|
|
350
|
+
|
|
351
|
+
# Builds every pair of one sampled list with itself.
|
|
352
|
+
#
|
|
353
|
+
# @param list [Array<String>] the list to sample and pair
|
|
354
|
+
# @return [Array<Array(String, String)>] the sampled list's self cross product
|
|
355
|
+
def pairs(list)
|
|
356
|
+
sampled = sample(list)
|
|
357
|
+
sampled.product(sampled)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# The two-list twin of `pairs`, for constructs whose sides need different operand sets.
|
|
361
|
+
#
|
|
362
|
+
# @param left [Array<String>] the left-hand list to sample
|
|
363
|
+
# @param right [Array<String>] the right-hand list to sample
|
|
364
|
+
# @return [Array<Array(String, String)>] the cross product of the sampled lists
|
|
365
|
+
def cross(left, right) = sample(left).product(sample(right))
|
|
366
|
+
|
|
367
|
+
# Every boolean-typed expression up to `max_depth`, deduplicated.
|
|
368
|
+
#
|
|
369
|
+
# @param max_depth [Integer] maximum recursive depth to generate up to
|
|
370
|
+
# @return [Array<String>] the deduplicated expressions
|
|
371
|
+
def all_predicates(max_depth = MAX_DEPTH)
|
|
372
|
+
productions(:boolean, max_depth).uniq
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# Interprets one predicate against the synthetic state.
|
|
376
|
+
#
|
|
377
|
+
# A true/false answer or a clean `EvaluationError` is the sublanguage working; only
|
|
378
|
+
# any other escaping error is a finding.
|
|
379
|
+
#
|
|
380
|
+
# @param expr [String] a generated or hand-written expression source
|
|
381
|
+
# @return [Hash{Symbol => Object}] `{ok: true, result:}`, `{ok: true, result: :refused,
|
|
382
|
+
# message:}` for `EvaluationError`, or `{ok: false, error:}` for anything else
|
|
383
|
+
def check(expr)
|
|
384
|
+
result = Hecks::Bluebook::Expression::Evaluator.call(expr, synthetic_state, synthetic_attrs)
|
|
385
|
+
{ ok: true, result: result }
|
|
386
|
+
rescue Hecks::Bluebook::Expression::EvaluationError => e
|
|
387
|
+
{ ok: true, result: :refused, message: e.message }
|
|
388
|
+
rescue StandardError => e
|
|
389
|
+
{ ok: false, error: e }
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "open3"
|
|
3
|
+
require_relative "form_census"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Fuzzing
|
|
7
|
+
# Asks an agent to write candidate bluebooks from the corpus's form-pair census.
|
|
8
|
+
# Opt-in: `hecks quality_control tick` never runs it; an agent call is costly and
|
|
9
|
+
# nondeterministic.
|
|
10
|
+
module CombinationMiner
|
|
11
|
+
PROMPT_TEMPLATE = "qa/combination_miner/prompt.md".freeze
|
|
12
|
+
HYPOTHESIS_FILE = "HYPOTHESIS.md".freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def corpus_paths(root)
|
|
17
|
+
Hecks::Corpus.members(:stress, :example, root: root).map(&:path)
|
|
18
|
+
.select { |path| Hecks::Corpus.bluebook_files(path) }
|
|
19
|
+
.sort
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def recent_bug_titles(root, limit: 60)
|
|
23
|
+
out, status = Open3.capture2("git", "log", "--format=%s", "--grep=BUG#", "-n", limit.to_s, chdir: root)
|
|
24
|
+
status.success? ? out.lines.map(&:strip).reject(&:empty?) : []
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def brief(paths, root:, bug_titles:)
|
|
28
|
+
covered = Hash.new { |hash, key| hash[key] = [] }
|
|
29
|
+
skipped = []
|
|
30
|
+
paths.each do |path|
|
|
31
|
+
FormCensus.covered_pairs(FormCensus.census(path)).each { |pair, names| covered[pair].concat(names) }
|
|
32
|
+
rescue StandardError, ScriptError => e
|
|
33
|
+
skipped << "#{relative(path, root)} (#{e.class}: #{e.message.lines.first&.strip})"
|
|
34
|
+
end
|
|
35
|
+
{ "forms" => FormCensus::FORMS.keys, "corpus" => paths.map { |path| relative(path, root) },
|
|
36
|
+
"unmet_pairs" => (FormCensus.pairs - covered.keys).sort,
|
|
37
|
+
"single_carrier_pairs" => covered.select { |_, names| names.uniq.size == 1 }
|
|
38
|
+
.map { |pair, names| "#{pair} (only #{names.first})" }.sort,
|
|
39
|
+
"skipped" => skipped, "recent_bugs" => bug_titles, "covered" => covered }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def prompt(root, brief, count:, out_dir:)
|
|
43
|
+
substitutions = {
|
|
44
|
+
"count" => count.to_s, "out_dir" => out_dir, "forms" => brief["forms"].join(", "),
|
|
45
|
+
"corpus" => bulleted(brief["corpus"]), "unmet_pairs" => bulleted(brief["unmet_pairs"]),
|
|
46
|
+
"single_carrier_pairs" => bulleted(brief["single_carrier_pairs"]),
|
|
47
|
+
"recent_bugs" => bulleted(brief["recent_bugs"]), "skipped" => bulleted(brief["skipped"])
|
|
48
|
+
}
|
|
49
|
+
File.read(File.join(root, PROMPT_TEMPLATE)).gsub(/\{\{(\w+)\}\}/) { substitutions.fetch(Regexp.last_match(1)) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def repair_prompt(failures, out_dir:)
|
|
53
|
+
listed = failures.map { |candidate, error| "- #{candidate[:bluebook]}\n boot error: #{error}" }.join("\n")
|
|
54
|
+
<<~PROMPT
|
|
55
|
+
REPAIR ROUND. You wrote candidate Hecks bluebooks under #{out_dir} for the QA combination miner.
|
|
56
|
+
These did not boot. Edit each file IN PLACE so it boots, keeping the construct combination its
|
|
57
|
+
#{HYPOTHESIS_FILE} names (update the hypothesis if the fix changes the shape). Do not create new
|
|
58
|
+
candidates and do not touch anything outside #{out_dir}.
|
|
59
|
+
|
|
60
|
+
#{listed}
|
|
61
|
+
PROMPT
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# One bluebook per candidate: the first, alphabetically, if an agent wrote more.
|
|
65
|
+
def candidates(out_dir)
|
|
66
|
+
Dir[File.join(out_dir, "*")].select { |dir| File.directory?(dir) }.sort.filter_map do |dir|
|
|
67
|
+
bluebook = Dir[File.join(dir, "*.bluebook")].min
|
|
68
|
+
next unless bluebook
|
|
69
|
+
|
|
70
|
+
hypothesis = File.join(dir, HYPOTHESIS_FILE)
|
|
71
|
+
{ slug: File.basename(dir), dir: dir, bluebook: bluebook,
|
|
72
|
+
hypothesis: File.exist?(hypothesis) ? File.read(hypothesis).strip : nil }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Informational, never a gate: an agent may aim at a shape the census does not name yet.
|
|
77
|
+
def new_pairs(candidate_dir, covered)
|
|
78
|
+
FormCensus.covered_pairs(FormCensus.census(candidate_dir)).keys.reject { |pair| covered.key?(pair) }.sort
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def relative(path, root) = path.delete_prefix("#{root}/")
|
|
82
|
+
|
|
83
|
+
def bulleted(items) = items.empty? ? "(none)" : items.map { |item| "- #{item}" }.join("\n")
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|