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
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "open3"
|
|
5
|
+
require_relative "../cli/qa_main_gate"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Adapters
|
|
9
|
+
# The `ImageRoll` port's adapter. `classify` reads a green commit of embryonaut_platform's
|
|
10
|
+
# change set
|
|
11
|
+
# and answers whether only the console container's inputs changed; `roll` builds the console
|
|
12
|
+
# image
|
|
13
|
+
# and rolls it with the platform's own `make deploy-service`. Both answer the event their
|
|
14
|
+
# policy
|
|
15
|
+
# waits for, or raise, which the runtime records as the refusal.
|
|
16
|
+
class ImageRoll
|
|
17
|
+
# The repository this adapter rolls, and the one service it rolls.
|
|
18
|
+
PLATFORM_REPO = "heckslabs/embryonaut_platform"
|
|
19
|
+
APP = "console"
|
|
20
|
+
|
|
21
|
+
# The console container's inputs, as the platform's Dockerfile copies them. A path outside
|
|
22
|
+
# them is
|
|
23
|
+
# infrastructure: default-deny, so a new top-level directory waits for a person.
|
|
24
|
+
IMAGE_FILES = %w[Dockerfile Gemfile Gemfile.lock lib/telemetry_ingress.rb lib/site_roster.rb].freeze
|
|
25
|
+
IMAGE_DIRS = %w[bluebook/ vendor/ deploy/console/ lib/telemetry_ingress/ lib/site_roster/].freeze
|
|
26
|
+
|
|
27
|
+
# The bluebook's translation edges move a box's data, so a person releases them even under a
|
|
28
|
+
# bluebook.
|
|
29
|
+
OUTSIDE_IMAGE_DIRS = %w[bluebook/translations/].freeze
|
|
30
|
+
|
|
31
|
+
# The default platform checkout the roll builds from; `platform_root:` overrides it.
|
|
32
|
+
PLATFORM_ROOT = File.expand_path("~/Projects/embryonaut_platform")
|
|
33
|
+
|
|
34
|
+
# Raised when a step refuses; its message is the refusal's reason.
|
|
35
|
+
class Refused < RuntimeError; end
|
|
36
|
+
|
|
37
|
+
# The outside-world commands; a spec injects a stub in their place.
|
|
38
|
+
module Commands
|
|
39
|
+
module_function
|
|
40
|
+
|
|
41
|
+
# @return [Array(String, Boolean)] the build's output and whether it exited 0
|
|
42
|
+
def docker_build(dir)
|
|
43
|
+
output, status = Open3.capture2e("docker", "build", "--platform", "linux/arm64",
|
|
44
|
+
"-t", "embryonaut-platform-console:latest", ".", chdir: dir)
|
|
45
|
+
[output, status.success?]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [Array(String, Boolean)] the roll's output and whether it exited 0
|
|
49
|
+
def deploy_service(dir)
|
|
50
|
+
output, status = Open3.capture2e("make", "deploy-service", "SERVICE=#{APP}",
|
|
51
|
+
chdir: File.join(dir, "deploy-aws/box-generated"))
|
|
52
|
+
[output, status.success?]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Whether one changed path is part of the console container's inputs.
|
|
57
|
+
#
|
|
58
|
+
# @param path [String] a repository-relative path
|
|
59
|
+
# @return [Boolean]
|
|
60
|
+
def self.image_path?(path)
|
|
61
|
+
return false if OUTSIDE_IMAGE_DIRS.any? { |dir| path.start_with?(dir) }
|
|
62
|
+
|
|
63
|
+
IMAGE_FILES.include?(path) || IMAGE_DIRS.any? { |dir| path.start_with?(dir) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @param root [String, nil] the Hecks checkout, whose QA ledger holds the quick gate's
|
|
67
|
+
# records
|
|
68
|
+
# @param platform_root [String] the embryonaut_platform checkout the roll builds from
|
|
69
|
+
# @param commands [Module] the outside-world commands; a spec injects a stub
|
|
70
|
+
# @param ledger [#query, nil] the QA ledger the quick gate's records are read from; booted
|
|
71
|
+
# from
|
|
72
|
+
# `root` when nil
|
|
73
|
+
def initialize(root: nil, platform_root: PLATFORM_ROOT, commands: Commands, ledger: nil, **)
|
|
74
|
+
@root = root || Dir.pwd
|
|
75
|
+
@platform_root = platform_root
|
|
76
|
+
@commands = commands
|
|
77
|
+
@ledger = ledger
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Classifies one green commit: `image` when every changed path is a container input, `infra`
|
|
81
|
+
# otherwise. The classifier reads no quick gate: an image-only commit rolls on its green
|
|
82
|
+
# remote CI alone, and an infra commit is held for a person.
|
|
83
|
+
#
|
|
84
|
+
# @param commit [Hash, String] the commit
|
|
85
|
+
# @param branch [Hash, String] the branch; only main rolls
|
|
86
|
+
# @param repo [Hash, String] `owner/name`; only embryonaut_platform rolls
|
|
87
|
+
# @return [Hash] `commit`, `app`, `kind` and `paths`
|
|
88
|
+
def classify(commit:, branch:, repo:, **)
|
|
89
|
+
sha = value_of(commit)
|
|
90
|
+
refuse_unless_rollable(value_of(branch), value_of(repo))
|
|
91
|
+
paths = changed_paths(sha)
|
|
92
|
+
kind = image_only?(paths) ? "image" : "infra"
|
|
93
|
+
{ commit: wrap(sha), app: wrap(APP), kind: wrap(kind), paths: wrap(paths.join("\n")) }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Builds the console image and rolls it. An infra commit rolls only when the quick gate on
|
|
97
|
+
# record for it is green; a failed build refuses; a failed roll answers `failed`.
|
|
98
|
+
#
|
|
99
|
+
# @param commit [Hash, String] the commit being rolled
|
|
100
|
+
# @param app [Hash, String] the service; only the console rolls
|
|
101
|
+
# @return [Hash] `commit`, `app` and `status` (`done` or `failed`)
|
|
102
|
+
def roll(commit:, app:, **)
|
|
103
|
+
refuse_infra_without_gate(value_of(commit))
|
|
104
|
+
output, built = @commands.docker_build(@platform_root)
|
|
105
|
+
raise Refused, "the console image did not build: #{tail(output)}" unless built
|
|
106
|
+
|
|
107
|
+
output, rolled = @commands.deploy_service(@platform_root)
|
|
108
|
+
{ commit: wrap(value_of(commit)), app: wrap(value_of(app)), status: { value: rolled ? "done" : "failed" },
|
|
109
|
+
output: output }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
def refuse_unless_rollable(branch, repo)
|
|
115
|
+
raise Refused, "only main rolls, not #{branch}" unless branch == "main"
|
|
116
|
+
raise Refused, "only #{PLATFORM_REPO} rolls, not #{repo}" unless repo == PLATFORM_REPO
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# An infra commit is the fail-closed case: its roll needs the quick gate on record green. An
|
|
120
|
+
# image-only commit rolls on remote CI's green verdict alone.
|
|
121
|
+
def refuse_infra_without_gate(sha)
|
|
122
|
+
return if image_only?(changed_paths(sha))
|
|
123
|
+
return if gate_green?(sha)
|
|
124
|
+
|
|
125
|
+
raise Refused, "#{sha[0, 7]} changes paths outside the console image and the quick gate on record for it is not green"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def image_only?(paths) = paths.all? { |path| self.class.image_path?(path) }
|
|
129
|
+
|
|
130
|
+
def changed_paths(sha)
|
|
131
|
+
output, status = Open3.capture2e("gh", "api", "repos/#{PLATFORM_REPO}/commits/#{sha}",
|
|
132
|
+
"--jq", ".files[].filename")
|
|
133
|
+
raise Refused, "gh could not list the changes of #{sha[0, 7]}: #{output.lines.first&.strip}" unless status.success?
|
|
134
|
+
|
|
135
|
+
paths = output.lines.map(&:strip).reject(&:empty?)
|
|
136
|
+
raise Refused, "#{sha[0, 7]} changes no path" if paths.empty?
|
|
137
|
+
|
|
138
|
+
paths
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# The most recent quick-gate record for the commit, read from the QA ledger. A commit with no
|
|
142
|
+
# record is not green: the gate has not said so.
|
|
143
|
+
def gate_green?(sha)
|
|
144
|
+
row = ledger.query("QualityControl::MainCheck.All").find { |check| check[:reference][:value] == sha }
|
|
145
|
+
row&.dig(:verdict, :value) == "green"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def ledger = @ledger ||= Hecks.boot(File.join(@root, "qa/bluebook"))
|
|
149
|
+
|
|
150
|
+
def wrap(value) = { value: value }
|
|
151
|
+
|
|
152
|
+
# The last lines of a command's output, which is where its failure is named.
|
|
153
|
+
def tail(text) = text.lines.last(3).join
|
|
154
|
+
|
|
155
|
+
def value_of(value) = value.is_a?(Hash) ? value.transform_keys(&:to_s)["value"] : value
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Binds the `MainMaintenance` port to `MainMaintenance` for any boot that loads the QualityControl bluebook.
|
|
2
|
+
# The implementation is required by name, not relative to this file, so a copy of this directory shares
|
|
3
|
+
# the one implementation already loaded.
|
|
4
|
+
require "hecks/quality_control/adapters/main_maintenance"
|
|
5
|
+
|
|
6
|
+
Hecks.adapter "MainMaintenance" do
|
|
7
|
+
port "MainMaintenance"
|
|
8
|
+
end
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "open3"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require_relative "../cli/qa_main_gate"
|
|
7
|
+
require_relative "qa_era_mint"
|
|
8
|
+
require_relative "qa_auto_mint"
|
|
9
|
+
|
|
10
|
+
module Hecks
|
|
11
|
+
module Adapters
|
|
12
|
+
# The `MainMaintenance` port adapter: the bodies of the steps a maintenance run asks for. `gate`
|
|
13
|
+
# runs the quick gate on local main through `QaMainGate`; `reconcile` runs `Era.Reconcile`'s
|
|
14
|
+
# read-only
|
|
15
|
+
# plan and writes only when the `maintenance_confirm` dial is true; `push` moves the push
|
|
16
|
+
# train's
|
|
17
|
+
# checkout to main's head and sends it with the full gate and confirmation. Each answers the
|
|
18
|
+
# event its
|
|
19
|
+
# policy waits for, or raises, which the runtime records as the refusal.
|
|
20
|
+
class MainMaintenance
|
|
21
|
+
# Raised when a step refuses; its message is the refusal's reason.
|
|
22
|
+
class Refused < RuntimeError; end
|
|
23
|
+
|
|
24
|
+
# Where a stranded landing is recorded. The owner resolves it by removing the file.
|
|
25
|
+
STRANDED_DIR = ENV.fetch("HECKS_MINT_STATE", File.expand_path("~/.claude/hecks-dev/mint")).freeze
|
|
26
|
+
|
|
27
|
+
# The launcher commands the steps run outside the ledger: the reconcile plan and write, the
|
|
28
|
+
# mint, the
|
|
29
|
+
# landing, and the push train. A spec injects a stub in their place.
|
|
30
|
+
module Commands
|
|
31
|
+
# The push train's own launcher and its detached checkout.
|
|
32
|
+
TRAIN_CHECKOUT = File.expand_path("~/.claude/hecks-train")
|
|
33
|
+
TRAIN_LAUNCHER = File.join(TRAIN_CHECKOUT, "exe/hecks")
|
|
34
|
+
|
|
35
|
+
module_function
|
|
36
|
+
|
|
37
|
+
# The mint of one era of a domain, through the era check with the mint command's request.
|
|
38
|
+
#
|
|
39
|
+
# @return [Array(String, Boolean)] the minted era's label or the refusal, and whether it
|
|
40
|
+
# minted
|
|
41
|
+
def mint_era(root, domain:, era:, request:, ledger: nil)
|
|
42
|
+
QaEraMint.call(root, domain: domain, era: era, request: request, ledger: ledger)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The auto-mint rule's facts of one ledger: its live watermark, the edge and the shape diff.
|
|
46
|
+
#
|
|
47
|
+
# @return [Hash] see `QaAutoMint.facts`
|
|
48
|
+
def auto_mint_facts(ledger)
|
|
49
|
+
QaAutoMint.facts(ledger)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# The journal rows a run's own record wrote above a watermark.
|
|
53
|
+
#
|
|
54
|
+
# @return [Integer]
|
|
55
|
+
def own_rows_after(ledger, run, watermark)
|
|
56
|
+
QaAutoMint.own_rows_after(ledger, run, watermark)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Lands a minted era's branch on main through the landing command, with confirmation.
|
|
60
|
+
#
|
|
61
|
+
# @return [Array(String, Boolean)]
|
|
62
|
+
def land(root, branch)
|
|
63
|
+
launch(root, root, "landing.land!", "checkout.value=#{root}", "branch.value=#{branch}", "--confirm",
|
|
64
|
+
"--wait")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The read-only dry run of `Era.Reconcile`.
|
|
68
|
+
#
|
|
69
|
+
# @return [Array(String, Boolean)] the plan's output and whether it exited 0
|
|
70
|
+
def reconcile_plan(root)
|
|
71
|
+
launch(root, root, "query", "era.reconcile_plan")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Writes the reconciliation, confirmed, for one run.
|
|
75
|
+
#
|
|
76
|
+
# @return [Array(String, Boolean)]
|
|
77
|
+
def reconcile_write(root, run)
|
|
78
|
+
launch(root, root, "era.reconcile!", "run.value=#{run}", "confirm.value=true", "--wait")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Moves the train checkout to a commit, detached, and sends the branch through the train
|
|
82
|
+
# with the
|
|
83
|
+
# full gate and confirmation.
|
|
84
|
+
#
|
|
85
|
+
# @return [Array(String, Boolean)] the train's output and whether it exited 0
|
|
86
|
+
def train_push(root, sha)
|
|
87
|
+
output, status = Open3.capture2e("git", "-C", TRAIN_CHECKOUT, "checkout", "--detach", sha)
|
|
88
|
+
return [output, false] unless status.success?
|
|
89
|
+
|
|
90
|
+
launch(TRAIN_CHECKOUT, root, "SendTrain.board!", "checkout.value=#{root}", "remote.value=origin",
|
|
91
|
+
"branch.value=main", "full_gate.value=true", "confirm.value=true", "--wait")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# @return [Array(String, Boolean)]
|
|
95
|
+
def launch(dir, root, *argv)
|
|
96
|
+
output, status = Open3.capture2e(File.join(dir, "exe/hecks"), *argv, chdir: root)
|
|
97
|
+
[output, status.success?]
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @param aggregate [Object, nil] unused; the runtime passes the held record
|
|
102
|
+
# @param settings [Hash] unused
|
|
103
|
+
# @param root [String, nil] the repository root whose local main the steps act on
|
|
104
|
+
# @param commands [Module] the outside-world commands; a spec injects a stub
|
|
105
|
+
def initialize(aggregate: nil, settings: {}, root: nil, commands: Commands)
|
|
106
|
+
@root = root || Dir.pwd
|
|
107
|
+
@commands = commands
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Runs the quick gate on main and answers its verdict.
|
|
111
|
+
#
|
|
112
|
+
# @param run [Hash, String] the run key, as a value object or a bare string
|
|
113
|
+
# @param sha [Hash, String] the commit the run is for
|
|
114
|
+
# @return [Hash] `run`, `sha` and `color`
|
|
115
|
+
def gate(run:, sha:, **)
|
|
116
|
+
exit_code = Hecks::QualityControlCli::QaMainGate.call([], root: @root)
|
|
117
|
+
raise Refused, "the quick gate could not run (exit #{exit_code})" if exit_code == 1
|
|
118
|
+
|
|
119
|
+
{ run: wrap(run), sha: wrap(sha), color: { value: exit_code.zero? ? "green" : "red" } }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Plans the reconcile read-only, then writes it only when `maintenance_confirm` is true.
|
|
123
|
+
#
|
|
124
|
+
# @return [Hash] `run`, `sha`, `color` and `verdict` (`reported` or `written`)
|
|
125
|
+
def reconcile(run:, sha:, color:, **)
|
|
126
|
+
output, planned = @commands.reconcile_plan(@root)
|
|
127
|
+
raise Refused, "the reconcile plan refused: #{output.strip}" unless planned
|
|
128
|
+
|
|
129
|
+
verdict = write_reconcile?(run) ? "written" : "reported"
|
|
130
|
+
{ run: wrap(run), sha: wrap(sha), color: wrap(color), verdict: { value: verdict } }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Mints one era of a domain. Refuses while a stranded landing is unresolved, and unless the
|
|
134
|
+
# rehearsal
|
|
135
|
+
# said would_mint. A mint runs when the owner confirmed it or the auto-mint rule holds
|
|
136
|
+
# (`authorize!`); a mint the rule does not cover is refused as "needs owner approval".
|
|
137
|
+
#
|
|
138
|
+
# @param request [Hash] the `MintRequested` attributes: `run`, `domain`, `era`, `sha`,
|
|
139
|
+
# `branch`,
|
|
140
|
+
# `watermark`, `rehearsal_verdict`, `refusal_total`, `ledger_dir` and `confirm`
|
|
141
|
+
# @return [Hash] `run`, `domain`, `era`, `sha`, `branch` and `label`
|
|
142
|
+
def mint(**request)
|
|
143
|
+
refuse_while_stranded!
|
|
144
|
+
refuse_unrehearsed!(value_of(request[:rehearsal_verdict]))
|
|
145
|
+
label = run_mint!(request, authorize!(request))
|
|
146
|
+
%i[run domain era sha branch].to_h { |key| [key, wrap(request[key])] }.merge(label: wrap(label))
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Answers a held mint's approval request: the mint waits for the owner, and nothing follows
|
|
150
|
+
# it.
|
|
151
|
+
#
|
|
152
|
+
# @return [Hash] `domain`, `era` and `reason`
|
|
153
|
+
def approval(domain:, era:, reason:, **)
|
|
154
|
+
{ domain: wrap(domain), era: wrap(era), reason: wrap(reason) }
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Lands the branch that carries a minted era onto main in the same step. A landing that fails
|
|
158
|
+
# leaves
|
|
159
|
+
# the ledger ahead of main, so the run is stranded: the marker is written, and every later
|
|
160
|
+
# mint
|
|
161
|
+
# refuses until the owner removes it.
|
|
162
|
+
#
|
|
163
|
+
# @return [Hash] `run`, `era`, `sha` and `branch`, which `MintStranded` takes on refusal
|
|
164
|
+
def land(run:, era:, sha:, branch:, **)
|
|
165
|
+
output, landed = @commands.land(@root, value_of(branch))
|
|
166
|
+
strand!(run, era, sha, output) unless landed
|
|
167
|
+
{ run: wrap(run), era: wrap(era), sha: wrap(sha), branch: wrap(branch) }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Pushes local main through the train, after the most recent gate verdict on this commit is
|
|
171
|
+
# green and
|
|
172
|
+
# origin is an ancestor of main.
|
|
173
|
+
#
|
|
174
|
+
# @return [Hash] `run`, `sha` and `origin_sha`
|
|
175
|
+
def push(run:, sha:, **)
|
|
176
|
+
commit = value_of(sha)
|
|
177
|
+
raise Refused, "the most recent gate on #{commit[0, 7]} is not green" unless green_recorded?(commit)
|
|
178
|
+
raise Refused, "origin/main is not an ancestor of main" unless origin_ancestor?
|
|
179
|
+
|
|
180
|
+
output, passed = @commands.train_push(@root, commit)
|
|
181
|
+
raise Refused, "the train refused the push: #{output.strip}" unless passed
|
|
182
|
+
|
|
183
|
+
{ run: wrap(run), sha: wrap(commit), origin_sha: { value: git("rev-parse", "origin/main") } }
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
|
|
188
|
+
def write_reconcile?(run)
|
|
189
|
+
return false unless defined?(::QualityControlDials) && ::QualityControlDials.const_defined?(:MAINTENANCE_CONFIRM)
|
|
190
|
+
return false unless ::QualityControlDials::MAINTENANCE_CONFIRM == true
|
|
191
|
+
|
|
192
|
+
output, written = @commands.reconcile_write(@root, value_of(run))
|
|
193
|
+
raise Refused, "the reconcile write refused: #{output.strip}" unless written
|
|
194
|
+
|
|
195
|
+
true
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def wrap(value) = { value: value_of(value) }
|
|
199
|
+
|
|
200
|
+
def refuse_unrehearsed!(verdict)
|
|
201
|
+
raise Refused, "the rehearsal said #{verdict}, not would_mint" unless verdict == "would_mint"
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Lets a mint through when the owner confirmed it, or when the auto-mint rule holds on the
|
|
205
|
+
# ledger's
|
|
206
|
+
# facts at the live watermark, and answers that watermark. A stale watermark is a refusal; any
|
|
207
|
+
# other unmet rule holds the mint.
|
|
208
|
+
def authorize!(request)
|
|
209
|
+
ledger = ledger_of(request)
|
|
210
|
+
facts = @commands.auto_mint_facts(ledger)
|
|
211
|
+
stale = QaAutoMint.stale_for(@commands, ledger, value_of(request[:run]), value_of(request[:watermark]), facts[:watermark])
|
|
212
|
+
raise Refused, stale if stale
|
|
213
|
+
|
|
214
|
+
held = QaAutoMint.hold_reason(facts, value_of(request[:confirm]), value_of(request[:refusal_total]))
|
|
215
|
+
raise Refused, "needs owner approval: #{held}" if held
|
|
216
|
+
|
|
217
|
+
facts[:watermark]
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def ledger_of(request) = QaAutoMint.mintable_ledger_for(@root, value_of(request[:ledger_dir]))
|
|
221
|
+
|
|
222
|
+
# Runs the era check's mint through the mint command, and answers the label it minted. The
|
|
223
|
+
# mint is
|
|
224
|
+
# confirmed here, because `authorize!` has let it through.
|
|
225
|
+
def run_mint!(request, watermark)
|
|
226
|
+
output, minted = @commands.mint_era(@root, domain: value_of(request[:domain]),
|
|
227
|
+
era: value_of(request[:era]),
|
|
228
|
+
ledger: ledger_of(request),
|
|
229
|
+
request: {
|
|
230
|
+
confirm: true,
|
|
231
|
+
verdict: value_of(request[:rehearsal_verdict]),
|
|
232
|
+
watermark: watermark
|
|
233
|
+
})
|
|
234
|
+
raise Refused, output.strip unless minted
|
|
235
|
+
|
|
236
|
+
output.strip
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def stranded_path = File.join(STRANDED_DIR, "stranded.json")
|
|
240
|
+
|
|
241
|
+
def refuse_while_stranded!
|
|
242
|
+
return unless File.exist?(stranded_path)
|
|
243
|
+
|
|
244
|
+
raise Refused, "mints are refused until the stranded landing is resolved: #{File.read(stranded_path).strip}"
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def strand!(run, era, sha, output)
|
|
248
|
+
FileUtils.mkdir_p(STRANDED_DIR)
|
|
249
|
+
record = { run: value_of(run), era: value_of(era), sha: value_of(sha), reason: output.strip }
|
|
250
|
+
File.write(stranded_path, JSON.generate(record))
|
|
251
|
+
raise Refused, "the landing failed after the mint of era #{value_of(era)}: #{output.strip}"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def value_of(value) = value.is_a?(Hash) ? value.transform_keys(&:to_s)["value"] : value
|
|
255
|
+
|
|
256
|
+
# The most recent MainCheck record for the commit, read from the QA ledger.
|
|
257
|
+
def green_recorded?(commit)
|
|
258
|
+
row = ledger.query("QualityControl::MainCheck.All").find { |check| check[:reference][:value] == commit }
|
|
259
|
+
row&.dig(:verdict, :value) == "green"
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def ledger = @ledger ||= Hecks.boot(File.join(@root, "qa/bluebook"))
|
|
263
|
+
|
|
264
|
+
def origin_ancestor?
|
|
265
|
+
_, status = Open3.capture2e("git", "-C", @root, "merge-base", "--is-ancestor", "origin/main", "main")
|
|
266
|
+
status.success?
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def git(*argv)
|
|
270
|
+
output = Open3.capture2e("git", "-C", @root, *argv).first
|
|
271
|
+
output.strip
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Binds the `PumpTools` port to `PumpTools`, which runs the event pump once for a requested `EventPump.Pump`.
|
|
2
|
+
# Required by name, not relative, so a copy of this directory shares the one implementation loaded.
|
|
3
|
+
require "hecks/quality_control/adapters/pump_tools"
|
|
4
|
+
|
|
5
|
+
Hecks.adapter "PumpTools" do
|
|
6
|
+
port "PumpTools"
|
|
7
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "qa_tool"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
# The `PumpTools` port's adapter: answers an `EventPump`'s request by running the pump once, as
|
|
8
|
+
# its own process. An answer of 0 is a pump that ran, refusals included; anything else is an
|
|
9
|
+
# operational error and is refused with its report.
|
|
10
|
+
class PumpTools < QaTool
|
|
11
|
+
# @param run [Hash, String, nil] the pump run's name; the pump itself takes no arguments
|
|
12
|
+
# @return [Hash] `text:` what the pump printed
|
|
13
|
+
def execute(run: nil)
|
|
14
|
+
run_command("qa_event_pump", answers: [0])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Binds the `PushDue` port of `PushNudge` to `PushDueReader`, which asks the rehearsal adapter's `Due`
|
|
2
|
+
# whether a push of local main is due. Required by name, not relative, so a copy of this directory shares
|
|
3
|
+
# the one implementation loaded.
|
|
4
|
+
require "hecks/quality_control/adapters/push_due_reader"
|
|
5
|
+
|
|
6
|
+
Hecks.adapter "PushDueReader" do
|
|
7
|
+
port "PushDue"
|
|
8
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks/runtime/asking"
|
|
4
|
+
require "hecks/runtime/errors"
|
|
5
|
+
require "hecks/runtime/row_sweep"
|
|
6
|
+
require "hecks/hecks/adapters/git_rehearsal"
|
|
7
|
+
require "hecks/hecks/adapters/push_size"
|
|
8
|
+
|
|
9
|
+
module Hecks
|
|
10
|
+
module Adapters
|
|
11
|
+
# The `PushDue` port's adapter for `PushNudge`: reads whether a push of local main is due and
|
|
12
|
+
# whether the `push-due` Work row is already open, and answers the flags and numbers the
|
|
13
|
+
# bluebook's policies file, revise or finish the row from.
|
|
14
|
+
#
|
|
15
|
+
# The git reading is `GitRehearsal#due`, called as it is: this class only parses the line it
|
|
16
|
+
# answers and applies the thresholds. It fetches, pushes and merges nothing. The thresholds are
|
|
17
|
+
# the QualityControl world's `push_nudge` setting (`commits:` ahead, `hours:` old,
|
|
18
|
+
# `urgent_commits:`), else `PushSize::DEFAULTS`.
|
|
19
|
+
class PushDueReader
|
|
20
|
+
# The thresholds when the world declares none.
|
|
21
|
+
DEFAULTS = PushSize::DEFAULTS
|
|
22
|
+
|
|
23
|
+
# The world verb that carries the thresholds.
|
|
24
|
+
VERB = PushSize::VERB
|
|
25
|
+
|
|
26
|
+
# The key of the one Work row.
|
|
27
|
+
WORK = "push-due"
|
|
28
|
+
|
|
29
|
+
# The title of the Work row.
|
|
30
|
+
TITLE = "a push of main is due"
|
|
31
|
+
|
|
32
|
+
AHEAD = /(\d+) commit\(s\) ahead/
|
|
33
|
+
OLDEST = /oldest unpushed ([\d.]+) hours/
|
|
34
|
+
# Everything up to the first line break.
|
|
35
|
+
FIRST_LINE = /[^\n]*/
|
|
36
|
+
|
|
37
|
+
RED_NOW = /last (?:rehearsal|quick): red [^;\n]*\(the current /
|
|
38
|
+
|
|
39
|
+
# The thresholds a registry's QualityControl world declares.
|
|
40
|
+
#
|
|
41
|
+
# @param registry [Runtime::Registry, nil]
|
|
42
|
+
# @return [Hash{Symbol => Integer, Float}] `commits:`, `hours:` and `urgent_commits:`
|
|
43
|
+
def self.thresholds(registry) = PushSize.thresholds(registry)
|
|
44
|
+
|
|
45
|
+
# @param aggregate [Object, nil] unused
|
|
46
|
+
# @param settings [Hash] unused
|
|
47
|
+
# @param root [String, nil] a directory inside the repository; this repository when nil
|
|
48
|
+
# @param rehearsal [#due, nil] the rehearsal adapter; `GitRehearsal` when nil
|
|
49
|
+
def initialize(aggregate: nil, settings: {}, root: nil, rehearsal: nil)
|
|
50
|
+
@root = root || File.expand_path("../../../..", __dir__)
|
|
51
|
+
@rehearsal = rehearsal || GitRehearsal.new
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @param _held [Hash] the `PushNudge` record
|
|
55
|
+
# @return [Hash{Symbol => Hash}] `due:` and `raised:` ("yes"/"no"), `work:`, `title:`,
|
|
56
|
+
# `detail:`
|
|
57
|
+
# @raise [Runtime::GivenNotMet] when the refs cannot be read
|
|
58
|
+
def read(**_held)
|
|
59
|
+
text = @rehearsal.due(checkout: @root).fetch(:text)
|
|
60
|
+
limits = self.class.thresholds(registry)
|
|
61
|
+
{ due: flag(due?(text, limits)), raised: flag(raised?), work: { value: WORK }, title: { value: title(text, limits) },
|
|
62
|
+
detail: { value: detail(text, limits) } }
|
|
63
|
+
rescue ConsoleCapture::Failure => e
|
|
64
|
+
raise Runtime::GivenNotMet, "the refs could not be read: #{first_line(e.message)}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def detail(text, limits)
|
|
70
|
+
"#{text.delete_prefix("push due: ")} (thresholds: #{limits[:commits]} commits, #{limits[:hours]} hours, " \
|
|
71
|
+
"urgent at #{limits[:urgent_commits]})"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# The row's title, naming the size class once the commits ahead pass a threshold.
|
|
75
|
+
def title(text, limits) = PushSize.title(TITLE, text[AHEAD, 1].to_i, limits)
|
|
76
|
+
|
|
77
|
+
def first_line(text) = text[FIRST_LINE].strip
|
|
78
|
+
|
|
79
|
+
def due?(text, limits)
|
|
80
|
+
return false unless text.start_with?("push due: yes")
|
|
81
|
+
|
|
82
|
+
text[AHEAD, 1].to_i >= limits[:commits] || text[OLDEST, 1].to_f >= limits[:hours] || text.match?(RED_NOW)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def flag(value) = { value: value ? "yes" : "no" }
|
|
86
|
+
|
|
87
|
+
# Whether the push-due row is open now: planned or started.
|
|
88
|
+
def raised?
|
|
89
|
+
sweep = Runtime::RowSweep.new(registry)
|
|
90
|
+
aggregate = sweep.query_aggregate("Tickets", "Work", verb: "Work.Undone")
|
|
91
|
+
sweep.rows("Tickets", aggregate, "Undone", {}).any? { |row| row[:id].to_s == WORK }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def registry
|
|
95
|
+
Runtime::Asking.registry or raise Runtime::GivenNotMet, "a push is checked only when its PushNudge asks"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|