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
|
@@ -30,7 +30,7 @@ module Hecks
|
|
|
30
30
|
# @return [Boolean] true when the row was pending and is now claimed; false when it is
|
|
31
31
|
# unknown or another claimer got there first
|
|
32
32
|
# @raise [SQLite3::Exception] if the update fails
|
|
33
|
-
def outbox_claim(id)
|
|
33
|
+
def outbox_claim(id)
|
|
34
34
|
@db.execute(
|
|
35
35
|
"UPDATE hecks_outbox SET status = 'claimed', attempts = attempts + 1, claimed_at = ? " \
|
|
36
36
|
"WHERE id = ? AND status = 'pending'",
|
|
@@ -48,7 +48,7 @@ module Hecks
|
|
|
48
48
|
# @param error [String, nil] the failure description, or nil to store NULL
|
|
49
49
|
# @return [Boolean] true when exactly one row was updated; false when no row has `id`
|
|
50
50
|
# @raise [SQLite3::Exception] if the update fails
|
|
51
|
-
def outbox_settle(id, status:, error: nil)
|
|
51
|
+
def outbox_settle(id, status:, error: nil)
|
|
52
52
|
@db.execute(
|
|
53
53
|
"UPDATE hecks_outbox SET status = ?, error = ?, settled_at = ? WHERE id = ?",
|
|
54
54
|
[status.to_s, error, Time.now.utc.iso8601, id]
|
|
@@ -97,7 +97,7 @@ module Hecks
|
|
|
97
97
|
# @param id [String, Object] the aggregate identity, journalled as `id.to_s`
|
|
98
98
|
# @return [Boolean] always true
|
|
99
99
|
# @raise [SQLite3::Exception] if either statement fails
|
|
100
|
-
def delete(id)
|
|
100
|
+
def delete(id)
|
|
101
101
|
entry = Ports::Persistence::Entry.new(operation: "delete", id: id.to_s, state: nil)
|
|
102
102
|
append(entry)
|
|
103
103
|
project(entry)
|
|
@@ -15,10 +15,30 @@ module Hecks
|
|
|
15
15
|
@db.execute(
|
|
16
16
|
"CREATE TABLE IF NOT EXISTS #{quoted_table} (id TEXT PRIMARY KEY#{", " unless columns.empty?}#{columns.join(", ")})"
|
|
17
17
|
)
|
|
18
|
+
ensure_aggregate_columns!
|
|
18
19
|
# Called here so D1, which reuses this module, gets automatic indexing too.
|
|
19
20
|
ensure_indexes!
|
|
20
21
|
end
|
|
21
22
|
|
|
23
|
+
# CREATE TABLE IF NOT EXISTS never adds a column to an existing table, so an attribute the
|
|
24
|
+
# aggregate gained after its table was made gets its column here: nullable, since every row
|
|
25
|
+
# written before it holds no value. It only adds; a column the aggregate dropped is kept.
|
|
26
|
+
# SQLite column names are case-insensitive, so presence is compared that way too.
|
|
27
|
+
def ensure_aggregate_columns!
|
|
28
|
+
present = @db.execute("PRAGMA table_info(#{quoted_table})").map { |row| row["name"].to_s.downcase }
|
|
29
|
+
persisted_fields.reject { |field| present.include?(field[:name].to_s.downcase) }.each do |field|
|
|
30
|
+
add_column_once!(field)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Another process or isolate may add the same column between the read and this ALTER;
|
|
35
|
+
# that duplicate is the outcome wanted, so only that error is let through.
|
|
36
|
+
def add_column_once!(field)
|
|
37
|
+
@db.execute("ALTER TABLE #{quoted_table} ADD COLUMN #{quote_ident(field[:name])} #{field[:sql_type]}")
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
raise unless e.message.include?("duplicate column name")
|
|
40
|
+
end
|
|
41
|
+
|
|
22
42
|
def create_event_table!
|
|
23
43
|
@db.execute(Ddl::EVENTS)
|
|
24
44
|
# Backs #events_for's per-record lookup (a `corrects` command's history read).
|
|
@@ -3,6 +3,7 @@ require "fileutils"
|
|
|
3
3
|
|
|
4
4
|
require_relative "sql_query_builder"
|
|
5
5
|
require_relative "sqlite/schema_builder"
|
|
6
|
+
require_relative "sqlite/name_guard"
|
|
6
7
|
require_relative "sqlite/codec"
|
|
7
8
|
require_relative "sqlite/dialect"
|
|
8
9
|
require_relative "sqlite/events"
|
|
@@ -28,6 +29,7 @@ module Hecks
|
|
|
28
29
|
class Sqlite
|
|
29
30
|
include SqlQueryBuilder
|
|
30
31
|
include SchemaBuilder
|
|
32
|
+
include NameGuard
|
|
31
33
|
include Codec
|
|
32
34
|
include Repository
|
|
33
35
|
include Journal
|
|
@@ -70,6 +72,7 @@ module Hecks
|
|
|
70
72
|
# Scopes saga rows; falls back to the aggregate's name for a directly built adapter.
|
|
71
73
|
@domain = settings.fetch(:domain) { aggregate.name }.to_s
|
|
72
74
|
open_database
|
|
75
|
+
refuse_orphaned_rows!
|
|
73
76
|
create_tables!
|
|
74
77
|
end
|
|
75
78
|
|
|
@@ -85,7 +88,9 @@ module Hecks
|
|
|
85
88
|
def transaction(&)
|
|
86
89
|
return yield if @db.transaction_active?
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
# Immediate, so the write lock is taken up front: a deferred transaction that reads and then
|
|
92
|
+
# writes fails at once when another process holds the file, and the busy timeout never runs.
|
|
93
|
+
@db.transaction(:immediate, &)
|
|
89
94
|
end
|
|
90
95
|
|
|
91
96
|
# Names the aggregate's table; the journal table and outbox rows are keyed off it.
|
|
@@ -98,6 +103,9 @@ module Hecks
|
|
|
98
103
|
def open_database
|
|
99
104
|
FileUtils.mkdir_p(File.dirname(@path))
|
|
100
105
|
@db = SQLite3::Database.new(@path)
|
|
106
|
+
# Several processes may boot one journal at once (the gate's checks do), so a busy file
|
|
107
|
+
# is waited for rather than refused as "database is locked".
|
|
108
|
+
@db.busy_timeout = 10_000
|
|
101
109
|
@db.results_as_hash = true
|
|
102
110
|
# The append is the recovery commit point, so the fsync policy is explicit.
|
|
103
111
|
@db.execute("PRAGMA synchronous = FULL")
|
|
@@ -37,7 +37,7 @@ module Hecks
|
|
|
37
37
|
# @param adapter [String, Hash, nil] the adapter the overlay binds; PostgresEra when none
|
|
38
38
|
# @return [Hash{Symbol => Object}] `:slug`, `:domain`, `:realm`, `:schema` and `:output`
|
|
39
39
|
# @raise [Refused] when a value is outside its allow-list or the path leaves `environments/`
|
|
40
|
-
def write_overlay(slug:, domain:, realm:, schema:, database:, directory:, adapter: nil, **)
|
|
40
|
+
def write_overlay(slug:, domain:, realm:, schema:, database:, directory:, adapter: nil, **)
|
|
41
41
|
values = { slug: unwrap(slug), domain: unwrap(domain), realm: unwrap(realm),
|
|
42
42
|
schema: unwrap(schema), database: unwrap(database),
|
|
43
43
|
adapter: adapter_name(adapter) }
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
# Says, once per process, when a linked worktree lacks the gitignored overlay files its main
|
|
4
|
+
# checkout keeps. Those files exist only in the main checkout, so a command run from a
|
|
5
|
+
# worktree stores in Memory without saying so. This warns; it never blocks the command.
|
|
6
|
+
module WorktreeOverlay
|
|
7
|
+
# The line a linked worktree's `.git` file holds, naming the directory in the main checkout.
|
|
8
|
+
GITDIR_LINE = /\Agitdir: (.+)\s*\z/
|
|
9
|
+
|
|
10
|
+
# Where the overlay files live, relative to a checkout's root.
|
|
11
|
+
OVERLAY_PATTERNS = ["lib/hecks/hecks/*.local.hecksagon", "lib/hecks/hecks/*.local.world",
|
|
12
|
+
"environments/local.hecksagon", "environments/local.world"].freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Warns on standard error the first time a domain loads from a linked worktree that lacks
|
|
17
|
+
# overlay files of its main checkout. Nothing is printed again in the same process.
|
|
18
|
+
#
|
|
19
|
+
# @param directory [String] the domain directory being loaded
|
|
20
|
+
# @param err [#puts] where the warning goes
|
|
21
|
+
# @return [String, nil] the warning printed, or nil when there was nothing to say
|
|
22
|
+
def warn_once(directory, err: $stderr)
|
|
23
|
+
return if @warned
|
|
24
|
+
|
|
25
|
+
text = warning_for(directory)
|
|
26
|
+
return unless text
|
|
27
|
+
|
|
28
|
+
@warned = true
|
|
29
|
+
err.puts(text)
|
|
30
|
+
text
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The warning for a directory inside a linked worktree, or nil when none applies.
|
|
34
|
+
#
|
|
35
|
+
# @param directory [String] a directory inside a checkout
|
|
36
|
+
# @return [String, nil]
|
|
37
|
+
def warning_for(directory)
|
|
38
|
+
_main, files = gap(directory)
|
|
39
|
+
message(files)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# The main checkout a linked worktree was made from, and the overlay files that checkout
|
|
43
|
+
# holds and this worktree lacks. Nothing is returned for a checkout that is not a worktree.
|
|
44
|
+
#
|
|
45
|
+
# @param directory [String] a directory inside a checkout
|
|
46
|
+
# @return [Array(String, Array<String>), Array(nil, Array)] the main checkout's root, then the
|
|
47
|
+
# relative paths of the overlay files it holds and the worktree lacks
|
|
48
|
+
def gap(directory)
|
|
49
|
+
worktree = checkout_root(directory)
|
|
50
|
+
main = worktree && main_checkout(worktree)
|
|
51
|
+
return [nil, []] unless main
|
|
52
|
+
|
|
53
|
+
[main, missing(overlay_files(main), overlay_files(worktree))]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Relative paths of the overlay files that a checkout holds.
|
|
57
|
+
#
|
|
58
|
+
# @param root [String] a checkout's root
|
|
59
|
+
# @return [Array<String>] sorted relative paths
|
|
60
|
+
def overlay_files(root)
|
|
61
|
+
OVERLAY_PATTERNS.flat_map { |pattern| Dir.glob(File.join(root, pattern)) }
|
|
62
|
+
.map { |path| path.delete_prefix("#{root}/") }
|
|
63
|
+
.sort
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The overlay files the main checkout holds and the worktree does not.
|
|
67
|
+
#
|
|
68
|
+
# @param main [Array<String>] relative paths in the main checkout
|
|
69
|
+
# @param worktree [Array<String>] relative paths in the worktree
|
|
70
|
+
# @return [Array<String>]
|
|
71
|
+
def missing(main, worktree)
|
|
72
|
+
main - worktree
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# The one-line warning naming the files and the store they change.
|
|
76
|
+
#
|
|
77
|
+
# @param files [Array<String>] relative paths the worktree lacks
|
|
78
|
+
# @return [String, nil] the warning, or nil when no file is missing
|
|
79
|
+
def message(files)
|
|
80
|
+
return if files.empty?
|
|
81
|
+
|
|
82
|
+
"hecks: this worktree lacks #{files.join(", ")} from the main checkout; " \
|
|
83
|
+
"bluebooks that use them store in Memory here, not in the main checkout's store"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# The root of the checkout a directory is in, and whether that checkout is a linked worktree.
|
|
87
|
+
#
|
|
88
|
+
# @param directory [String]
|
|
89
|
+
# @return [String, nil] the root when it is a linked worktree, else nil
|
|
90
|
+
def checkout_root(directory)
|
|
91
|
+
root = ascend_to_git(File.expand_path(directory))
|
|
92
|
+
root if root && File.file?(File.join(root, ".git"))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# The main checkout a linked worktree was made from, found through its `.git` file.
|
|
96
|
+
#
|
|
97
|
+
# @param worktree [String] a linked worktree's root
|
|
98
|
+
# @return [String, nil]
|
|
99
|
+
def main_checkout(worktree)
|
|
100
|
+
gitdir = File.read(File.join(worktree, ".git"))[GITDIR_LINE, 1]
|
|
101
|
+
return unless gitdir
|
|
102
|
+
|
|
103
|
+
common = File.expand_path("../..", File.expand_path(gitdir, worktree))
|
|
104
|
+
File.dirname(common)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Walks up from a directory to the first one holding a `.git` entry.
|
|
108
|
+
#
|
|
109
|
+
# @param directory [String] an absolute path
|
|
110
|
+
# @return [String, nil]
|
|
111
|
+
def ascend_to_git(directory)
|
|
112
|
+
root = Pathname.new(directory).ascend.find { |dir| dir.join(".git").exist? }
|
|
113
|
+
root&.to_s
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -4,6 +4,10 @@ module Hecks
|
|
|
4
4
|
module Cli
|
|
5
5
|
# Rewrites the shorthand spellings of a command line into plain `name=value` words.
|
|
6
6
|
module Shorthand
|
|
7
|
+
# The declared types a bare `--name` flag may stand for: a plain Boolean, or a `Switch`,
|
|
8
|
+
# which wraps one.
|
|
9
|
+
BOOLEAN_TYPES = %w[Boolean Switch].freeze
|
|
10
|
+
|
|
7
11
|
module_function
|
|
8
12
|
|
|
9
13
|
# Rewrites the short forms into `name=value`: `--name` for a Boolean (a following `yes`,
|
|
@@ -58,7 +62,7 @@ module Hecks
|
|
|
58
62
|
def flag(name, options)
|
|
59
63
|
name = name.tr("-", "_") unless options.key?(name) || options.keys.any? { |key| key.start_with?("#{name}.") }
|
|
60
64
|
path = options.key?(name) ? name : Cli.expand(name, options)
|
|
61
|
-
return path if options.dig(path, :type)
|
|
65
|
+
return path if BOOLEAN_TYPES.include?(options.dig(path, :type))
|
|
62
66
|
|
|
63
67
|
raise Runtime::NotFound, "--#{name} is a flag, but this command has no Boolean argument #{name.inspect}"
|
|
64
68
|
end
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require "json"
|
|
2
|
+
require_relative "run_reference"
|
|
3
|
+
require_relative "read_context"
|
|
2
4
|
|
|
3
5
|
module Hecks
|
|
4
6
|
module Adapters
|
|
@@ -9,41 +11,67 @@ module Hecks
|
|
|
9
11
|
module Answers
|
|
10
12
|
# What a dispatch needs beyond the spec: the parsed arguments, whether `--wait` was given,
|
|
11
13
|
# and the bluebook and launcher setting the command belongs to.
|
|
12
|
-
Invocation = Struct.new(:args, :wait, :bluebook, :launcher, :text)
|
|
14
|
+
Invocation = Struct.new(:args, :wait, :bluebook, :launcher, :text, :plan)
|
|
13
15
|
|
|
14
16
|
# The flag that asks for a command's recorded output as plain text and nothing else.
|
|
15
17
|
TEXT = "--text".freeze
|
|
16
18
|
|
|
19
|
+
# The flag that asks what a command would write and announce, writing nothing.
|
|
20
|
+
PLAN = "--plan".freeze
|
|
21
|
+
|
|
17
22
|
# Parses one resolved command's arguments, runs it as a query or command, and turns the
|
|
18
|
-
# outcome, or the domain's refusal, into `[json_or_message, status]`.
|
|
19
|
-
#
|
|
23
|
+
# outcome, or the domain's refusal, into `[json_or_message, status]`. A word the command
|
|
24
|
+
# does not take, a value its type cannot hold or a flag it lacks is a line that could
|
|
25
|
+
# not be read (`ExitStatus::USAGE`); everything the domain says no to, a missing record
|
|
26
|
+
# included, is `REFUSED`. With `--wait`, a question whose report names a gap
|
|
27
|
+
# (`LauncherOptions.gap_reported?`) is refused too.
|
|
20
28
|
#
|
|
21
29
|
# @param bluebook [Bluebook::Declaration] the bluebook the command belongs to
|
|
22
30
|
# @param launcher [Hash, nil] the bluebook's `launcher` world setting; nil when not opted
|
|
23
31
|
# in
|
|
24
|
-
def dispatch(runtime, spec, name, rest, program, asking, bluebook: nil, launcher: nil)
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
def dispatch(runtime, spec, name, rest, program, asking, bluebook: nil, launcher: nil)
|
|
33
|
+
plan = rest.include?(PLAN)
|
|
34
|
+
args, wait, text = command_line(spec, plan ? rest - [PLAN] : rest, launcher)
|
|
35
|
+
run(runtime, spec, Invocation.new(args, wait, bluebook, launcher, text, plan), name, program, asking)
|
|
36
|
+
rescue Runtime::NotFound, Runtime::TypeMismatch => e
|
|
37
|
+
[help_pointer(e, name, program, asking), ExitStatus::USAGE]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Runs a parsed line as a query or a command, and shapes the domain's refusal.
|
|
41
|
+
# @api private
|
|
42
|
+
def run(runtime, spec, invocation, name, program, asking)
|
|
43
|
+
return plan_or_refuse(runtime, spec, invocation, name) if invocation.plan
|
|
44
|
+
return answer_query(runtime, spec, invocation.args, invocation.wait, invocation.launcher) if spec[:kind] == :query
|
|
27
45
|
|
|
28
|
-
run_command(runtime, spec,
|
|
46
|
+
run_command(runtime, spec, invocation)
|
|
29
47
|
rescue Runtime::NotFound, Runtime::TypeMismatch => e
|
|
30
|
-
# A
|
|
31
|
-
[
|
|
48
|
+
# A missing record needs the same next step as a bad argument: read the help.
|
|
49
|
+
[help_pointer(e, name, program, asking), ExitStatus::REFUSED]
|
|
32
50
|
rescue *Runtime::DOMAIN_REFUSALS => e
|
|
33
51
|
# The refusal is the bluebook's own sentence, verbatim.
|
|
34
|
-
[e
|
|
52
|
+
[coded(e), ExitStatus::REFUSED]
|
|
35
53
|
rescue StandardError => e
|
|
36
54
|
# So is a wrapped tool's, when a question's adapter refuses to answer.
|
|
37
55
|
raise unless tool_refusal?(e)
|
|
38
56
|
|
|
39
|
-
[e.message,
|
|
57
|
+
[e.message, ExitStatus::REFUSED]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A refusal's text, led by its stable code so a script can branch on it.
|
|
61
|
+
# @api private
|
|
62
|
+
def coded(error) = "[#{error.code}] #{error.message}"
|
|
63
|
+
|
|
64
|
+
# An error's message, then the line that prints the command's help.
|
|
65
|
+
# @api private
|
|
66
|
+
def help_pointer(error, name, program, asking)
|
|
67
|
+
"#{coded(error)}\n\n #{program} #{"query " if asking}#{name} --help"
|
|
40
68
|
end
|
|
41
69
|
|
|
42
70
|
# The parsed arguments of a command line, whether to wait for the reactions, and whether
|
|
43
71
|
# `--text` asked for the recorded output alone (which waits).
|
|
44
72
|
def command_line(spec, rest, launcher)
|
|
45
73
|
text = launcher ? rest.include?(TEXT) : false
|
|
46
|
-
rest, wait = LauncherOptions.take_wait(spec, rest - [TEXT]
|
|
74
|
+
rest, wait = LauncherOptions.take_wait(spec, launcher ? rest - [TEXT] : rest)
|
|
47
75
|
[Cli.arguments(spec, rest), text || wait || LauncherOptions.settled?(launcher, spec), text]
|
|
48
76
|
end
|
|
49
77
|
|
|
@@ -55,16 +83,43 @@ module Hecks
|
|
|
55
83
|
ancestor_names.include?(CliRunner::TOOL_REFUSAL)
|
|
56
84
|
end
|
|
57
85
|
|
|
86
|
+
# Answers `--plan`: a command's plan, or usage for a query, which writes nothing to plan.
|
|
87
|
+
# @api private
|
|
88
|
+
def plan_or_refuse(runtime, spec, invocation, name)
|
|
89
|
+
return plan_refused_for_query(name) if spec[:kind] == :query
|
|
90
|
+
|
|
91
|
+
plan_answer(runtime, spec, invocation)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Lists what a command would write and announce, writing nothing. A refusal the real run
|
|
95
|
+
# would give is answered as that refusal.
|
|
96
|
+
# @api private
|
|
97
|
+
def plan_answer(runtime, spec, invocation)
|
|
98
|
+
lines = runtime.plan_flat(spec[:command], **normalized_request(spec, invocation.args))
|
|
99
|
+
[lines.empty? ? "would not write or announce anything" : lines.join("\n"), ExitStatus::ANSWERED]
|
|
100
|
+
rescue *Runtime::DOMAIN_REFUSALS, Runtime::NotFound, Runtime::TypeMismatch => e
|
|
101
|
+
[coded(e), ExitStatus::REFUSED]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# A query has nothing to write, so `--plan` on one is a usage mistake.
|
|
105
|
+
# @api private
|
|
106
|
+
def plan_refused_for_query(name)
|
|
107
|
+
["hecks: #{name} is a query and writes nothing, so --plan has nothing to show", ExitStatus::USAGE]
|
|
108
|
+
end
|
|
109
|
+
|
|
58
110
|
# Runs a command and answers its outcome, settled when `--wait` asks for it.
|
|
59
111
|
def run_command(runtime, spec, invocation)
|
|
60
|
-
args, minted =
|
|
112
|
+
args, minted = RunReference.prepare(runtime, spec, invocation.args, invocation.launcher)
|
|
113
|
+
replayed = RunReplay.answer(runtime, spec, args)
|
|
114
|
+
return replayed if replayed
|
|
115
|
+
|
|
61
116
|
handle = runtime.dispatch_flat(spec[:command], normalized_request(spec, args))
|
|
62
|
-
extra = refusals_and_run(handle, minted)
|
|
117
|
+
extra = refusals_and_run(handle, minted, args)
|
|
63
118
|
if invocation.wait
|
|
64
119
|
return settled(runtime, spec, handle, invocation.bluebook, invocation.launcher, extra, text: invocation.text)
|
|
65
120
|
end
|
|
66
121
|
|
|
67
|
-
[JSON.pretty_generate(outcome(handle, extra)),
|
|
122
|
+
[JSON.pretty_generate(outcome(handle, extra)), ExitStatus::ANSWERED]
|
|
68
123
|
end
|
|
69
124
|
|
|
70
125
|
# The request a command takes from its parsed arguments.
|
|
@@ -73,8 +128,8 @@ module Hecks
|
|
|
73
128
|
end
|
|
74
129
|
|
|
75
130
|
# The refused reactions of the dispatch, led by the minted run key when one was.
|
|
76
|
-
def refusals_and_run(handle, minted)
|
|
77
|
-
extra = refused_answer(handle)
|
|
131
|
+
def refusals_and_run(handle, minted, args = {})
|
|
132
|
+
extra = refused_answer(handle).merge(ids: RunReference.ids(args, handle.id))
|
|
78
133
|
minted ? { run: minted }.merge(extra) : extra
|
|
79
134
|
end
|
|
80
135
|
|
|
@@ -92,12 +147,12 @@ module Hecks
|
|
|
92
147
|
# questions that refuse a run they do not hold
|
|
93
148
|
# @return [Array(String, Integer)] the answer and the status
|
|
94
149
|
def answer_query(runtime, spec, args, wait, launcher = nil)
|
|
95
|
-
rows = runtime.query(spec[:command], **args)
|
|
96
|
-
return [unknown_run(args),
|
|
150
|
+
rows = runtime.query(spec[:command], **ReadContext.fill(spec, args))
|
|
151
|
+
return [unknown_run(args), ExitStatus::REFUSED] if rows.empty? && LauncherOptions.unknown_run?(launcher, spec)
|
|
97
152
|
|
|
98
153
|
text = text_answer(spec, rows)
|
|
99
154
|
[text || JSON.pretty_generate(rows.map { |row| Json.materialize(row) }),
|
|
100
|
-
wait && LauncherOptions.gap_reported?(text) ?
|
|
155
|
+
wait && LauncherOptions.gap_reported?(text) ? ExitStatus::REFUSED : ExitStatus::ANSWERED]
|
|
101
156
|
end
|
|
102
157
|
|
|
103
158
|
# What a question about one run answers when the process holds no such run, for a
|
|
@@ -151,8 +206,8 @@ module Hecks
|
|
|
151
206
|
|
|
152
207
|
# Shapes a port operation's outcome, which has no state: each event with its full payload.
|
|
153
208
|
#
|
|
154
|
-
# The answer lives only in the payloads, so names alone would drop it.
|
|
155
|
-
# for refusal events too, since a healthy no is an answer, not a misuse.
|
|
209
|
+
# The answer lives only in the payloads, so names alone would drop it. The status stays
|
|
210
|
+
# `ANSWERED` for refusal events too, since a healthy no is an answer, not a misuse.
|
|
156
211
|
def answered(handle)
|
|
157
212
|
# A port operation hydrates no instance, so the handle's `id` is nil by design.
|
|
158
213
|
{ id: handle.id || handle.events.first&.id,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
module Driving
|
|
4
|
+
module CliRunner
|
|
5
|
+
# The bang rule: a line that writes says so with `!`, and a command written without it is
|
|
6
|
+
# refused, naming the spelling that writes. Extended into `CliRunner`.
|
|
7
|
+
module BangRule
|
|
8
|
+
# The word a line names as typed, before the launcher's own rewrites.
|
|
9
|
+
def typed_word(argv)
|
|
10
|
+
CliRunner::QUERY_WORDS.include?(argv.first) ? argv[1] : argv.first
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The answer a line gets before any command runs: its help, or its refusal for a
|
|
14
|
+
# command written without its bang.
|
|
15
|
+
def early_answer(scope, cli, line)
|
|
16
|
+
return [command_help(scope, line[:name], line[:asking]), ExitStatus::ANSWERED] if line[:argv][1..].include?("--help")
|
|
17
|
+
|
|
18
|
+
bang_less_refusal(cli, line[:asking], line[:word], line[:name], scope[:program])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# A command written without its `!` is refused. A query, and a name that is not a
|
|
22
|
+
# command, pass.
|
|
23
|
+
#
|
|
24
|
+
# @return [Array(String, Integer), nil] the refusal and its usage status, or nil
|
|
25
|
+
def bang_less_refusal(cli, asking, word, name, program)
|
|
26
|
+
return nil if asking || word.nil? || word.end_with?("!")
|
|
27
|
+
return nil unless cli[:names][:command].key?(name)
|
|
28
|
+
|
|
29
|
+
["#{program}: #{word} is a command and writes; write it as #{word}!", ExitStatus::USAGE]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
module Driving
|
|
4
|
+
module CliRunner
|
|
5
|
+
# The launcher word `completion <shell>` (ADR 0163, plan step 7): the script that completes
|
|
6
|
+
# the launcher's words in that shell, written from the same listing the help prints.
|
|
7
|
+
module CompletionWords
|
|
8
|
+
# The answer to `completion <shell>`: the script on stdout, or the usage line when the
|
|
9
|
+
# shell is missing or not one this projection writes.
|
|
10
|
+
def completion_answer(scope, argv)
|
|
11
|
+
return unless argv.first == "completion"
|
|
12
|
+
|
|
13
|
+
shell = argv[1]
|
|
14
|
+
script = script_for(scope, shell)
|
|
15
|
+
return { answer: ["usage: #{scope[:program]} completion <#{shells_word}>", ExitStatus::USAGE] } unless script
|
|
16
|
+
|
|
17
|
+
{ answer: [script, ExitStatus::ANSWERED] }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The script for one shell, or nil when the projection writes none for it.
|
|
21
|
+
def script_for(scope, shell)
|
|
22
|
+
return unless Projector::CliProjector::Completion::SHELLS.include?(shell)
|
|
23
|
+
|
|
24
|
+
words = Projector::CliProjector.completion_words(scope[:bluebook], scope[:cli], scope[:shown])
|
|
25
|
+
Projector::CliProjector.completion_script(shell, scope[:program], words)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The shells named in the usage line.
|
|
29
|
+
def shells_word
|
|
30
|
+
Projector::CliProjector::Completion::SHELLS.join("|")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
module Driving
|
|
4
|
+
module CliRunner
|
|
5
|
+
# The launcher's `--json` flag (ADR 0163, plan step 9): `hecks --json` and
|
|
6
|
+
# `hecks <module> --json` print the listing's entries as JSON, from the same projection the
|
|
7
|
+
# help prints. Extended into `CliRunner`.
|
|
8
|
+
module JsonWords
|
|
9
|
+
JSON_FLAG = "--json".freeze
|
|
10
|
+
|
|
11
|
+
# The answer to a line that asks for the listing as JSON, or nil when it does not.
|
|
12
|
+
#
|
|
13
|
+
# @param scope [Hash] the runner's scope for the line: the bluebook, its projection, the
|
|
14
|
+
# launcher and the options the help is shown with
|
|
15
|
+
# @param argv [Array<String>] the words of the line
|
|
16
|
+
# @return [Hash, nil] the answer, or nil when the line does not carry the flag
|
|
17
|
+
def json_answer(scope, argv)
|
|
18
|
+
return unless argv.include?(JSON_FLAG)
|
|
19
|
+
|
|
20
|
+
words = argv.reject { |word| word == JSON_FLAG }
|
|
21
|
+
module_word = words.find { |word| !word.start_with?("--") }
|
|
22
|
+
return { answer: [json_text(scope, module_word, words), ExitStatus::ANSWERED] } if known_or_none?(scope, module_word)
|
|
23
|
+
|
|
24
|
+
{ answer: ["usage: #{scope[:program]} [<module>] --json", ExitStatus::USAGE] }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The JSON text for the listing, limited to the module named, if any.
|
|
28
|
+
def json_text(scope, module_word, words)
|
|
29
|
+
name = module_word && Projector::CliProjector.module_named(scope[:bluebook], module_word)
|
|
30
|
+
options = json_options(scope, words).merge(module: name)
|
|
31
|
+
Projector::CliProjector.json_listing(scope[:bluebook], scope[:cli][:commands], scope[:cli][:questions], options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# The listing's options for JSON: the audience the help shows, or with `--all` the
|
|
35
|
+
# maintainer's audience and the internal entries too.
|
|
36
|
+
def json_options(scope, words)
|
|
37
|
+
return scope[:shown] unless words.include?("--all")
|
|
38
|
+
|
|
39
|
+
search_options(scope, true)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Whether a line names no module, or a module the bluebook declares.
|
|
43
|
+
def known_or_none?(scope, word)
|
|
44
|
+
word.nil? || known_module?(scope, word)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Whether a word names a module of the bluebook.
|
|
48
|
+
def known_module?(scope, word)
|
|
49
|
+
!Projector::CliProjector.module_named(scope[:bluebook], word).nil?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "../usage_cache"
|
|
3
|
+
|
|
4
|
+
module Hecks
|
|
5
|
+
module Adapters
|
|
6
|
+
module Driving
|
|
7
|
+
module CliRunner
|
|
8
|
+
# Every name the launcher accepts, by the scope it is typed in, for a check that reads text
|
|
9
|
+
# rather than running a line. Extended into `CliRunner`.
|
|
10
|
+
#
|
|
11
|
+
# The index is the projection's own name table: the same one `hecks --all` lists from and
|
|
12
|
+
# `resolve` looks a typed word up in, so a name the launcher would refuse is not in it. It
|
|
13
|
+
# is worked out once and remembered through `UsageCache`, which keys it to the declarations
|
|
14
|
+
# and the code that projects them.
|
|
15
|
+
module NameIndex
|
|
16
|
+
# The command line a remembered index stands for, which no real line can be.
|
|
17
|
+
CACHE_LINE = ["--name-index"].freeze
|
|
18
|
+
|
|
19
|
+
# The scope of the program's own bluebook; an attached bluebook's scope is its first word
|
|
20
|
+
# (`deploy` for `hecks deploy ...`).
|
|
21
|
+
OWN_SCOPE = "".freeze
|
|
22
|
+
|
|
23
|
+
# @param runtime [#registry] a booted domain, or what `Hecks.describe` answers
|
|
24
|
+
# @param program [String] how the caller is invoked
|
|
25
|
+
# @return [Hash{String => Hash}] per scope: `"command"` and `"question"` map each accepted
|
|
26
|
+
# spelling to the name as listed, and `"modules"` lists the module words
|
|
27
|
+
def name_index(runtime:, program: "hecks")
|
|
28
|
+
text, = UsageCache.fetch(runtime, CACHE_LINE, program, audience: "maintainer") do
|
|
29
|
+
[JSON.generate(scopes_of(runtime, program)), 0]
|
|
30
|
+
end
|
|
31
|
+
JSON.parse(text)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [Hash{String => Hash}] every scope's table, worked out from the projections
|
|
35
|
+
def scopes_of(runtime, program)
|
|
36
|
+
own = { OWN_SCOPE => scope_table(runtime, [], program) }
|
|
37
|
+
attached_bluebooks(runtime).each_with_object(own) do |name, scopes|
|
|
38
|
+
word = Naming.snake(name)
|
|
39
|
+
scopes[word] = scope_table(runtime, [word], program)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [Hash] one scope's `"command"`, `"question"` and `"modules"` tables
|
|
44
|
+
def scope_table(runtime, argv, program)
|
|
45
|
+
bluebook, _, program = bluebook_for(runtime, argv, program)
|
|
46
|
+
launcher = LauncherOptions.settings(runtime, bluebook.name)
|
|
47
|
+
options = LauncherOptions.projection(launcher, program).merge(audience(runtime, launcher, maintainer: true))
|
|
48
|
+
cli = Projector.call(:cli, bluebook: bluebook, options: options)
|
|
49
|
+
{ "command" => listed(cli, :command, :commands), "question" => listed(cli, :question, :questions),
|
|
50
|
+
"modules" => Projector::CliProjector.module_names(bluebook).map { |name| Naming.snake(name) } }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Hash{String => String}] each spelling of a kind, with the name as listed
|
|
54
|
+
def listed(cli, kind, specs)
|
|
55
|
+
cli[:names][kind].to_h do |spelling, id|
|
|
56
|
+
[spelling, Projector::CliProjector.verb_form(cli[specs][id] || {}, spelling)]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Adapters
|
|
3
|
+
module Driving
|
|
4
|
+
module CliRunner
|
|
5
|
+
# The session's checkout, for reads only. A read of a checkout's state that names no checkout
|
|
6
|
+
# takes the one the session set in `HECKS_CHECKOUT`; a command never does. A command names its
|
|
7
|
+
# own target, because a write must land where it was asked to, not where the session last was.
|
|
8
|
+
module ReadContext
|
|
9
|
+
# The environment variable a session sets to name its checkout.
|
|
10
|
+
VARIABLE = "HECKS_CHECKOUT".freeze
|
|
11
|
+
|
|
12
|
+
# The aggregate whose queries read a checkout's state.
|
|
13
|
+
READS = /Workspace\./
|
|
14
|
+
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
# @param spec [Hash] the resolved question or command
|
|
18
|
+
# @param args [Hash] the parsed arguments, keyed by name
|
|
19
|
+
# @param env [Hash] the process environment
|
|
20
|
+
# @return [Hash] the arguments, with checkout set from the session when a read names none
|
|
21
|
+
def fill(spec, args, env: ENV)
|
|
22
|
+
checkout = env[VARIABLE]
|
|
23
|
+
return args if checkout.nil? || checkout.empty? || args.key?(:checkout)
|
|
24
|
+
return args unless spec[:kind] == :query && spec[:command].to_s.match?(READS)
|
|
25
|
+
|
|
26
|
+
args.merge(checkout: { value: checkout })
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|