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,168 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks/ci_speed/adapters/local_runner/refused"
|
|
4
|
+
require "hecks/ci_speed/adapters/local_runner/refs"
|
|
5
|
+
require "hecks/ci_speed/adapters/local_runner/catalog"
|
|
6
|
+
require "hecks/ci_speed/adapters/local_runner/checkouts"
|
|
7
|
+
require "hecks/ci_speed/adapters/local_runner/launcher"
|
|
8
|
+
require "hecks/ci_speed/adapters/local_runner/load_average"
|
|
9
|
+
require "hecks/ci_speed/adapters/local_runner/verdict"
|
|
10
|
+
require "hecks/ci_speed/adapters/local_runner/answer"
|
|
11
|
+
|
|
12
|
+
module Hecks
|
|
13
|
+
module Adapters
|
|
14
|
+
# The `LocalRunner` port's adapter: times a definition's steps in two temporary checkouts, one
|
|
15
|
+
# of the base ref and one of the candidate ref, and answers with the numbers.
|
|
16
|
+
#
|
|
17
|
+
# Each side first runs every step once untimed, so the build caches a fresh checkout lacks are
|
|
18
|
+
# paid before timing starts. The steps then run interleaved, base then candidate then base
|
|
19
|
+
# again, so a change in the machine's load while the experiment runs lands on both sides. A
|
|
20
|
+
# step the machine cannot stand in for is named in `unmeasured` and left out of both sides.
|
|
21
|
+
# Both checkouts are removed when the run ends, however it ends, and the checkout that asked
|
|
22
|
+
# is never written.
|
|
23
|
+
class LocalRunner
|
|
24
|
+
# The sides of an experiment, in the order a round samples them.
|
|
25
|
+
SIDES = %i[base candidate].freeze
|
|
26
|
+
|
|
27
|
+
# What a step's `needs` can be and still run on this machine.
|
|
28
|
+
LOCAL_NEEDS = %w[none].freeze
|
|
29
|
+
|
|
30
|
+
# The samples taken when an experiment names no number.
|
|
31
|
+
DEFAULT_REPEATS = 3
|
|
32
|
+
|
|
33
|
+
# One side of an experiment: which it is, its checkout, and the launcher that runs its steps.
|
|
34
|
+
Side = Struct.new(:name, :path, :launcher)
|
|
35
|
+
|
|
36
|
+
# @return [Array<Hash>] every sample in the order it was taken: its round, side, seconds and
|
|
37
|
+
# the checkout it ran in
|
|
38
|
+
attr_reader :trail
|
|
39
|
+
|
|
40
|
+
# @return [Array<Hash>] the untimed pass in each checkout before sampling began: its side
|
|
41
|
+
# and the seconds it took, which no verdict uses
|
|
42
|
+
attr_reader :warm_up
|
|
43
|
+
|
|
44
|
+
# @param registry [Runtime::Registry, nil] the booted registry whose CiSpeed bluebook holds
|
|
45
|
+
# the definitions; unused when `catalog` is given
|
|
46
|
+
# @param catalog [Catalog, nil] the definitions to read instead of the bluebook's rows
|
|
47
|
+
# @param root [String, nil] the checkout that asks, whose refs are resolved and whose
|
|
48
|
+
# generated tree is copied; this repository when nil
|
|
49
|
+
# @param scratch [String, nil] where the temporary checkouts are made; `$CLAUDE_JOB_DIR/tmp`
|
|
50
|
+
# when that is set, else the system's temporary directory
|
|
51
|
+
def initialize(registry: nil, catalog: nil, root: nil, scratch: nil)
|
|
52
|
+
@registry = registry
|
|
53
|
+
@catalog = catalog
|
|
54
|
+
@root = root || File.expand_path("../../../..", __dir__)
|
|
55
|
+
@scratch = scratch || job_scratch
|
|
56
|
+
@trail = []
|
|
57
|
+
@warm_up = []
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Runs the experiment named by `held`.
|
|
61
|
+
#
|
|
62
|
+
# @param held [Hash] the `Experiment` record: `measures`, `cache_state`, `base_ref`,
|
|
63
|
+
# `candidate_ref`, `repeats` and `lever` when set
|
|
64
|
+
# @return [Hash{Symbol => Hash}] the answer, each field in the shape `Experiment::Complete`
|
|
65
|
+
# takes: the times, the spread and saving, the load, what went unmeasured, the verdict,
|
|
66
|
+
# what it rests on, and the lever to tell with the estimate it should hold
|
|
67
|
+
# @raise [Refused] when the definition is unknown, disagrees with the experiment about the
|
|
68
|
+
# cache state, no step can be measured, a ref does not resolve, or a step ends badly
|
|
69
|
+
def measure(**held)
|
|
70
|
+
asked = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
|
|
71
|
+
definition = definition_for(asked)
|
|
72
|
+
shas = Refs.resolve(@root, asked)
|
|
73
|
+
load = LoadAverage.now
|
|
74
|
+
sampled = sample_both(definition, shas, asked[:repeats] || DEFAULT_REPEATS)
|
|
75
|
+
answer(asked, definition, sampled, load)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def definition_for(asked)
|
|
81
|
+
definition = catalog.fetch(asked.fetch(:measures))
|
|
82
|
+
return definition if definition.cache_state == asked.fetch(:cache_state)
|
|
83
|
+
|
|
84
|
+
raise Refused, "#{definition.name} measures cache state #{definition.cache_state}, " \
|
|
85
|
+
"but the experiment stands for #{asked.fetch(:cache_state)}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def catalog
|
|
89
|
+
@catalog ||= Catalog.from_bluebook(@registry&.bluebook("CiSpeed") || raise(Refused, "no CiSpeed bluebook is booted"))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Checks the two sides out, works out which steps both can run, and samples them interleaved.
|
|
93
|
+
def sample_both(definition, shas, repeats)
|
|
94
|
+
copy_from = @root if definition.generated_tree?
|
|
95
|
+
refuse_missing_tree(copy_from)
|
|
96
|
+
Checkouts.with(root: @root, shas: shas, scratch: @scratch) do |paths|
|
|
97
|
+
sides = paths.map { |name, path| Side.new(name, path, Launcher.new(path)) }
|
|
98
|
+
steps, unmeasured = measurable(definition.steps, sides)
|
|
99
|
+
warm(sides, steps, copy_from)
|
|
100
|
+
{ unmeasured: unmeasured, samples: rounds(sides, steps, copy_from, repeats) }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Runs every step once in each checkout before anything is timed. A fresh checkout holds no
|
|
105
|
+
# build caches, and the first run in it would pay for them on one side of the first pair.
|
|
106
|
+
def warm(sides, steps, copy_from)
|
|
107
|
+
sides.each do |side|
|
|
108
|
+
Checkouts.reset_generated_tree(side.path, copy_from)
|
|
109
|
+
seconds = steps.sum { |step| side.launcher.time(step) }
|
|
110
|
+
@warm_up << { side: side.name, seconds: seconds }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Splits steps into those both sides can run here and a note for each that cannot.
|
|
115
|
+
def measurable(steps, sides)
|
|
116
|
+
notes = []
|
|
117
|
+
kept = steps.select do |step|
|
|
118
|
+
reason = unmeasurable(step, sides)
|
|
119
|
+
notes << "#{step.name}: #{reason}" if reason
|
|
120
|
+
reason.nil?
|
|
121
|
+
end
|
|
122
|
+
raise Refused, "no step could be measured here: #{notes.join("; ")}" if kept.empty?
|
|
123
|
+
|
|
124
|
+
[kept, notes]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def unmeasurable(step, sides)
|
|
128
|
+
return "needs #{step.needs}, which a local run does not stand in for" unless LOCAL_NEEDS.include?(step.needs)
|
|
129
|
+
|
|
130
|
+
sides.each do |side|
|
|
131
|
+
return "#{step.verb} or an argument it is given is unknown to the #{side.name} ref" unless side.launcher.knows?(step)
|
|
132
|
+
end
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# One round samples each side once, base first, and the rounds follow one another.
|
|
137
|
+
def rounds(sides, steps, copy_from, repeats)
|
|
138
|
+
taken = Array.new(repeats) { |round| sides.map { |side| sample(round, side, steps, copy_from) } }
|
|
139
|
+
taken.flatten.group_by { |sample| sample[:side] }.transform_values { |own| own.map { |one| one[:seconds] } }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def refuse_missing_tree(copy_from)
|
|
143
|
+
return if copy_from.nil? || File.directory?(File.join(copy_from, Checkouts::GENERATED_TREE))
|
|
144
|
+
|
|
145
|
+
raise Refused, "the definition needs a generated tree, and #{copy_from} holds none at #{Checkouts::GENERATED_TREE}"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def sample(round, side, steps, copy_from)
|
|
149
|
+
Checkouts.reset_generated_tree(side.path, copy_from)
|
|
150
|
+
seconds = steps.sum { |step| side.launcher.time(step) }
|
|
151
|
+
taken = { round: round, side: side.name, seconds: seconds, checkout: side.path }
|
|
152
|
+
@trail << taken
|
|
153
|
+
taken
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def answer(asked, definition, sampled, load)
|
|
157
|
+
verdict = Verdict.new(base: sampled[:samples].fetch(:base), candidate: sampled[:samples].fetch(:candidate))
|
|
158
|
+
Answer.build(asked: asked, definition: definition.name, verdict: verdict, load: load,
|
|
159
|
+
unmeasured: sampled[:unmeasured])
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def job_scratch
|
|
163
|
+
job = ENV.fetch("CLAUDE_JOB_DIR", nil)
|
|
164
|
+
File.join(job, "tmp") if job && !job.empty?
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks/ci_speed/adapters/local_runner"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
# A `LocalRunner` that replays samples recorded here instead of running anything, for
|
|
8
|
+
# `ci_speed.behaviors`: a behaviors boot must be deterministic and fast, and the real adapter
|
|
9
|
+
# makes two checkouts and times real work. The verdict, the saving and the estimate are worked
|
|
10
|
+
# out by the real adapter's own `Verdict` and `Answer`, so only the timing is replaced.
|
|
11
|
+
class ReplayedRunner
|
|
12
|
+
# The samples each experiment name replays, in seconds, as base and candidate.
|
|
13
|
+
RECORDINGS = {
|
|
14
|
+
"wide_win" => { base: [120.0, 122.0, 124.0], candidate: [90.0, 91.0, 92.0] },
|
|
15
|
+
"within_noise" => { base: [120.0, 126.0, 123.0], candidate: [121.0, 124.0, 122.0] },
|
|
16
|
+
"wide_loss" => { base: [90.0, 91.0, 92.0], candidate: [120.0, 122.0, 124.0] }
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
# The load average every replay reports.
|
|
20
|
+
LOAD = 2.5
|
|
21
|
+
|
|
22
|
+
# @param aggregate [Object, nil] unused
|
|
23
|
+
def initialize(aggregate: nil); end
|
|
24
|
+
|
|
25
|
+
# @param held [Hash] the `Experiment` record
|
|
26
|
+
# @return [Hash{Symbol => Hash}] the answer, as the real adapter words it
|
|
27
|
+
# @raise [LocalRunner::Refused] when nothing is recorded for the experiment's name
|
|
28
|
+
def measure(**held)
|
|
29
|
+
asked = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
|
|
30
|
+
samples = RECORDINGS.fetch(asked.fetch(:name)) do
|
|
31
|
+
raise LocalRunner::Refused, "no samples are recorded for #{asked[:name]}; recorded: #{RECORDINGS.keys.join(", ")}"
|
|
32
|
+
end
|
|
33
|
+
verdict = LocalRunner::Verdict.new(**samples)
|
|
34
|
+
LocalRunner::Answer.build(asked: asked, definition: asked.fetch(:measures), verdict: verdict, load: LOAD,
|
|
35
|
+
unmeasured: [])
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
Hecks.behaviors "CiSpeed" do
|
|
2
|
+
vision "A run is written down as it finished, and a change is kept only when a following run of its cache state beat the baseline by the margin."
|
|
3
|
+
|
|
4
|
+
# `ci_speed.hecksagon` binds every aggregate to Memory and attaches Governance, so a boot of these
|
|
5
|
+
# files passes the memory-only guard and the role check.
|
|
6
|
+
loads "../../../spec/fixtures/ci_speed/ci_speed.hecksagon", "ci_speed.bluebook", "ci_speed.ports.hecksagon"
|
|
7
|
+
|
|
8
|
+
test "Observe writes down a run as it finished" do
|
|
9
|
+
tests "Observe", on: "Run"
|
|
10
|
+
input run_id: { value: "1001" }, commit: { value: "93f8e68c6" }, wall_seconds: { value: 240 },
|
|
11
|
+
cache_state: { value: "miss" }, conclusion: { value: "success" }, budget_seconds: { value: 180 },
|
|
12
|
+
longest_pole: { value: "rspec" }
|
|
13
|
+
expect emits: ["RunObserved"]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test "RecordJob refuses a job time once the run is analysed" do
|
|
17
|
+
tests "RecordJob", on: "Run"
|
|
18
|
+
setup "CiSpeed::Run.Observe", run_id: { value: "1401" }, commit: { value: "93f8e68c6" },
|
|
19
|
+
wall_seconds: { value: 150 }, cache_state: { value: "hit" }, conclusion: { value: "success" },
|
|
20
|
+
budget_seconds: { value: 180 }, longest_pole: { value: "rspec" }
|
|
21
|
+
setup "CiSpeed::Run.AnalyzeWarmUnderBudget", run: "1401", seconds: { value: 150 }
|
|
22
|
+
input run: "1401", job: { value: "rspec" }, seconds: { value: 90 }, critical: { value: "yes" }
|
|
23
|
+
expect refused: "a run's job times are written before it is analysed"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "AnalyzeWarmUnderBudget refuses a cache-miss run" do
|
|
27
|
+
tests "AnalyzeWarmUnderBudget", on: "Run"
|
|
28
|
+
setup "CiSpeed::Run.Observe", run_id: { value: "1301" }, commit: { value: "93f8e68c6" },
|
|
29
|
+
wall_seconds: { value: 150 }, cache_state: { value: "miss" }, conclusion: { value: "success" },
|
|
30
|
+
budget_seconds: { value: 180 }, longest_pole: { value: "rspec" }
|
|
31
|
+
input run: "1301", seconds: { value: 150 }
|
|
32
|
+
expect refused: "a warm run is a cache hit that finished within budget"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# A cache-miss run over budget proposes a lever for its longest pole, and its over-budget
|
|
36
|
+
# verdict is witnessed by the Budget.
|
|
37
|
+
test "A cache-miss run over budget proposes a lever for its longest pole" do
|
|
38
|
+
tests "AnalyzeMissOverBudget", on: "Run"
|
|
39
|
+
setup "CiSpeed::Budget.Open", name: { value: "main" }, target_seconds: { value: 180 }
|
|
40
|
+
setup "CiSpeed::Run.Observe", run_id: { value: "1002" }, commit: { value: "93f8e68c6" },
|
|
41
|
+
wall_seconds: { value: 240 }, cache_state: { value: "miss" }, conclusion: { value: "success" },
|
|
42
|
+
budget_seconds: { value: 180 }, longest_pole: { value: "rspec" }
|
|
43
|
+
setup "CiSpeed::Run.RecordJob", run: "1002", job: { value: "rspec" }, seconds: { value: 200 },
|
|
44
|
+
critical: { value: "yes" }
|
|
45
|
+
input run: "1002", seconds: { value: 240 }, pole: { value: "rspec" }
|
|
46
|
+
expect emits: %w[MissRunOverBudget MissRunWitnessed LeverProposed]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# A lever is kept when a following run of the same cache state beats its baseline by the margin.
|
|
50
|
+
test "Keep keeps an attempted lever that a same-cache run beat by the margin" do
|
|
51
|
+
tests "Keep", on: "Lever"
|
|
52
|
+
setup "CiSpeed::Lever.Propose", name: { value: "postgres_io" },
|
|
53
|
+
change: { value: "postgres io specs on fewer shards" }, pole: { value: "postgres_io" },
|
|
54
|
+
affects: { value: "miss" }, expected_seconds: { value: 30 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
55
|
+
setup "CiSpeed::Lever.Attempt", lever: "postgres_io", baseline_run: { value: "1100" },
|
|
56
|
+
baseline_seconds: { value: 300 }, baseline_cache: { value: "miss" }
|
|
57
|
+
input lever: "postgres_io", following_run: { value: "1101" }, following_seconds: { value: 250 },
|
|
58
|
+
following_cache: { value: "miss" }, evidence: { value: "1a2b3c4d" }, saved_seconds: { value: 50 }
|
|
59
|
+
expect emits: ["LeverKept"]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test "Keep refuses a saving that is not the baseline less the following time" do
|
|
63
|
+
tests "Keep", on: "Lever"
|
|
64
|
+
setup "CiSpeed::Lever.Propose", name: { value: "postgres_io" },
|
|
65
|
+
change: { value: "postgres io specs on fewer shards" }, pole: { value: "postgres_io" },
|
|
66
|
+
affects: { value: "miss" }, expected_seconds: { value: 30 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
67
|
+
setup "CiSpeed::Lever.Attempt", lever: "postgres_io", baseline_run: { value: "1100" },
|
|
68
|
+
baseline_seconds: { value: 300 }, baseline_cache: { value: "miss" }
|
|
69
|
+
input lever: "postgres_io", following_run: { value: "1101" }, following_seconds: { value: 250 },
|
|
70
|
+
following_cache: { value: "miss" }, evidence: { value: "1a2b3c4d" }, saved_seconds: { value: 10 }
|
|
71
|
+
expect refused: "a kept lever says what it really saved"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# A following run that is not faster by the margin reverts the lever.
|
|
75
|
+
test "Revert reverts an attempted lever that the following run did not beat" do
|
|
76
|
+
tests "Revert", on: "Lever"
|
|
77
|
+
setup "CiSpeed::Lever.Propose", name: { value: "rspec_4_shards" },
|
|
78
|
+
change: { value: "rspec on fewer shards" }, pole: { value: "rspec" },
|
|
79
|
+
affects: { value: "miss" }, expected_seconds: { value: 30 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
80
|
+
setup "CiSpeed::Lever.Attempt", lever: "rspec_4_shards", baseline_run: { value: "1200" },
|
|
81
|
+
baseline_seconds: { value: 300 }, baseline_cache: { value: "miss" }
|
|
82
|
+
input lever: "rspec_4_shards", following_run: { value: "1201" }, following_seconds: { value: 295 },
|
|
83
|
+
following_cache: { value: "miss" }
|
|
84
|
+
expect emits: ["LeverReverted"]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test "Keep refuses a following run of a different cache state" do
|
|
88
|
+
tests "Keep", on: "Lever"
|
|
89
|
+
setup "CiSpeed::Lever.Propose", name: { value: "postgres_io" },
|
|
90
|
+
change: { value: "postgres io specs on fewer shards" }, pole: { value: "postgres_io" },
|
|
91
|
+
affects: { value: "both" }, expected_seconds: { value: 30 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
92
|
+
setup "CiSpeed::Lever.Attempt", lever: "postgres_io", baseline_run: { value: "1100" },
|
|
93
|
+
baseline_seconds: { value: 300 }, baseline_cache: { value: "miss" }
|
|
94
|
+
input lever: "postgres_io", following_run: { value: "1101" }, following_seconds: { value: 200 },
|
|
95
|
+
following_cache: { value: "hit" }, evidence: { value: "1a2b3c4d" }, saved_seconds: { value: 100 }
|
|
96
|
+
expect refused: "a following run is of the cache state the lever was measured on"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test "Attempt refuses a lever measured on a cache state it does not affect" do
|
|
100
|
+
tests "Attempt", on: "Lever"
|
|
101
|
+
setup "CiSpeed::Lever.Propose", name: { value: "feature_binaries" },
|
|
102
|
+
change: { value: "feature binaries built in legs" }, pole: { value: "feature_binaries" },
|
|
103
|
+
affects: { value: "hit" }, expected_seconds: { value: 40 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
104
|
+
input lever: "feature_binaries", baseline_run: { value: "1300" }, baseline_seconds: { value: 300 },
|
|
105
|
+
baseline_cache: { value: "miss" }
|
|
106
|
+
expect refused: "a lever is measured on the cache state it affects"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
test "Reconsider refuses a reverted lever whose inputs have not changed" do
|
|
110
|
+
tests "Reconsider", on: "Lever"
|
|
111
|
+
setup "CiSpeed::Lever.Propose", name: { value: "rspec_4_shards" },
|
|
112
|
+
change: { value: "rspec on fewer shards" }, pole: { value: "rspec" },
|
|
113
|
+
affects: { value: "miss" }, expected_seconds: { value: 30 }, basis: { value: "unestimated" }, inputs: { value: "abc123" }
|
|
114
|
+
setup "CiSpeed::Lever.Attempt", lever: "rspec_4_shards", baseline_run: { value: "1200" },
|
|
115
|
+
baseline_seconds: { value: 300 }, baseline_cache: { value: "miss" }
|
|
116
|
+
setup "CiSpeed::Lever.Revert", lever: "rspec_4_shards", following_run: { value: "1201" },
|
|
117
|
+
following_seconds: { value: 295 }, following_cache: { value: "miss" }
|
|
118
|
+
input lever: "rspec_4_shards", new_inputs: { value: "abc123" }
|
|
119
|
+
expect refused: "a reverted lever is retried only when its inputs have changed"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
test "Recall keeps a lever that history settled, with the commit that settled it" do
|
|
123
|
+
tests "Recall", on: "Lever"
|
|
124
|
+
setup "CiSpeed::Lever.Propose", name: { value: "host_test_build" },
|
|
125
|
+
change: { value: "host test build warmed into its own cache" }, pole: { value: "host_test_build" },
|
|
126
|
+
affects: { value: "both" }, expected_seconds: { value: 0 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
127
|
+
input lever: "host_test_build", evidence: { value: "504f0e0d8" }
|
|
128
|
+
expect emits: ["LeverLearned"]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test "Complete refuses while the latest cache-miss run is over budget" do
|
|
132
|
+
tests "Complete", on: "Budget"
|
|
133
|
+
setup "CiSpeed::Budget.Open", name: { value: "main" }, target_seconds: { value: 180 }
|
|
134
|
+
setup "CiSpeed::Budget.WitnessWarm", budget: "main", seconds: { value: 150 }
|
|
135
|
+
setup "CiSpeed::Budget.WitnessMiss", budget: "main", seconds: { value: 200 }
|
|
136
|
+
input budget: "main"
|
|
137
|
+
expect refused: "both cache states are under budget"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# The effort completes once the latest warm run and the latest cache-miss run are both under
|
|
141
|
+
# budget. The warm verdict is witnessed by its own policy in setup.
|
|
142
|
+
test "A cache-miss run under budget completes the effort when the warm run is under budget" do
|
|
143
|
+
tests "AnalyzeMissUnderBudget", on: "Run"
|
|
144
|
+
setup "CiSpeed::Budget.Open", name: { value: "main" }, target_seconds: { value: 180 }
|
|
145
|
+
setup "CiSpeed::Run.Observe", run_id: { value: "1201" }, commit: { value: "93f8e68c6" },
|
|
146
|
+
wall_seconds: { value: 150 }, cache_state: { value: "hit" }, conclusion: { value: "success" },
|
|
147
|
+
budget_seconds: { value: 180 }, longest_pole: { value: "rspec" }
|
|
148
|
+
setup "CiSpeed::Run.AnalyzeWarmUnderBudget", run: "1201", seconds: { value: 150 }
|
|
149
|
+
setup "CiSpeed::Run.Observe", run_id: { value: "1202" }, commit: { value: "93f8e68c6" },
|
|
150
|
+
wall_seconds: { value: 170 }, cache_state: { value: "miss" }, conclusion: { value: "success" },
|
|
151
|
+
budget_seconds: { value: 180 }, longest_pole: { value: "rspec" }
|
|
152
|
+
input run: "1202", seconds: { value: 170 }
|
|
153
|
+
expect emits: %w[MissRunUnderBudget MissRunWitnessed BudgetMet]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# The backlog is what drives the attempts: the biggest expected saving is tried first.
|
|
157
|
+
test "Next is the proposed lever with the biggest expected saving" do
|
|
158
|
+
tests "Next", on: "Lever", kind: :query
|
|
159
|
+
setup "CiSpeed::Lever.Propose", name: { value: "small_win" }, change: { value: "a small change" },
|
|
160
|
+
pole: { value: "rspec" }, affects: { value: "both" }, expected_seconds: { value: 20 },
|
|
161
|
+
basis: { value: "run 40438675259 job times" }, inputs: { value: "" }
|
|
162
|
+
setup "CiSpeed::Lever.Propose", name: { value: "big_win" }, change: { value: "a big change" },
|
|
163
|
+
pole: { value: "rspec" }, affects: { value: "both" }, expected_seconds: { value: 90 },
|
|
164
|
+
basis: { value: "run 40438675259 job times" }, inputs: { value: "" }
|
|
165
|
+
setup "CiSpeed::Lever.Propose", name: { value: "middling_win" }, change: { value: "a middling change" },
|
|
166
|
+
pole: { value: "rspec" }, affects: { value: "both" }, expected_seconds: { value: 50 },
|
|
167
|
+
basis: { value: "run 40438675259 job times" }, inputs: { value: "" }
|
|
168
|
+
expect count: 1, name: { value: "big_win" }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test "Reestimate revises the saving a proposed lever is expected to make" do
|
|
172
|
+
tests "Reestimate", on: "Lever"
|
|
173
|
+
setup "CiSpeed::Lever.Propose", name: { value: "fuzz_sqlite" }, change: { value: "split the fuzz sqlite job" },
|
|
174
|
+
pole: { value: "checks_fuzz_sqlite" }, affects: { value: "hit" }, expected_seconds: { value: 0 },
|
|
175
|
+
basis: { value: "unestimated" }, inputs: { value: "" }
|
|
176
|
+
input lever: "fuzz_sqlite", new_expected_seconds: { value: 60 },
|
|
177
|
+
new_basis: { value: "run 40438675259: the job ran 191s, the next slowest 183s" }
|
|
178
|
+
expect emits: ["LeverReestimated"]
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
test "Reestimate refuses an estimate that says nothing about what it rests on" do
|
|
182
|
+
tests "Reestimate", on: "Lever"
|
|
183
|
+
setup "CiSpeed::Lever.Propose", name: { value: "fuzz_sqlite" }, change: { value: "split the fuzz sqlite job" },
|
|
184
|
+
pole: { value: "checks_fuzz_sqlite" }, affects: { value: "hit" }, expected_seconds: { value: 0 },
|
|
185
|
+
basis: { value: "unestimated" }, inputs: { value: "" }
|
|
186
|
+
input lever: "fuzz_sqlite", new_expected_seconds: { value: 60 }, new_basis: { value: "unestimated" }
|
|
187
|
+
expect refused: "a revised estimate says what it rests on"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Meeting 180 seconds is a milestone: the target drops and the backlog goes on.
|
|
191
|
+
test "Reopen sets a lower target once the last one is met" do
|
|
192
|
+
tests "Reopen", on: "Budget"
|
|
193
|
+
setup "CiSpeed::Budget.Open", name: { value: "main" }, target_seconds: { value: 180 }
|
|
194
|
+
setup "CiSpeed::Budget.WitnessWarm", budget: "main", seconds: { value: 150 }
|
|
195
|
+
setup "CiSpeed::Budget.WitnessMiss", budget: "main", seconds: { value: 170 }
|
|
196
|
+
input budget: "main", new_target_seconds: { value: 150 }
|
|
197
|
+
expect emits: ["BudgetReopened"]
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
test "Reopen refuses a target that is not lower than the one met" do
|
|
201
|
+
tests "Reopen", on: "Budget"
|
|
202
|
+
setup "CiSpeed::Budget.Open", name: { value: "main" }, target_seconds: { value: 180 }
|
|
203
|
+
setup "CiSpeed::Budget.WitnessWarm", budget: "main", seconds: { value: 150 }
|
|
204
|
+
setup "CiSpeed::Budget.WitnessMiss", budget: "main", seconds: { value: 170 }
|
|
205
|
+
input budget: "main", new_target_seconds: { value: 200 }
|
|
206
|
+
expect refused: "a new target is lower than the one met"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# The experiments below are answered by `spec/fixtures/ci_speed/replayed_runner.adapter`, which
|
|
210
|
+
# replays recorded samples under the experiment's name (`wide_win`, `within_noise`, `wide_loss`)
|
|
211
|
+
# and refuses any other name. The real `LocalRunner` makes two checkouts and times real work, so
|
|
212
|
+
# `spec/ci_speed_local_runner_spec.rb` holds it instead.
|
|
213
|
+
test "Request refuses a candidate that is the same ref as its base" do
|
|
214
|
+
tests "Request", on: "Experiment"
|
|
215
|
+
input name: { value: "same_ref" }, lever: { value: "" }, measures: { value: "regenerate_corpus_cold" },
|
|
216
|
+
cache_state: { value: "miss" }, base_ref: { value: "HEAD" }, candidate_ref: { value: "HEAD" },
|
|
217
|
+
repeats: { value: 3 }
|
|
218
|
+
expect refused: "a candidate is a different ref from its base"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
test "Request refuses a single sample, which has no spread to judge it by" do
|
|
222
|
+
tests "Request", on: "Experiment"
|
|
223
|
+
input name: { value: "one_sample" }, lever: { value: "" }, measures: { value: "regenerate_corpus_cold" },
|
|
224
|
+
cache_state: { value: "miss" }, base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" },
|
|
225
|
+
repeats: { value: 1 }
|
|
226
|
+
expect refused: "an experiment is repeated at least twice"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
test "A measured faster result completes" do
|
|
230
|
+
tests "Request", on: "Experiment"
|
|
231
|
+
input name: { value: "wide_win" }, lever: { value: "" }, measures: { value: "regenerate_corpus_cold" },
|
|
232
|
+
cache_state: { value: "miss" }, base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" },
|
|
233
|
+
repeats: { value: 3 }
|
|
234
|
+
expect emits: %w[ExperimentRequested ExperimentAnswered ExperimentMeasured]
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
test "A result inside the spread is inconclusive and re-estimates nothing" do
|
|
238
|
+
tests "Request", on: "Experiment"
|
|
239
|
+
setup "CiSpeed::Lever.Propose", name: { value: "parallel_rustfmt" },
|
|
240
|
+
change: { value: "rustfmt on one thread per core" }, pole: { value: "generated_rust" },
|
|
241
|
+
affects: { value: "miss" }, expected_seconds: { value: 0 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
242
|
+
input name: { value: "within_noise" }, lever: { value: "parallel_rustfmt" },
|
|
243
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
244
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
245
|
+
expect emits: %w[ExperimentRequested ExperimentAnswered ExperimentMeasured]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
test "A faster conclusive result re-estimates the lever it names" do
|
|
249
|
+
tests "Request", on: "Experiment"
|
|
250
|
+
setup "CiSpeed::Lever.Propose", name: { value: "parallel_rustfmt" },
|
|
251
|
+
change: { value: "rustfmt on one thread per core" }, pole: { value: "generated_rust" },
|
|
252
|
+
affects: { value: "miss" }, expected_seconds: { value: 0 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
253
|
+
input name: { value: "wide_win" }, lever: { value: "parallel_rustfmt" },
|
|
254
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
255
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
256
|
+
expect emits: %w[ExperimentRequested ExperimentAnswered ExperimentMeasured LeverReestimated]
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
test "The lever carries what the experiment measured, as its estimate" do
|
|
260
|
+
tests "Next", on: "Lever", kind: :query
|
|
261
|
+
setup "CiSpeed::Lever.Propose", name: { value: "parallel_rustfmt" },
|
|
262
|
+
change: { value: "rustfmt on one thread per core" }, pole: { value: "generated_rust" },
|
|
263
|
+
affects: { value: "miss" }, expected_seconds: { value: 0 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
264
|
+
setup "CiSpeed::Experiment.Request", name: { value: "wide_win" }, lever: { value: "parallel_rustfmt" },
|
|
265
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
266
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
267
|
+
expect count: 1, name: { value: "parallel_rustfmt" }, expected_seconds: { value: 31 }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
test "A slower result says nothing to the backlog" do
|
|
271
|
+
tests "Request", on: "Experiment"
|
|
272
|
+
setup "CiSpeed::Lever.Propose", name: { value: "parallel_rustfmt" },
|
|
273
|
+
change: { value: "rustfmt on one thread per core" }, pole: { value: "generated_rust" },
|
|
274
|
+
affects: { value: "miss" }, expected_seconds: { value: 0 }, basis: { value: "unestimated" }, inputs: { value: "" }
|
|
275
|
+
input name: { value: "wide_loss" }, lever: { value: "parallel_rustfmt" },
|
|
276
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
277
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
278
|
+
expect emits: %w[ExperimentRequested ExperimentAnswered ExperimentMeasured]
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
test "Request is faulted when the runner refuses it" do
|
|
282
|
+
tests "Request", on: "Experiment"
|
|
283
|
+
input name: { value: "unrecorded" }, lever: { value: "" }, measures: { value: "regenerate_corpus_cold" },
|
|
284
|
+
cache_state: { value: "miss" }, base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" },
|
|
285
|
+
repeats: { value: 3 }
|
|
286
|
+
expect emits: %w[ExperimentRequested ExperimentRefused ExperimentFaulted]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
test "A fault records why" do
|
|
290
|
+
tests "Outcome", on: "Experiment", kind: :query
|
|
291
|
+
setup "CiSpeed::Experiment.Request", name: { value: "unrecorded" }, lever: { value: "" },
|
|
292
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
293
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
294
|
+
input name: { value: "unrecorded" }
|
|
295
|
+
expect count: 1, status: "faulted",
|
|
296
|
+
refusal: { value: "Hecks::Adapters::LocalRunner::Refused: no samples are recorded for unrecorded; " \
|
|
297
|
+
"recorded: wide_win, within_noise, wide_loss" }
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# A verdict has to say what the numbers say. The record here is faulted, not requested, because
|
|
301
|
+
# the givens are checked before the lifecycle, and they are what is held to account.
|
|
302
|
+
test "Complete refuses a faster verdict whose saving is not larger than the spread" do
|
|
303
|
+
tests "Complete", on: "Experiment"
|
|
304
|
+
setup "CiSpeed::Experiment.Request", name: { value: "unrecorded" }, lever: { value: "" },
|
|
305
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
306
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
307
|
+
input experiment: "unrecorded", base_seconds: { value: 120.0 }, candidate_seconds: { value: 118.0 },
|
|
308
|
+
spread_seconds: { value: 6.0 }, saved_seconds: { value: 2.0 }, load: { value: 2.5 },
|
|
309
|
+
unmeasured: { value: "" }, verdict: { value: "faster" }, basis: { value: "a guess" },
|
|
310
|
+
reestimates: { value: "" }, expected_seconds: { value: 2 }
|
|
311
|
+
expect refused: "a faster verdict needs a saving larger than the spread"
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
test "Complete refuses an estimate on a result that is not faster" do
|
|
315
|
+
tests "Complete", on: "Experiment"
|
|
316
|
+
setup "CiSpeed::Experiment.Request", name: { value: "unrecorded" }, lever: { value: "" },
|
|
317
|
+
measures: { value: "regenerate_corpus_cold" }, cache_state: { value: "miss" },
|
|
318
|
+
base_ref: { value: "HEAD~1" }, candidate_ref: { value: "HEAD" }, repeats: { value: 3 }
|
|
319
|
+
input experiment: "unrecorded", base_seconds: { value: 120.0 }, candidate_seconds: { value: 118.0 },
|
|
320
|
+
spread_seconds: { value: 6.0 }, saved_seconds: { value: 2.0 }, load: { value: 2.5 },
|
|
321
|
+
unmeasured: { value: "" }, verdict: { value: "inconclusive" }, basis: { value: "a guess" },
|
|
322
|
+
reestimates: { value: "" }, expected_seconds: { value: 2 }
|
|
323
|
+
expect refused: "only a faster verdict carries an estimate"
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
test "Record keeps a finding, with its cause and the remedy still to try" do
|
|
327
|
+
tests "Record", on: "Finding"
|
|
328
|
+
input name: { value: "cache_download_stall" }, status: { value: "untried" },
|
|
329
|
+
symptom: { value: "one gem cache download stopped at 91% for about 80 seconds" },
|
|
330
|
+
cause: { value: "the cache service, seen once" },
|
|
331
|
+
remedy: { value: "set SEGMENT_DOWNLOAD_TIMEOUT_MINS to about a minute and check what a timeout does" }
|
|
332
|
+
expect emits: %w[FindingRecorded]
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
test "Record refuses a finding with no name" do
|
|
336
|
+
tests "Record", on: "Finding"
|
|
337
|
+
input name: { value: "" }, status: { value: "open" },
|
|
338
|
+
symptom: { value: "a symptom" }, cause: { value: "a cause" }, remedy: { value: "a remedy" }
|
|
339
|
+
expect refused: "must match"
|
|
340
|
+
end
|
|
341
|
+
end
|