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
|
@@ -51,7 +51,7 @@ Hecks.bluebook "QualityControl" do
|
|
|
51
51
|
# Comma-joined mode names recorded at release from what the runner inferred. Stored so
|
|
52
52
|
# `EligibleFor` can answer why a mode never ran; inference at sweep time still decides.
|
|
53
53
|
attribute :capabilities, Capabilities
|
|
54
|
-
attribute :reason, TargetReason
|
|
54
|
+
attribute :reason, TargetReason, optional: true
|
|
55
55
|
|
|
56
56
|
value_object "TargetReference" do
|
|
57
57
|
attribute :value, String, matches: :present
|
|
@@ -352,7 +352,7 @@ Hecks.bluebook "QualityControl" do
|
|
|
352
352
|
attribute :reference, SweepReference
|
|
353
353
|
attribute :engineer, Engineer
|
|
354
354
|
attribute :made, CheckCount
|
|
355
|
-
attribute :notes, SweepNotes
|
|
355
|
+
attribute :notes, SweepNotes, optional: true
|
|
356
356
|
# A counter, not a flag (a sweep can bend several gates) or a list (`where` cannot test
|
|
357
357
|
# emptiness).
|
|
358
358
|
attribute :waived, WaiverCount
|
|
@@ -747,12 +747,12 @@ Hecks.bluebook "QualityControl" do
|
|
|
747
747
|
attribute :submitter, Submitter
|
|
748
748
|
attribute :order, BugOrder
|
|
749
749
|
attribute :tags, list_of(Tag)
|
|
750
|
-
attribute :site, BugSite
|
|
751
|
-
attribute :cause, BugCause
|
|
752
|
-
attribute :commit, CommitRef
|
|
753
|
-
attribute :verification, Verification
|
|
754
|
-
attribute :reason, BugReason
|
|
755
|
-
attribute :next_step, NextStep
|
|
750
|
+
attribute :site, BugSite, optional: true
|
|
751
|
+
attribute :cause, BugCause, optional: true
|
|
752
|
+
attribute :commit, CommitRef, optional: true
|
|
753
|
+
attribute :verification, Verification, optional: true
|
|
754
|
+
attribute :reason, BugReason, optional: true
|
|
755
|
+
attribute :next_step, NextStep, optional: true
|
|
756
756
|
attribute :waived, WaiverCount
|
|
757
757
|
# The same signature as `Sweep.waived_by`; absent until a person waives.
|
|
758
758
|
attribute :waived_by, WaivedBy, optional: true
|
|
@@ -1207,6 +1207,14 @@ Hecks.bluebook "QualityControl" do
|
|
|
1207
1207
|
order_by :sequence
|
|
1208
1208
|
end
|
|
1209
1209
|
|
|
1210
|
+
# `hecks quality_control bug.fix_and_land --bug BUG#n` is the script. It is a query because the
|
|
1211
|
+
# records it writes are the Bug commands above, and the branch, commit, landing and push live
|
|
1212
|
+
# outside the ledger. It stops, and writes nothing, on a bug triaged bigger.
|
|
1213
|
+
query "FixAndLand" do
|
|
1214
|
+
description "Takes one self-contained bug through a fix on a fresh branch, the quick gate on that exact commit, a landing on local main and a push through the push train. A bigger bug stops here, untouched."
|
|
1215
|
+
order_by :sequence
|
|
1216
|
+
end
|
|
1217
|
+
|
|
1210
1218
|
query "All" do
|
|
1211
1219
|
description "Every bug ever logged — what a runner mints the next reference from."
|
|
1212
1220
|
order_by :sequence
|
|
@@ -1225,8 +1233,8 @@ Hecks.bluebook "QualityControl" do
|
|
|
1225
1233
|
attribute :citation, AngleCitation
|
|
1226
1234
|
attribute :proposer, Proposer
|
|
1227
1235
|
attribute :proposed_at, Instant
|
|
1228
|
-
attribute :resolution, AngleResolution
|
|
1229
|
-
attribute :reason, AngleReason
|
|
1236
|
+
attribute :resolution, AngleResolution, optional: true
|
|
1237
|
+
attribute :reason, AngleReason, optional: true
|
|
1230
1238
|
|
|
1231
1239
|
value_object "AngleReference" do
|
|
1232
1240
|
attribute :value, String, matches: :present
|
|
@@ -1825,7 +1833,7 @@ Hecks.bluebook "QualityControl" do
|
|
|
1825
1833
|
attribute :number, ImprovementNumber
|
|
1826
1834
|
attribute :url, ImprovementUrl
|
|
1827
1835
|
attribute :branch, ImprovementBranch
|
|
1828
|
-
attribute :commit, CommitRef
|
|
1836
|
+
attribute :commit, CommitRef, optional: true
|
|
1829
1837
|
attribute :title, ImprovementTitle
|
|
1830
1838
|
# See `Patch.opened_at`.
|
|
1831
1839
|
attribute :opened_at, Instant
|
|
@@ -1967,6 +1975,822 @@ Hecks.bluebook "QualityControl" do
|
|
|
1967
1975
|
end
|
|
1968
1976
|
end
|
|
1969
1977
|
|
|
1978
|
+
# The quick gate run on local main, in a temporary worktree of it. One record per commit checked, so a
|
|
1979
|
+
# tick that finds the same commit again does not log the same red checks twice.
|
|
1980
|
+
aggregate "MainCheck" do
|
|
1981
|
+
description "One run of the quick gate on local main at one commit, and whether every one of its checks came back green."
|
|
1982
|
+
|
|
1983
|
+
identified_by :reference
|
|
1984
|
+
|
|
1985
|
+
attribute :reference, MainCommit
|
|
1986
|
+
attribute :verdict, one_of("green", "red")
|
|
1987
|
+
attribute :red_checks, RedCount
|
|
1988
|
+
|
|
1989
|
+
value_object "MainCommit" do
|
|
1990
|
+
attribute :value, String, matches: :git_sha
|
|
1991
|
+
end
|
|
1992
|
+
|
|
1993
|
+
value_object "RedCount" do
|
|
1994
|
+
attribute :value, Integer, default: 0
|
|
1995
|
+
invariant("a count of red checks is not negative") { !value.negative? }
|
|
1996
|
+
end
|
|
1997
|
+
|
|
1998
|
+
# Written as soon as the gate has answered, before any red check is logged or fixed, so the record
|
|
1999
|
+
# says what the gate said even when what follows fails.
|
|
2000
|
+
command "Record" do
|
|
2001
|
+
role "QA engineer"
|
|
2002
|
+
goal "Write down what the quick gate said about one commit of main"
|
|
2003
|
+
|
|
2004
|
+
attribute :reference, MainCommit
|
|
2005
|
+
attribute :verdict, one_of("green", "red")
|
|
2006
|
+
attribute :red_checks, RedCount
|
|
2007
|
+
|
|
2008
|
+
given("a red verdict names a red check, and a green one names none") do
|
|
2009
|
+
(verdict.value == "red" && red_checks.value.positive?) || (verdict.value == "green" && red_checks.value == 0)
|
|
2010
|
+
end
|
|
2011
|
+
|
|
2012
|
+
emits "MainCheckRecorded"
|
|
2013
|
+
end
|
|
2014
|
+
|
|
2015
|
+
# `hecks quality_control main_check.check_main` is the tick's step. It answers from the record when the
|
|
2016
|
+
# commit has one; otherwise it runs the gate, logs each red check as a bug and fixes the self-contained
|
|
2017
|
+
# ones. It is a query because it reads the commit and runs the gate; every write it makes is a
|
|
2018
|
+
# command of the Bug and Sweep aggregates.
|
|
2019
|
+
query "CheckMain" do
|
|
2020
|
+
description "Runs the quick gate on local main in a temporary worktree of it and records the verdict, logging each red check as a bug."
|
|
2021
|
+
order_by :reference
|
|
2022
|
+
end
|
|
2023
|
+
|
|
2024
|
+
query "All" do
|
|
2025
|
+
description "Every commit of main the quick gate has been run on, with its verdict."
|
|
2026
|
+
order_by :reference
|
|
2027
|
+
end
|
|
2028
|
+
end
|
|
2029
|
+
|
|
2030
|
+
# The event pump: each attached domain's policies read the events past their cursors and react to
|
|
2031
|
+
# them. The pump's own writes are the cursors below; it appends to no domain's event log.
|
|
2032
|
+
aggregate "EventCursor" do
|
|
2033
|
+
description "How far one consumer has read one domain's event log, as the count of entries it has reacted to. One row per (log, consumer)."
|
|
2034
|
+
|
|
2035
|
+
identified_by :key
|
|
2036
|
+
|
|
2037
|
+
attribute :key, CursorKey
|
|
2038
|
+
attribute :log, CursorDomain
|
|
2039
|
+
attribute :consumer, CursorDomain
|
|
2040
|
+
attribute :position, CursorPosition
|
|
2041
|
+
attribute :read_at, CursorReadAt, optional: true
|
|
2042
|
+
|
|
2043
|
+
value_object "CursorKey" do
|
|
2044
|
+
attribute :value, String, matches: :present
|
|
2045
|
+
invariant("a cursor is keyed by its log and consumer") { !value.to_s.empty? }
|
|
2046
|
+
end
|
|
2047
|
+
|
|
2048
|
+
value_object "CursorReadAt" do
|
|
2049
|
+
attribute :value, String, matches: :present
|
|
2050
|
+
end
|
|
2051
|
+
|
|
2052
|
+
value_object "CursorDomain" do
|
|
2053
|
+
attribute :value, String, matches: :present
|
|
2054
|
+
invariant("a cursor names its domain") { !value.to_s.empty? }
|
|
2055
|
+
end
|
|
2056
|
+
|
|
2057
|
+
value_object "CursorPosition" do
|
|
2058
|
+
attribute :value, Integer, default: 0
|
|
2059
|
+
invariant("a position is not negative") { !value.negative? }
|
|
2060
|
+
end
|
|
2061
|
+
|
|
2062
|
+
command "Start" do
|
|
2063
|
+
role "QA engineer"
|
|
2064
|
+
goal "Open a consumer's cursor on one domain's event log, at the start of the log"
|
|
2065
|
+
|
|
2066
|
+
attribute :key, CursorKey
|
|
2067
|
+
attribute :log, CursorDomain
|
|
2068
|
+
attribute :consumer, CursorDomain
|
|
2069
|
+
|
|
2070
|
+
emits "CursorStarted"
|
|
2071
|
+
end
|
|
2072
|
+
|
|
2073
|
+
# The pump passes only the position it has just reacted to, so a cursor moves forward in practice.
|
|
2074
|
+
command "Advance" do
|
|
2075
|
+
role "QA engineer"
|
|
2076
|
+
goal "Move one consumer's cursor past the entries it has reacted to"
|
|
2077
|
+
|
|
2078
|
+
attribute :position, CursorPosition, sets: true
|
|
2079
|
+
|
|
2080
|
+
emits "CursorAdvanced"
|
|
2081
|
+
end
|
|
2082
|
+
|
|
2083
|
+
query "All" do
|
|
2084
|
+
description "Every cursor the event pump holds, with the position each consumer has read to."
|
|
2085
|
+
order_by :key
|
|
2086
|
+
end
|
|
2087
|
+
end
|
|
2088
|
+
|
|
2089
|
+
# One policy's reaction to one event, recorded once the policy's command has answered: delivered or
|
|
2090
|
+
# refused. The pump checks a row before it runs the policy, so a reaction already on the ledger is not
|
|
2091
|
+
# run again, whatever the cursor says. Keyed by (consumer, event, policy), so the event's other policies
|
|
2092
|
+
# for the same consumer still run.
|
|
2093
|
+
aggregate "EventReaction" do
|
|
2094
|
+
description "A policy's reaction to one event, once its command has answered. One row per (consumer, event, policy)."
|
|
2095
|
+
|
|
2096
|
+
identified_by :key
|
|
2097
|
+
|
|
2098
|
+
attribute :key, ReactionKey
|
|
2099
|
+
attribute :consumer, ReactionConsumer
|
|
2100
|
+
attribute :event_id, ReactionEvent
|
|
2101
|
+
attribute :policy, ReactionPolicy
|
|
2102
|
+
|
|
2103
|
+
value_object "ReactionKey" do
|
|
2104
|
+
attribute :value, String, matches: :present
|
|
2105
|
+
invariant("a reaction is keyed by its consumer, event and policy") { !value.to_s.empty? }
|
|
2106
|
+
end
|
|
2107
|
+
|
|
2108
|
+
value_object "ReactionConsumer" do
|
|
2109
|
+
attribute :value, String, matches: :present
|
|
2110
|
+
invariant("a reaction names its consumer") { !value.to_s.empty? }
|
|
2111
|
+
end
|
|
2112
|
+
|
|
2113
|
+
value_object "ReactionEvent" do
|
|
2114
|
+
attribute :value, String, matches: :present
|
|
2115
|
+
invariant("a reaction names the event it answered") { !value.to_s.empty? }
|
|
2116
|
+
end
|
|
2117
|
+
|
|
2118
|
+
value_object "ReactionPolicy" do
|
|
2119
|
+
attribute :value, String, matches: :present
|
|
2120
|
+
invariant("a reaction names its policy") { !value.to_s.empty? }
|
|
2121
|
+
end
|
|
2122
|
+
|
|
2123
|
+
command "Record" do
|
|
2124
|
+
role "QA engineer"
|
|
2125
|
+
goal "Record that one consumer's policy has answered one event, so the pump does not run it again"
|
|
2126
|
+
|
|
2127
|
+
attribute :key, ReactionKey
|
|
2128
|
+
attribute :consumer, ReactionConsumer
|
|
2129
|
+
attribute :event_id, ReactionEvent
|
|
2130
|
+
attribute :policy, ReactionPolicy
|
|
2131
|
+
|
|
2132
|
+
emits "EventReacted"
|
|
2133
|
+
end
|
|
2134
|
+
|
|
2135
|
+
query "All" do
|
|
2136
|
+
description "Every reaction the event pump has recorded, by its key."
|
|
2137
|
+
order_by :key
|
|
2138
|
+
end
|
|
2139
|
+
end
|
|
2140
|
+
|
|
2141
|
+
# One run of the event pump, requested as a command and answered by the `PumpTools` port, which runs
|
|
2142
|
+
# `hecks quality_control qa_event_pump`. The QA tick runs the same pump as its last step.
|
|
2143
|
+
aggregate "EventPump" do
|
|
2144
|
+
description "One run of the event pump: every attached domain's policies reacting to the events past their cursors, and what each reaction answered."
|
|
2145
|
+
|
|
2146
|
+
identified_by :run
|
|
2147
|
+
|
|
2148
|
+
attribute :run, PumpRun
|
|
2149
|
+
|
|
2150
|
+
value_object "PumpRun" do
|
|
2151
|
+
attribute :value, String, matches: :present
|
|
2152
|
+
invariant("a pump run is named") { !value.to_s.empty? }
|
|
2153
|
+
end
|
|
2154
|
+
|
|
2155
|
+
command "Pump" do
|
|
2156
|
+
role "QA engineer"
|
|
2157
|
+
goal "Run the event pump once: each attached domain's policies react to the events past their cursors, and every refusal is named"
|
|
2158
|
+
|
|
2159
|
+
attribute :run, PumpRun
|
|
2160
|
+
|
|
2161
|
+
emits "PumpRequested"
|
|
2162
|
+
end
|
|
2163
|
+
end
|
|
2164
|
+
|
|
2165
|
+
policy "PumpOnRequest" do
|
|
2166
|
+
on "EventPump.PumpRequested"
|
|
2167
|
+
ask :execute, with: { run: :run }
|
|
2168
|
+
end
|
|
2169
|
+
|
|
2170
|
+
# The maintenance of local main as events and policies. A coder's `Submission.WorkSubmitted` starts
|
|
2171
|
+
# a run. Each step's body is an `ask` of a port the `MainMaintenance` adapter answers: the quick gate,
|
|
2172
|
+
# the reconcile, the push through the train. The answer is an event, and a policy turns each event into
|
|
2173
|
+
# the next step. A refusal is a named event, and nothing follows it.
|
|
2174
|
+
aggregate "Maintenance" do
|
|
2175
|
+
description "One run of local main's maintenance: the quick gate on a submitted commit, the reconcile, and the push through the train."
|
|
2176
|
+
|
|
2177
|
+
identified_by :run
|
|
2178
|
+
|
|
2179
|
+
attribute :run, MaintenanceRun
|
|
2180
|
+
attribute :sha, MaintenanceSha
|
|
2181
|
+
# The gate's colour and the reconcile's verdict. A run opened only to mint an era (`MintEra`) never
|
|
2182
|
+
# runs the gate or the reconcile, so its row holds neither.
|
|
2183
|
+
attribute :color, one_of("green", "red"), optional: true
|
|
2184
|
+
attribute :verdict, one_of("reported", "written", "refused"), optional: true
|
|
2185
|
+
|
|
2186
|
+
value_object "MaintenanceRun" do
|
|
2187
|
+
attribute :value, String, matches: :present
|
|
2188
|
+
invariant("a run names its branch") { !value.to_s.empty? }
|
|
2189
|
+
end
|
|
2190
|
+
|
|
2191
|
+
value_object "MaintenanceSha" do
|
|
2192
|
+
attribute :value, String, matches: :git_sha
|
|
2193
|
+
end
|
|
2194
|
+
|
|
2195
|
+
# The era a mint created, as the Minted event carries it.
|
|
2196
|
+
value_object "MintedEra" do
|
|
2197
|
+
attribute :value, Integer
|
|
2198
|
+
end
|
|
2199
|
+
|
|
2200
|
+
# Opens a run for a submitted commit of main; the gate is the first step it asks for.
|
|
2201
|
+
command "Start" do
|
|
2202
|
+
role "QA engineer"
|
|
2203
|
+
goal "Open the maintenance of main for one submitted commit"
|
|
2204
|
+
|
|
2205
|
+
attribute :run, MaintenanceRun
|
|
2206
|
+
attribute :sha, MaintenanceSha
|
|
2207
|
+
|
|
2208
|
+
emits "RunStarted"
|
|
2209
|
+
end
|
|
2210
|
+
|
|
2211
|
+
# Refuses a red gate: the policy that reads `GateVerdict` red calls it, and nothing reconciles or pushes.
|
|
2212
|
+
command "RefuseGate" do
|
|
2213
|
+
role "QA engineer"
|
|
2214
|
+
goal "Stop a run whose quick gate on main is red"
|
|
2215
|
+
|
|
2216
|
+
attribute :run, MaintenanceRun
|
|
2217
|
+
attribute :color, one_of("green", "red")
|
|
2218
|
+
|
|
2219
|
+
given("only a red verdict is refused") { color.value == "red" }
|
|
2220
|
+
|
|
2221
|
+
emits "GateRefused"
|
|
2222
|
+
end
|
|
2223
|
+
|
|
2224
|
+
# Asks for the reconcile once the gate is green.
|
|
2225
|
+
command "RequestReconcile" do
|
|
2226
|
+
role "QA engineer"
|
|
2227
|
+
goal "Ask for the reconcile of a commit whose quick gate is green"
|
|
2228
|
+
|
|
2229
|
+
attribute :run, MaintenanceRun
|
|
2230
|
+
attribute :sha, MaintenanceSha
|
|
2231
|
+
attribute :color, one_of("green", "red")
|
|
2232
|
+
|
|
2233
|
+
given("only a green gate is reconciled") { color.value == "green" }
|
|
2234
|
+
|
|
2235
|
+
emits "ReconcileRequested"
|
|
2236
|
+
end
|
|
2237
|
+
|
|
2238
|
+
# Asks for the push once the reconcile has not refused and the gate is green.
|
|
2239
|
+
command "RequestPush" do
|
|
2240
|
+
role "QA engineer"
|
|
2241
|
+
goal "Ask for the push of a commit whose gate is green and whose reconcile did not refuse"
|
|
2242
|
+
|
|
2243
|
+
attribute :run, MaintenanceRun
|
|
2244
|
+
attribute :sha, MaintenanceSha
|
|
2245
|
+
attribute :color, one_of("green", "red")
|
|
2246
|
+
attribute :verdict, one_of("reported", "written", "refused")
|
|
2247
|
+
|
|
2248
|
+
given("the reconcile did not refuse and the gate is green") do
|
|
2249
|
+
verdict.value != "refused" && color.value == "green"
|
|
2250
|
+
end
|
|
2251
|
+
|
|
2252
|
+
emits "PushRequested"
|
|
2253
|
+
end
|
|
2254
|
+
|
|
2255
|
+
value_object "MintVerdict" do
|
|
2256
|
+
attribute :value, String, one_of: ["would_mint", "would_refuse", "needs_edge", "cannot_boot", "empty_copy"]
|
|
2257
|
+
end
|
|
2258
|
+
|
|
2259
|
+
# Records what the rehearsal of a domain's next era concluded, at the ledger watermark it read. The mint
|
|
2260
|
+
# policy reads the verdict off `MintRequested`, so a mint is only ever asked for a rehearsal that said
|
|
2261
|
+
# would_mint.
|
|
2262
|
+
command "RecordRehearsalVerdict" do
|
|
2263
|
+
role "QA engineer"
|
|
2264
|
+
goal "Record what the rehearsal of a domain's next era concluded, and the watermark it read"
|
|
2265
|
+
|
|
2266
|
+
attribute :run, MaintenanceRun
|
|
2267
|
+
attribute :domain, String
|
|
2268
|
+
attribute :watermark, Integer
|
|
2269
|
+
attribute :rehearsal_verdict, MintVerdict
|
|
2270
|
+
|
|
2271
|
+
emits "RehearsalVerdict"
|
|
2272
|
+
end
|
|
2273
|
+
|
|
2274
|
+
# The confirmation of a mint: the owner's `--confirm` flag, which the launcher reads as a Boolean. A mint
|
|
2275
|
+
# the auto-mint rule covers runs without it; every other mint needs it.
|
|
2276
|
+
value_object "Confirmation" do
|
|
2277
|
+
attribute :value, Boolean
|
|
2278
|
+
end
|
|
2279
|
+
|
|
2280
|
+
# Why a mint was refused, as the refusal the mint entry point names. A held mint says "needs owner
|
|
2281
|
+
# approval", which the approval policy reads.
|
|
2282
|
+
value_object "MintRefusal" do
|
|
2283
|
+
attribute :value, String
|
|
2284
|
+
end
|
|
2285
|
+
|
|
2286
|
+
# The single entry point for a mint of a domain's next era. It is the only command that asks for a mint:
|
|
2287
|
+
# a boot never mints, and the mint names the commit its landing puts on main, so the ledger and main move
|
|
2288
|
+
# together. The rehearsal ref and the expected watermark are checked against the live ledger by the era check.
|
|
2289
|
+
# `refusal_total` is the rehearsal's refusal count and `ledger_dir` the bluebook directory of the ledger
|
|
2290
|
+
# the era belongs to (the QualityControl ledger when omitted). A mint with no `confirm` runs only when
|
|
2291
|
+
# the auto-mint rule (`AutoMintAdditive`) holds; the mint entry point checks it.
|
|
2292
|
+
command "MintEra" do
|
|
2293
|
+
role "QA engineer"
|
|
2294
|
+
goal "Mint a domain's next era, against the rehearsal of that same era and the watermark it read"
|
|
2295
|
+
attribute :run, MaintenanceRun
|
|
2296
|
+
attribute :domain, String
|
|
2297
|
+
attribute :era, Integer
|
|
2298
|
+
attribute :sha, MaintenanceSha
|
|
2299
|
+
attribute :branch, String
|
|
2300
|
+
attribute :rehearsal_ref, String
|
|
2301
|
+
attribute :watermark, Integer
|
|
2302
|
+
attribute :rehearsal_verdict, MintVerdict
|
|
2303
|
+
attribute :refusal_total, Integer, optional: true
|
|
2304
|
+
attribute :ledger_dir, String, optional: true
|
|
2305
|
+
attribute :confirm, Confirmation, optional: true
|
|
2306
|
+
|
|
2307
|
+
emits "MintRequested"
|
|
2308
|
+
end
|
|
2309
|
+
|
|
2310
|
+
# Refuses a mint whose rehearsal did not say would_mint, and nothing mints or lands after it. It also
|
|
2311
|
+
# carries the refusal the mint entry point named when it held a mint for the owner.
|
|
2312
|
+
command "RefuseMint" do
|
|
2313
|
+
role "QA engineer"
|
|
2314
|
+
goal "Stop a mint whose rehearsal did not say would_mint"
|
|
2315
|
+
|
|
2316
|
+
attribute :run, MaintenanceRun
|
|
2317
|
+
attribute :domain, String
|
|
2318
|
+
attribute :era, Integer
|
|
2319
|
+
attribute :rehearsal_verdict, MintVerdict
|
|
2320
|
+
attribute :refusal, MintRefusal, optional: true
|
|
2321
|
+
|
|
2322
|
+
given("only a rehearsal that did not say would_mint is refused") { rehearsal_verdict.value != "would_mint" }
|
|
2323
|
+
|
|
2324
|
+
emits "MintRefused"
|
|
2325
|
+
end
|
|
2326
|
+
end
|
|
2327
|
+
|
|
2328
|
+
# One release PR: the bump of the version on main, opened as a PR and approved on GitHub by the owner. The
|
|
2329
|
+
# approval is written as the release trailer on the merge, which is the line `Hecks::Release::Approval`
|
|
2330
|
+
# reads. A PR is approved only when every auto-approval condition holds (see ReleaseCondition); a failed
|
|
2331
|
+
# condition is a named refusal and nothing is approved.
|
|
2332
|
+
aggregate "ReleasePR" do
|
|
2333
|
+
description "One release PR: the version bump opened on GitHub, approved by the owner only when every auto-approval condition holds."
|
|
2334
|
+
|
|
2335
|
+
identified_by :release
|
|
2336
|
+
|
|
2337
|
+
attribute :release, ReleaseVersion
|
|
2338
|
+
attribute :branch, ReleaseBranch
|
|
2339
|
+
attribute :sha, MaintenanceSha
|
|
2340
|
+
attribute :verdict, one_of("open", "approved", "refused")
|
|
2341
|
+
|
|
2342
|
+
value_object "ReleaseBranch" do
|
|
2343
|
+
attribute :value, String, matches: :present
|
|
2344
|
+
end
|
|
2345
|
+
|
|
2346
|
+
value_object "ReleaseVersion" do
|
|
2347
|
+
attribute :value, String
|
|
2348
|
+
invariant("a release names a semantic version") { value.to_s.match?(/\A[0-9]+\.[0-9]+\.[0-9]+\z/) }
|
|
2349
|
+
end
|
|
2350
|
+
|
|
2351
|
+
# The four conditions an approval needs, each named so a refusal says which one failed. `met` is the only
|
|
2352
|
+
# value an approval accepts; the Ruby judge (`Hecks::Release::Conditions.judge`) answers the first failure
|
|
2353
|
+
# in this order: the commit is on stable's head, the required checks passed on it, the CHANGELOG has a
|
|
2354
|
+
# dated `## [<version>]` heading, and every version file names the same version.
|
|
2355
|
+
value_object "ReleaseCondition" do
|
|
2356
|
+
attribute :value, String, one_of: ["met", "not_on_stable_head", "checks_not_green",
|
|
2357
|
+
"changelog_undated", "version_mismatch"]
|
|
2358
|
+
end
|
|
2359
|
+
|
|
2360
|
+
# The owner who approves each release PR. The trailer line names this person; no other name is approved.
|
|
2361
|
+
value_object "ReleaseApprover" do
|
|
2362
|
+
attribute :value, String, one_of: ["Chris Young"]
|
|
2363
|
+
end
|
|
2364
|
+
|
|
2365
|
+
# The commit-message trailer an approval writes. It is the `release_trailer` of the stable `Lane` row
|
|
2366
|
+
# (Vocabulary), which `Hecks::Release::Approval` reads, so the check accepts what the policy writes.
|
|
2367
|
+
value_object "ReleaseTrailer" do
|
|
2368
|
+
attribute :value, String, one_of: ["Release-Approved-By"]
|
|
2369
|
+
end
|
|
2370
|
+
|
|
2371
|
+
# Opens the release PR for a version bump on a branch. The open is answered by the `ReleaseGh` port.
|
|
2372
|
+
command "Open" do
|
|
2373
|
+
role "Release owner"
|
|
2374
|
+
goal "Open the release PR for a version bump on main, so the owner can approve it on GitHub"
|
|
2375
|
+
|
|
2376
|
+
attribute :release, ReleaseVersion
|
|
2377
|
+
attribute :branch, ReleaseBranch
|
|
2378
|
+
attribute :sha, MaintenanceSha
|
|
2379
|
+
|
|
2380
|
+
emits "ReleaseOpenRequested"
|
|
2381
|
+
end
|
|
2382
|
+
|
|
2383
|
+
# Records the result of the four auto-approval conditions for one release PR. The caller names the approver
|
|
2384
|
+
# and the trailer, which the approval policy passes on to the approval.
|
|
2385
|
+
command "Check" do
|
|
2386
|
+
role "Release owner"
|
|
2387
|
+
goal "Record which auto-approval condition held for a release PR, naming the first one that failed"
|
|
2388
|
+
|
|
2389
|
+
attribute :release, ReleaseVersion
|
|
2390
|
+
attribute :sha, MaintenanceSha
|
|
2391
|
+
attribute :condition, ReleaseCondition
|
|
2392
|
+
attribute :approver, ReleaseApprover
|
|
2393
|
+
attribute :trailer, ReleaseTrailer
|
|
2394
|
+
|
|
2395
|
+
emits "ReleaseChecked"
|
|
2396
|
+
end
|
|
2397
|
+
|
|
2398
|
+
# Approves a release PR whose conditions all held. Only a condition of `met` is approved; the trailer
|
|
2399
|
+
# is then written on the merge by the `ReleaseGh` port.
|
|
2400
|
+
command "Approve" do
|
|
2401
|
+
role "Release owner"
|
|
2402
|
+
goal "Approve a release PR once every auto-approval condition holds, writing the release trailer for the owner"
|
|
2403
|
+
|
|
2404
|
+
attribute :release, ReleaseVersion
|
|
2405
|
+
attribute :sha, MaintenanceSha
|
|
2406
|
+
attribute :condition, ReleaseCondition
|
|
2407
|
+
attribute :approver, ReleaseApprover
|
|
2408
|
+
attribute :trailer, ReleaseTrailer
|
|
2409
|
+
|
|
2410
|
+
given("only a release whose conditions all held is approved") { condition.value == "met" }
|
|
2411
|
+
|
|
2412
|
+
emits "ReleaseApproved"
|
|
2413
|
+
end
|
|
2414
|
+
|
|
2415
|
+
# Refuses a release PR one of whose conditions failed, and names that condition.
|
|
2416
|
+
command "Refuse" do
|
|
2417
|
+
role "Release owner"
|
|
2418
|
+
goal "Refuse a release PR, naming the auto-approval condition that failed"
|
|
2419
|
+
|
|
2420
|
+
attribute :release, ReleaseVersion
|
|
2421
|
+
attribute :condition, ReleaseCondition
|
|
2422
|
+
|
|
2423
|
+
given("only a release with a failed condition is refused") { condition.value != "met" }
|
|
2424
|
+
|
|
2425
|
+
emits "ReleaseRefused"
|
|
2426
|
+
end
|
|
2427
|
+
end
|
|
2428
|
+
|
|
2429
|
+
# What remote CI said about one commit of a repository's main, once every job it ran for that
|
|
2430
|
+
# commit
|
|
2431
|
+
# settled. The Runner adapter answers `Check`; a green verdict is announced as `CiGreen`, and a
|
|
2432
|
+
# red one
|
|
2433
|
+
# as `CiRed` with the failing jobs. Lives here, beside the roll it feeds: a policy reads only
|
|
2434
|
+
# events
|
|
2435
|
+
# its own bluebook emits.
|
|
2436
|
+
aggregate "Head" do
|
|
2437
|
+
description "One commit of a repository's main, and whether remote CI passed every job it ran for that commit."
|
|
2438
|
+
|
|
2439
|
+
identified_by :commit
|
|
2440
|
+
|
|
2441
|
+
attribute :commit, HeadCommit
|
|
2442
|
+
attribute :branch, HeadBranch
|
|
2443
|
+
attribute :repo, HeadRepo
|
|
2444
|
+
attribute :color, one_of("green", "red")
|
|
2445
|
+
attribute :failing_jobs, FailingJobs
|
|
2446
|
+
|
|
2447
|
+
value_object "HeadCommit" do
|
|
2448
|
+
attribute :value, String, pattern: '^[0-9a-f]{40}$'
|
|
2449
|
+
end
|
|
2450
|
+
|
|
2451
|
+
value_object "HeadBranch" do
|
|
2452
|
+
attribute :value, String, matches: :present
|
|
2453
|
+
invariant("a head names its branch") { !value.to_s.empty? }
|
|
2454
|
+
end
|
|
2455
|
+
|
|
2456
|
+
value_object "HeadRepo" do
|
|
2457
|
+
# GitHub's `owner/name`.
|
|
2458
|
+
attribute :value, String, pattern: '^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$'
|
|
2459
|
+
end
|
|
2460
|
+
|
|
2461
|
+
# The failing jobs of a red run, comma-separated; empty for a green one.
|
|
2462
|
+
value_object "FailingJobs" do
|
|
2463
|
+
attribute :value, String, default: ""
|
|
2464
|
+
end
|
|
2465
|
+
|
|
2466
|
+
# Asks remote CI about one commit. Only main is judged: a commit on a branch says nothing about
|
|
2467
|
+
# main.
|
|
2468
|
+
command "Request" do
|
|
2469
|
+
role "CI engineer"
|
|
2470
|
+
goal "Ask remote CI what it said about one commit of a repository's main"
|
|
2471
|
+
|
|
2472
|
+
attribute :commit, HeadCommit
|
|
2473
|
+
attribute :branch, HeadBranch
|
|
2474
|
+
attribute :repo, HeadRepo
|
|
2475
|
+
|
|
2476
|
+
given("only main is judged") { branch.value == "main" }
|
|
2477
|
+
|
|
2478
|
+
emits "HeadRequested"
|
|
2479
|
+
end
|
|
2480
|
+
|
|
2481
|
+
# Records a green verdict. Refused for any other colour: a red head is never announced as
|
|
2482
|
+
# green.
|
|
2483
|
+
command "Green" do
|
|
2484
|
+
role "System"
|
|
2485
|
+
goal "Announce that remote CI passed every job it ran for one commit of main"
|
|
2486
|
+
|
|
2487
|
+
attribute :commit, HeadCommit
|
|
2488
|
+
attribute :branch, HeadBranch
|
|
2489
|
+
attribute :repo, HeadRepo
|
|
2490
|
+
attribute :color, one_of("green", "red")
|
|
2491
|
+
|
|
2492
|
+
given("only a green verdict is announced") { color.value == "green" }
|
|
2493
|
+
|
|
2494
|
+
emits "CiGreen"
|
|
2495
|
+
end
|
|
2496
|
+
|
|
2497
|
+
# Records a red verdict, naming the jobs that failed. Refused for any other colour.
|
|
2498
|
+
command "Red" do
|
|
2499
|
+
role "System"
|
|
2500
|
+
goal "Announce that remote CI refused one commit of main, and which jobs failed"
|
|
2501
|
+
|
|
2502
|
+
attribute :commit, HeadCommit
|
|
2503
|
+
attribute :repo, HeadRepo
|
|
2504
|
+
attribute :color, one_of("green", "red")
|
|
2505
|
+
attribute :failing_jobs, FailingJobs
|
|
2506
|
+
|
|
2507
|
+
given("only a red verdict names the jobs that failed") do
|
|
2508
|
+
color.value == "red" && !failing_jobs.value.to_s.empty?
|
|
2509
|
+
end
|
|
2510
|
+
|
|
2511
|
+
emits "CiRed"
|
|
2512
|
+
end
|
|
2513
|
+
end
|
|
2514
|
+
|
|
2515
|
+
# One spec file that is red on main, keyed `red-<spec path slug>`. A red run reports each failing
|
|
2516
|
+
# spec file; the first report opens the row and a later one only updates what it knew, so a spec
|
|
2517
|
+
# red for days is one row, and `since` is the day it first went red. A settled run that no longer
|
|
2518
|
+
# fails the file clears it. Tickets mirrors it as a Work row for QA (`PlanWorkWhenSpecWentRed`, `FinishWorkWhenSpecWentGreen`).
|
|
2519
|
+
aggregate "RedSpec" do
|
|
2520
|
+
description "One spec file that is red on main: how many examples fail, the first failure, the run that saw it last, and the day it first went red."
|
|
2521
|
+
|
|
2522
|
+
identified_by :spec
|
|
2523
|
+
|
|
2524
|
+
attribute :spec, SpecKey
|
|
2525
|
+
attribute :path, SpecPath
|
|
2526
|
+
attribute :failures, FailureCount
|
|
2527
|
+
attribute :first_failure, FailureLine, optional: true
|
|
2528
|
+
attribute :examples, FailureLine, optional: true
|
|
2529
|
+
attribute :last_run, RunId
|
|
2530
|
+
attribute :commit, SpecCommit
|
|
2531
|
+
attribute :since, SeenOn
|
|
2532
|
+
attribute :title, WorkLine
|
|
2533
|
+
attribute :detail, WorkLine
|
|
2534
|
+
attribute :cleared_by, RunId, optional: true
|
|
2535
|
+
|
|
2536
|
+
value_object "SpecKey" do
|
|
2537
|
+
attribute :value, String, pattern: '^red-[a-z0-9_-]+$'
|
|
2538
|
+
end
|
|
2539
|
+
|
|
2540
|
+
value_object "SpecPath" do
|
|
2541
|
+
attribute :value, String, matches: :present
|
|
2542
|
+
end
|
|
2543
|
+
|
|
2544
|
+
value_object "FailureCount" do
|
|
2545
|
+
attribute :value, Integer
|
|
2546
|
+
invariant("a red spec has failing examples") { value.positive? }
|
|
2547
|
+
end
|
|
2548
|
+
|
|
2549
|
+
# Text as the failing run printed it, shortened by the reader.
|
|
2550
|
+
value_object "FailureLine" do
|
|
2551
|
+
attribute :value, String, default: ""
|
|
2552
|
+
end
|
|
2553
|
+
|
|
2554
|
+
# A line of the Work row the spec mirrors into.
|
|
2555
|
+
value_object "WorkLine" do
|
|
2556
|
+
attribute :value, String, matches: :present
|
|
2557
|
+
end
|
|
2558
|
+
|
|
2559
|
+
value_object "RunId" do
|
|
2560
|
+
attribute :value, String, matches: :present
|
|
2561
|
+
end
|
|
2562
|
+
|
|
2563
|
+
value_object "SpecCommit" do
|
|
2564
|
+
attribute :value, String, matches: :present
|
|
2565
|
+
end
|
|
2566
|
+
|
|
2567
|
+
# An ISO 8601 date, read from the clock by the run reader, never by the bluebook.
|
|
2568
|
+
value_object "SeenOn" do
|
|
2569
|
+
attribute :value, String, matches: :present
|
|
2570
|
+
end
|
|
2571
|
+
|
|
2572
|
+
# A cleared file that fails again goes back to red: the row reopens, it is never filed twice.
|
|
2573
|
+
lifecycle :status, default: "red" do
|
|
2574
|
+
mark :failure, "red"
|
|
2575
|
+
transition "Clear" => "green", from: "red"
|
|
2576
|
+
transition "Reopen" => "red", from: "green"
|
|
2577
|
+
end
|
|
2578
|
+
|
|
2579
|
+
# Opens the row for a spec file. A spec already red is not reported twice: see `Update`.
|
|
2580
|
+
command "Open" do
|
|
2581
|
+
role "System"
|
|
2582
|
+
goal "Record that a spec file is red on main"
|
|
2583
|
+
|
|
2584
|
+
attribute :spec, SpecKey, sets: true
|
|
2585
|
+
attribute :path, SpecPath, sets: true
|
|
2586
|
+
attribute :failures, FailureCount, sets: true
|
|
2587
|
+
attribute :first_failure, FailureLine, optional: true, sets: true
|
|
2588
|
+
attribute :examples, FailureLine, optional: true, sets: true
|
|
2589
|
+
attribute :last_run, RunId, sets: true
|
|
2590
|
+
attribute :commit, SpecCommit, sets: true
|
|
2591
|
+
attribute :since, SeenOn, sets: true
|
|
2592
|
+
attribute :title, WorkLine, sets: true
|
|
2593
|
+
attribute :detail, WorkLine, sets: true
|
|
2594
|
+
|
|
2595
|
+
emits "SpecWentRed"
|
|
2596
|
+
end
|
|
2597
|
+
|
|
2598
|
+
# A spec still red in a later run: what the latest run saw replaces what the row knew; `since` stays.
|
|
2599
|
+
command "Update" do
|
|
2600
|
+
role "System"
|
|
2601
|
+
goal "Record what a later red run saw of a spec file that was already red"
|
|
2602
|
+
|
|
2603
|
+
reference_to RedSpec
|
|
2604
|
+
attribute :failures, FailureCount, sets: true
|
|
2605
|
+
attribute :first_failure, FailureLine, optional: true, sets: true
|
|
2606
|
+
attribute :examples, FailureLine, optional: true, sets: true
|
|
2607
|
+
attribute :last_run, RunId, sets: true
|
|
2608
|
+
attribute :commit, SpecCommit, sets: true
|
|
2609
|
+
attribute :detail, WorkLine, sets: true
|
|
2610
|
+
|
|
2611
|
+
emits "SpecStillRed"
|
|
2612
|
+
end
|
|
2613
|
+
|
|
2614
|
+
# A spec that was cleared and failed again: what the new red run saw replaces what the row knew,
|
|
2615
|
+
# and `since` is the day it went red this time.
|
|
2616
|
+
command "Reopen" do
|
|
2617
|
+
role "System"
|
|
2618
|
+
goal "Record that a spec file cleared earlier is red on main again"
|
|
2619
|
+
|
|
2620
|
+
reference_to RedSpec
|
|
2621
|
+
attribute :failures, FailureCount, sets: true
|
|
2622
|
+
attribute :first_failure, FailureLine, optional: true, sets: true
|
|
2623
|
+
attribute :examples, FailureLine, optional: true, sets: true
|
|
2624
|
+
attribute :last_run, RunId, sets: true
|
|
2625
|
+
attribute :commit, SpecCommit, sets: true
|
|
2626
|
+
attribute :since, SeenOn, sets: true
|
|
2627
|
+
attribute :title, WorkLine, sets: true
|
|
2628
|
+
attribute :detail, WorkLine, sets: true
|
|
2629
|
+
|
|
2630
|
+
emits "SpecWentRedAgain"
|
|
2631
|
+
end
|
|
2632
|
+
|
|
2633
|
+
# `seen_in` is the run that last saw the file fail; a run that did see it fails to clear it.
|
|
2634
|
+
command "Clear" do
|
|
2635
|
+
role "System"
|
|
2636
|
+
goal "Record that a settled run of main no longer fails a spec file"
|
|
2637
|
+
|
|
2638
|
+
reference_to RedSpec
|
|
2639
|
+
attribute :run, RunId
|
|
2640
|
+
attribute :seen_in, RunId
|
|
2641
|
+
|
|
2642
|
+
given("a run that still saw the file fail does not clear it") { run.value != seen_in.value }
|
|
2643
|
+
|
|
2644
|
+
sets :cleared_by, to: :run
|
|
2645
|
+
|
|
2646
|
+
emits "SpecWentGreen"
|
|
2647
|
+
end
|
|
2648
|
+
|
|
2649
|
+
query "OnMain" do
|
|
2650
|
+
description "The red specs on main: every spec file still red, with the day it first went red and the run that last saw it fail."
|
|
2651
|
+
where(status: "red")
|
|
2652
|
+
order_by :since
|
|
2653
|
+
end
|
|
2654
|
+
end
|
|
2655
|
+
|
|
2656
|
+
# One CI run of main read for its failing spec files. The Reader port reports each failing file
|
|
2657
|
+
# to `RedSpec` and answers what the run settled to.
|
|
2658
|
+
aggregate "MainRun" do
|
|
2659
|
+
description "One CI run of main, read for the spec files it failed."
|
|
2660
|
+
|
|
2661
|
+
identified_by :run
|
|
2662
|
+
|
|
2663
|
+
attribute :run, MainRunId
|
|
2664
|
+
attribute :repo, HeadRepo
|
|
2665
|
+
attribute :commit, SpecCommit, optional: true
|
|
2666
|
+
attribute :settled, SettledFlag, optional: true
|
|
2667
|
+
|
|
2668
|
+
value_object "MainRunId" do
|
|
2669
|
+
attribute :value, String, matches: :present
|
|
2670
|
+
end
|
|
2671
|
+
|
|
2672
|
+
# "yes" once every job that runs specs finished, so a spec absent from the failures passed.
|
|
2673
|
+
value_object "SettledFlag" do
|
|
2674
|
+
attribute :value, String, default: ""
|
|
2675
|
+
end
|
|
2676
|
+
|
|
2677
|
+
command "Request" do
|
|
2678
|
+
role "CI engineer"
|
|
2679
|
+
goal "Ask for one CI run of main to be read for the spec files it failed"
|
|
2680
|
+
|
|
2681
|
+
attribute :run, MainRunId, sets: true
|
|
2682
|
+
attribute :repo, HeadRepo, sets: true
|
|
2683
|
+
|
|
2684
|
+
emits "MainRunReadRequested"
|
|
2685
|
+
end
|
|
2686
|
+
|
|
2687
|
+
command "Record" do
|
|
2688
|
+
role "System"
|
|
2689
|
+
goal "Keep how a read run settled"
|
|
2690
|
+
|
|
2691
|
+
reference_to MainRun
|
|
2692
|
+
attribute :commit, SpecCommit, sets: true
|
|
2693
|
+
attribute :settled, SettledFlag, sets: true
|
|
2694
|
+
|
|
2695
|
+
emits "MainRunRecorded"
|
|
2696
|
+
end
|
|
2697
|
+
end
|
|
2698
|
+
|
|
2699
|
+
# The image roll of one commit of embryonaut_platform's main. A commit whose remote CI is green
|
|
2700
|
+
# is
|
|
2701
|
+
# classified by the paths it changed: only the console container's inputs roll by themselves, and
|
|
2702
|
+
# anything else waits for a person. A commit rolls once; a second request finds the roll under
|
|
2703
|
+
# way.
|
|
2704
|
+
aggregate "ImageRoll" do
|
|
2705
|
+
description "One commit of embryonaut_platform's main: whether its container image was rolled, or waits for a person."
|
|
2706
|
+
|
|
2707
|
+
identified_by :commit
|
|
2708
|
+
|
|
2709
|
+
attribute :commit, CommitRef
|
|
2710
|
+
attribute :app, AppName
|
|
2711
|
+
attribute :paths, ChangedPaths
|
|
2712
|
+
attribute :outcome, one_of("done", "failed")
|
|
2713
|
+
|
|
2714
|
+
lifecycle :roll, default: "idle" do
|
|
2715
|
+
transition "Request" => "requested", from: "idle"
|
|
2716
|
+
transition "NeedsApproval" => "awaiting_approval", from: "idle"
|
|
2717
|
+
transition "Finish" => "finished", from: "requested"
|
|
2718
|
+
mark :terminal, "awaiting_approval", "finished"
|
|
2719
|
+
end
|
|
2720
|
+
|
|
2721
|
+
value_object "CommitRef" do
|
|
2722
|
+
attribute :value, String, pattern: '^[0-9a-f]{40}$'
|
|
2723
|
+
end
|
|
2724
|
+
|
|
2725
|
+
value_object "AppName" do
|
|
2726
|
+
attribute :value, String, matches: :present
|
|
2727
|
+
invariant("an app is named") { !value.to_s.empty? }
|
|
2728
|
+
end
|
|
2729
|
+
|
|
2730
|
+
value_object "RollBranch" do
|
|
2731
|
+
attribute :value, String, matches: :present
|
|
2732
|
+
end
|
|
2733
|
+
|
|
2734
|
+
value_object "RollRepo" do
|
|
2735
|
+
# GitHub's `owner/name`.
|
|
2736
|
+
attribute :value, String, pattern: '^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$'
|
|
2737
|
+
end
|
|
2738
|
+
|
|
2739
|
+
# The changed paths of the commit, newline-separated, as the classifier read them.
|
|
2740
|
+
value_object "ChangedPaths" do
|
|
2741
|
+
attribute :value, String, default: ""
|
|
2742
|
+
end
|
|
2743
|
+
|
|
2744
|
+
# Takes a green commit of the platform's main into the roll's chain; the classifier answers
|
|
2745
|
+
# next.
|
|
2746
|
+
command "Consider" do
|
|
2747
|
+
role "System"
|
|
2748
|
+
goal "Take one green commit of embryonaut_platform's main into the image roll's chain"
|
|
2749
|
+
|
|
2750
|
+
attribute :commit, CommitRef
|
|
2751
|
+
attribute :branch, RollBranch
|
|
2752
|
+
attribute :repo, RollRepo
|
|
2753
|
+
|
|
2754
|
+
emits "RollConsidered"
|
|
2755
|
+
end
|
|
2756
|
+
|
|
2757
|
+
# Opens the roll of one classified commit; only an idle one may be requested.
|
|
2758
|
+
command "Request" do
|
|
2759
|
+
role "System"
|
|
2760
|
+
goal "Start the image roll of one commit whose changes touch only the console container's inputs"
|
|
2761
|
+
|
|
2762
|
+
attribute :commit, CommitRef
|
|
2763
|
+
attribute :app, AppName
|
|
2764
|
+
|
|
2765
|
+
emits "RollRequested"
|
|
2766
|
+
end
|
|
2767
|
+
|
|
2768
|
+
# Holds a commit whose changes reach past the container: a person releases it.
|
|
2769
|
+
command "NeedsApproval" do
|
|
2770
|
+
role "System"
|
|
2771
|
+
goal "Hold one commit whose changes reach past the container's inputs for a person to approve"
|
|
2772
|
+
|
|
2773
|
+
attribute :commit, CommitRef
|
|
2774
|
+
attribute :paths, ChangedPaths
|
|
2775
|
+
|
|
2776
|
+
emits "RollNeedsApproval"
|
|
2777
|
+
end
|
|
2778
|
+
|
|
2779
|
+
# Records how a requested roll ended, done or failed.
|
|
2780
|
+
command "Finish" do
|
|
2781
|
+
role "System"
|
|
2782
|
+
goal "Record how the image roll of one commit ended"
|
|
2783
|
+
|
|
2784
|
+
reference_to ImageRoll
|
|
2785
|
+
attribute :app, AppName
|
|
2786
|
+
attribute :status, one_of("done", "failed")
|
|
2787
|
+
|
|
2788
|
+
sets :outcome, to: :status
|
|
2789
|
+
|
|
2790
|
+
emits "RollDone"
|
|
2791
|
+
end
|
|
2792
|
+
end
|
|
2793
|
+
|
|
1970
2794
|
# One CI run against one commit. A clearance is minted per commit, so a later commit is stale
|
|
1971
2795
|
# by simply having none.
|
|
1972
2796
|
aggregate "Clearance" do
|
|
@@ -2002,6 +2826,17 @@ Hecks.bluebook "QualityControl" do
|
|
|
2002
2826
|
emits "ClearanceStarted"
|
|
2003
2827
|
end
|
|
2004
2828
|
|
|
2829
|
+
# Start and ask CI in one step: the verdict comes back as `SuitePassed` or `SuiteFailed`, and
|
|
2830
|
+
# `ClearOnPass` and `RefuseOnFail` settle the record. `Start` alone records a verdict CI gave elsewhere.
|
|
2831
|
+
command "Check" do
|
|
2832
|
+
role "QA engineer"
|
|
2833
|
+
goal "Put a commit through CI and record the verdict it gives"
|
|
2834
|
+
|
|
2835
|
+
attribute :commit, CommitRef
|
|
2836
|
+
|
|
2837
|
+
emits "ClearanceChecked"
|
|
2838
|
+
end
|
|
2839
|
+
|
|
2005
2840
|
command "Passed" do
|
|
2006
2841
|
role "System"
|
|
2007
2842
|
goal "Record that the suite went green against this commit"
|
|
@@ -2126,6 +2961,31 @@ Hecks.bluebook "QualityControl" do
|
|
|
2126
2961
|
group_by :status, :number
|
|
2127
2962
|
end
|
|
2128
2963
|
|
|
2964
|
+
# The fixer does the work of a fix; the ledger records each step it reports, so only these policies
|
|
2965
|
+
# write a bug's state after logging. Each names the fixer event it reacts to, and the Bug command
|
|
2966
|
+
# it records.
|
|
2967
|
+
policy "RecordClaimOnAttemptClaimed" do
|
|
2968
|
+
on "Attempt.AttemptClaimed"
|
|
2969
|
+
trigger Bug::Claim, with: { bug: :reference, held_by: :held_by, now: :now }
|
|
2970
|
+
end
|
|
2971
|
+
|
|
2972
|
+
policy "RecordInvestigationOnAttemptInvestigated" do
|
|
2973
|
+
on "Attempt.AttemptInvestigated"
|
|
2974
|
+
trigger Bug::Investigate, with: { bug: :reference, site: :site, cause: :cause }
|
|
2975
|
+
end
|
|
2976
|
+
|
|
2977
|
+
# The fix commit is recorded as the bug's fixed state; `BugCiWatch` starts on the `BugFixed` it emits.
|
|
2978
|
+
policy "RecordFixOnFixReady" do
|
|
2979
|
+
on "Attempt.FixReady"
|
|
2980
|
+
trigger Bug::Fix, with: { reference: :reference, commit: :commit }
|
|
2981
|
+
end
|
|
2982
|
+
|
|
2983
|
+
# A verified fix is the ledger's verified state, recorded with the evidence the fixer names.
|
|
2984
|
+
policy "RecordVerifyOnFixVerified" do
|
|
2985
|
+
on "Attempt.FixVerified"
|
|
2986
|
+
trigger Bug::Verify, with: { bug: :reference, evidence: :evidence }
|
|
2987
|
+
end
|
|
2988
|
+
|
|
2129
2989
|
# `Ticket.Close` is the only way a ticket leaves `filed`, and only the outside can know it
|
|
2130
2990
|
# happened, so the fact arrives by whichever route reaches us first.
|
|
2131
2991
|
policy "CloseWhenClosedUpstream" do
|
|
@@ -2133,6 +2993,11 @@ Hecks.bluebook "QualityControl" do
|
|
|
2133
2993
|
trigger Ticket::Close
|
|
2134
2994
|
end
|
|
2135
2995
|
|
|
2996
|
+
policy "RunWhenChecked" do
|
|
2997
|
+
on "Clearance.ClearanceChecked"
|
|
2998
|
+
ask :run, with: { commit: :commit }
|
|
2999
|
+
end
|
|
3000
|
+
|
|
2136
3001
|
# The adapter decides by answering or refusing, the only branch a policy can express.
|
|
2137
3002
|
policy "ClearOnPass" do
|
|
2138
3003
|
on "Clearance.SuitePassed"
|
|
@@ -2184,4 +3049,259 @@ Hecks.bluebook "QualityControl" do
|
|
|
2184
3049
|
reason: { value: "a check surprised — a person releases with hecks quality_control query sweep.run <target> --release --notes" }
|
|
2185
3050
|
}
|
|
2186
3051
|
end
|
|
3052
|
+
|
|
3053
|
+
# A requested head is read from remote CI by the CiHead port; the answer is the verdict's event.
|
|
3054
|
+
policy "CheckHeadOnRequest" do
|
|
3055
|
+
on "Head.HeadRequested"
|
|
3056
|
+
ask :check, with: { commit: :commit, branch: :branch, repo: :repo }
|
|
3057
|
+
end
|
|
3058
|
+
|
|
3059
|
+
policy "GreenOnHeadChecked" do
|
|
3060
|
+
on "Head.HeadChecked"
|
|
3061
|
+
where { color.value == "green" }
|
|
3062
|
+
trigger Head::Green, with: { commit: :commit, branch: :branch, repo: :repo, color: :color }
|
|
3063
|
+
end
|
|
3064
|
+
|
|
3065
|
+
policy "RedOnHeadChecked" do
|
|
3066
|
+
on "Head.HeadChecked"
|
|
3067
|
+
where { color.value == "red" }
|
|
3068
|
+
trigger Head::Red, with: { commit: :commit, repo: :repo, color: :color, failing_jobs: :failing_jobs }
|
|
3069
|
+
end
|
|
3070
|
+
|
|
3071
|
+
# A run of main read for its failing spec files. The reader reports each failing file to RedSpec
|
|
3072
|
+
# (opening a row or updating it) before it answers.
|
|
3073
|
+
policy "ReadRunOnRequest" do
|
|
3074
|
+
on "MainRun.MainRunReadRequested"
|
|
3075
|
+
ask :read, with: { run: :run, repo: :repo }
|
|
3076
|
+
end
|
|
3077
|
+
|
|
3078
|
+
policy "RecordTheRunRead" do
|
|
3079
|
+
on "MainRun.MainRunRead"
|
|
3080
|
+
trigger MainRun::Record, with: { commit: :commit, settled: :settled }
|
|
3081
|
+
end
|
|
3082
|
+
|
|
3083
|
+
# A settled run clears every red spec it did not see fail; `Clear` refuses one it did, which stays open.
|
|
3084
|
+
policy "ClearSpecsOnSettledRun" do
|
|
3085
|
+
on "MainRun.MainRunRead"
|
|
3086
|
+
where { settled.value == "yes" }
|
|
3087
|
+
for_each "RedSpec.OnMain"
|
|
3088
|
+
trigger RedSpec::Clear, with: { spec: :spec, run: :run, seen_in: :last_run }
|
|
3089
|
+
end
|
|
3090
|
+
|
|
3091
|
+
# The image roll's chain. A green remote CI on embryonaut_platform's main is classified by the
|
|
3092
|
+
# `ImageRoll` port: the answer is `ImageClassified`, and a refusal (the change set unreadable)
|
|
3093
|
+
# ends the chain. Only the classifier's verdict decides; an infra commit is held, and its roll
|
|
3094
|
+
# needs a green quick gate on record.
|
|
3095
|
+
policy "RollImages" do
|
|
3096
|
+
on "Head.CiGreen"
|
|
3097
|
+
where { repo.value == "heckslabs/embryonaut_platform" }
|
|
3098
|
+
trigger ImageRoll::Consider, with: { commit: :commit, branch: :branch, repo: :repo }
|
|
3099
|
+
end
|
|
3100
|
+
|
|
3101
|
+
policy "ClassifyConsidered" do
|
|
3102
|
+
on "ImageRoll.RollConsidered"
|
|
3103
|
+
ask :classify, with: { commit: :commit, branch: :branch, repo: :repo }
|
|
3104
|
+
end
|
|
3105
|
+
|
|
3106
|
+
policy "RollWhenImageOnly" do
|
|
3107
|
+
on "ImageRoll.ImageClassified"
|
|
3108
|
+
where { kind.value == "image" }
|
|
3109
|
+
trigger ImageRoll::Request, with: { commit: :commit, app: :app }
|
|
3110
|
+
end
|
|
3111
|
+
|
|
3112
|
+
policy "HoldWhenInfra" do
|
|
3113
|
+
on "ImageRoll.ImageClassified"
|
|
3114
|
+
where { kind.value == "infra" }
|
|
3115
|
+
trigger ImageRoll::NeedsApproval, with: { commit: :commit, paths: :paths }
|
|
3116
|
+
end
|
|
3117
|
+
|
|
3118
|
+
policy "RunRollOnRequest" do
|
|
3119
|
+
on "ImageRoll.RollRequested"
|
|
3120
|
+
ask :roll, with: { commit: :commit, app: :app }
|
|
3121
|
+
end
|
|
3122
|
+
|
|
3123
|
+
policy "FinishOnRollAnswered" do
|
|
3124
|
+
on "ImageRoll.RollAnswered"
|
|
3125
|
+
trigger ImageRoll::Finish, with: { commit: :commit, app: :app, status: :status }
|
|
3126
|
+
end
|
|
3127
|
+
|
|
3128
|
+
policy "FinishOnRollRefused" do
|
|
3129
|
+
on "ImageRoll.RollRefused"
|
|
3130
|
+
trigger ImageRoll::Finish, with: { commit: :commit, app: :app, status: { value: "failed" } }
|
|
3131
|
+
end
|
|
3132
|
+
|
|
3133
|
+
# The main-maintenance chain, one policy per event. Each `ask` is answered by the `MainMaintenance` port;
|
|
3134
|
+
# each `trigger` is a command above. The events are the contract: `WorkSubmitted(branch, sha)` from the
|
|
3135
|
+
# coder side, `GateVerdict(run, sha, color)`, `ReconcileRequested`, `ReconcileDone(run, sha, color,
|
|
3136
|
+
# verdict)`, `PushRequested`, `Pushed(run, sha, origin_sha)`, and the refusals `GateRefused`,
|
|
3137
|
+
# `ReconcileRefused`, `PushRefused`.
|
|
3138
|
+
policy "StartOnSubmission" do
|
|
3139
|
+
on "Submission.WorkSubmitted"
|
|
3140
|
+
trigger Maintenance::Start, with: { run: :branch, sha: :sha }
|
|
3141
|
+
end
|
|
3142
|
+
|
|
3143
|
+
policy "GateOnStart" do
|
|
3144
|
+
on "Maintenance.RunStarted"
|
|
3145
|
+
ask :gate, with: { run: :run, sha: :sha }
|
|
3146
|
+
end
|
|
3147
|
+
|
|
3148
|
+
policy "RefuseOnRedGate" do
|
|
3149
|
+
on "Maintenance.GateVerdict"
|
|
3150
|
+
where { color.value == "red" }
|
|
3151
|
+
trigger Maintenance::RefuseGate, with: { run: :run, color: :color }
|
|
3152
|
+
end
|
|
3153
|
+
|
|
3154
|
+
policy "ReconcileOnGreenGate" do
|
|
3155
|
+
on "Maintenance.GateVerdict"
|
|
3156
|
+
where { color.value == "green" }
|
|
3157
|
+
trigger Maintenance::RequestReconcile, with: { run: :run, sha: :sha, color: :color }
|
|
3158
|
+
end
|
|
3159
|
+
|
|
3160
|
+
policy "ReconcileOnRequest" do
|
|
3161
|
+
on "Maintenance.ReconcileRequested"
|
|
3162
|
+
ask :reconcile, with: { run: :run, sha: :sha, color: :color }
|
|
3163
|
+
end
|
|
3164
|
+
|
|
3165
|
+
policy "PushOnReconciled" do
|
|
3166
|
+
on "Maintenance.ReconcileDone"
|
|
3167
|
+
where { verdict.value != "refused" && color.value == "green" }
|
|
3168
|
+
trigger Maintenance::RequestPush, with: { run: :run, sha: :sha, color: :color, verdict: :verdict }
|
|
3169
|
+
end
|
|
3170
|
+
|
|
3171
|
+
policy "PushOnRequest" do
|
|
3172
|
+
on "Maintenance.PushRequested"
|
|
3173
|
+
ask :push, with: { run: :run, sha: :sha }
|
|
3174
|
+
end
|
|
3175
|
+
|
|
3176
|
+
# The mint chain. `MintRequested` carries the rehearsal's verdict and the watermark it read; the mint is
|
|
3177
|
+
# asked only for a would_mint verdict, and the refusal is the same named event as every other refusal.
|
|
3178
|
+
# A mint's landing follows it in the same step; a failed landing is `MintStranded`, the event a refused
|
|
3179
|
+
# `Land` ask names.
|
|
3180
|
+
policy "RefuseMintWithoutVerdict" do
|
|
3181
|
+
on "Maintenance.MintRequested"
|
|
3182
|
+
where { rehearsal_verdict.value != "would_mint" }
|
|
3183
|
+
trigger Maintenance::RefuseMint, with: { run: :run, domain: :domain, era: :era, rehearsal_verdict: :rehearsal_verdict }
|
|
3184
|
+
end
|
|
3185
|
+
|
|
3186
|
+
# The auto-mint rule, declared. A mint without the owner's confirm runs only when all four hold, and the
|
|
3187
|
+
# mint entry point (`Adapters::MainMaintenance#mint`, checked by `Adapters::QaAutoMint`) enforces it:
|
|
3188
|
+
# (a) the translation edge leaving the held era is empty: no aggregate block, derive, drop, rename,
|
|
3189
|
+
# convert, retype or rekey;
|
|
3190
|
+
# (b) every change in the shape diff is additive: an attribute an existing aggregate gained is optional,
|
|
3191
|
+
# and a new aggregate, required attributes included, adds no field to an existing one;
|
|
3192
|
+
# (c) the rehearsal said would_mint with a refusal total of 0, at the live watermark;
|
|
3193
|
+
# (d) no stranded marker exists.
|
|
3194
|
+
# Otherwise the mint is held: the entry point refuses it as "needs owner approval", and the policy below
|
|
3195
|
+
# asks for the approval, which answers `MintNeedsApproval` and stops. A stale watermark or a stranded
|
|
3196
|
+
# marker is a refusal, never a held mint. The ask forwards no `ledger_dir`: an optional attribute a call
|
|
3197
|
+
# leaves out is not on the event, so the entry point takes the QualityControl ledger by default.
|
|
3198
|
+
policy "AutoMintAdditive" do
|
|
3199
|
+
on "Maintenance.MintRequested"
|
|
3200
|
+
where { rehearsal_verdict.value == "would_mint" }
|
|
3201
|
+
ask :mint, with: { run: :run, domain: :domain, era: :era, sha: :sha, branch: :branch,
|
|
3202
|
+
watermark: :watermark, rehearsal_verdict: :rehearsal_verdict,
|
|
3203
|
+
refusal_total: :refusal_total, confirm: :confirm }
|
|
3204
|
+
end
|
|
3205
|
+
|
|
3206
|
+
# Holds a mint the auto-mint rule does not cover for the owner. Reads the refusal the entry point named.
|
|
3207
|
+
policy "AskOwnerApprovalOnHeldMint" do
|
|
3208
|
+
on "Maintenance.MintRefused"
|
|
3209
|
+
where { refusal && refusal.value.start_with?("needs owner approval") }
|
|
3210
|
+
ask :approval, with: { domain: :domain, era: :era, reason: :refusal }
|
|
3211
|
+
end
|
|
3212
|
+
|
|
3213
|
+
policy "LandOnMinted" do
|
|
3214
|
+
on "Maintenance.Minted"
|
|
3215
|
+
where { branch.value != "" }
|
|
3216
|
+
ask :land, with: { run: :run, era: :era, sha: :sha, branch: :branch }
|
|
3217
|
+
end
|
|
3218
|
+
|
|
3219
|
+
# The release PR chain. A version bump opens its PR; the conditions judged on `ReleaseChecked` either
|
|
3220
|
+
# approve it (every condition `met`) or refuse it by the name of the condition that failed. An approval
|
|
3221
|
+
# writes the release trailer on the merge through the `ReleaseGh` port.
|
|
3222
|
+
policy "OpenOnReleaseRequest" do
|
|
3223
|
+
on "ReleasePR.ReleaseOpenRequested"
|
|
3224
|
+
ask :open_pull_request, with: { release: :release, branch: :branch, sha: :sha }
|
|
3225
|
+
end
|
|
3226
|
+
|
|
3227
|
+
policy "ApproveOnConditionsMet" do
|
|
3228
|
+
on "ReleasePR.ReleaseChecked"
|
|
3229
|
+
where { condition.value == "met" }
|
|
3230
|
+
trigger ReleasePR::Approve, with: { release: :release, sha: :sha, condition: :condition,
|
|
3231
|
+
approver: :approver, trailer: :trailer }
|
|
3232
|
+
end
|
|
3233
|
+
|
|
3234
|
+
policy "RefuseOnFailedCondition" do
|
|
3235
|
+
on "ReleasePR.ReleaseChecked"
|
|
3236
|
+
where { condition.value != "met" }
|
|
3237
|
+
trigger ReleasePR::Refuse, with: { release: :release, condition: :condition }
|
|
3238
|
+
end
|
|
3239
|
+
|
|
3240
|
+
policy "WriteTrailerOnApproved" do
|
|
3241
|
+
on "ReleasePR.ReleaseApproved"
|
|
3242
|
+
ask :write_trailer, with: { approver: :approver, trailer: :trailer }
|
|
3243
|
+
end
|
|
3244
|
+
|
|
3245
|
+
# ---- The push nudge ----------------------------------------------------------------------------
|
|
3246
|
+
# Local main drifting ahead of origin/main is red that nobody sees. Each tick checks once whether a
|
|
3247
|
+
# push is due and keeps ONE Work row, `push-due`, for QA: filed when the push is due beyond the
|
|
3248
|
+
# world's thresholds, updated while it stays due, finished when it no longer is. The check reads
|
|
3249
|
+
# refs git already holds (`PushRehearsal.Due`); it never fetches, pushes or merges. Tickets turns the
|
|
3250
|
+
# answer into the row (`PlanWorkWhenPushDue`, `ReviseWorkWhenPushStillDue`, `FinishWorkWhenPushSettled`).
|
|
3251
|
+
aggregate "PushNudge" do
|
|
3252
|
+
description "One check of whether a push of local main is due: whether it is, whether the push-due Work row is already open, and the numbers."
|
|
3253
|
+
|
|
3254
|
+
identified_by :nudge
|
|
3255
|
+
|
|
3256
|
+
attribute :nudge, NudgeKey
|
|
3257
|
+
attribute :due, NudgeFlag, optional: true
|
|
3258
|
+
attribute :raised, NudgeFlag, optional: true
|
|
3259
|
+
attribute :work, NudgeLine, optional: true
|
|
3260
|
+
attribute :title, NudgeLine, optional: true
|
|
3261
|
+
attribute :detail, NudgeLine, optional: true
|
|
3262
|
+
|
|
3263
|
+
value_object "NudgeKey" do
|
|
3264
|
+
attribute :value, String, matches: :present
|
|
3265
|
+
end
|
|
3266
|
+
|
|
3267
|
+
# "yes" or "no".
|
|
3268
|
+
value_object "NudgeFlag" do
|
|
3269
|
+
attribute :value, String, default: ""
|
|
3270
|
+
end
|
|
3271
|
+
|
|
3272
|
+
value_object "NudgeLine" do
|
|
3273
|
+
attribute :value, String, default: ""
|
|
3274
|
+
end
|
|
3275
|
+
|
|
3276
|
+
command "Check" do
|
|
3277
|
+
role "QA engineer"
|
|
3278
|
+
goal "Ask whether a push of local main is due, from the refs git already holds"
|
|
3279
|
+
|
|
3280
|
+
attribute :nudge, NudgeKey, sets: true
|
|
3281
|
+
|
|
3282
|
+
emits "PushDueCheckRequested"
|
|
3283
|
+
end
|
|
3284
|
+
|
|
3285
|
+
command "Record" do
|
|
3286
|
+
role "System"
|
|
3287
|
+
goal "Keep what a check found"
|
|
3288
|
+
|
|
3289
|
+
reference_to PushNudge
|
|
3290
|
+
attribute :due, NudgeFlag, sets: true
|
|
3291
|
+
attribute :raised, NudgeFlag, sets: true
|
|
3292
|
+
attribute :detail, NudgeLine, sets: true
|
|
3293
|
+
|
|
3294
|
+
emits "PushDueRecorded"
|
|
3295
|
+
end
|
|
3296
|
+
end
|
|
3297
|
+
|
|
3298
|
+
policy "ReadPushDueOnCheck" do
|
|
3299
|
+
on "PushNudge.PushDueCheckRequested"
|
|
3300
|
+
ask :read, with: { nudge: :nudge }
|
|
3301
|
+
end
|
|
3302
|
+
|
|
3303
|
+
policy "RecordThePushDueRead" do
|
|
3304
|
+
on "PushNudge.PushDueRead"
|
|
3305
|
+
trigger PushNudge::Record, with: { due: :due, raised: :raised, detail: :detail }
|
|
3306
|
+
end
|
|
2187
3307
|
end
|