hecks 6.0.0 → 7.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 +19 -12
- data/lib/hecks/adapters/driven/claude_code.rb +2 -2
- data/lib/hecks/adapters/driven/folder.rb +10 -1
- data/lib/hecks/adapters/driven/folder_overlay.rb +15 -0
- data/lib/hecks/adapters/driven/heki.rb +1 -1
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +1 -1
- data/lib/hecks/adapters/driven/memory/outbox_rows.rb +2 -2
- data/lib/hecks/adapters/driven/postgres/name_guard.rb +25 -0
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -3
- data/lib/hecks/adapters/driven/postgres/repository.rb +1 -1
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +1 -1
- data/lib/hecks/adapters/driven/postgres.rb +3 -0
- data/lib/hecks/adapters/driven/postgres_era/boot.rb +28 -16
- data/lib/hecks/adapters/driven/postgres_era/class_methods.rb +27 -7
- data/lib/hecks/adapters/driven/postgres_era/dialect.rb +10 -5
- data/lib/hecks/adapters/driven/postgres_era/field_cache_provisioner.rb +39 -0
- data/lib/hecks/adapters/driven/postgres_era/journal.rb +52 -13
- data/lib/hecks/adapters/driven/postgres_era/lineage/chain_sql.rb +29 -49
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_sql.rb +73 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.json +10 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/direct_verified.rb +65 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename.rb +77 -25
- data/lib/hecks/adapters/driven/postgres_era/lineage/domain_rename_state.rb +108 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_integrity.rb +11 -6
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +63 -5
- data/lib/hecks/adapters/driven/postgres_era/lineage/layered_sql.rb +64 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/ledger_reset.rb +150 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_provisioning.rb +85 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +11 -7
- data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +11 -5
- data/lib/hecks/adapters/driven/postgres_era/lineage/split_sql.rb +76 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/sql_templates.rb +9 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage.rb +10 -2
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/context.rb +23 -3
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +3 -1
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/disposable_ledger.rb +119 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolution.rb +219 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +68 -71
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/held_era.rb +68 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/ledger_change.rb +63 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_decision.rb +163 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/mint_request.rb +24 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +59 -21
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/refusals.rb +24 -11
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +40 -6
- data/lib/hecks/adapters/driven/postgres_era/shared_tables.rb +32 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +12 -0
- data/lib/hecks/adapters/driven/postgres_era.rb +25 -10
- data/lib/hecks/adapters/driven/prism.rb +0 -1
- data/lib/hecks/adapters/driven/sql_query_builder.rb +1 -0
- data/lib/hecks/adapters/driven/sqlite/dispatch_claims.rb +1 -1
- data/lib/hecks/adapters/driven/sqlite/name_guard.rb +25 -0
- data/lib/hecks/adapters/driven/sqlite/outbox.rb +2 -2
- data/lib/hecks/adapters/driven/sqlite/repository.rb +1 -1
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +20 -0
- data/lib/hecks/adapters/driven/sqlite.rb +9 -1
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +1 -1
- data/lib/hecks/adapters/driven/worktree_overlay.rb +117 -0
- data/lib/hecks/adapters/driving/cli/shorthand.rb +5 -1
- data/lib/hecks/adapters/driving/cli.rb +1 -1
- data/lib/hecks/adapters/driving/cli_runner/answers.rb +77 -22
- data/lib/hecks/adapters/driving/cli_runner/bang_rule.rb +35 -0
- data/lib/hecks/adapters/driving/cli_runner/completion_words.rb +36 -0
- data/lib/hecks/adapters/driving/cli_runner/json_words.rb +55 -0
- data/lib/hecks/adapters/driving/cli_runner/name_index.rb +63 -0
- data/lib/hecks/adapters/driving/cli_runner/read_context.rb +32 -0
- data/lib/hecks/adapters/driving/cli_runner/renamed_names.rb +49 -0
- data/lib/hecks/adapters/driving/cli_runner/resolution.rb +43 -17
- data/lib/hecks/adapters/driving/cli_runner/resume_words.rb +63 -0
- data/lib/hecks/adapters/driving/cli_runner/run_reference.rb +66 -0
- data/lib/hecks/adapters/driving/cli_runner/run_replay.rb +118 -0
- data/lib/hecks/adapters/driving/cli_runner/search_words.rb +35 -0
- data/lib/hecks/adapters/driving/cli_runner/settling.rb +6 -5
- data/lib/hecks/adapters/driving/cli_runner/streaming.rb +11 -10
- data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +1 -1
- data/lib/hecks/adapters/driving/cli_runner/tour_words.rb +77 -0
- data/lib/hecks/adapters/driving/cli_runner/verb_names.rb +36 -4
- data/lib/hecks/adapters/driving/cli_runner/verbosity.rb +75 -0
- data/lib/hecks/adapters/driving/cli_runner.rb +106 -7
- data/lib/hecks/adapters/driving/context_line.rb +85 -0
- data/lib/hecks/adapters/driving/exit_status.rb +31 -0
- data/lib/hecks/adapters/driving/launcher_options.rb +7 -5
- data/lib/hecks/adapters/driving/mcp/progress_sink.rb +45 -0
- data/lib/hecks/adapters/driving/mcp/tool_calls.rb +7 -5
- data/lib/hecks/adapters/driving/mcp.rb +25 -5
- data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +40 -7
- data/lib/hecks/adapters/driving/mcp_scope.rb +8 -7
- data/lib/hecks/adapters/driving/ruby/aggregate_module/hooks.rb +154 -0
- data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +64 -93
- data/lib/hecks/adapters/driving/usage_log.rb +146 -0
- data/lib/hecks/adapters/driving/write_guard.rb +55 -0
- data/lib/hecks/adapters/driving.rb +0 -1
- data/lib/hecks/behaviors/dsl.rb +5 -1
- data/lib/hecks/behaviors/expectations/boot.rb +0 -1
- data/lib/hecks/bluebook/acknowledgements.rb +1 -1
- data/lib/hecks/bluebook/aggregate.rb +21 -18
- data/lib/hecks/bluebook/assembly/contracts/sagas.rb +2 -0
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +18 -13
- data/lib/hecks/bluebook/behaviour/aggregate.rb +27 -3
- data/lib/hecks/bluebook/command.rb +16 -5
- data/lib/hecks/bluebook/declaration.rb +32 -4
- data/lib/hecks/bluebook/domain_port.rb +7 -3
- data/lib/hecks/bluebook/dsl/aggregate_builder/relationships.rb +0 -2
- data/lib/hecks/bluebook/dsl/aggregate_builder/renaming.rb +25 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +3 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +0 -1
- data/lib/hecks/bluebook/dsl/audience_word.rb +40 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/metadata.rb +56 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/modules.rb +80 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/correlation_keys.rb +51 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +1 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +17 -34
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +8 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +13 -3
- data/lib/hecks/bluebook/dsl/entity_builder.rb +0 -2
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +6 -4
- data/lib/hecks/bluebook/dsl/kinds.rb +53 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +9 -2
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +25 -15
- data/lib/hecks/bluebook/dsl/translation_builder.rb +16 -1
- data/lib/hecks/bluebook/dsl/word_gate.rb +1 -1
- data/lib/hecks/bluebook/dsl.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/judge/identity.rb +9 -4
- data/lib/hecks/bluebook/meta_validator/plan/category.rb +10 -2
- data/lib/hecks/bluebook/meta_validator/plan/verbs.rb +9 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +3 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/reading.rb +7 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +7 -2
- data/lib/hecks/bluebook/meta_validator/shapes.rb +3 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot/disk_cache.rb +1 -1
- data/lib/hecks/bluebook/model_check/aggregate_checks.rb +27 -0
- data/lib/hecks/bluebook/model_check/ask_checks.rb +25 -0
- data/lib/hecks/bluebook/model_check/reaction_chains.rb +114 -0
- data/lib/hecks/bluebook/model_check/reaction_cycles.rb +53 -0
- data/lib/hecks/bluebook/model_check/reaction_depth_checks.rb +58 -0
- data/lib/hecks/bluebook/model_check/reaction_walk.rb +62 -0
- data/lib/hecks/bluebook/model_check.rb +5 -27
- data/lib/hecks/bluebook/process_manager.rb +20 -3
- data/lib/hecks/bluebook/translation.rb +5 -3
- data/lib/hecks/bluebook/translation_plan.rb +9 -2
- data/lib/hecks/ci_pipeline/adapters/ci_cache.adapter +7 -0
- data/lib/hecks/ci_pipeline/adapters/ci_cache.rb +39 -0
- data/lib/hecks/ci_pipeline/adapters/ci_runner.adapter +7 -0
- data/lib/hecks/ci_pipeline/adapters/ci_runner.rb +55 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.behaviors +322 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.bluebook +938 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.hecksagon +12 -0
- data/lib/hecks/ci_pipeline/ci_pipeline.ports.hecksagon +16 -0
- data/lib/hecks/ci_speed/adapters/ci_reader.adapter +7 -0
- data/lib/hecks/ci_speed/adapters/ci_reader.rb +141 -0
- data/lib/hecks/ci_speed/adapters/local_runner/answer.rb +41 -0
- data/lib/hecks/ci_speed/adapters/local_runner/catalog.rb +89 -0
- data/lib/hecks/ci_speed/adapters/local_runner/checkouts.rb +89 -0
- data/lib/hecks/ci_speed/adapters/local_runner/launcher.rb +69 -0
- data/lib/hecks/ci_speed/adapters/local_runner/load_average.rb +38 -0
- data/lib/hecks/ci_speed/adapters/local_runner/refs.rb +39 -0
- data/lib/hecks/ci_speed/adapters/local_runner/refused.rb +11 -0
- data/lib/hecks/ci_speed/adapters/local_runner/verdict.rb +71 -0
- data/lib/hecks/ci_speed/adapters/local_runner.adapter +7 -0
- data/lib/hecks/ci_speed/adapters/local_runner.rb +168 -0
- data/lib/hecks/ci_speed/adapters/replayed_runner.rb +39 -0
- data/lib/hecks/ci_speed/ci_speed.behaviors +341 -0
- data/lib/hecks/ci_speed/ci_speed.bluebook +1073 -0
- data/lib/hecks/ci_speed/ci_speed.hecksagon +11 -0
- data/lib/hecks/ci_speed/ci_speed.ports.hecksagon +21 -0
- data/lib/hecks/ci_workflows/ci_workflows.behaviors +13 -0
- data/lib/hecks/ci_workflows/ci_workflows.bluebook +173 -0
- data/lib/hecks/ci_workflows/ci_workflows.hecksagon +15 -0
- data/lib/hecks/coder/coder.bluebook +385 -0
- data/lib/hecks/coder/coder.hecksagon +12 -0
- data/lib/hecks/command_names/check.rb +39 -0
- data/lib/hecks/command_names/extractor.rb +67 -0
- data/lib/hecks/command_names/index.rb +40 -0
- data/lib/hecks/command_names/resolution.rb +81 -0
- data/lib/hecks/command_names/scan.rb +54 -0
- data/lib/hecks/command_names/sources.rb +73 -0
- data/lib/hecks/command_names.rb +26 -0
- data/lib/hecks/composer/jobs.rb +1 -1
- data/lib/hecks/composer/toolbox.rb +8 -1
- data/lib/hecks/corpus/generated_key.rb +205 -0
- data/lib/hecks/corpus/listing.rb +34 -0
- data/lib/hecks/corpus/rust.rb +27 -11
- data/lib/hecks/corpus/sources.rb +2 -1
- data/lib/hecks/corpus.rb +37 -42
- data/lib/hecks/deprecation.rb +23 -0
- data/lib/hecks/doc/reference/readme.rb +1 -1
- data/lib/hecks/doc/reference/rendering.rb +2 -2
- data/lib/hecks/doc/reference.rb +1 -1
- data/lib/hecks/embryonaut_bluebook/manifest.rb +1 -1
- data/lib/hecks/fixer/fixer.bluebook +240 -0
- data/lib/hecks/fixer/fixer.hecksagon +17 -0
- data/lib/hecks/framework_bluebooks.rb +32 -7
- data/lib/hecks/fuzzing/concurrent_dispatch/world_copy.rb +1 -0
- data/lib/hecks/fuzzing/isolated_boot/postgres_scratch.rb +11 -12
- data/lib/hecks/fuzzing/isolated_boot/worlds.rb +23 -5
- data/lib/hecks/fuzzing/isolated_boot.rb +1 -1
- data/lib/hecks/fuzzing/mutation/checks.rb +3 -3
- data/lib/hecks/grammar/translation.bluebook +1 -1
- data/lib/hecks/grammar/translation_rules.json +64 -0
- data/lib/hecks/hecks/adapter_words.json +7 -0
- data/lib/hecks/hecks/adapters/area_overlap.rb +156 -0
- data/lib/hecks/hecks/adapters/claude_agents.rb +8 -3
- data/lib/hecks/hecks/adapters/codebase/batch_runs.rb +60 -0
- data/lib/hecks/hecks/adapters/codebase/changed_specs.rb +52 -0
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +3 -2
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +14 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_queries.rb +53 -0
- data/lib/hecks/hecks/adapters/codebase/generated_keys.rb +31 -0
- data/lib/hecks/hecks/adapters/codebase/impacted_specs.rb +110 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +2 -2
- data/lib/hecks/hecks/adapters/codebase/launcher_text.rb +39 -0
- data/lib/hecks/hecks/adapters/codebase/minitest_runs.rb +52 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +51 -8
- data/lib/hecks/hecks/adapters/codebase/run_options.rb +35 -0
- data/lib/hecks/hecks/adapters/codebase/scripting.rb +39 -0
- data/lib/hecks/hecks/adapters/codebase/search.rb +1 -1
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +79 -51
- data/lib/hecks/hecks/adapters/codebase/spec_files/report.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/spec_files/shared_run.rb +73 -0
- data/lib/hecks/hecks/adapters/codebase/spec_files.rb +95 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +53 -4
- data/lib/hecks/hecks/adapters/codebase/test_scope.rb +105 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +48 -34
- data/lib/hecks/hecks/adapters/console_capture.rb +1 -1
- data/lib/hecks/hecks/adapters/cost_explorer.rb +9 -1
- data/lib/hecks/hecks/adapters/dispatching/brief_text.rb +51 -0
- data/lib/hecks/hecks/adapters/dispatching/launcher.rb +97 -0
- data/lib/hecks/hecks/adapters/dispatching/plan.rb +82 -0
- data/lib/hecks/hecks/adapters/dispatching/rows.rb +66 -0
- data/lib/hecks/hecks/adapters/dispatching/settings.rb +81 -0
- data/lib/hecks/hecks/adapters/dispatching/settler.rb +40 -0
- data/lib/hecks/hecks/adapters/dispatching.adapter +7 -0
- data/lib/hecks/hecks/adapters/dispatching.rb +93 -0
- data/lib/hecks/hecks/adapters/doctor_reading/report.rb +27 -0
- data/lib/hecks/hecks/adapters/doctor_reading.adapter +7 -0
- data/lib/hecks/hecks/adapters/doctor_reading.rb +161 -0
- data/lib/hecks/hecks/adapters/git_checkout.rb +1 -1
- data/lib/hecks/hecks/adapters/git_commit.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_commit.rb +61 -0
- data/lib/hecks/hecks/adapters/git_landing/finisher.rb +82 -0
- data/lib/hecks/hecks/adapters/git_landing/foreign_hold.rb +111 -0
- data/lib/hecks/hecks/adapters/git_landing/line.rb +171 -0
- data/lib/hecks/hecks/adapters/git_landing/lineup.rb +98 -0
- data/lib/hecks/hecks/adapters/git_landing/merger.rb +1 -1
- data/lib/hecks/hecks/adapters/git_landing/numbering.rb +54 -0
- data/lib/hecks/hecks/adapters/git_landing/rivals.rb +59 -0
- data/lib/hecks/hecks/adapters/git_landing/ticket.rb +156 -0
- data/lib/hecks/hecks/adapters/git_landing/tidy.rb +147 -0
- data/lib/hecks/hecks/adapters/git_landing/train.rb +104 -0
- data/lib/hecks/hecks/adapters/git_landing/verdict.rb +64 -0
- data/lib/hecks/hecks/adapters/git_landing/waiting.rb +120 -0
- data/lib/hecks/hecks/adapters/git_landing.rb +106 -20
- data/lib/hecks/hecks/adapters/git_main_pull.rb +99 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/bench.rb +82 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/due.rb +84 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted/skips.rb +47 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted/spec_run.rb +75 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/impacted.rb +181 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/line.rb +76 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/reading.rb +24 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/record.rb +146 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/corpus.rb +25 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map/needles.rb +61 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/spec_map.rb +105 -0
- data/lib/hecks/hecks/adapters/git_rehearsal/stages.rb +118 -0
- data/lib/hecks/hecks/adapters/git_rehearsal.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_rehearsal.rb +141 -0
- data/lib/hecks/hecks/adapters/git_train/bench.rb +15 -15
- data/lib/hecks/hecks/adapters/git_train/branch_guard.rb +62 -0
- data/lib/hecks/hecks/adapters/git_train/carriage.rb +27 -28
- data/lib/hecks/hecks/adapters/git_train/launcher_shape.rb +75 -0
- data/lib/hecks/hecks/adapters/git_train/mint_step.rb +47 -0
- data/lib/hecks/hecks/adapters/git_train/settlement.rb +167 -0
- data/lib/hecks/hecks/adapters/git_train.rb +73 -15
- data/lib/hecks/hecks/adapters/git_worktree_add.adapter +7 -0
- data/lib/hecks/hecks/adapters/git_worktree_add.rb +68 -0
- data/lib/hecks/hecks/adapters/github_pull_requests.adapter +7 -0
- data/lib/hecks/hecks/adapters/github_pull_requests.rb +109 -0
- data/lib/hecks/hecks/adapters/host_http.rb +6 -6
- data/lib/hecks/hecks/adapters/in_process_boot.rb +10 -8
- data/lib/hecks/hecks/adapters/in_process_operations.rb +11 -17
- data/lib/hecks/hecks/adapters/in_process_undo.rb +17 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +13 -4
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +28 -15
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +17 -1
- data/lib/hecks/hecks/adapters/journal_store/held_domain/renaming.rb +45 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +31 -5
- data/lib/hecks/hecks/adapters/journal_store/held_mint.rb +128 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/attestation.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/readings/boot_status.rb +58 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/composition.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/outcomes.rb +76 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/postgres_reader.rb +44 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/reader.rb +64 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/report.rb +102 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/sqlite_reader.rb +43 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/stores.rb +80 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/subscribers.rb +72 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace/summary.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/event_trace.rb +39 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/command_line.rb +57 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/edge_guards.rb +107 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/inspection.rb +94 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/plan.rb +66 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/report.rb +72 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/store.rb +34 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/watermark_guards.rb +86 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan/world.rb +66 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/mint_plan.rb +36 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/projection_audit.rb +64 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/scaffolding.rb +3 -3
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/database_reading.rb +113 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status/read_only.rb +33 -0
- data/lib/hecks/hecks/adapters/journal_store/readings/sqlite_status.rb +32 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +13 -1
- data/lib/hecks/hecks/adapters/journal_store/reconcile_report.rb +60 -0
- data/lib/hecks/hecks/adapters/journal_store/reconciliation.rb +121 -0
- data/lib/hecks/hecks/adapters/journal_store/translation_write/shape_edge.rb +59 -0
- data/lib/hecks/hecks/adapters/journal_store/translation_write.rb +123 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +16 -0
- data/lib/hecks/hecks/adapters/landed_work.adapter +7 -0
- data/lib/hecks/hecks/adapters/landed_work.rb +52 -0
- data/lib/hecks/hecks/adapters/local_files.rb +6 -6
- data/lib/hecks/hecks/adapters/process_pool.rb +3 -2
- data/lib/hecks/hecks/adapters/push_size.rb +57 -0
- data/lib/hecks/hecks/adapters/qa_quiescing.adapter +7 -0
- data/lib/hecks/hecks/adapters/qa_quiescing.rb +57 -0
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +30 -3
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +63 -3
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +29 -6
- data/lib/hecks/hecks/adapters/rehearsal/subject.rb +11 -5
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +10 -1
- data/lib/hecks/hecks/adapters/rust_workspace.rb +1 -1
- data/lib/hecks/hecks/adapters/settings_reading/disposable_ledger.rb +32 -0
- data/lib/hecks/hecks/adapters/settings_reading/push_nudge.rb +26 -0
- data/lib/hecks/hecks/adapters/settings_reading/stores.rb +76 -0
- data/lib/hecks/hecks/adapters/settings_reading/test_scope.rb +28 -0
- data/lib/hecks/hecks/adapters/settings_reading.rb +28 -2
- data/lib/hecks/hecks/adapters/started_work.rb +42 -0
- data/lib/hecks/hecks/adapters/terminal.rb +12 -10
- data/lib/hecks/hecks/adapters/where_reading.adapter +7 -0
- data/lib/hecks/hecks/adapters/where_reading.rb +64 -0
- data/lib/hecks/hecks/adapters/work_areas.rb +57 -0
- data/lib/hecks/hecks/adapters/work_limits.rb +57 -0
- data/lib/hecks/hecks/build/build.bluebook +576 -0
- data/lib/hecks/hecks/check/check.bluebook +966 -0
- data/lib/hecks/hecks/codebase.behaviors +61 -5
- data/lib/hecks/hecks/composer.behaviors +1 -1
- data/lib/hecks/hecks/context_map.hecksagon +1 -1
- data/lib/hecks/hecks/custodian.behaviors +33 -7
- data/lib/hecks/hecks/delegate/delegate.bluebook +355 -0
- data/lib/hecks/hecks/deliver/deliver.bluebook +945 -0
- data/lib/hecks/hecks/deploy.behaviors +1 -1
- data/lib/hecks/hecks/evolve/evolve.bluebook +788 -0
- data/lib/hecks/hecks/find/find.bluebook +81 -0
- data/lib/hecks/hecks/hecks.behaviors +1 -1
- data/lib/hecks/hecks/hecks.bluebook +0 -133
- data/lib/hecks/hecks/hecks.contextmap +2 -0
- data/lib/hecks/hecks/hecks.hecksagon +185 -29
- data/lib/hecks/hecks/hecks.world +35 -9
- data/lib/hecks/hecks/implicit_moves.json +24 -0
- data/lib/hecks/hecks/migrate/migrate.bluebook +1066 -0
- data/lib/hecks/hecks/operate/operate.bluebook +695 -0
- data/lib/hecks/hecks/quiesce/quiesce.bluebook +117 -0
- data/lib/hecks/hecks/rehearse/rehearse.bluebook +133 -0
- data/lib/hecks/hecks/release/release.bluebook +916 -0
- data/lib/hecks/hecks/serve/serve.bluebook +134 -0
- data/lib/hecks/hecks/shapes.json +1 -15
- data/lib/hecks/hecks/site.behaviors +1 -1
- data/lib/hecks/hecks/start/start.bluebook +194 -0
- data/lib/hecks/hecks/test/test.bluebook +638 -0
- data/lib/hecks/hecks/tickets.world +14 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +22 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +34 -0
- data/lib/hecks/language/bluebook/command.bluebook +35 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +14 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +174 -54
- data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +14 -0
- data/lib/hecks/language/kinds/run.kind +120 -0
- data/lib/hecks/language/oidc.json +10 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +24 -0
- data/lib/hecks/module_folders.rb +31 -0
- data/lib/hecks/ports/key_vault.rb +1 -1
- data/lib/hecks/ports/persistence/append_only.rb +26 -8
- data/lib/hecks/ports/persistence/binding_policy.rb +3 -1
- data/lib/hecks/ports/persistence/codec_boundary.rb +1 -1
- data/lib/hecks/ports/persistence/mint_door.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +6 -5
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +5 -1
- data/lib/hecks/ports/persistence/plugins/era/era_status.rb +48 -0
- data/lib/hecks/ports/persistence/plugins/era/projected_bluebook.rb +127 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/additive_shape.rb +107 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/compose.rb +155 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/compose_render.rb +79 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/edge_files.rb +49 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/edge_route.rb +61 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/implicit_edge.rb +67 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reconcile.rb +130 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reconcile_files.rb +35 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +13 -5
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +5 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +1 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +11 -3
- data/lib/hecks/ports/persistence/stored_name_guard.rb +36 -0
- data/lib/hecks/ports/persistence.rb +2 -0
- data/lib/hecks/projections/ci_pipeline/table/checks.rb +137 -0
- data/lib/hecks/projections/ci_pipeline/table/lookup.rb +59 -0
- data/lib/hecks/projections/ci_pipeline/table/refusals.rb +58 -0
- data/lib/hecks/projections/ci_pipeline/table/rows.rb +119 -0
- data/lib/hecks/projections/ci_pipeline/table/tree.rb +30 -0
- data/lib/hecks/projections/ci_pipeline/table/typing.rb +92 -0
- data/lib/hecks/projections/ci_pipeline/table.rb +112 -0
- data/lib/hecks/projections/ci_pipeline/workflows.rb +162 -0
- data/lib/hecks/projections/ci_pipeline/yaml_text.rb +104 -0
- data/lib/hecks/projections/deploy/box/hosting.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_recipe.rb +1 -1
- data/lib/hecks/projections/deploy/box/roll_scripts.rb +1 -1
- data/lib/hecks/projections/deploy/box.rb +1 -1
- data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +1 -1
- data/lib/hecks/projections/deploy/templates/lambda/Makefile.tmpl +3 -3
- data/lib/hecks/projections/undo.rb +46 -0
- data/lib/hecks/projections.rb +2 -0
- data/lib/hecks/projector/cli_projector/claims.rb +11 -0
- data/lib/hecks/projector/cli_projector/command_help.rb +6 -1
- data/lib/hecks/projector/cli_projector/command_specs.rb +11 -1
- data/lib/hecks/projector/cli_projector/completion.rb +87 -0
- data/lib/hecks/projector/cli_projector/everyday.rb +40 -0
- data/lib/hecks/projector/cli_projector/json_listing.rb +77 -0
- data/lib/hecks/projector/cli_projector/listing.rb +1 -1
- data/lib/hecks/projector/cli_projector/modules.rb +39 -0
- data/lib/hecks/projector/cli_projector/query_specs.rb +1 -0
- data/lib/hecks/projector/cli_projector/renames.rb +58 -0
- data/lib/hecks/projector/cli_projector/search.rb +74 -0
- data/lib/hecks/projector/cli_projector/usage.rb +23 -6
- data/lib/hecks/projector/cli_projector.rb +24 -1
- data/lib/hecks/quality_control/adapters/ci_head.adapter +8 -0
- data/lib/hecks/quality_control/adapters/image_roll.adapter +9 -0
- data/lib/hecks/quality_control/adapters/image_roll.rb +158 -0
- data/lib/hecks/quality_control/adapters/main_maintenance.adapter +8 -0
- data/lib/hecks/quality_control/adapters/main_maintenance.rb +275 -0
- data/lib/hecks/quality_control/adapters/pump_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/pump_tools.rb +18 -0
- data/lib/hecks/quality_control/adapters/push_due_reader.adapter +8 -0
- data/lib/hecks/quality_control/adapters/push_due_reader.rb +99 -0
- data/lib/hecks/quality_control/adapters/qa_auto_mint.rb +183 -0
- data/lib/hecks/quality_control/adapters/qa_era_mint.rb +94 -0
- data/lib/hecks/quality_control/adapters/qa_quiesce_marker.rb +126 -0
- data/lib/hecks/quality_control/adapters/run_keys.rb +36 -0
- data/lib/hecks/quality_control/adapters/run_reader.adapter +7 -0
- data/lib/hecks/quality_control/adapters/run_reader.rb +188 -0
- data/lib/hecks/quality_control/cli/child.rb +1 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains/scanning.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +3 -3
- data/lib/hecks/quality_control/cli/qa_event_pump/attached.rb +67 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/consumer.rb +103 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/cursors.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/reactions.rb +46 -0
- data/lib/hecks/quality_control/cli/qa_event_pump/reader.rb +30 -0
- data/lib/hecks/quality_control/cli/qa_event_pump.rb +76 -0
- data/lib/hecks/quality_control/cli/qa_fix_main_bug/publishing.rb +79 -0
- data/lib/hecks/quality_control/cli/qa_fix_main_bug.rb +167 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains/evaluation.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_generated_domains/promotion.rb +3 -3
- data/lib/hecks/quality_control/cli/qa_main_gate/gate_run.rb +52 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/logging.rb +70 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/shell.rb +47 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/sweeping.rb +59 -0
- data/lib/hecks/quality_control/cli/qa_main_gate/worktree.rb +62 -0
- data/lib/hecks/quality_control/cli/qa_main_gate.rb +135 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_pr_check/checking.rb +2 -3
- data/lib/hecks/quality_control/cli/qa_push_nudge.rb +48 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles/seed.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep/seat.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_tick/event_pump_step.rb +34 -0
- data/lib/hecks/quality_control/cli/qa_tick/output.rb +16 -1
- data/lib/hecks/quality_control/cli/qa_tick/push_nudge_step.rb +28 -0
- data/lib/hecks/quality_control/cli/qa_tick/quiesce_guard.rb +51 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +36 -8
- data/lib/hecks/quality_control/quality_control.behaviors +65 -0
- data/lib/hecks/quality_control/quality_control.bluebook +1131 -11
- data/lib/hecks/quality_control/quality_control.hecksagon +11 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +138 -0
- data/lib/hecks/query_ir/touchpoints.rb +5 -7
- data/lib/hecks/refused.rb +21 -0
- data/lib/hecks/release/approval.rb +6 -3
- data/lib/hecks/release/conditions.rb +46 -0
- data/lib/hecks/release/runner/gem_publisher.rb +4 -4
- data/lib/hecks/release/version_commit.rb +48 -0
- data/lib/hecks/runtime/command_interpreter/hydration.rb +5 -4
- data/lib/hecks/runtime/command_interpreter/persisting.rb +11 -3
- data/lib/hecks/runtime/command_interpreter.rb +2 -2
- data/lib/hecks/runtime/command_rules/admissibility.rb +0 -2
- data/lib/hecks/runtime/command_rules/emission.rb +0 -1
- data/lib/hecks/runtime/dependency_planning/expression_reads.rb +0 -1
- data/lib/hecks/runtime/dispatcher/planning.rb +24 -0
- data/lib/hecks/runtime/dispatcher/routing.rb +6 -0
- data/lib/hecks/runtime/dispatcher/value_routing.rb +54 -0
- data/lib/hecks/runtime/dispatcher.rb +7 -1
- data/lib/hecks/runtime/dry_run_plan.rb +60 -0
- data/lib/hecks/runtime/entity_element/location.rb +0 -1
- data/lib/hecks/runtime/entity_element/mutations.rb +0 -1
- data/lib/hecks/runtime/entity_interpreter/locating.rb +5 -0
- data/lib/hecks/runtime/entity_interpreter.rb +0 -1
- data/lib/hecks/runtime/errors.rb +26 -0
- data/lib/hecks/runtime/instance.rb +0 -1
- data/lib/hecks/runtime/invocation_builder.rb +0 -1
- data/lib/hecks/runtime/outbox/consumer_runner.rb +9 -1
- data/lib/hecks/runtime/outbox/relay.rb +25 -4
- data/lib/hecks/runtime/outbox/runnable.rb +3 -1
- data/lib/hecks/runtime/outbox.rb +6 -2
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +18 -2
- data/lib/hecks/runtime/policy_interpreter.rb +17 -9
- data/lib/hecks/runtime/port_operation_interpreter.rb +21 -7
- data/lib/hecks/runtime/query_interpreter/arguments.rb +6 -5
- data/lib/hecks/runtime/reaction_invocation.rb +0 -1
- data/lib/hecks/runtime/refusal_wording.rb +12 -1
- data/lib/hecks/runtime/registry/context_maps.rb +1 -5
- data/lib/hecks/runtime/registry/declarations.rb +34 -4
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +15 -1
- data/lib/hecks/runtime/registry/runtime_state.rb +10 -0
- data/lib/hecks/runtime/registry/world_defaults.rb +24 -2
- data/lib/hecks/runtime/registry/world_names.rb +99 -0
- data/lib/hecks/runtime/registry.rb +33 -27
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +10 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +29 -3
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +0 -1
- data/lib/hecks/runtime/saga_interpreter/lifecycle.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter.rb +46 -2
- data/lib/hecks/runtime/value/coercion.rb +36 -8
- data/lib/hecks/rust_build/conformance.rb +16 -5
- data/lib/hecks/rust_build/parser.rb +25 -0
- data/lib/hecks/rust_build/project_rust/codegen_run.rb +45 -12
- data/lib/hecks/rust_build/project_rust/declared.rb +80 -0
- data/lib/hecks/rust_build/project_rust/features_header.rb +22 -0
- data/lib/hecks/rust_build/project_rust/manifest.rb +96 -0
- data/lib/hecks/rust_build/project_rust/meta.rb +36 -0
- data/lib/hecks/rust_build/project_rust.rb +28 -90
- data/lib/hecks/rust_build/write_if_changed.rb +19 -4
- data/lib/hecks/rust_build.rb +2 -1
- data/lib/hecks/rust_format.rb +32 -2
- data/lib/hecks/secrets.rb +111 -0
- data/lib/hecks/shape_ledger/edge_hygiene.rb +170 -0
- data/lib/hecks/shape_ledger/scope.rb +51 -0
- data/lib/hecks/shape_ledger/status.rb +89 -0
- data/lib/hecks/shape_ledger.rb +78 -33
- data/lib/hecks/site/bluebook/site.bluebook +1 -0
- data/lib/hecks/storehouse/audit.rb +34 -4
- data/lib/hecks/storehouse/callers.rb +8 -0
- data/lib/hecks/storehouse/dispatching.rb +14 -3
- data/lib/hecks/storehouse/identity.rb +41 -0
- data/lib/hecks/storehouse/querying.rb +7 -7
- data/lib/hecks/storehouse.rb +28 -10
- data/lib/hecks/tickets/bluebook/adapters/work_areas.adapter +7 -0
- data/lib/hecks/tickets/bluebook/adapters/work_limits.adapter +7 -0
- data/lib/hecks/tickets/bluebook/tickets.behaviors +70 -0
- data/lib/hecks/tickets/bluebook/tickets.bluebook +323 -28
- data/lib/hecks/tickets/bluebook/tickets.hecksagon +7 -0
- data/lib/hecks/tickets/bluebook/tickets.ports.hecksagon +17 -0
- data/lib/hecks/{cli → tools}/behaviors.rb +1 -1
- data/lib/hecks/{cli → tools}/canonicalise.rb +1 -1
- data/lib/hecks/{cli → tools}/check_engine_agreement.rb +1 -1
- data/lib/hecks/{cli → tools}/check_era.rb +6 -6
- data/lib/hecks/tools/ci_gates.rb +8 -2
- data/lib/hecks/tools/ci_workflows.rb +98 -0
- data/lib/hecks/{cli → tools}/console.rb +1 -1
- data/lib/hecks/{cli → tools}/deploy_template_diff.rb +1 -1
- data/lib/hecks/{cli → tools}/doc_coverage.rb +2 -2
- data/lib/hecks/{cli → tools}/document.rb +1 -1
- data/lib/hecks/{cli → tools}/domain_stub.rb +1 -1
- data/lib/hecks/{cli → tools}/domain_writer.rb +1 -1
- data/lib/hecks/tools/downstream_model_check.rb +122 -0
- data/lib/hecks/tools/evolve_run.rb +2 -2
- data/lib/hecks/{cli → tools}/expected_era.rb +1 -1
- data/lib/hecks/{cli → tools}/expression_projection.rb +1 -1
- data/lib/hecks/{cli → tools}/follow.rb +1 -1
- data/lib/hecks/tools/fuzz_sweep/options.rb +40 -5
- data/lib/hecks/tools/fuzz_sweep/pool.rb +12 -1
- data/lib/hecks/tools/fuzz_sweep/shards.rb +155 -0
- data/lib/hecks/tools/fuzz_sweep.rb +11 -5
- data/lib/hecks/tools/gate.rb +38 -29
- data/lib/hecks/tools/gate_memo/local_files.rb +33 -0
- data/lib/hecks/tools/gate_memo/rehearsal.rb +54 -0
- data/lib/hecks/tools/gate_memo/ruby_files.rb +152 -0
- data/lib/hecks/tools/gate_memo/session.rb +114 -0
- data/lib/hecks/tools/gate_memo/standalone.rb +67 -0
- data/lib/hecks/tools/gate_memo.rb +196 -0
- data/lib/hecks/tools/gate_report.rb +56 -0
- data/lib/hecks/{cli → tools}/history.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_agent.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_aggregate.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_draft.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_record.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_run.rb +2 -2
- data/lib/hecks/{cli → tools}/interview_session/agent_state.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/catalog.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/manual_findings.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session/proposals.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_session.rb +2 -2
- data/lib/hecks/{cli → tools}/interview_shape/lifecycle.rb +1 -1
- data/lib/hecks/{cli → tools}/interview_shape.rb +1 -1
- data/lib/hecks/{cli → tools}/ir.rb +1 -1
- data/lib/hecks/tools/lanes/files.rb +1 -1
- data/lib/hecks/tools/lanes/watch_workflow.rb +6 -8
- data/lib/hecks/tools/lanes/workflow.rb +1 -1
- data/lib/hecks/tools/lanes.rb +1 -1
- data/lib/hecks/{cli → tools}/mcp.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check/examination.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check/sources.rb +1 -1
- data/lib/hecks/{cli → tools}/model_check.rb +1 -1
- data/lib/hecks/tools/move_disables/reasons.rb +35 -0
- data/lib/hecks/tools/move_disables.rb +211 -0
- data/lib/hecks/tools/move_former_name.rb +105 -0
- data/lib/hecks/{cli → tools}/pattern_cases.rb +1 -1
- data/lib/hecks/{cli → tools}/persistence_notice.rb +1 -1
- data/lib/hecks/{cli → tools}/present.rb +1 -1
- data/lib/hecks/{cli → tools}/project_cli/launcher_source.rb +32 -22
- data/lib/hecks/{cli → tools}/project_cli/templates.rb +22 -15
- data/lib/hecks/{cli → tools}/project_cli.rb +11 -7
- data/lib/hecks/{cli → tools}/project_diagrams.rb +3 -3
- data/lib/hecks/{cli → tools}/project_glossary.rb +2 -2
- data/lib/hecks/{cli → tools}/reference.rb +2 -2
- data/lib/hecks/{cli → tools}/refresh_projections.rb +1 -1
- data/lib/hecks/{cli → tools}/refresh_rspec_runtime_baseline.rb +1 -1
- data/lib/hecks/tools/regeneration_run/pool.rb +148 -0
- data/lib/hecks/tools/regeneration_run/scratch.rb +76 -0
- data/lib/hecks/tools/regeneration_run.rb +125 -103
- data/lib/hecks/{cli → tools}/release.rb +1 -1
- data/lib/hecks/{cli → tools}/release_gem.rb +1 -1
- data/lib/hecks/{cli → tools}/rspec_io_parallel_files.rb +1 -1
- data/lib/hecks/{cli → tools}/rspec_shard_files.rb +1 -1
- data/lib/hecks/{cli → tools}/run.rb +9 -2
- data/lib/hecks/{cli → tools}/run_expectations.rb +1 -1
- data/lib/hecks/{cli → tools}/seed_semantics_corpus.rb +4 -4
- data/lib/hecks/{cli → tools}/serve_query_ir_mcp.rb +1 -1
- data/lib/hecks/{cli → tools}/shape.rb +3 -2
- data/lib/hecks/{cli → tools}/smoke_http/checks.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http/settings.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http/transport.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_http.rb +1 -1
- data/lib/hecks/{cli → tools}/smoke_test.rb +1 -1
- data/lib/hecks/{cli → tools}/spec_example.rb +1 -1
- data/lib/hecks/tools/stage_progress.rb +54 -0
- data/lib/hecks/{cli → tools}/statements.rb +1 -1
- data/lib/hecks/{cli → tools}/stores.rb +1 -1
- data/lib/hecks/{cli → tools}/stress_concurrency_specs/reporting.rb +1 -1
- data/lib/hecks/{cli → tools}/stress_concurrency_specs/usage.rb +4 -4
- data/lib/hecks/{cli → tools}/stress_concurrency_specs.rb +3 -3
- data/lib/hecks/tools/tenant_provisioning.rb +23 -0
- data/lib/hecks/tools/tools_doc.rb +10 -8
- data/lib/hecks/tools/translation_audit/edges.rb +21 -16
- data/lib/hecks/tools/translation_audit/verdicts.rb +1 -1
- data/lib/hecks/tools/translation_audit.rb +1 -1
- data/lib/hecks/tools/translation_scaffold.rb +1 -1
- data/lib/hecks/tools.rb +4 -1
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +61 -31
- data/lib/hecks/workflow_pagination/judge.rb +48 -0
- data/lib/hecks/workflow_pagination/statement.rb +50 -0
- data/lib/hecks/workflow_pagination.rb +58 -0
- data/lib/hecks.rb +2 -0
- data/lib/rubocop/cop/hecks/bare_event_and_query_names.rb +58 -0
- data/lib/rubocop/cop/hecks/correlates_by_aggregate.rb +39 -0
- data/lib/rubocop/cop/hecks/creating_command_sets.rb +75 -0
- data/lib/rubocop/cop/hecks/invariant_expression_language.rb +47 -0
- data/lib/rubocop/cop/hecks/lifecycle_needs_attribute.rb +58 -0
- data/lib/rubocop/cop/hecks/no_id_string_attribute.rb +49 -0
- data/lib/rubocop/cop/hecks/one_terminal_mark_per_lifecycle.rb +47 -0
- data/lib/rubocop/cop/hecks/value_object_shorthand.rb +56 -0
- data/prebuilt/13c04bdc5970295b310f0a980d397ba722232c8da99cc1a0cdb383249921e871.marshal +0 -0
- data/prebuilt/e3857b77f47d9ecc1787b2e1f5136364f3cb3444ef4aea5479f3b98167affea2.marshal +0 -0
- data/qa/settings.yml +23 -0
- data/rust/.gitignore +0 -6
- data/rust/Cargo.toml +2 -1
- data/rust/build/Cargo.toml +1 -1
- data/rust/build/src/binding_pass.rs +57 -4
- data/rust/build/src/pipeline.rs +6 -4
- data/rust/build/src/resolve.rs +1 -0
- data/rust/codegen/Cargo.toml +1 -1
- data/rust/codegen/src/domain_generator.rs +3 -0
- data/rust/codegen/src/json_codec.rs +182 -23
- data/rust/codegen/src/one_of_references.rs +1 -0
- data/rust/codegen/src/queries.rs +20 -2
- data/rust/codegen/src/registry.rs +21 -5
- data/rust/expr/Cargo.toml +1 -1
- data/rust/host/Cargo.toml +1 -1
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/core/Cargo.toml +1 -1
- data/rust/host/src/bin/mint_harness.rs +1 -0
- data/rust/host/src/boot.rs +1 -0
- data/rust/host/src/store/mint.rs +40 -6
- data/rust/lsp/Cargo.toml +1 -1
- data/rust/parser/Cargo.toml +1 -1
- data/rust/parser/src/build/correlation_keys.rs +125 -0
- data/rust/parser/src/build/mod.rs +1 -0
- data/rust/parser/src/emit.rs +55 -3
- data/rust/parser/src/ir.rs +33 -1
- data/rust/parser/src/keywords.rs +289 -1
- data/rust/parser/src/main.rs +2 -0
- data/rust/parser/src/parse/aggregate.rs +10 -1
- data/rust/parser/src/parse/audience.rs +65 -0
- data/rust/parser/src/parse/command.rs +14 -0
- data/rust/parser/src/parse/declaration.rs +97 -0
- data/rust/parser/src/parse/domain_port.rs +6 -0
- data/rust/parser/src/parse/mod.rs +1 -0
- data/rust/parser/src/parse/process_manager.rs +17 -10
- data/rust/parser/src/parse/world.rs +12 -8
- data/rust/parser/src/render_ruby.rs +9 -0
- data/rust/parser/src/sentence/format.rs +3 -0
- data/rust/parser/src/sentence/process.rs +6 -2
- data/rust/src/exemplar/json.rs +17 -0
- data/rust/src/kernel/cli.rs +27 -3
- data/rust/src/kernel/dispatch.rs +4 -2
- data/rust/src/kernel/json.rs +62 -0
- data/rust/src/kernel/orchestrate.rs +28 -3
- data/rust/src/kernel/orchestrate_guard_tests.rs +12 -12
- data/rust/web/Cargo.toml +1 -1
- metadata +389 -96
- data/lib/hecks/cli/command_table.rb +0 -72
- data/lib/hecks/cli/launcher_words.rb +0 -168
- data/lib/hecks/cli.rb +0 -133
- data/lib/hecks/hecks/agents.bluebook +0 -246
- data/lib/hecks/hecks/codebase.bluebook +0 -3209
- data/lib/hecks/hecks/custodian.bluebook +0 -1300
- data/lib/hecks/hecks/ledger.bluebook +0 -190
- data/lib/hecks/hecks/rehearsal.bluebook +0 -437
- data/lib/hecks/hecks/tooling.bluebook +0 -1234
- data/lib/hecks/hecks/translations/2-148748.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-15a2e4.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-1b447c.bluebook +0 -5
- data/lib/hecks/hecks/translations/2-240474.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-44446d.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-46ca26.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-473eab.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-75cc28.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-781c07.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-84c18b.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-aa5fff.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-bfdb48.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-cd96d8.bluebook +0 -10
- data/lib/hecks/hecks/translations/2-d43f71.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-eea577.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-f53248.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-fbb677.bluebook +0 -2
- data/lib/hecks/hecks/translations/2-ffdf12.bluebook +0 -6
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +0 -36
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +0 -56
- data/prebuilt/31cf81e12f16236ad26249be590cfea3799c9db67432e6a4ef54b801c355b6ae.marshal +0 -0
- data/prebuilt/68ecb2bd3abb1a221007db4f2b0375834c13aaccac8f2b99778e8517f11aa113.marshal +0 -0
- data/prebuilt/verdicts-0328c2403383837d780ad5ed81d1da351c56436b894cf9015b5d56b8f1f1bf10.json +0 -1
|
@@ -99,14 +99,14 @@ module Hecks
|
|
|
99
99
|
[argv.first(split), argv.drop(split + 1).reject { |arg| arg == "--against" }]
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
# `hecks project_rust
|
|
102
|
+
# `hecks build.project_rust!` reads exactly `<name>/bluebook/<name>.bluebook`, so refuse anything
|
|
103
103
|
# else early.
|
|
104
104
|
def refuse_unless_stress_domain_shaped!(path)
|
|
105
105
|
expected = File.join(path, "bluebook", "#{File.basename(path)}.bluebook")
|
|
106
106
|
return if File.file?(expected)
|
|
107
107
|
|
|
108
108
|
raise UsageError, "#{path} is not shaped like a stress domain: expected #{expected} to exist " \
|
|
109
|
-
"(`<name>/bluebook/<name>.bluebook` — a flat file breaks `hecks project_rust
|
|
109
|
+
"(`<name>/bluebook/<name>.bluebook` — a flat file breaks `hecks build.project_rust!`; " \
|
|
110
110
|
"see qa/stress_domains/ledger_ordering/NOTES.md)"
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -121,7 +121,7 @@ module Hecks
|
|
|
121
121
|
raise Stopped
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
JSON.parse(out).
|
|
124
|
+
JSON.parse(out).filter_map { |row| row["path"] }
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
def normalize(path) = File.expand_path(path, @root)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module QualityControlCli
|
|
5
|
+
class QaEventPump
|
|
6
|
+
# The domains the pump reads and reacts for: each name with the directory that boots it. The
|
|
7
|
+
# ledger, `QualityControl`, is the one whose `EventCursor` rows hold the positions.
|
|
8
|
+
class Attached
|
|
9
|
+
# @param root [String] the repository root the default directories are found under
|
|
10
|
+
# @param env [Hash{String => String}] `QA_SWEEP_DOMAIN_DIR` overrides the ledger's directory
|
|
11
|
+
# @param dirs [Hash{String => String}, nil] the directories by domain name, in place of the
|
|
12
|
+
# defaults
|
|
13
|
+
def initialize(root:, env: ENV, dirs: nil)
|
|
14
|
+
@dirs = dirs || default_dirs(root, env)
|
|
15
|
+
@runtimes = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Array<String>] the attached domain names, in the order the pump visits them
|
|
19
|
+
def names = @dirs.keys
|
|
20
|
+
|
|
21
|
+
# @param name [String] a domain name
|
|
22
|
+
# @return [Boolean] whether the pump attaches this domain
|
|
23
|
+
def known?(name) = @dirs.key?(name)
|
|
24
|
+
|
|
25
|
+
# @return [Array<Hecks::Registry>] the registries of every domain booted so far this run
|
|
26
|
+
def registries = @runtimes.values.map(&:registry)
|
|
27
|
+
|
|
28
|
+
# @param name [String] an attached domain name
|
|
29
|
+
# @return [String] the directory that boots it
|
|
30
|
+
def dir(name) = @dirs.fetch(name)
|
|
31
|
+
|
|
32
|
+
# @param name [String] an attached domain name
|
|
33
|
+
# @return [Hecks::Runtime::Dispatcher] the domain booted once, and kept for the run
|
|
34
|
+
def runtime(name)
|
|
35
|
+
@runtimes[name] ||= Hecks.boot(dir(name))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Whether a domain booted in this process has already delivered `policy` for `event`. The
|
|
39
|
+
# reaction log keeps the event id each reaction answered, so a second run of the same event
|
|
40
|
+
# in this process is skipped whatever the cursor says.
|
|
41
|
+
#
|
|
42
|
+
# @param event [Hecks::Runtime::Event] the event, with its id
|
|
43
|
+
# @param policy [Hecks::Bluebook::Policy] the policy about to run
|
|
44
|
+
# @return [Boolean] true when a delivered reaction for this event and policy is logged
|
|
45
|
+
def reacted?(event, policy)
|
|
46
|
+
registries.any? do |registry|
|
|
47
|
+
registry.reaction_log.any? do |record|
|
|
48
|
+
record[:delivered] && record[:policy] == policy.name && record[:on] == event.name &&
|
|
49
|
+
registry.reaction_event(record) == event.id
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def default_dirs(root, env)
|
|
57
|
+
{
|
|
58
|
+
"QualityControl" => env.fetch("QA_SWEEP_DOMAIN_DIR", File.join(root, "qa/bluebook")),
|
|
59
|
+
"Fixer" => File.join(root, "lib/hecks/fixer"),
|
|
60
|
+
"Coder" => File.join(root, "lib/hecks/coder"),
|
|
61
|
+
"CiPipeline" => File.join(root, "lib/hecks/ci_pipeline")
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks/naming"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module QualityControlCli
|
|
7
|
+
class QaEventPump
|
|
8
|
+
# One attached domain as a consumer: the logs of the domains its hecksagon subscribes to, read
|
|
9
|
+
# past each cursor, with the policies that react to each event run through the domain's own
|
|
10
|
+
# runtime. A subscription to a domain the pump does not attach is named, not read.
|
|
11
|
+
class Consumer
|
|
12
|
+
# @param name [String] the consumer's domain name
|
|
13
|
+
# @param attached [Attached] the attached domains
|
|
14
|
+
# @param cursors [Cursors] where the positions are kept
|
|
15
|
+
# @param reactions [Reactions] where the reactions already made are kept
|
|
16
|
+
def initialize(name, attached:, cursors:, reactions:)
|
|
17
|
+
@name = name
|
|
18
|
+
@attached = attached
|
|
19
|
+
@cursors = cursors
|
|
20
|
+
@reactions = reactions
|
|
21
|
+
@failed = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [Boolean] whether reading or reacting stopped this consumer
|
|
25
|
+
def failed? = @failed
|
|
26
|
+
|
|
27
|
+
# Reads every attached log this consumer subscribes to, and names each subscription it
|
|
28
|
+
# cannot read.
|
|
29
|
+
#
|
|
30
|
+
# @return [Array<String>] one line per reaction and per problem
|
|
31
|
+
def lines
|
|
32
|
+
producers.flat_map { |producer| read(producer) } + unattached
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def runtime = @attached.runtime(@name)
|
|
38
|
+
|
|
39
|
+
def subscribed
|
|
40
|
+
(runtime.registry.hecksagon(@name)&.subscriptions || []).filter_map { |event| Naming.qualifier(event) }.uniq
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def producers = subscribed.select { |domain| @attached.known?(domain) }
|
|
44
|
+
|
|
45
|
+
def unattached
|
|
46
|
+
(subscribed - producers).map { |domain| "#{@name} subscribes to #{domain}, which the pump does not attach" }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Reads one producer's log past this consumer's cursor, reacting to each entry in turn. A
|
|
50
|
+
# stop leaves the cursor on the last entry that was reacted to.
|
|
51
|
+
def read(producer)
|
|
52
|
+
start = @cursors.position(producer, @name)
|
|
53
|
+
entries = Reader.after(@attached.dir(producer), start)[:events]
|
|
54
|
+
entries.each_with_index.flat_map { |entry, index| react(producer, entry, start + index + 1) }
|
|
55
|
+
rescue StandardError => e
|
|
56
|
+
@failed = true
|
|
57
|
+
["#{@name} <- #{producer}: stopped, #{e.class}: #{e.message}"]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Runs each policy that reacts to the entry and that neither the ledger nor this process
|
|
61
|
+
# holds a reaction for, then moves the cursor past it. A reaction is recorded as soon as
|
|
62
|
+
# its policy answers, before the cursor moves. The reactions and the cursor share one
|
|
63
|
+
# transaction where the ledger's store has one, so a stop between them rolls both back
|
|
64
|
+
# and the rerun repeats both.
|
|
65
|
+
def react(producer, entry, position)
|
|
66
|
+
event = Reader.event(entry)
|
|
67
|
+
@cursors.transaction do
|
|
68
|
+
lines = runtime.outbox.policies_for(event, producer).flat_map do |policy, home|
|
|
69
|
+
next [] if reacted?(event, policy)
|
|
70
|
+
|
|
71
|
+
fire(event, policy, home, producer, position)
|
|
72
|
+
end
|
|
73
|
+
@cursors.advance(producer, @name, position)
|
|
74
|
+
lines
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Whether the policy has already reacted to this event: recorded in the ledger by an
|
|
79
|
+
# earlier pass, or delivered in this process by a domain attached here, by either path.
|
|
80
|
+
def reacted?(event, policy)
|
|
81
|
+
@reactions.recorded?(@name, event.id, policy.name) || @attached.reacted?(event, policy)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def fire(event, policy, home, producer, position)
|
|
85
|
+
log = runtime.reactions
|
|
86
|
+
before = log.size
|
|
87
|
+
runtime.outbox.react_policy(event, policy: policy, home: home, domain: producer,
|
|
88
|
+
event_uid: "#{producer}##{position}")
|
|
89
|
+
records = log.drop(before)
|
|
90
|
+
@reactions.record(@name, event.id, policy.name) if records.any?
|
|
91
|
+
records.map { |record| describe(record, policy, event, producer) }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def describe(record, policy, event, producer)
|
|
95
|
+
label = "#{@name} <- #{producer} #{event.name}: #{policy.name}"
|
|
96
|
+
return "reacted: #{label}" if record[:delivered]
|
|
97
|
+
|
|
98
|
+
"refused: #{label}: #{record[:reason]}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module QualityControlCli
|
|
5
|
+
class QaEventPump
|
|
6
|
+
# The positions the pump has read to, kept as the ledger's `EventCursor` rows: one per (log,
|
|
7
|
+
# consumer). A row is opened at the start of the log the first time a consumer reads it.
|
|
8
|
+
class Cursors
|
|
9
|
+
# @param runtime [Hecks::Runtime::Dispatcher] the booted ledger the rows live in
|
|
10
|
+
def initialize(runtime)
|
|
11
|
+
@runtime = runtime
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @param log [String] the domain whose event log is read
|
|
15
|
+
# @param consumer [String] the domain whose policies react
|
|
16
|
+
# @return [Integer] the count of log entries the consumer has reacted to
|
|
17
|
+
def position(log, consumer)
|
|
18
|
+
row = row_for(key(log, consumer)) || open_row(log, consumer)
|
|
19
|
+
row[:position][:value]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Moves one consumer's cursor past the entries it has reacted to.
|
|
23
|
+
#
|
|
24
|
+
# @param log [String] the domain whose event log was read
|
|
25
|
+
# @param consumer [String] the domain whose policies reacted
|
|
26
|
+
# @param position [Integer] the count of entries now reacted to
|
|
27
|
+
# @return [void]
|
|
28
|
+
def advance(log, consumer, position)
|
|
29
|
+
@runtime.dispatch_flat("QualityControl::EventCursor.Advance", to: key(log, consumer), position: position)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Runs the block in one transaction on the ledger's store where that store has one, so a
|
|
33
|
+
# reaction and the cursor past it commit together or not at all. A store without
|
|
34
|
+
# transactions (Memory) yields, and the reaction log is then the only guard against a rerun.
|
|
35
|
+
#
|
|
36
|
+
# @yield the reaction and the cursor move, as one unit
|
|
37
|
+
# @return [Object] the block's own value
|
|
38
|
+
def transaction(&)
|
|
39
|
+
repository = @runtime.registry.repository("QualityControl", cursor_aggregate)
|
|
40
|
+
repository.respond_to?(:transaction) ? repository.transaction(&) : yield
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def cursor_aggregate = ledger_bluebook.aggregates.find { |aggregate| aggregate.hecks_name == "EventCursor" }
|
|
46
|
+
|
|
47
|
+
def ledger_bluebook = @runtime.registry.bluebook("QualityControl")
|
|
48
|
+
|
|
49
|
+
def key(log, consumer) = "#{log}/#{consumer}"
|
|
50
|
+
|
|
51
|
+
def row_for(key) = @runtime.query("QualityControl::EventCursor.All").find { |row| row[:key][:value] == key }
|
|
52
|
+
|
|
53
|
+
def open_row(log, consumer)
|
|
54
|
+
@runtime.dispatch_flat("QualityControl::EventCursor.Start", key: key(log, consumer), log: log, consumer: consumer)
|
|
55
|
+
row_for(key(log, consumer))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module QualityControlCli
|
|
5
|
+
class QaEventPump
|
|
6
|
+
# The reactions the pump has made, kept as the ledger's `EventReaction` rows: one per
|
|
7
|
+
# (consumer, event, policy). The pump asks before it runs a policy, and records the reaction
|
|
8
|
+
# once the policy's command has answered, delivered or refused. The keys are read once, on
|
|
9
|
+
# first use, and kept for the run, so a pass costs one query however many events it reads.
|
|
10
|
+
class Reactions
|
|
11
|
+
# @param runtime [Hecks::Runtime::Dispatcher] the booted ledger the rows live in
|
|
12
|
+
def initialize(runtime)
|
|
13
|
+
@runtime = runtime
|
|
14
|
+
@known = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param consumer [String] the domain whose policy would run
|
|
18
|
+
# @param event_id [String] the id of the event the policy would react to
|
|
19
|
+
# @param policy [String] the policy's name
|
|
20
|
+
# @return [Boolean] whether the ledger already holds this reaction
|
|
21
|
+
def recorded?(consumer, event_id, policy)
|
|
22
|
+
known.include?(key(consumer, event_id, policy))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param consumer [String] the domain whose policy answered
|
|
26
|
+
# @param event_id [String] the id of the event it answered
|
|
27
|
+
# @param policy [String] the policy's name
|
|
28
|
+
# @return [void]
|
|
29
|
+
def record(consumer, event_id, policy)
|
|
30
|
+
row = key(consumer, event_id, policy)
|
|
31
|
+
@runtime.dispatch_flat("QualityControl::EventReaction.Record", key: row, consumer: consumer,
|
|
32
|
+
event_id: event_id, policy: policy)
|
|
33
|
+
known << row
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def known
|
|
39
|
+
@known ||= @runtime.query("QualityControl::EventReaction.All").to_set { |row| row[:key][:value] }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def key(consumer, event_id, policy) = "#{consumer}/#{event_id}/#{policy}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "hecks/hecks/adapters/in_process_boot"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module QualityControlCli
|
|
8
|
+
class QaEventPump
|
|
9
|
+
# Reads a domain's event log past a cursor through the `Operation.Follow` query, and turns
|
|
10
|
+
# each entry back into an event a policy can react to.
|
|
11
|
+
module Reader
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# @param dir [String] the directory of the domain whose log is read
|
|
15
|
+
# @param position [Integer] the count of entries already read
|
|
16
|
+
# @return [Hash] `cursor:` the count now read to, and `events:` the entries past `position`
|
|
17
|
+
# (each with its payload as JSON text, as the query answers it)
|
|
18
|
+
def after(dir, position)
|
|
19
|
+
Hecks::Adapters::InProcessBoot.new.follow(domain: dir, since: position, wait: 0)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param entry [Hash] one entry the query answered
|
|
23
|
+
# @return [Hecks::Runtime::Event] the event, with its payload parsed back to a hash
|
|
24
|
+
def event(entry)
|
|
25
|
+
Hecks::Runtime::Outbox.event_from(entry.merge("payload" => JSON.parse(entry["payload"])))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../hecks"
|
|
4
|
+
# The era subsystem does not load with core (ADR 0033); the QualityControl ledger binds it.
|
|
5
|
+
require_relative "../../ports/persistence/plugins/era"
|
|
6
|
+
require_relative "qa_event_pump/attached"
|
|
7
|
+
require_relative "qa_event_pump/cursors"
|
|
8
|
+
require_relative "qa_event_pump/reactions"
|
|
9
|
+
require_relative "qa_event_pump/reader"
|
|
10
|
+
require_relative "qa_event_pump/consumer"
|
|
11
|
+
|
|
12
|
+
module Hecks
|
|
13
|
+
module QualityControlCli
|
|
14
|
+
# The command behind `hecks quality_control event_pump.pump!`: reads each attached domain's
|
|
15
|
+
# event log past its cursor and runs the policies that react to what it reads. A consumer reads
|
|
16
|
+
# the logs its hecksagon subscribes to, and each cursor is one (log, consumer) row of the
|
|
17
|
+
# ledger's `EventCursor`. The pump writes no domain's event log.
|
|
18
|
+
#
|
|
19
|
+
# A policy that has an `EventReaction` row for its event is not run again. A refused reaction is
|
|
20
|
+
# recorded and named, and the cursor moves past it. A cursor does not move for an event whose
|
|
21
|
+
# reaction could not run at all: that consumer stops, and the pump exits 1.
|
|
22
|
+
class QaEventPump
|
|
23
|
+
EXIT_OK = 0
|
|
24
|
+
EXIT_ERROR = 1
|
|
25
|
+
|
|
26
|
+
USAGE = "usage: hecks quality_control event_pump.pump!"
|
|
27
|
+
|
|
28
|
+
# Runs the pump, or prints its usage for `--help`.
|
|
29
|
+
#
|
|
30
|
+
# @param argv [Array<String>] no arguments
|
|
31
|
+
# @param root [String] the repository root the attached domains are found under
|
|
32
|
+
# @param env [Hash{String => String}] `QA_SWEEP_DOMAIN_DIR` picks the ledger's bluebook
|
|
33
|
+
# directory
|
|
34
|
+
# @return [Integer] 0 when every consumer read its logs, 1 when one could not
|
|
35
|
+
# @raise [SystemExit] when given arguments
|
|
36
|
+
def self.call(argv, root:, env: ENV)
|
|
37
|
+
return reject(argv) unless argv.empty?
|
|
38
|
+
|
|
39
|
+
new(root: root, env: env).run
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param argv [Array<String>] the arguments given
|
|
43
|
+
# @return [Integer] 0 for `--help`
|
|
44
|
+
# @raise [SystemExit] for any other argument
|
|
45
|
+
def self.reject(argv)
|
|
46
|
+
return puts(USAGE) && EXIT_OK if %w[-h --help].include?(argv.first)
|
|
47
|
+
|
|
48
|
+
abort "#{USAGE}\nthis command takes no arguments — one pump is always the same pump"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @param root [String] the repository root
|
|
52
|
+
# @param env [Hash{String => String}] the environment the ledger's directory is read from
|
|
53
|
+
# @param attached [Attached, nil] the attached domains; built from `root` and `env` when
|
|
54
|
+
# absent
|
|
55
|
+
def initialize(root:, env: ENV, attached: nil)
|
|
56
|
+
@attached = attached || Attached.new(root: root, env: env)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Runs every consumer once and prints what each reaction did.
|
|
60
|
+
#
|
|
61
|
+
# @return [Integer] 0 or 1, as `call` answers
|
|
62
|
+
def run
|
|
63
|
+
ledger = @attached.runtime("QualityControl")
|
|
64
|
+
cursors = Cursors.new(ledger)
|
|
65
|
+
reactions = Reactions.new(ledger)
|
|
66
|
+
consumers = @attached.names.map do |name|
|
|
67
|
+
Consumer.new(name, attached: @attached, cursors: cursors, reactions: reactions)
|
|
68
|
+
end
|
|
69
|
+
lines = consumers.flat_map(&:lines)
|
|
70
|
+
lines.each { |line| puts line }
|
|
71
|
+
puts "event pump: #{lines.size} line(s) reported"
|
|
72
|
+
consumers.any?(&:failed?) ? EXIT_ERROR : EXIT_OK
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module QualityControlCli
|
|
5
|
+
class QaFixMainBug
|
|
6
|
+
# What happens after a fix is committed: the ledger records the investigation and the fix, the branch
|
|
7
|
+
# lands on local main, the ledger records the verification, and main is pushed through the push train.
|
|
8
|
+
# The push runs only after the quick gate is green on main's head, and origin's main is fetched right
|
|
9
|
+
# before it.
|
|
10
|
+
module Publishing
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# Records where the bug lives and why, before any fix is attempted. Only a logged bug is
|
|
14
|
+
# investigated; a bug already investigated keeps its first note.
|
|
15
|
+
def investigate(row)
|
|
16
|
+
return unless row[:status] == "logged"
|
|
17
|
+
|
|
18
|
+
files = files_of(row)
|
|
19
|
+
::QualityControl::Bug.find(row[:reference][:value]).investigate!(
|
|
20
|
+
site: { value: files.empty? ? "the quick gate's output" : files.join(", ") },
|
|
21
|
+
cause: { value: "the quick gate's #{check_id(row)} check is red on main" }
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def stuck(row, reason)
|
|
26
|
+
Outcome.new(EXIT_STUCK,
|
|
27
|
+
"stays a bug: #{reason} (#{row[:reference][:value]}); left investigating for the owner")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def land_and_push(row, branch, sha)
|
|
31
|
+
reference = row[:reference][:value]
|
|
32
|
+
bug = ::QualityControl::Bug.find(reference)
|
|
33
|
+
bug.fix!(reference: { value: reference }, commit: { value: sha })
|
|
34
|
+
output, landed = @shell.land(@root, branch)
|
|
35
|
+
return Outcome.new(EXIT_STUCK, "stopped: landing #{branch} was refused: #{output.strip}") unless landed
|
|
36
|
+
|
|
37
|
+
delete_branch(branch)
|
|
38
|
+
bug.verify!(evidence: { value: "quick gate green on #{sha[0, 7]} and landed on local main from #{branch}" })
|
|
39
|
+
push_main(reference)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def delete_branch(branch)
|
|
43
|
+
QaMainGate::Worktree.try(@root, "branch", "-d", branch)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Array<QaMainGate::GateRun::Result>] the checks that are red on a commit of main
|
|
47
|
+
def red_at(head)
|
|
48
|
+
QaMainGate::Worktree.with(root: @root, ref: head) { |dir| @gate.run(dir) }.reject(&:passed)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def push_main(reference)
|
|
52
|
+
head = QaMainGate::Worktree.git!(@root, "rev-parse", "main")
|
|
53
|
+
reds = red_at(head)
|
|
54
|
+
return unpushed("main at #{head[0, 7]} is red: #{reds.map(&:id).join(", ")}") if reds.any?
|
|
55
|
+
|
|
56
|
+
behind = behind_origin
|
|
57
|
+
return unpushed(behind) if behind
|
|
58
|
+
|
|
59
|
+
output, pushed = @shell.push(@root)
|
|
60
|
+
return Outcome.new(EXIT_OK, "landed and pushed #{reference} (main at #{head[0, 7]})") if pushed
|
|
61
|
+
|
|
62
|
+
unpushed("the push train refused main: #{output.strip}")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Fetches origin's main right before the push. @return [String, nil] why main cannot be pushed as it is
|
|
66
|
+
def behind_origin
|
|
67
|
+
QaMainGate::Worktree.git!(@root, "fetch", "origin", "main")
|
|
68
|
+
return nil if QaMainGate::Worktree.git?(@root, "merge-base", "--is-ancestor", "origin/main", "main")
|
|
69
|
+
|
|
70
|
+
"origin/main has commits local main does not have; pull main first (nothing was pushed)"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def unpushed(reason)
|
|
74
|
+
Outcome.new(EXIT_STUCK, "landed, not pushed: #{reason}")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../hecks"
|
|
4
|
+
# The era subsystem does not load with core (ADR 0033); the QualityControl ledger binds it.
|
|
5
|
+
require_relative "../../ports/persistence/plugins/era"
|
|
6
|
+
require_relative "qa_main_gate/gate_run"
|
|
7
|
+
require_relative "qa_main_gate/worktree"
|
|
8
|
+
require_relative "qa_main_gate/shell"
|
|
9
|
+
require_relative "qa_main_gate/logging"
|
|
10
|
+
require_relative "qa_fix_main_bug/publishing"
|
|
11
|
+
|
|
12
|
+
module Hecks
|
|
13
|
+
module QualityControlCli
|
|
14
|
+
# The command behind `hecks quality_control bug.fix_and_land --bug BUG#n`: takes one self-contained red-main
|
|
15
|
+
# bug through a fix on a fresh branch off main, the quick gate on that exact commit, a landing on local main,
|
|
16
|
+
# and a push through the push train. A bug triaged bigger, or one whose fixer changes nothing or leaves a
|
|
17
|
+
# check red, stops before anything lands and stays open for the owner. Nothing is landed unless the gate is
|
|
18
|
+
# green on the commit, and nothing is pushed unless the gate is green on main's head.
|
|
19
|
+
#
|
|
20
|
+
# Exit 0 when the fix is landed (pushed, or the push's refusal is printed), 1 when refused before any fix,
|
|
21
|
+
# 2 when the fix stays red.
|
|
22
|
+
class QaFixMainBug
|
|
23
|
+
include Publishing
|
|
24
|
+
|
|
25
|
+
EXIT_OK = 0
|
|
26
|
+
EXIT_REFUSED = 1
|
|
27
|
+
EXIT_STUCK = 2
|
|
28
|
+
|
|
29
|
+
# The file a `rubocop` offense line starts with, as `file.rb:12:3: C: ...` prints it.
|
|
30
|
+
RUBOCOP_OFFENSE = /^(\S+\.rb):\d+:\d+:/
|
|
31
|
+
|
|
32
|
+
# The trailer every commit the practice writes carries.
|
|
33
|
+
TRAILER = "Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>"
|
|
34
|
+
|
|
35
|
+
USAGE = "usage: hecks quality_control bug.fix_and_land --bug BUG#n"
|
|
36
|
+
|
|
37
|
+
# The outcome of one bug's attempt.
|
|
38
|
+
#
|
|
39
|
+
# @!attribute [r] code
|
|
40
|
+
# @return [Integer] the exit status this attempt earns
|
|
41
|
+
# @!attribute [r] message
|
|
42
|
+
# @return [String] one line for the report
|
|
43
|
+
Outcome = Struct.new(:code, :message)
|
|
44
|
+
|
|
45
|
+
# A fix attempt that did not produce a green commit.
|
|
46
|
+
Stuck = Struct.new(:reason)
|
|
47
|
+
|
|
48
|
+
# Runs the command.
|
|
49
|
+
#
|
|
50
|
+
# @param argv [Array<String>] `--bug BUG#n`
|
|
51
|
+
# @param root [String] the repository root
|
|
52
|
+
# @param env [Hash{String => String}] `QA_SWEEP_DOMAIN_DIR` picks another ledger
|
|
53
|
+
# @param gate [#run] the quick gate's runner; a spec injects one
|
|
54
|
+
# @param shell [Module] the fixer, landing and push commands; a spec injects one
|
|
55
|
+
# @return [Integer] the exit status
|
|
56
|
+
def self.call(argv, root:, env: ENV, gate: QaMainGate::GateRun, shell: QaMainGate::Shell)
|
|
57
|
+
reference = parse(argv)
|
|
58
|
+
return EXIT_REFUSED unless reference
|
|
59
|
+
|
|
60
|
+
runtime = Hecks.boot(env.fetch("QA_SWEEP_DOMAIN_DIR", File.join(root, "qa/bluebook")))
|
|
61
|
+
outcome = new(runtime: runtime, root: root, gate: gate, shell: shell).fix(reference)
|
|
62
|
+
puts outcome.message
|
|
63
|
+
outcome.code
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @return [String, nil] the reference, or nil after printing the usage for bad arguments
|
|
67
|
+
def self.parse(argv)
|
|
68
|
+
index = argv.index("--bug")
|
|
69
|
+
return argv[index + 1] if index && argv[index + 1]
|
|
70
|
+
|
|
71
|
+
warn USAGE
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @param runtime [Object] the booted QualityControl ledger
|
|
76
|
+
# @param root [String] the repository root
|
|
77
|
+
# @param gate [#run] the quick gate's runner
|
|
78
|
+
# @param shell [Module] the fixer, landing and push commands
|
|
79
|
+
def initialize(runtime:, root:, gate:, shell:)
|
|
80
|
+
@runtime = runtime
|
|
81
|
+
@root = root
|
|
82
|
+
@gate = gate
|
|
83
|
+
@shell = shell
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @param reference [String] the bug's reference, such as `BUG#12`
|
|
87
|
+
# @return [Outcome] what happened, once, in one line
|
|
88
|
+
def fix(reference)
|
|
89
|
+
row = bug_row(reference)
|
|
90
|
+
refusal = refusal_for(reference, row)
|
|
91
|
+
return Outcome.new(EXIT_REFUSED, "refused: #{refusal}") if refusal
|
|
92
|
+
|
|
93
|
+
attempt(row)
|
|
94
|
+
rescue QaMainGate::Worktree::Failed => e
|
|
95
|
+
Outcome.new(EXIT_STUCK, "stopped: #{e.message}")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def attempt(row)
|
|
101
|
+
branch = branch_for(row[:reference][:value])
|
|
102
|
+
return Outcome.new(EXIT_REFUSED, "refused: branch #{branch} already exists") if branch_exists?(branch)
|
|
103
|
+
|
|
104
|
+
investigate(row)
|
|
105
|
+
outcome = QaMainGate::Worktree.with(root: @root, ref: "main", branch: branch) { |dir| fix_in(dir, row) }
|
|
106
|
+
return stuck(row, outcome.reason) if outcome.is_a?(Stuck)
|
|
107
|
+
|
|
108
|
+
land_and_push(row, branch, outcome)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def bug_row(reference)
|
|
112
|
+
@runtime.query("QualityControl::Bug.All").find { |row| row[:reference][:value] == reference }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @return [String, nil] why the bug is not fixed by this command, nil when it may be
|
|
116
|
+
def refusal_for(reference, row)
|
|
117
|
+
return "no such bug #{reference}" unless row
|
|
118
|
+
return "#{reference} is triaged #{row[:disposition][:value]}; a bigger bug is left for the owner" unless
|
|
119
|
+
row[:disposition][:value] == "self_contained"
|
|
120
|
+
return "#{reference} is #{row[:status]}; nothing to fix" unless %w[logged investigating].include?(row[:status])
|
|
121
|
+
|
|
122
|
+
"no mechanical fixer for #{check_id(row)}" unless QaMainGate::Logging::SELF_CONTAINED.include?(check_id(row))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @return [String] the gate check the bug is about, such as `rubocop`
|
|
126
|
+
def check_id(row)
|
|
127
|
+
(row[:name] && row[:name][:value]).to_s.delete_prefix("main-red-").tr("-", "_")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @return [Array<String>] the files the failing check named, from its own output
|
|
131
|
+
def files_of(row)
|
|
132
|
+
row[:demonstration][:value].scan(RUBOCOP_OFFENSE).flatten.uniq
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def branch_for(reference)
|
|
136
|
+
"qa/red-main-#{reference.downcase.tr("#", "-")}"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def branch_exists?(branch)
|
|
140
|
+
QaMainGate::Worktree.git?(@root, "rev-parse", "--verify", "--quiet", "refs/heads/#{branch}")
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# The fixer runs, then the gate on the exact commit it makes. Returns the commit, or what kept it red.
|
|
144
|
+
def fix_in(dir, row)
|
|
145
|
+
@shell.rubocop(dir, files_of(row))
|
|
146
|
+
return Stuck.new("the fixer changed nothing") unless changed?(dir)
|
|
147
|
+
|
|
148
|
+
sha = commit(dir, row)
|
|
149
|
+
reds = @gate.run(dir).reject(&:passed)
|
|
150
|
+
return sha if reds.empty?
|
|
151
|
+
|
|
152
|
+
Stuck.new("the quick gate is still red on the fix: #{reds.map(&:id).join(", ")}")
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def changed?(dir)
|
|
156
|
+
!QaMainGate::Worktree.git!(dir, "status", "--porcelain").empty?
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def commit(dir, row)
|
|
160
|
+
QaMainGate::Worktree.git!(dir, "add", "-A")
|
|
161
|
+
title = "Fix the quick gate on main: #{check_id(row)} (#{row[:reference][:value]})"
|
|
162
|
+
QaMainGate::Worktree.git!(dir, "commit", "-m", title, "-m", TRAILER)
|
|
163
|
+
QaMainGate::Worktree.git!(dir, "rev-parse", "HEAD")
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -86,7 +86,7 @@ module Hecks
|
|
|
86
86
|
|
|
87
87
|
def sync_scratch!
|
|
88
88
|
FileUtils.mkdir_p(@scratch)
|
|
89
|
-
sources = %w[Cargo.toml Cargo.lock src].map { |entry| File.join(@root, "rust", entry) }
|
|
89
|
+
sources = %w[Cargo.toml Cargo.lock src expr].map { |entry| File.join(@root, "rust", entry) }
|
|
90
90
|
system("rsync", "-a", "--delete", "--exclude", "target", *sources, "#{@scratch}/") or
|
|
91
91
|
abort "rsync into #{@scratch} failed"
|
|
92
92
|
end
|