hecks 2.8.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +50 -7
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +32 -100
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +149 -136
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +48 -38
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +16 -50
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +49 -67
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +39 -661
- data/lib/hecks/bluebook/hexagon.rb +18 -33
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +87 -352
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +122 -596
- data/lib/hecks/bluebook/pattern_subset.rb +49 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +27 -51
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +9 -99
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- data/lib/hecks/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +5 -23
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +4 -6
- data/lib/hecks/cli/mcp.rb +5 -6
- data/lib/hecks/cli/model_check.rb +24 -88
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +223 -64
- data/lib/hecks/cli/project_diagrams.rb +4 -10
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +15 -61
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +7 -19
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -6
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +216 -73
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +14 -34
- data/lib/hecks/doors/handle.rb +206 -0
- data/lib/hecks/doors/json_door.rb +132 -0
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
- data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
- data/lib/hecks/doors/ruby_door.rb +77 -0
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +5 -72
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +23 -51
- data/lib/hecks/forms/app.rb +21 -76
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +31 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +19 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +47 -108
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +12 -44
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +40 -207
- data/lib/hecks/projections/deploy/lambda.rb +191 -708
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +3 -59
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +48 -147
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +22 -584
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +16 -43
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +13 -32
- data/lib/hecks/projections/reference.rb +4 -18
- data/lib/hecks/projections/rust_vocabulary.rb +13 -251
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +154 -400
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +5 -8
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +15 -9
- data/lib/hecks/release/runner/npm_publisher.rb +9 -53
- data/lib/hecks/release/runner/preflight.rb +29 -20
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +31 -23
- data/lib/hecks/release/runner.rb +60 -38
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +15 -39
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +50 -104
- data/lib/hecks/runtime/dispatcher.rb +134 -243
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +14 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +109 -194
- data/lib/hecks/runtime/outbox.rb +39 -262
- data/lib/hecks/runtime/policy_interpreter.rb +43 -202
- data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
- data/lib/hecks/runtime/query_interpreter.rb +122 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +28 -87
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +213 -227
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +156 -247
- data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +162 -760
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +15 -84
- data/lib/hecks/runtime.rb +35 -69
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +155 -582
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +52 -90
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +478 -12
- data/lib/hecks/facade/cli_door.rb +0 -178
- data/lib/hecks/facade/cli_runner.rb +0 -271
- data/lib/hecks/facade/handle.rb +0 -293
- data/lib/hecks/facade/json_door.rb +0 -247
- data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
- data/lib/hecks/facade/surface/chapter.rb +0 -116
- data/lib/hecks/facade/surface.rb +0 -61
- data/lib/hecks/mcp_door_scope.rb +0 -176
data/lib/hecks/projector.rb
CHANGED
|
@@ -1,60 +1,13 @@
|
|
|
1
1
|
module Hecks
|
|
2
|
-
# A named registry of "canonical IR in, external artifact out" tools
|
|
3
|
-
#
|
|
4
|
-
# such tool was its own thing with its own call shape: `Exporter`
|
|
5
|
-
# (registry-wide, consumed directly by bin/ir, bin/project_rust, and
|
|
6
|
-
# translation/audit's approval digest — untouched by this file, still
|
|
7
|
-
# exactly what those three read), and `RustProjection::Projector`
|
|
8
|
-
# (`rust/project.rb`, a whole separate Ruby program under a
|
|
9
|
-
# confusingly-identical module name) are the two that already exist.
|
|
10
|
-
# Neither is registered here — retrofitting either is real, separate
|
|
11
|
-
# work (Rust's generator is a whole second toolchain; a UL/OIDC
|
|
12
|
-
# projector doesn't exist yet at all) — but `:ir` is, as a genuine,
|
|
13
|
-
# working, golden-tested example of the shape every future projector
|
|
14
|
-
# (`:rust`, `:ul`, `:openid`, ...) is meant to follow.
|
|
2
|
+
# A named registry of "canonical IR in, external artifact out" tools, each
|
|
3
|
+
# taking one bluebook's IR and answering a derived artifact (`:ir`, `:docs`, ...).
|
|
15
4
|
#
|
|
16
|
-
#
|
|
17
|
-
# every real projection target (Rust/UL/OIDC all project one domain at
|
|
18
|
-
# a time), and deliberately narrower than `Exporter.call`'s own
|
|
19
|
-
# multi-domain shape.
|
|
5
|
+
# Projector.call(:ir, bluebook: chapter)
|
|
20
6
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# a projection takes a chapter's declaration and answers something
|
|
27
|
-
# that describes the domain: its IR, its storage shape, an OIDC scope
|
|
28
|
-
# manifest, the parser's keyword table, the reference pages. Inert,
|
|
29
|
-
# derived, and runnable against any chapter that carries what it
|
|
30
|
-
# declares it needs. These are what `register` holds.
|
|
31
|
-
#
|
|
32
|
-
# an export takes a declaration and its bindings and answers
|
|
33
|
-
# something that is the domain, running elsewhere — rust/project.rb's
|
|
34
|
-
# generated crate, the WASM artifact, the CloudFormation template
|
|
35
|
-
# `lib/hecks/projections/deploy` renders. It needs the
|
|
36
|
-
# `.world`/`.hecksagon` a projection never looks at, because a
|
|
37
|
-
# running system has to know how it is wired. A target that needs
|
|
38
|
-
# this declares `needs_world: true` (`Target#projects_as`) and reads
|
|
39
|
-
# `options.fetch(:world)`; `Projector.call`'s own `world:` keyword is
|
|
40
|
-
# what carries it, merged into `options` before the target ever runs.
|
|
41
|
-
#
|
|
42
|
-
# a state projection takes records — a domain after dispatch — and is
|
|
43
|
-
# a read-model question wearing the same word.
|
|
44
|
-
# `bin/expression_projection` is the one of these: its operators are
|
|
45
|
-
# not declared anywhere, they are what exists after
|
|
46
|
-
# `Grammar.expression` replays expression_operators.json's ledger of
|
|
47
|
-
# dispatches. Converting it into this registry would be a category
|
|
48
|
-
# error, however much its name suggests otherwise.
|
|
49
|
-
#
|
|
50
|
-
# ## One word, three other meanings
|
|
51
|
-
#
|
|
52
|
-
# Worth naming too, because grepping "projection" turns all of these up
|
|
53
|
-
# and none is the above:
|
|
54
|
-
#
|
|
55
|
-
# Ports::Projection read-model catch-up, events folded into state
|
|
56
|
-
# bin/project forces that catch-up by hand
|
|
57
|
-
# RustProjection rust/project.rb's own separate toolchain
|
|
7
|
+
# A projection is inert and derived from a chapter's declaration. An export
|
|
8
|
+
# (rust crate, WASM, CloudFormation) also needs `.world` bindings and declares
|
|
9
|
+
# `needs_world: true`. State projections (`hecks project_expression_tables`) and
|
|
10
|
+
# `Ports::Projection` read-model catch-up are different things and not registered.
|
|
58
11
|
module Projector
|
|
59
12
|
class UnknownProjector < StandardError; end
|
|
60
13
|
# A chapter-scoped projector was handed something that is not a chapter.
|
|
@@ -62,14 +15,8 @@ module Hecks
|
|
|
62
15
|
|
|
63
16
|
module_function
|
|
64
17
|
|
|
65
|
-
# `projector` needs only to answer `call(bluebook:, options:)` — a
|
|
66
|
-
# module, a class with a class method, or any object responding to
|
|
67
|
-
# `call` all work. Re-registering a name replaces it outright,
|
|
68
|
-
# deliberately unguarded: a spec re-registering a stub under the same
|
|
69
|
-
# name between examples is the ordinary case, not a footgun to fence
|
|
70
|
-
# against.
|
|
71
18
|
# Adds `projector` to the registry under `name`, replacing anything
|
|
72
|
-
# already registered there.
|
|
19
|
+
# already registered there (deliberately unguarded, so specs can stub).
|
|
73
20
|
#
|
|
74
21
|
# @param name [String, Symbol] the key `projector` is looked up by (converted to a symbol)
|
|
75
22
|
# @param projector [Module, Class, #call] anything answering `call(bluebook:, options:)`
|
|
@@ -81,24 +28,14 @@ module Hecks
|
|
|
81
28
|
# Runs the projector registered under `name` against `bluebook`,
|
|
82
29
|
# after refusing a construct it does not admit.
|
|
83
30
|
#
|
|
84
|
-
# `bluebook:` is kept as the keyword because it is the shipped
|
|
85
|
-
# spelling and every existing caller uses it — but what it accepts is
|
|
86
|
-
# any construct that emits IR, and `admits!` is what decides whether
|
|
87
|
-
# this target can actually take the one handed over.
|
|
88
|
-
#
|
|
89
31
|
# @param name [String, Symbol] the registered projector's key
|
|
90
|
-
# @param bluebook [Bluebook::Behaviour::Chapter, Hecks::IR] the
|
|
91
|
-
# IR-emitting construct to project
|
|
32
|
+
# @param bluebook [Bluebook::Behaviour::Chapter, Hecks::IR] the construct to project
|
|
92
33
|
# @param options [Hash] projector-specific options, passed through unchanged
|
|
93
|
-
# @param world [Bluebook::World, nil]
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
# receives it as a separate argument.
|
|
97
|
-
# @return [Object] whatever the projector's own `call` returns: typically a
|
|
98
|
-
# `Hash`/`String` artifact, or a `Hash{String => String}` file tree
|
|
34
|
+
# @param world [Bluebook::World, nil] bindings an export needs (`needs_world: true`);
|
|
35
|
+
# merged into `options[:world]`
|
|
36
|
+
# @return [Object] whatever the projector's own `call` returns
|
|
99
37
|
# @raise [UnknownProjector] if no projector is registered under `name`
|
|
100
|
-
# @raise [WrongConstruct] if `bluebook` lacks
|
|
101
|
-
# projector requires, or if the projector needs `world:` and none is given
|
|
38
|
+
# @raise [WrongConstruct] if `bluebook` lacks what the projector requires
|
|
102
39
|
def call(name, bluebook:, options: {}, world: nil)
|
|
103
40
|
projector = registry.fetch(name.to_sym) do
|
|
104
41
|
raise UnknownProjector, "no projector registered for #{name.inspect} — registered: #{registered.sort.inspect}"
|
|
@@ -107,31 +44,17 @@ module Hecks
|
|
|
107
44
|
projector.call(bluebook: bluebook, options: world ? options.merge(world: world) : options)
|
|
108
45
|
end
|
|
109
46
|
|
|
110
|
-
# Refuses `construct` if it lacks a capability or declared aggregate
|
|
111
|
-
# `
|
|
112
|
-
# this is what enforces that, before the projector runs.
|
|
113
|
-
#
|
|
114
|
-
# One check covers both shapes. An ordinary construct includes its
|
|
115
|
-
# capabilities and a class-shaped one — Command, Entity, ValueObject
|
|
116
|
-
# — extends them, and `is_a?` consults the singleton chain, so it
|
|
117
|
-
# answers for an extended module as readily as an included one. This
|
|
118
|
-
# started as two checks on the assumption it would not; a spec
|
|
119
|
-
# asserting the assumption failed, which is the only reason the
|
|
120
|
-
# redundant half was noticed.
|
|
47
|
+
# Refuses `construct` if it lacks a capability or declared aggregate `projector` requires.
|
|
48
|
+
# One `is_a?` check covers included and extended capabilities alike.
|
|
121
49
|
#
|
|
122
50
|
# @param name [String, Symbol] the projector's registered key, used in the message
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# @param construct [Bluebook::Behaviour::Chapter, Hecks::IR] the chapter or
|
|
128
|
-
# IR-emitting construct offered to the projector
|
|
129
|
-
# @param world [Bluebook::World, nil] the `world:` given to `Projector.call`, checked
|
|
130
|
-
# against the target's own `needs_world:` declaration
|
|
51
|
+
# @param projector [Module, Class, #call] the target; consulted for `projection_requires`,
|
|
52
|
+
# `projection_declares` and `projection_needs_world?` when it answers them
|
|
53
|
+
# @param construct [Bluebook::Behaviour::Chapter, Hecks::IR] the construct offered
|
|
54
|
+
# @param world [Bluebook::World, nil] the `world:` given to `Projector.call`
|
|
131
55
|
# @return [void]
|
|
132
|
-
# @raise [WrongConstruct] if
|
|
133
|
-
#
|
|
134
|
-
# and `world` is nil
|
|
56
|
+
# @raise [WrongConstruct] if a required capability or aggregate is missing, or the
|
|
57
|
+
# projector needs `world:` and `world` is nil
|
|
135
58
|
def admits!(name, projector, construct, world = nil)
|
|
136
59
|
needed = projector.respond_to?(:projection_requires) ? projector.projection_requires : []
|
|
137
60
|
missing = needed.reject { |capability| capable?(construct, capability) }
|
|
@@ -190,11 +113,8 @@ module Hecks
|
|
|
190
113
|
@registry ||= {}
|
|
191
114
|
end
|
|
192
115
|
|
|
193
|
-
#
|
|
194
|
-
# (`
|
|
195
|
-
# (`:oidc`). Both resolve here, so the constant form is added
|
|
196
|
-
# surface rather than a replacement — every `Projector.call(:ir, ...)`
|
|
197
|
-
# written before this existed keeps working untouched.
|
|
116
|
+
# Resolves a target given as a constant (`Projections::OIDC`) or a bare
|
|
117
|
+
# key (`:oidc`) to the key it is registered under.
|
|
198
118
|
#
|
|
199
119
|
# @param target [String, Symbol, #projection_key] a registered key, or a target
|
|
200
120
|
# that declared its own key with `Target#projects_as`
|
|
@@ -205,15 +125,10 @@ module Hecks
|
|
|
205
125
|
target
|
|
206
126
|
end
|
|
207
127
|
|
|
208
|
-
#
|
|
209
|
-
# returns an artifact and never touches disk, which is what lets
|
|
210
|
-
# spec/projector_spec.rb compare `:ir`'s output against a golden
|
|
211
|
-
# fixture without a tmpdir. `out:` is the only thing that writes.
|
|
128
|
+
# Writes `artifact` to `out`; a projector itself never touches disk.
|
|
212
129
|
#
|
|
213
|
-
# `as:` comes from the projection's
|
|
214
|
-
#
|
|
215
|
-
# Hash that simply happens to hold strings are the same object to
|
|
216
|
-
# Ruby; only the projection knows which it meant.
|
|
130
|
+
# `as:` comes from the projection's `emits:` declaration, since a file tree
|
|
131
|
+
# and a Hash of strings are the same object to Ruby.
|
|
217
132
|
#
|
|
218
133
|
# @param artifact [Hash, String] the projector's output; a file tree when `as: :files`
|
|
219
134
|
# @param out [String] the path to write to; a directory when `as: :files`
|
|
@@ -226,8 +141,7 @@ module Hecks
|
|
|
226
141
|
out
|
|
227
142
|
end
|
|
228
143
|
|
|
229
|
-
#
|
|
230
|
-
# report what happened without re-deriving it from the tree.
|
|
144
|
+
# Writes each `files` entry under `directory`, answering the paths written.
|
|
231
145
|
#
|
|
232
146
|
# @param files [Hash{String => String}] relative path => contents
|
|
233
147
|
# @param directory [String] the directory to write the tree under
|
|
@@ -249,8 +163,7 @@ require "json"
|
|
|
249
163
|
require_relative "projector/exporter"
|
|
250
164
|
require_relative "projector/ir_projector"
|
|
251
165
|
require_relative "projector/target"
|
|
252
|
-
#
|
|
253
|
-
# else — so unlike a target they are safe to pull in from here.
|
|
166
|
+
# These need only `Naming`, not this file, so they are safe to load from here.
|
|
254
167
|
require_relative "projector/docs_projector"
|
|
255
168
|
require_relative "projector/narrate_projector"
|
|
256
169
|
require_relative "projector/cli_projector"
|
|
@@ -260,9 +173,5 @@ Hecks::Projector.register(:docs, Hecks::Projector::DocsProjector)
|
|
|
260
173
|
Hecks::Projector.register(:narrate, Hecks::Projector::NarrateProjector)
|
|
261
174
|
Hecks::Projector.register(:cli, Hecks::Projector::CliProjector)
|
|
262
175
|
|
|
263
|
-
#
|
|
264
|
-
#
|
|
265
|
-
# needs `Target` and the registry), so requiring them back from here
|
|
266
|
-
# would close a genuine `circular require considered harmful` loop. Ruby
|
|
267
|
-
# tolerates it; the warning is still right, and load order is the kind of
|
|
268
|
-
# thing that only breaks once someone requires a target on its own.
|
|
176
|
+
# Targets are required from lib/hecks.rb, not here: each requires this file, so
|
|
177
|
+
# requiring them back would close a circular require.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Binds the `Agent` port to `Agent`; `hecks quality_control mine_combinations` asks it to write candidate domains.
|
|
2
|
+
# Required by name, not relative, so a copy of this directory shares the one implementation loaded.
|
|
3
|
+
require "hecks/quality_control/adapters/agent"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "Agent" do
|
|
6
|
+
port "Agent"
|
|
7
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
require "shellwords"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
# The `Agent` port's adapter: hands a prompt to an agent on the command line and lets it work
|
|
9
|
+
# in the checkout, the way `hecks quality_control mine_combinations` asks one for candidate
|
|
10
|
+
# domains.
|
|
11
|
+
#
|
|
12
|
+
# Not the interviewer behind the framework's `agent` port (`ClaudeCode`), which reads one
|
|
13
|
+
# JSON answer back: this agent edits files, so the only answer is whether it finished.
|
|
14
|
+
class Agent
|
|
15
|
+
# An agent that could not start, or ended with a failure.
|
|
16
|
+
class Failed < StandardError; end
|
|
17
|
+
|
|
18
|
+
# The command run when neither the caller nor `QA_MINER_AGENT` names one.
|
|
19
|
+
DEFAULT_COMMAND = ["claude", "-p", "--permission-mode", "acceptEdits",
|
|
20
|
+
"--allowedTools", "Read,Glob,Grep,Write,Edit"].freeze
|
|
21
|
+
|
|
22
|
+
# @param aggregate [Object, nil] unused
|
|
23
|
+
# @param settings [Hash] unused
|
|
24
|
+
# @param root [String, nil] unused
|
|
25
|
+
def initialize(aggregate: nil, settings: {}, root: nil); end
|
|
26
|
+
|
|
27
|
+
# The command an ask runs.
|
|
28
|
+
#
|
|
29
|
+
# @param command [String, Array<String>, nil] a command line, or its words
|
|
30
|
+
# @return [Array<String>] `command` as words; `QA_MINER_AGENT` else `DEFAULT_COMMAND` when nil
|
|
31
|
+
def command_for(command = nil)
|
|
32
|
+
command ||= ENV.fetch("QA_MINER_AGENT", nil)
|
|
33
|
+
return DEFAULT_COMMAND unless command
|
|
34
|
+
|
|
35
|
+
command.is_a?(String) ? Shellwords.split(command) : command
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Runs the agent with `prompt` on its standard input.
|
|
39
|
+
#
|
|
40
|
+
# @param prompt [String] what the agent is asked to do
|
|
41
|
+
# @param command [String, Array<String>, nil] the agent's command; see `command_for`
|
|
42
|
+
# @param chdir [String] the directory the agent works in
|
|
43
|
+
# @param log [String, nil] a file the agent's output is appended to
|
|
44
|
+
# @return [String] the agent's output
|
|
45
|
+
# @raise [Failed] when the agent cannot start or exits non-zero
|
|
46
|
+
def ask(prompt:, chdir:, command: nil, log: nil)
|
|
47
|
+
words = command_for(command)
|
|
48
|
+
output, status = Open3.capture2e(*words, stdin_data: prompt, chdir: chdir)
|
|
49
|
+
File.open(log, "a") { |file| file.puts(output) } if log
|
|
50
|
+
return output if status.success?
|
|
51
|
+
|
|
52
|
+
raise Failed, "agent exited #{status.exitstatus}: #{output.lines.last(5).join.strip}"
|
|
53
|
+
rescue SystemCallError => e
|
|
54
|
+
raise Failed, "agent could not start (#{words.first}): #{e.message}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Binds the `AngleTools` port to `AngleTools`, which answers `Angle`'s query: the seed of the backlog.
|
|
2
|
+
# Required by name, not relative, so a copy of this directory shares the one implementation loaded.
|
|
3
|
+
require "hecks/quality_control/adapters/angle_tools"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "AngleTools" do
|
|
6
|
+
port "AngleTools"
|
|
7
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "qa_tool"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
# The `AngleTools` port's adapter: answers `Angle`'s query by running the seed of the backlog.
|
|
8
|
+
class AngleTools < QaTool
|
|
9
|
+
# @return [Hash] `text:` each starting lead's outcome: proposed, or already on file
|
|
10
|
+
def seed
|
|
11
|
+
run_command("qa_seed_angles")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module QA
|
|
5
|
+
# Records what CI said about one commit as a `QualityControl::Clearance`.
|
|
6
|
+
module ClearanceRecorder
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# Conclusions that count as green; same vocabulary as `GithubChecks::PASSING`.
|
|
10
|
+
# A `check_suite` conclusion aggregates one GitHub App's runs only, so callers decide
|
|
11
|
+
# which suites may pass a commit.
|
|
12
|
+
PASSING = %w[success neutral skipped].freeze
|
|
13
|
+
|
|
14
|
+
# Returns the Clearance for `commit`, starting one if none exists.
|
|
15
|
+
# `AlreadyExists` from a redelivered webhook racing another start is swallowed.
|
|
16
|
+
def ensure_started(commit)
|
|
17
|
+
QualityControl::Clearance.find(commit) ||
|
|
18
|
+
QualityControl::Clearance.start!(commit: { value: commit })
|
|
19
|
+
rescue Hecks::Runtime::AlreadyExists
|
|
20
|
+
QualityControl::Clearance.find(commit)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Starts and settles the Clearance for `commit`; the first verdict recorded stands.
|
|
24
|
+
# An already-settled record is returned unchanged, so redelivery cannot raise
|
|
25
|
+
# `LifecycleRefused`.
|
|
26
|
+
#
|
|
27
|
+
# @return the settled Clearance
|
|
28
|
+
def record(commit:, passed:, summary:)
|
|
29
|
+
cleared = ensure_started(commit)
|
|
30
|
+
return cleared if cleared.status != "running"
|
|
31
|
+
|
|
32
|
+
passed ? cleared.passed!(summary: { value: summary }) : cleared.failed!(refusal: { value: summary })
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Binds the `ClearanceTools` port to `ClearanceTools`, which answers `Clearance`'s query: the PR check.
|
|
2
|
+
# Required by name, not relative, so a copy of this directory shares the one implementation loaded.
|
|
3
|
+
require "hecks/quality_control/adapters/clearance_tools"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "ClearanceTools" do
|
|
6
|
+
port "ClearanceTools"
|
|
7
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "qa_tool"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
# The `ClearanceTools` port's adapter: answers `Clearance`'s query by running the PR check. A
|
|
8
|
+
# newly red PR ends the check with status 2, which is an answer; anything else it calls an
|
|
9
|
+
# error is refused with its report.
|
|
10
|
+
class ClearanceTools < QaTool
|
|
11
|
+
# @return [Hash] `text:` what the check found for each open PR the ledger tracks
|
|
12
|
+
def check_pull_requests
|
|
13
|
+
run_command("qa_pr_check", answers: [0, 2])
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Binds the `GitPr` port to `GitPr`; the ledger's scripts ask it for every `git` and `gh` call.
|
|
2
|
+
# Required by name, not relative, so a copy of this directory shares the one implementation loaded.
|
|
3
|
+
require "hecks/quality_control/adapters/git_pr"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "GitPr" do
|
|
6
|
+
port "GitPr"
|
|
7
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
# The `GitPr` port's adapter: the `git` and `gh` calls behind a pull request the QA practice
|
|
9
|
+
# opens or checks, and the two rules that need the outside world to answer.
|
|
10
|
+
#
|
|
11
|
+
# The rules a ledger record can answer (the branch prefix, the bug being fixed, the angle
|
|
12
|
+
# being under investigation) are `given`s on `Patch.Open` and `Improvement.Open`. The two
|
|
13
|
+
# here need the repository or a count of today's pull requests: the per-day cap and the fix
|
|
14
|
+
# commit being an ancestor of `HEAD`.
|
|
15
|
+
class GitPr
|
|
16
|
+
# A rule the adapter enforces refused the request; nothing was opened.
|
|
17
|
+
class Refusal < StandardError; end
|
|
18
|
+
|
|
19
|
+
# `git` or `gh` could not do what was asked, whatever the request.
|
|
20
|
+
class CommandFailed < StandardError; end
|
|
21
|
+
|
|
22
|
+
# A commit sha as it may be handed to `git` as a revision.
|
|
23
|
+
SHA_PATTERN = /\A[0-9a-fA-F]{7,40}\z/
|
|
24
|
+
|
|
25
|
+
# The remote a branch is pushed to and `gh pr create --head` reads it from.
|
|
26
|
+
REMOTE = "origin"
|
|
27
|
+
|
|
28
|
+
# What `gh pr view` says when the branch simply has no pull request.
|
|
29
|
+
NO_PR = /no pull requests? found/i
|
|
30
|
+
|
|
31
|
+
# The fields `gh pr view` is asked for when a PR is opened or looked up by branch.
|
|
32
|
+
VIEW_FIELDS = "number,url,headRefName,headRefOid,title,state"
|
|
33
|
+
|
|
34
|
+
# @param aggregate [Object, nil] unused
|
|
35
|
+
# @param settings [Hash] unused
|
|
36
|
+
# @param root [String, nil] unused
|
|
37
|
+
# @param repo_dir [String] the checkout `git` and `gh` run in; `QA_REPO_DIR` picks one so a
|
|
38
|
+
# spec can use a throwaway repository and a fake `gh`
|
|
39
|
+
def initialize(aggregate: nil, settings: {}, root: nil, repo_dir: ENV.fetch("QA_REPO_DIR", Dir.pwd))
|
|
40
|
+
@repo_dir = repo_dir
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [String] the checkout's current branch
|
|
44
|
+
# @raise [Refusal] when the directory is not a git checkout
|
|
45
|
+
def branch
|
|
46
|
+
out, _err, status = git("rev-parse", "--abbrev-ref", "HEAD")
|
|
47
|
+
raise Refusal, "not a git checkout at #{@repo_dir}" unless status.success?
|
|
48
|
+
|
|
49
|
+
out
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [String] the commit `HEAD` names
|
|
53
|
+
def head = git("rev-parse", "HEAD").first
|
|
54
|
+
|
|
55
|
+
# Refuses a checkout with uncommitted work, since a PR opened from it would not carry it.
|
|
56
|
+
#
|
|
57
|
+
# @return [void]
|
|
58
|
+
# @raise [Refusal] when `git status` cannot be read or reports changes
|
|
59
|
+
def assert_clean_tree!
|
|
60
|
+
dirty, _err, status = git("status", "--porcelain")
|
|
61
|
+
raise Refusal, "could not read git status at #{@repo_dir}" unless status.success?
|
|
62
|
+
return if dirty.empty?
|
|
63
|
+
|
|
64
|
+
raise Refusal, "the working tree at #{@repo_dir} is dirty — commit or discard first:\n#{dirty}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Refuses one more pull request than the day's cap allows; a cap of zero is no cap.
|
|
68
|
+
#
|
|
69
|
+
# @param opened_today [Integer] how many PRs the ledger recorded since local midnight
|
|
70
|
+
# @param cap [Integer] `PR_CAP_PER_DAY`
|
|
71
|
+
# @return [void]
|
|
72
|
+
# @raise [Refusal] when `opened_today` has reached a positive `cap`
|
|
73
|
+
def assert_under_daily_cap!(opened_today:, cap:)
|
|
74
|
+
return unless cap.positive? && opened_today >= cap
|
|
75
|
+
|
|
76
|
+
raise Refusal, "#{opened_today} PR(s) already opened since local midnight, and " \
|
|
77
|
+
"QualityControlDials::PR_CAP_PER_DAY is #{cap} — leave this as an open Bug/Angle " \
|
|
78
|
+
"and open it tomorrow, or raise the dial in qa/settings.yml"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Refuses a fix commit that is not part of the branch being opened.
|
|
82
|
+
#
|
|
83
|
+
# @param commit [String] the commit the ledger says fixes the bug
|
|
84
|
+
# @param owner [String] what the commit belongs to, worded into the refusal (`"BUG#1"`)
|
|
85
|
+
# @return [void]
|
|
86
|
+
# @raise [Refusal] when `commit` is not a sha or not an ancestor of `HEAD`
|
|
87
|
+
def assert_ancestor!(commit:, owner:)
|
|
88
|
+
assert_sha!(commit, owner)
|
|
89
|
+
_out, _err, status = git("merge-base", "--is-ancestor", "--", commit, "HEAD")
|
|
90
|
+
return if status.success?
|
|
91
|
+
|
|
92
|
+
raise Refusal, "#{owner}'s own fix commit #{commit[0, 7]} is not an ancestor of HEAD " \
|
|
93
|
+
"(#{head[0, 7]}) on #{branch} — the PR must carry the commit the ledger says fixes it"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Refuses a fix commit that the pushed branch does not carry: `gh pr create --head` opens
|
|
97
|
+
# the pull request from the remote branch, not from the local checkout.
|
|
98
|
+
#
|
|
99
|
+
# @param branch [String] the head branch
|
|
100
|
+
# @param commit [String] the commit the ledger says fixes the bug
|
|
101
|
+
# @param owner [String] what the commit belongs to, worded into the refusal
|
|
102
|
+
# @return [void]
|
|
103
|
+
# @raise [Refusal] when the branch is not on the remote, or its tip does not carry `commit`
|
|
104
|
+
def assert_pushed!(branch:, commit:, owner:)
|
|
105
|
+
assert_sha!(commit, owner)
|
|
106
|
+
out, err, status = git("ls-remote", "--heads", REMOTE, "refs/heads/#{branch}")
|
|
107
|
+
raise Refusal, "could not read #{REMOTE} for #{branch}: #{err}" unless status.success?
|
|
108
|
+
|
|
109
|
+
tip = out.split.first.to_s
|
|
110
|
+
raise Refusal, "#{branch} is not pushed to #{REMOTE} — push it before opening the PR" if tip.empty?
|
|
111
|
+
|
|
112
|
+
assert_carries!(tip, commit, owner, "the pushed #{REMOTE}/#{branch}")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Refuses a pull request whose head does not carry the fix commit.
|
|
116
|
+
#
|
|
117
|
+
# @param head [String] the PR's head commit, as `gh` reports it
|
|
118
|
+
# @param commit [String] the commit the ledger says fixes the bug
|
|
119
|
+
# @param owner [String] what the commit belongs to, worded into the refusal
|
|
120
|
+
# @return [void]
|
|
121
|
+
# @raise [Refusal] when `head` is not a sha, or does not carry `commit`
|
|
122
|
+
def assert_pr_head!(head:, commit:, owner:)
|
|
123
|
+
assert_sha!(commit, owner)
|
|
124
|
+
assert_sha!(head, "the PR head")
|
|
125
|
+
assert_carries!(head, commit, owner, "the PR head")
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# The open PR for a branch.
|
|
129
|
+
#
|
|
130
|
+
# @param branch [String] the head branch
|
|
131
|
+
# @return [Hash{Symbol => Object}, nil] `gh pr view`'s fields, or nil when no PR is open
|
|
132
|
+
# @raise [CommandFailed] when `gh` failed for any reason but the branch having no PR
|
|
133
|
+
def open_pull_request(branch)
|
|
134
|
+
out, err, status = gh("pr", "view", branch, "--json", VIEW_FIELDS)
|
|
135
|
+
unless status.success?
|
|
136
|
+
return nil if err.match?(NO_PR)
|
|
137
|
+
|
|
138
|
+
raise CommandFailed, "gh pr view #{branch} failed — #{err.empty? ? out : err}"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
view = JSON.parse(out, symbolize_names: true)
|
|
142
|
+
view[:state] == "OPEN" ? view : nil
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Opens a PR from `branch`.
|
|
146
|
+
#
|
|
147
|
+
# @param branch [String] the head branch
|
|
148
|
+
# @param title [String] the PR's title
|
|
149
|
+
# @param body [String] the PR's description
|
|
150
|
+
# @param draft [Boolean] open it as a draft
|
|
151
|
+
# @return [String] what `gh pr create` printed, the PR's URL
|
|
152
|
+
# @raise [CommandFailed] when `gh` refuses
|
|
153
|
+
def create_pull_request(branch:, title:, body:, draft: false)
|
|
154
|
+
args = ["pr", "create", "--head", branch, "--title", title, "--body", body]
|
|
155
|
+
args << "--draft" if draft
|
|
156
|
+
out, err, status = gh(*args)
|
|
157
|
+
raise CommandFailed, "gh pr create failed — #{err.empty? ? out : err}" unless status.success?
|
|
158
|
+
|
|
159
|
+
out
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Queues a squash merge for when the PR's checks pass.
|
|
163
|
+
#
|
|
164
|
+
# @param number [Integer] the PR's number
|
|
165
|
+
# @return [void]
|
|
166
|
+
# @raise [CommandFailed] when `gh` refuses
|
|
167
|
+
def merge_when_green(number)
|
|
168
|
+
_out, err, status = gh("pr", "merge", number.to_s, "--auto", "--squash")
|
|
169
|
+
raise CommandFailed, "gh pr merge --auto failed — #{err}" unless status.success?
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# A tracked PR's state and head commit, read live: a push mints a new commit to clear.
|
|
173
|
+
#
|
|
174
|
+
# @param number [Integer] the PR's number
|
|
175
|
+
# @return [Hash{Symbol => Object}] `state`, `headRefOid` and `url`
|
|
176
|
+
# @raise [CommandFailed] when `gh` cannot read it
|
|
177
|
+
def pull_request(number)
|
|
178
|
+
parse(gh("pr", "view", number.to_s, "--json", "state,headRefOid,url"), "gh pr view failed")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# A tracked PR's checks, as `gh` reports them.
|
|
182
|
+
#
|
|
183
|
+
# @param number [Integer] the PR's number
|
|
184
|
+
# @return [Array<Hash{Symbol => Object}>] each check's `name`, `state`, `bucket`, `workflow`
|
|
185
|
+
# @raise [CommandFailed] when `gh` cannot read them
|
|
186
|
+
def checks(number)
|
|
187
|
+
parse(gh("pr", "checks", number.to_s, "--json", "name,state,bucket,workflow"), "gh pr checks failed")
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
private
|
|
191
|
+
|
|
192
|
+
def assert_sha!(value, owner)
|
|
193
|
+
return if value.to_s.match?(SHA_PATTERN)
|
|
194
|
+
|
|
195
|
+
raise Refusal, "#{owner}'s commit #{value.to_s.inspect} does not look like a sha"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def assert_carries!(tip, commit, owner, label)
|
|
199
|
+
_out, _err, status = git("merge-base", "--is-ancestor", "--", commit, tip)
|
|
200
|
+
return if status.success?
|
|
201
|
+
|
|
202
|
+
raise Refusal, "#{owner}'s own fix commit #{commit[0, 7]} is not an ancestor of #{label} " \
|
|
203
|
+
"(#{tip[0, 7]}) — the PR must carry the commit the ledger says fixes it"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def parse(result, failure)
|
|
207
|
+
out, err, status = result
|
|
208
|
+
raise CommandFailed, "#{failure} — #{err.strip.empty? ? out.strip : err.strip}" unless status.success?
|
|
209
|
+
|
|
210
|
+
JSON.parse(out, symbolize_names: true)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def git(*) = run_tool("git", *)
|
|
214
|
+
|
|
215
|
+
def gh(*) = run_tool("gh", *)
|
|
216
|
+
|
|
217
|
+
def run_tool(tool, *)
|
|
218
|
+
out, err, status = Open3.capture3(tool, *, chdir: @repo_dir)
|
|
219
|
+
[out.strip, err.strip, status]
|
|
220
|
+
rescue Errno::ENOENT
|
|
221
|
+
raise Refusal, "#{tool} is not installed or not on PATH (or #{@repo_dir} is missing) — " \
|
|
222
|
+
"the practice cannot open or check a pull request without it"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Binds the `CI` port to `GithubChecks` for any boot that loads the QualityControl chapter.
|
|
2
|
+
# The implementation is required by name, not relative to this file, because the `.adapter` glob
|
|
3
|
+
# never loads the sibling `.rb` and a copy of this directory (a fuzz boot) must share the one
|
|
4
|
+
# implementation already loaded.
|
|
5
|
+
require "hecks/quality_control/adapters/github_checks"
|
|
6
|
+
|
|
7
|
+
Hecks.adapter "GithubChecks" do
|
|
8
|
+
port "CI"
|
|
9
|
+
end
|