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,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
require_relative "../release/runner"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module CLI
|
|
8
|
+
# The command behind `hecks publish`: tags the merged release commit, publishes the gem, and
|
|
9
|
+
# gets `@hecks/client` published to npm. See "Releasing" in CONTRIBUTING.md for the release PR.
|
|
10
|
+
#
|
|
11
|
+
# hecks publish --dry-run # every check and build, nothing tagged or published
|
|
12
|
+
# hecks publish # tag, gem, then wait for CI to publish the client
|
|
13
|
+
module Release
|
|
14
|
+
# The flags a run starts with, before any is named.
|
|
15
|
+
DEFAULT_FLAGS = { dry_run: false, gem_only: false, npm_only: false, npm_local: false,
|
|
16
|
+
no_wait: false, yes: false }.freeze
|
|
17
|
+
|
|
18
|
+
module_function
|
|
19
|
+
|
|
20
|
+
# Parses the flags and runs the release.
|
|
21
|
+
#
|
|
22
|
+
# @param argv [Array<String>] the command line's flags
|
|
23
|
+
# @param root [String] the repository root the release runs in
|
|
24
|
+
# @return [Integer] the release's exit status, or 2 for a flag it does not know
|
|
25
|
+
def call(argv, root:)
|
|
26
|
+
argv = argv.dup
|
|
27
|
+
flags = DEFAULT_FLAGS.dup
|
|
28
|
+
parser = parser_for(flags)
|
|
29
|
+
begin
|
|
30
|
+
parser.parse!(argv)
|
|
31
|
+
raise OptionParser::InvalidArgument, argv.join(" ") unless argv.empty?
|
|
32
|
+
|
|
33
|
+
return 0 if flags.delete(:help)
|
|
34
|
+
|
|
35
|
+
options = Hecks::Release::Runner::Options.new(**flags)
|
|
36
|
+
rescue OptionParser::ParseError, ArgumentError => e
|
|
37
|
+
warn "hecks publish: #{e.message}"
|
|
38
|
+
warn parser
|
|
39
|
+
return 2
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Hecks::Release::Runner.new(root: root, options: options).call
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param flags [Hash{Symbol => Boolean}] filled in as the parser reads each flag
|
|
46
|
+
# @return [OptionParser] the parser for `hecks publish`'s flags
|
|
47
|
+
def parser_for(flags)
|
|
48
|
+
OptionParser.new do |opts|
|
|
49
|
+
opts.banner = "Usage: hecks publish [--dry-run] [--gem-only | --npm-only] [--npm-local | --no-wait] [--yes]"
|
|
50
|
+
opts.separator("Tags the merged release commit, publishes the gem, and gets @hecks/client published.")
|
|
51
|
+
opts.separator("By default CI publishes the client from the tag and this waits for it.")
|
|
52
|
+
opts.on("--dry-run", "run every check and build; tag, push and publish nothing") { flags[:dry_run] = true }
|
|
53
|
+
opts.on("--gem-only", "publish the gem only") { flags[:gem_only] = true }
|
|
54
|
+
opts.on("--npm-only", "skip the gem: wait for CI's publish, or with --npm-local publish from here") do
|
|
55
|
+
flags[:npm_only] = true
|
|
56
|
+
end
|
|
57
|
+
opts.on("--npm-local", "publish @hecks/client from this machine (first publish, or CI is down)") do
|
|
58
|
+
flags[:npm_local] = true
|
|
59
|
+
end
|
|
60
|
+
opts.on("--no-wait", "do not wait for CI's publish to reach npm") { flags[:no_wait] = true }
|
|
61
|
+
opts.on("--yes", "answer the confirmations yes") { flags[:yes] = true }
|
|
62
|
+
opts.on("--help", "print this usage") do
|
|
63
|
+
puts opts
|
|
64
|
+
flags[:help] = true
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "../release/runner/commands"
|
|
5
|
+
require_relative "../hecks/adapters/codebase/gem_registry"
|
|
6
|
+
require_relative "../version"
|
|
7
|
+
|
|
8
|
+
module Hecks
|
|
9
|
+
module CLI
|
|
10
|
+
# The command behind `hecks publish_gem` and the release runner's gem step: builds the hecks
|
|
11
|
+
# gem and pushes it to rubygems.org, using a push-scoped API key from 1Password instead of
|
|
12
|
+
# `~/.gem/credentials`. It pushes the version it is given, `Hecks::VERSION` by default.
|
|
13
|
+
module ReleaseGem
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Builds and pushes the gem, refusing unless `op` is installed and the JS client is at the
|
|
17
|
+
# same version (`spec/hecks_client_version_spec.rb` pins that rule too).
|
|
18
|
+
#
|
|
19
|
+
# @param root [String] the repository root the gem is built from
|
|
20
|
+
# @param commands [#run!, #capture, nil] runs the child commands; a real one when nil
|
|
21
|
+
# @param out [IO] where progress goes
|
|
22
|
+
# @param err [IO] where a refusal goes
|
|
23
|
+
# @param version [String] the version to build and push
|
|
24
|
+
# @return [Integer] 0 once pushed, 1 when refused
|
|
25
|
+
def call(root:, commands: nil, out: $stdout, err: $stderr, version: Hecks::VERSION)
|
|
26
|
+
Dir.chdir(root) do
|
|
27
|
+
commands ||= Hecks::Release::Runner::Commands.new
|
|
28
|
+
registry = Hecks::Adapters::Codebase::GemRegistry.new(root: root, commands: commands)
|
|
29
|
+
refusal = refusal_for(root, commands, version)
|
|
30
|
+
if refusal
|
|
31
|
+
err.puts refusal
|
|
32
|
+
return 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
out.puts "Building and pushing hecks-#{version}.gem to rubygems.org " \
|
|
36
|
+
"(1Password will prompt for Touch ID)..."
|
|
37
|
+
registry.push!(version)
|
|
38
|
+
out.puts "Released hecks #{version}."
|
|
39
|
+
0
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @param root [String] the repository root
|
|
44
|
+
# @param commands [#run!, #capture] runs the child commands
|
|
45
|
+
# @param version [String] the version being released
|
|
46
|
+
# @return [String, nil] why the release cannot start, or nil when it can
|
|
47
|
+
def refusal_for(root, commands, version = Hecks::VERSION)
|
|
48
|
+
unless Hecks::Adapters::Codebase::SecretVault.new(commands: commands).installed?
|
|
49
|
+
return "1Password CLI (op) not found. Install: brew install 1password-cli"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
client_version = JSON.parse(File.read(File.join(root, "packages/hecks-client/package.json"))).fetch("version")
|
|
53
|
+
return nil if client_version == version
|
|
54
|
+
|
|
55
|
+
"packages/hecks-client is at #{client_version} but Hecks::VERSION is #{version}; bump the package first."
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "open3"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module CLI
|
|
8
|
+
# The command behind `hecks list_io_parallel_specs`: prints, one per line, the spec files with
|
|
9
|
+
# at least one example matching an RSpec tag filter. ci.yml hands the list to `parallel_rspec`
|
|
10
|
+
# instead of the whole `spec` directory.
|
|
11
|
+
#
|
|
12
|
+
# Given every spec file, parallel_tests ignores the runtime log unless it covers about 67% of
|
|
13
|
+
# them, so a tag-filtered job silently groups by file size. A dry run, not grep, picks the
|
|
14
|
+
# files so inherited tags, `~fuzzing` and shared examples count.
|
|
15
|
+
#
|
|
16
|
+
# The list is committed (`.github/postgres_io_spec_files.txt`). `--write FILE` refreshes it;
|
|
17
|
+
# `--check FILE` (CI's postgres_io_file_list job) fails on a stale list.
|
|
18
|
+
#
|
|
19
|
+
# hecks list_io_parallel_specs '<exclude-pattern regex>' -- --tag io --tag ~fuzzing
|
|
20
|
+
module RspecIoParallelFiles
|
|
21
|
+
module_function
|
|
22
|
+
|
|
23
|
+
# Lists the matching files, writes them, or checks a committed list.
|
|
24
|
+
#
|
|
25
|
+
# @param argv [Array<String>] `--check FILE` or `--write FILE` optionally, the exclude
|
|
26
|
+
# pattern, `--`, then the RSpec tag arguments
|
|
27
|
+
# @param root [String] the checkout whose `spec/` is searched; the dry run runs there
|
|
28
|
+
# @param out [IO] where the list goes when neither flag is given
|
|
29
|
+
# @param err [IO] where the tally and any staleness go
|
|
30
|
+
# @return [Integer] the exit status, 0 once done
|
|
31
|
+
# @raise [SystemExit] on a bad command line, an empty candidate set, a failed dry run, or a
|
|
32
|
+
# stale committed list
|
|
33
|
+
def call(argv, root: Dir.pwd, out: $stdout, err: $stderr)
|
|
34
|
+
argv = argv.dup
|
|
35
|
+
mode, list_path = argv.shift(2) if %w[--check --write].include?(argv.first)
|
|
36
|
+
abort "hecks list_io_parallel_specs: #{mode} needs a file path" if mode && list_path.nil?
|
|
37
|
+
|
|
38
|
+
exclude_arg, tag_args = parse(argv)
|
|
39
|
+
candidates = Dir.glob("spec/**/*_spec.rb", base: root).grep_v(Regexp.new(exclude_arg)).sort
|
|
40
|
+
refuse_empty_candidates(candidates)
|
|
41
|
+
files, example_count = matching_files(candidates, tag_args, root, err)
|
|
42
|
+
err.puts "hecks list_io_parallel_specs: #{files.size} of #{candidates.size} candidate files carry a " \
|
|
43
|
+
"matching example (#{example_count} examples total) under `#{tag_args.join(' ')}`"
|
|
44
|
+
|
|
45
|
+
case mode
|
|
46
|
+
when "--write" then File.write(File.expand_path(list_path, root), "#{files.join("\n")}\n")
|
|
47
|
+
when "--check" then check(files, File.expand_path(list_path, root), list_path, exclude_arg, tag_args, err)
|
|
48
|
+
else out.puts files
|
|
49
|
+
end
|
|
50
|
+
0
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @param argv [Array<String>] the exclude pattern, `--`, and the tag arguments
|
|
54
|
+
# @return [Array(String, Array<String>)] the pattern and the tag arguments
|
|
55
|
+
# @raise [SystemExit] with the usage line when either is missing
|
|
56
|
+
def parse(argv)
|
|
57
|
+
exclude_arg, *rest = argv
|
|
58
|
+
separator = rest.index("--")
|
|
59
|
+
usage = "usage: hecks list_io_parallel_specs '<exclude-pattern regex>' -- <rspec tag args...>"
|
|
60
|
+
abort usage unless exclude_arg && separator
|
|
61
|
+
tag_args = rest[(separator + 1)..]
|
|
62
|
+
abort usage if tag_args.nil? || tag_args.empty?
|
|
63
|
+
|
|
64
|
+
[exclude_arg, tag_args]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param candidates [Array<String>] the spec files left after the exclude pattern
|
|
68
|
+
# @return [void]
|
|
69
|
+
# @raise [SystemExit] when there are none, which means a broken pattern or an empty checkout
|
|
70
|
+
def refuse_empty_candidates(candidates)
|
|
71
|
+
return unless candidates.empty?
|
|
72
|
+
|
|
73
|
+
abort "hecks list_io_parallel_specs: found ZERO candidate spec files after applying the exclude " \
|
|
74
|
+
"pattern — that's almost certainly a broken pattern or an empty checkout, not a real empty " \
|
|
75
|
+
"test suite. Refusing to silently hand parallel_rspec nothing to run."
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Asks RSpec for a dry run of the candidates under the tag filter.
|
|
79
|
+
#
|
|
80
|
+
# @param candidates [Array<String>] the spec files to ask about
|
|
81
|
+
# @param tag_args [Array<String>] the RSpec tag arguments
|
|
82
|
+
# @param root [String] the directory the dry run runs in
|
|
83
|
+
# @param err [IO] where a failed run's stderr goes
|
|
84
|
+
# @return [Array(Array<String>, Integer)] the files with a matching example, and how many
|
|
85
|
+
# examples matched
|
|
86
|
+
# @raise [SystemExit] when the dry run fails, prints no JSON, or matches nothing
|
|
87
|
+
def matching_files(candidates, tag_args, root, err)
|
|
88
|
+
command = ["bundle", "exec", "rspec", "--dry-run", *tag_args, "--format", "json", *candidates]
|
|
89
|
+
stdout, stderr, status = Open3.capture3(*command, chdir: root)
|
|
90
|
+
unless status.success?
|
|
91
|
+
err.puts stderr
|
|
92
|
+
abort "hecks list_io_parallel_specs: `#{command.join(' ')}` exited #{status.exitstatus} — " \
|
|
93
|
+
"see stderr above. Refusing to guess a file list from a failed dry run."
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
start = stdout.index('{"version"')
|
|
97
|
+
abort "hecks list_io_parallel_specs: couldn't find RSpec's JSON output in the dry-run's stdout:\n#{stdout}" unless start
|
|
98
|
+
|
|
99
|
+
examples = JSON.parse(stdout[start..])["examples"] || []
|
|
100
|
+
files = examples.map { |e| e.fetch("file_path").sub(%r{\A\./}, "") }.uniq.sort
|
|
101
|
+
return [files, examples.size] unless files.empty?
|
|
102
|
+
|
|
103
|
+
abort "hecks list_io_parallel_specs: #{candidates.size} candidate files, but the dry run matched ZERO " \
|
|
104
|
+
"examples under `#{tag_args.join(' ')}` — that's almost certainly a broken tag filter, not a " \
|
|
105
|
+
"real empty set. Refusing to silently hand parallel_rspec nothing to run."
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @param files [Array<String>] the files that carry a matching example
|
|
109
|
+
# @param path [String] the committed list's absolute path
|
|
110
|
+
# @param shown [String] the path as the person typed it
|
|
111
|
+
# @param exclude_arg [String] the exclude pattern, for the refresh command
|
|
112
|
+
# @param tag_args [Array<String>] the tag arguments, for the refresh command
|
|
113
|
+
# @param err [IO] where the difference goes
|
|
114
|
+
# @return [void]
|
|
115
|
+
# @raise [SystemExit] when the committed list differs
|
|
116
|
+
def check(files, path, shown, exclude_arg, tag_args, err)
|
|
117
|
+
committed = File.exist?(path) ? File.readlines(path, chomp: true).reject(&:empty?) : []
|
|
118
|
+
missing = files - committed
|
|
119
|
+
stale = committed - files
|
|
120
|
+
return if missing.empty? && stale.empty?
|
|
121
|
+
|
|
122
|
+
err.puts "#{shown} is out of date."
|
|
123
|
+
err.puts named("carries a matching example but is not listed (would never run in the shards)", missing) if missing.any?
|
|
124
|
+
err.puts named("listed but carries no matching example any more", stale) if stale.any?
|
|
125
|
+
abort "Refresh it and commit the result:\n " \
|
|
126
|
+
"hecks list_io_parallel_specs --write #{shown} '#{exclude_arg}' -- #{tag_args.join(' ')}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @param heading [String] what the paths have in common
|
|
130
|
+
# @param paths [Array<String>] the paths
|
|
131
|
+
# @return [String] the heading with the paths under it
|
|
132
|
+
def named(heading, paths)
|
|
133
|
+
" #{heading}:\n #{paths.join("\n ")}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "parallel_tests/test/runner"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module CLI
|
|
7
|
+
# The command behind `hecks shard_specs`: prints the spec files assigned to one group
|
|
8
|
+
# (1-indexed) of a runtime-balanced N-way split. `rspec_shard` in ci-rspec.yml passes the
|
|
9
|
+
# committed runtime baseline so every leg agrees.
|
|
10
|
+
#
|
|
11
|
+
# It does not use `parallel_rspec --only-group`, which forces one process per leg; this suite
|
|
12
|
+
# is CPU-bound, so each leg would use one of four vCPUs. The group's list comes from
|
|
13
|
+
# `tests_in_groups`, leaving `parallel_rspec` its own workers.
|
|
14
|
+
module RspecShardFiles
|
|
15
|
+
USAGE = "usage: hecks shard_specs <group 1-indexed> <num_groups> [runtime_log_path]"
|
|
16
|
+
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
# Prints the files of one group.
|
|
20
|
+
#
|
|
21
|
+
# @param argv [Array<String>] the group, the number of groups, and optionally a runtime log
|
|
22
|
+
# @param root [String] the checkout whose `spec/` is split
|
|
23
|
+
# @param out [IO] where the files go, one per line
|
|
24
|
+
# @param err [IO] where the group's size goes
|
|
25
|
+
# @return [Integer] the exit status, 0 once printed
|
|
26
|
+
# @raise [SystemExit] on missing or out-of-range arguments, or when there are no spec files
|
|
27
|
+
def call(argv, root: Dir.pwd, out: $stdout, err: $stderr)
|
|
28
|
+
group_arg, num_groups_arg, runtime_log = argv
|
|
29
|
+
abort USAGE unless group_arg && num_groups_arg
|
|
30
|
+
|
|
31
|
+
group = Integer(group_arg)
|
|
32
|
+
num_groups = Integer(num_groups_arg)
|
|
33
|
+
abort "group must be between 1 and #{num_groups}, got #{group}" unless (1..num_groups).cover?(group)
|
|
34
|
+
|
|
35
|
+
files = Dir.glob("spec/**/*_spec.rb", base: root)
|
|
36
|
+
if files.empty?
|
|
37
|
+
abort "hecks shard_specs: found ZERO spec files under spec/ — " \
|
|
38
|
+
"refusing to hand parallel_rspec nothing to run"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
groups = Dir.chdir(root) { groups_of(files, num_groups, runtime_log && File.expand_path(runtime_log, root)) }
|
|
42
|
+
selected = groups[group - 1] || []
|
|
43
|
+
err.puts "hecks shard_specs: group #{group}/#{num_groups} has #{selected.size} of #{files.size} files"
|
|
44
|
+
out.puts selected
|
|
45
|
+
0
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Splits the files by recorded runtime, falling back to file size on a cold cache.
|
|
49
|
+
#
|
|
50
|
+
# `allowed_missing_percent` covers gaps inside a log, not a missing file (`Runner.runtimes`
|
|
51
|
+
# raises `Errno::ENOENT`).
|
|
52
|
+
#
|
|
53
|
+
# @param files [Array<String>] the spec files, relative to the checkout
|
|
54
|
+
# @param num_groups [Integer] how many groups to split into
|
|
55
|
+
# @param runtime_log [String, nil] the runtime log's path, used when the file exists
|
|
56
|
+
# @return [Array<Array<String>>] the files of each group
|
|
57
|
+
def groups_of(files, num_groups, runtime_log)
|
|
58
|
+
options = { group_by: :runtime, allowed_missing_percent: 100 }
|
|
59
|
+
options[:runtime_log] = runtime_log if runtime_log && File.exist?(runtime_log)
|
|
60
|
+
ParallelTests::Test::Runner.tests_in_groups(files, num_groups, **options)
|
|
61
|
+
rescue Errno::ENOENT
|
|
62
|
+
ParallelTests::Test::Runner.tests_in_groups(files, num_groups, group_by: :filesize)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/hecks/cli/run.rb
CHANGED
|
@@ -6,24 +6,16 @@ require_relative "../ports/persistence/plugins/era"
|
|
|
6
6
|
|
|
7
7
|
module Hecks
|
|
8
8
|
module CLI
|
|
9
|
-
# The command behind `
|
|
9
|
+
# The command behind `hecks run`: dispatches one verb from the
|
|
10
10
|
# command line, or executes a JSON step list and reports instances, events,
|
|
11
11
|
# refusals, reactions, sagas and query rows.
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# cannot go stale. The step-list form takes a script path, `-` for stdin, or the
|
|
20
|
-
# JSON itself, which is how the corpus scripts under `spec/corpus/` are run.
|
|
21
|
-
#
|
|
22
|
-
# ## Standing in a domain is enough
|
|
23
|
-
#
|
|
24
|
-
# `Adapters::Folder#domain_root` walks up for the nearest `.hecksagon`, so inside
|
|
25
|
-
# a domain the path can be left off. The first argument is a domain only when it
|
|
26
|
-
# is a directory.
|
|
13
|
+
# `run bug.discover reference=BUG#1 severity=high …` needs no JSON; the verb
|
|
14
|
+
# tree and its arguments are projected from the bluebook, so this knows nothing
|
|
15
|
+
# about any domain and its help cannot go stale. The step-list form takes a
|
|
16
|
+
# script path, `-` for stdin, or the JSON itself. The first argument is a
|
|
17
|
+
# domain only when it is a directory; otherwise the nearest enclosing one is
|
|
18
|
+
# used.
|
|
27
19
|
module Run
|
|
28
20
|
module_function
|
|
29
21
|
|
|
@@ -59,40 +51,20 @@ module Hecks
|
|
|
59
51
|
abort unmet.join("\n") unless unmet.empty?
|
|
60
52
|
end
|
|
61
53
|
|
|
62
|
-
#
|
|
63
|
-
# the
|
|
64
|
-
#
|
|
65
|
-
# **No fall-through**. This is reached only when the argument is not
|
|
66
|
-
# script-shaped, so a near miss deserves the runner's "did you mean" rather
|
|
67
|
-
# than the step-list form's "no such script".
|
|
68
|
-
#
|
|
69
|
-
# @param domain [String] the domain's directory path
|
|
70
|
-
# @param argv [Array<String>] the arguments after the domain, e.g.
|
|
71
|
-
# `["bug.discover", "reference=BUG#1"]`
|
|
72
|
-
# @param program [String] the name the runner's help calls this command by
|
|
73
|
-
# @return [void]
|
|
74
|
-
# @raise [SystemExit] always
|
|
54
|
+
# No fall-through: reached only when the argument is not script-shaped, so a
|
|
55
|
+
# near miss deserves the runner's "did you mean" rather than the step-list
|
|
56
|
+
# form's "no such script".
|
|
75
57
|
def cli_form(domain, argv, program)
|
|
76
|
-
runtime = Hecks.boot(domain,
|
|
77
|
-
text, status =
|
|
58
|
+
runtime = Hecks.boot(domain, install_doors: false)
|
|
59
|
+
text, status = Doors::CliRunner.call(runtime: runtime, argv: argv, program: program)
|
|
78
60
|
status.zero? ? puts(text) : abort(text)
|
|
79
61
|
exit 0
|
|
80
62
|
end
|
|
81
63
|
|
|
82
|
-
# Says whether `arg` is a step list rather than a verb: stdin, inline JSON, or
|
|
83
|
-
# a file that exists.
|
|
84
|
-
#
|
|
85
|
-
# @param arg [String] the first argument after the domain
|
|
86
|
-
# @return [Boolean] true when `arg` is script-shaped
|
|
87
64
|
def script_shaped?(arg) = arg == "-" || arg.match?(/\A\s*\{/) || File.file?(arg)
|
|
88
65
|
|
|
89
|
-
#
|
|
90
|
-
# decided by looking, because a script beginning with `{` is not a filename
|
|
66
|
+
# Decided by looking, because a script beginning with `{` is not a filename
|
|
91
67
|
# anybody meant.
|
|
92
|
-
#
|
|
93
|
-
# @param script [String] `-`, inline JSON, or a file path
|
|
94
|
-
# @return [String] the script's JSON text
|
|
95
|
-
# @raise [SystemExit] when `script` names no file
|
|
96
68
|
def read_source(script)
|
|
97
69
|
case script
|
|
98
70
|
when "-" then $stdin.read
|
|
@@ -102,25 +74,14 @@ module Hecks
|
|
|
102
74
|
end
|
|
103
75
|
end
|
|
104
76
|
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
# @param source [String] the script's JSON text
|
|
109
|
-
# @return [Hash{String => Object}] the parsed script
|
|
110
|
-
# @raise [SystemExit] when `source` is not JSON
|
|
77
|
+
# Parsed before anything boots, because booting opens a real store and a typo
|
|
78
|
+
# in the JSON should cost a sentence, not a connection.
|
|
111
79
|
def parse(source)
|
|
112
80
|
JSON.parse(source)
|
|
113
81
|
rescue JSON::ParserError => e
|
|
114
82
|
abort "that is not JSON: #{e.message.lines.first.strip}"
|
|
115
83
|
end
|
|
116
84
|
|
|
117
|
-
# Runs every step and gathers what the runtime holds afterwards.
|
|
118
|
-
#
|
|
119
|
-
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
|
|
120
|
-
# @param steps [Array<Hash{String => Object}>] the script's steps, each a
|
|
121
|
-
# `"verb"` or a `"query"` with optional `"args"`
|
|
122
|
-
# @return [Hash{Symbol => Object}] `:instances`, `:events`, `:refusals`,
|
|
123
|
-
# `:reactions`, `:sagas` and `:queries`, in the order they are printed
|
|
124
85
|
def execute(runtime, steps)
|
|
125
86
|
refusals = []
|
|
126
87
|
queries = []
|
|
@@ -171,13 +132,6 @@ module Hecks
|
|
|
171
132
|
end
|
|
172
133
|
end
|
|
173
134
|
|
|
174
|
-
# Checks the script's `"expectations"` against what the run produced.
|
|
175
|
-
#
|
|
176
|
-
# @param expectations [Hash{String => Object}] the script's `"event_names"`,
|
|
177
|
-
# `"refusals"` and `"instances"` expectations; `{}` when it declares none
|
|
178
|
-
# @param report [Hash{Symbol => Object}] what `execute` answered
|
|
179
|
-
# @return [Array<String>] one message per unmet expectation; empty when every
|
|
180
|
-
# one held
|
|
181
135
|
def unmet_expectations(expectations, report)
|
|
182
136
|
missing_events = Array(expectations["event_names"]) - report[:events].map { |event| event[:name] }
|
|
183
137
|
unmet = []
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "../../hecks"
|
|
5
|
+
require_relative "../fuzzing"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module CLI
|
|
9
|
+
# The command behind `hecks seed_semantics_corpus`: seeds (or deliberately re-seeds) the
|
|
10
|
+
# `expect` block of semantics-corpus fixtures from the Ruby runtime. Review the result
|
|
11
|
+
# against `docs/semantics/bluebook-semantics.md` before committing.
|
|
12
|
+
#
|
|
13
|
+
# hecks seed_semantics_corpus # fill fixtures missing an expect
|
|
14
|
+
# SEED=refusal_kind_lifecycle hecks seed_semantics_corpus # re-seed one, deliberately
|
|
15
|
+
#
|
|
16
|
+
# The seeded expectation is the definition, not a recording: both runtimes are compared to it.
|
|
17
|
+
# `occurred_at` is stripped from events (C7.3/C9.1); refusals keep verb, error and kind (C8.2).
|
|
18
|
+
module SeedSemanticsCorpus
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
# Seeds the fixtures that need it and reports which.
|
|
22
|
+
#
|
|
23
|
+
# @param root [String] the checkout whose `spec/corpus/semantics/` is seeded
|
|
24
|
+
# @param env [Hash{String => String}] `SEED` names the one fixture to re-seed
|
|
25
|
+
# @param out [IO] where the report goes
|
|
26
|
+
# @return [Integer] the exit status, always 0
|
|
27
|
+
def call(root:, env: ENV, out: $stdout)
|
|
28
|
+
only = env.fetch("SEED", nil)
|
|
29
|
+
seeded = Dir.glob(File.join(root, "spec/corpus/semantics", "*.json")).filter_map do |path|
|
|
30
|
+
fixture = JSON.parse(File.read(path))
|
|
31
|
+
name = File.basename(path, ".json")
|
|
32
|
+
next if only ? only != name : fixture.key?("expect")
|
|
33
|
+
|
|
34
|
+
fixture["expect"] = expectation_for(root, fixture)
|
|
35
|
+
File.write(path, "#{JSON.pretty_generate(fixture)}\n")
|
|
36
|
+
name
|
|
37
|
+
end
|
|
38
|
+
report(out, seeded)
|
|
39
|
+
0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Replays the fixture's script against the Ruby runtime. Each refusal's `"kind"` is reduced
|
|
43
|
+
# to its class name; `occurred_at` is stripped from events.
|
|
44
|
+
#
|
|
45
|
+
# @param root [String] the checkout the fixture's domain path is relative to
|
|
46
|
+
# @param fixture [Hash] the parsed fixture: `domain` and `steps`
|
|
47
|
+
# @return [Hash{String => Array}] its `"expect"` block: refusals, instances, events
|
|
48
|
+
def expectation_for(root, fixture)
|
|
49
|
+
result = Hecks::Fuzzing::Replay.call(File.join(root, fixture["domain"]), fixture["steps"])
|
|
50
|
+
{
|
|
51
|
+
"refusals" => JSON.parse(JSON.generate(result[:refusals])).each { |r| r["kind"] = r["kind"]&.split("::")&.last },
|
|
52
|
+
"instances" => JSON.parse(JSON.generate(result[:instances])),
|
|
53
|
+
"events" => JSON.parse(JSON.generate(result[:events])).each { |e| e.delete("occurred_at") }
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param out [IO] where the report goes
|
|
58
|
+
# @param seeded [Array<String>] the fixtures written
|
|
59
|
+
# @return [void]
|
|
60
|
+
def report(out, seeded)
|
|
61
|
+
if seeded.empty?
|
|
62
|
+
out.puts "nothing to seed — every fixture carries its expect (pass SEED=<name> to re-seed one deliberately)"
|
|
63
|
+
else
|
|
64
|
+
out.puts "seeded: #{seeded.join(', ')}"
|
|
65
|
+
out.puts "review each expect against docs/semantics/bluebook-semantics.md before committing — " \
|
|
66
|
+
"it is the definition now"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../mcp_stdio_guard"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module CLI
|
|
7
|
+
# The command behind `hecks serve_query_ir_mcp` and `hecks serve_query_ir_mcp`: an MCP server
|
|
8
|
+
# exposing `Hecks::QueryIR`'s queries as tools, over newline-delimited JSON-RPC on stdio.
|
|
9
|
+
#
|
|
10
|
+
# Stdio only and unauthenticated (ADR 0062); the protocol lives in `Hecks::QueryIrMcp` and the
|
|
11
|
+
# query logic in `Hecks::QueryIR`. The stdio guard runs before the runtime loads, so a refused
|
|
12
|
+
# transport never boots anything.
|
|
13
|
+
module ServeQueryIrMcp
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Enforces stdio, then serves until stdin closes.
|
|
17
|
+
#
|
|
18
|
+
# @param argv [Array<String>] the arguments the server was started with
|
|
19
|
+
# @return [void]
|
|
20
|
+
# @raise [SystemExit] when the guard refuses the transport
|
|
21
|
+
def call(argv)
|
|
22
|
+
Hecks::McpStdioGuard.enforce_stdio!(server: "hecks-query-ir")
|
|
23
|
+
|
|
24
|
+
require_relative "../../hecks"
|
|
25
|
+
require_relative "../query_ir_mcp"
|
|
26
|
+
Hecks::QueryIrMcp.start(argv: argv)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "../../hecks"
|
|
5
|
+
# The `:shape` projection reads `Runtime::StorageShape`, which lives in the era persistence plugin
|
|
6
|
+
# core does not load by default (ADR 0033).
|
|
7
|
+
require_relative "../ports/persistence/plugins/era"
|
|
8
|
+
|
|
9
|
+
module Hecks
|
|
10
|
+
module CLI
|
|
11
|
+
# The command behind `hecks shape` and `hecks shape`: a bluebook's storage-shape projection, the
|
|
12
|
+
# same hash PostgresEra mints an era's label from, so two runs diff to show whether a bluebook
|
|
13
|
+
# change would bump an era.
|
|
14
|
+
module Shape
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
# Prints the projection of a bluebook file as JSON, or one `<Domain> <label>` line per domain
|
|
18
|
+
# of a directory (files in subdirectories are not read).
|
|
19
|
+
#
|
|
20
|
+
# @param argv [Array<String>] the bluebook file or directory, first
|
|
21
|
+
# @param program [String] the name the usage message calls this command by
|
|
22
|
+
# @return [void]
|
|
23
|
+
# @raise [SystemExit] when `argv` is empty, the path is missing or holds no bluebook
|
|
24
|
+
def call(argv, program: "hecks shape")
|
|
25
|
+
target = argv.first or abort "usage: #{program} <bluebook | directory of *.bluebook files>"
|
|
26
|
+
puts render(target)
|
|
27
|
+
rescue Runtime::NotFound => e
|
|
28
|
+
abort e.message
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param target [String] a bluebook file, or a directory of them
|
|
32
|
+
# @return [String] the storage-shape projection as JSON for a file, or one
|
|
33
|
+
# `<Domain> <label>` line per domain for a directory
|
|
34
|
+
# @raise [Runtime::NotFound] if the path does not exist or holds no bluebook
|
|
35
|
+
def render(target)
|
|
36
|
+
raise Runtime::NotFound, "#{target} does not exist" unless File.exist?(target)
|
|
37
|
+
|
|
38
|
+
directory = File.directory?(target)
|
|
39
|
+
files = directory ? Dir[File.join(target, "*.bluebook")] : [target]
|
|
40
|
+
raise Runtime::NotFound, "no *.bluebook files in #{target}" if files.empty?
|
|
41
|
+
|
|
42
|
+
registry = load_files(files)
|
|
43
|
+
return labels(registry) if directory
|
|
44
|
+
|
|
45
|
+
bluebook = registry.bluebooks.values.first or raise Runtime::NotFound, "#{target} declares no bluebook"
|
|
46
|
+
JSON.pretty_generate(Projector.call(:shape, bluebook: bluebook))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @param files [Array<String>] bluebook files
|
|
50
|
+
# @return [Runtime::Registry] a registry holding every bluebook the files declare
|
|
51
|
+
def load_files(files)
|
|
52
|
+
registry = Runtime::Registry.new
|
|
53
|
+
loading = Ports::Loading.bootstrap
|
|
54
|
+
Hecks.with_registry(registry) do
|
|
55
|
+
loading.load_library
|
|
56
|
+
files.each { |file| Kernel.eval(File.read(file), TOPLEVEL_BINDING, File.expand_path(file), 1) }
|
|
57
|
+
end
|
|
58
|
+
registry
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @param registry [Runtime::Registry] a loaded registry
|
|
62
|
+
# @return [String] one `<Domain> <label>` line per bluebook, sorted by name
|
|
63
|
+
def labels(registry)
|
|
64
|
+
registry.bluebooks.sort_by { |name, _| name.to_s }
|
|
65
|
+
.map { |name, bluebook| "#{name} #{Runtime::StorageShape.mint_label(bluebook)}" }
|
|
66
|
+
.join("\n")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|