From 7e653aefd4cf3d7e534c658c31dc6b510c1b77ef Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sat, 8 Aug 2026 19:15:49 +0000 Subject: [PATCH] Fix main-red witness import closure and surface located floor terminal refusals. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twenty-five discovery witnesses failed with no such function because extdeps grounding tests relied on pool-membership resolution instead of explicit imports; add the missing import rows. The coordinator previously replayed only walk terminal exit code 1 while the worker had already emitted the real batch refusal on stderr — walk_terminal_detail now carries mode, ci_failure_class_arm, and failure_details into the terminal receipt. Co-authored-by: Cursor --- .../extdeps_anemia_grounding_witness_test.dag | 23 +++++ .../extdeps_round2_grounding_witness_test.dag | 33 +++++++ .../claim/hardware_selection_witness_test.dag | 39 +++++++- src/v1/stage0/src/bin/claim_executor.rs | 91 +++++++++++++++++-- 4 files changed, 174 insertions(+), 12 deletions(-) diff --git a/dag/test/claim/extdeps_anemia_grounding_witness_test.dag b/dag/test/claim/extdeps_anemia_grounding_witness_test.dag index a80b78ef393..e6ac51e06ac 100644 --- a/dag/test/claim/extdeps_anemia_grounding_witness_test.dag +++ b/dag/test/claim/extdeps_anemia_grounding_witness_test.dag @@ -1,5 +1,28 @@ module test.claim.extdeps_anemia_grounding_witness + +import std.types { CommitSha, GitRef, Email, FilePath } +import extdeps.git { GitAuthor } +import extdeps.github.pulls { + PullRequestRef, PullReview, ReviewComment, Commented, +} +import extdeps.github.github { GitHubUser, User } +import gunbc.digest_render { digest_subject } +import extdeps.cpu.ampere { + altra_max_m12830_catalog, + ampere_altra_l1_cache_geometry, + ampere_altra_l1_cache_citations, + ampere_altra_l2_cache_geometry, + ampere_altra_l2_cache_citations, + ampere_altra_max_l3_cache_geometry, + ampere_altra_max_l3_cache_citations, +} +import extdeps.cpu.types { + CpuModelCatalogRow, CpuSocket, LandGridArray, +} +import extdeps.toolchain.types { Aarch64 } import extdeps.vendor.ampere { ampere } +import std.measure { watt, watt_count, hardware_thread_count, hertz } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly diff --git a/dag/test/claim/extdeps_round2_grounding_witness_test.dag b/dag/test/claim/extdeps_round2_grounding_witness_test.dag index dca09173432..8da8498d880 100644 --- a/dag/test/claim/extdeps_round2_grounding_witness_test.dag +++ b/dag/test/claim/extdeps_round2_grounding_witness_test.dag @@ -1,5 +1,38 @@ module test.claim.extdeps_round2_grounding_witness + +import extdeps.sql.migration { + sql_dialect_wire_label, Postgres, Mysql, Sqlite, + SqlMigrationStep, CreateTable, +} +import extdeps.http.server { + media_type_wire_label, text_html_utf8, text_plain_utf8, + TopLevelText, GET, ServedStaticRoute, +} +import std.http_path { PathTemplate } +import extdeps.cloud.cloud { + aws_region_wire_label, UsEast1, aws_service_wire_label, S3, + SigV4, Protocol, OidcToken, +} +import extdeps.cloud.gcp.gcp { + GcpApiEndpoint, GcpStorage, GcpSts, gcp_service_wire_label, + GcpProject, GcpServiceAccount, +} +import extdeps.cloud.gcp.errors { + gcp_error_example, gcp_rpc_code_label, parse_gcp_rpc_code, + GcpRpcCodePermissionDenied, GcpRpcCodeNotFound, GcpRpcCodeOther, +} +import extdeps.gpu.types { + gpu_compute_capability_sm_label, GpuComputeCapability, + GpuCapabilityLabelOk, GpuCapabilityLabelRejected, + GpuFacts, AcceleratorFacts, +} +import extdeps.vendor.nvidia { nvidia } +import extdeps.vendor.amd { amd } +import extdeps.vendor.intel { intel } import extdeps.vendor.ampere { ampere } +import extdeps.memory.types { MemoryFacts, Hbm } +import std.measure { byte_size } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly diff --git a/dag/test/claim/hardware_selection_witness_test.dag b/dag/test/claim/hardware_selection_witness_test.dag index 5b7e24ec427..47ecfffef3c 100644 --- a/dag/test/claim/hardware_selection_witness_test.dag +++ b/dag/test/claim/hardware_selection_witness_test.dag @@ -1,6 +1,37 @@ module test.claim.hardware_selection + import extdeps.vendor.ampere { ampere } -import std.measure { milliwatt } +import extdeps.vendor.sk_hynix { sk_hynix } +import extdeps.memory.types { + DramModuleCatalogRow, Registered, dram_generation_ddr4, bit_width, + dram_module_is_realizable, dram_module_required_die_density, +} +import extdeps.memory.jedec { ddr4_generation_catalog } +import extdeps.cpu.ampere { + ampere_altra_l1_cache_geometry, + ampere_altra_l1_cache_citations, + ampere_altra_l2_cache_geometry, + ampere_altra_l2_cache_citations, + ampere_altra_max_l3_cache_geometry, + ampere_altra_max_l3_cache_citations, +} +import extdeps.cpu.types { + CpuModelCatalogRow, CpuSocket, LandGridArray, +} +import extdeps.toolchain.types { Aarch64 } +import product.hardware_selection { + Platform, MemoryConfig, CpuCandidate, Motherboard, PsuModel, SystemConfig, HardwareAxes, + Gold, + effective_data_rate_mts, config_axes, dominates, axes_on_front, + psu_is_adequate, wall_draw_watts, config_is_realizable, + cost_micros_per_gib, bandwidth_per_watt, +} +import std.pareto { verdict_is_incomparable, verdict_dominates } +import std.measure { + watt, watt_count, byte_size, byte_size_count, + hertz, hardware_thread_count, money_amount_micro, +} +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -62,13 +93,13 @@ data mod_1rx8_32g_impossible: DramModuleCatalogRow = DramModuleCatalogRow { } data mem_1rx8_2dpc: MemoryConfig = MemoryConfig { - module: mod_1rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 2, power_per_chip: milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) + module: mod_1rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 2, power_per_chip: product.hardware_selection.milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) } data mem_2rx8_2dpc: MemoryConfig = MemoryConfig { - module: mod_2rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 2, power_per_chip: milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) + module: mod_2rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 2, power_per_chip: product.hardware_selection.milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) } data mem_1rx8_1dpc: MemoryConfig = MemoryConfig { - module: mod_1rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 1, power_per_chip: milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) + module: mod_1rx8_16g, jedec: ddr4_generation_catalog, dimms_per_channel: 1, power_per_chip: product.hardware_selection.milliwatt(count: 400), price_per_stick: money_amount_micro(count: 120000000) } data cpu_catalog: CpuModelCatalogRow = CpuModelCatalogRow { diff --git a/src/v1/stage0/src/bin/claim_executor.rs b/src/v1/stage0/src/bin/claim_executor.rs index 1398eb6b542..f8119f973e4 100644 --- a/src/v1/stage0/src/bin/claim_executor.rs +++ b/src/v1/stage0/src/bin/claim_executor.rs @@ -10869,12 +10869,19 @@ fn run() -> Result { &source_roots, ); v1_compiler::v1_interpreter::group_end(); + let any_failed = + outcome.any_failed || compile_clean_over_budget || !compile_clean_drift_receipt_ok; if outcome.any_failed { emit_falsifier_failure_class(&outcome.failure_details, &outcome.infra_faults); } - floor_terminal_fast_exit(walk_exit_code( - outcome.any_failed || compile_clean_over_budget || !compile_clean_drift_receipt_ok, - )) + let terminal_detail = walk_terminal_detail( + any_failed, + &outcome.failure_details, + &outcome.infra_faults, + compile_clean_over_budget, + compile_clean_drift_receipt_ok, + ); + floor_terminal_fast_exit(walk_exit_code(any_failed), &terminal_detail) } /// Typed terminal failure class for the falsifier/floor walk (brief Step 2, 2026-07-25): @@ -10978,6 +10985,40 @@ fn walk_exit_code(any_failed: bool) -> i32 { } } +/// Located refusal carried in the worker terminal receipt for the coordinator to replay. +/// +/// `floor_terminal_fast_exit` used to write only `walk terminal exit code N`, which the +/// thin coordinator then surfaced as the sole failure detail — a refusal that names +/// nothing is worse than none (DESIGN §5; receipt: run 31263508328 printed +/// `detail=walk terminal exit code 1` while the worker had already emitted the real +/// witness-red batch line on stderr that Actions dropped). +fn walk_terminal_detail( + any_failed: bool, + failure_details: &[String], + infra_faults: &[InfraFault], + compile_clean_over_budget: bool, + compile_clean_drift_receipt_ok: bool, +) -> String { + if !any_failed { + return "walk terminal exit code 0".to_string(); + } + let mode = falsifier_failure_mode_with_faults(failure_details, infra_faults); + let mut parts = vec![format!( + "walk terminal exit code 1 mode={mode} ci_failure_class_arm={}", + ci_failure_class_arm(mode) + )]; + if !failure_details.is_empty() { + parts.push(failure_details.join(" | ")); + } + if compile_clean_over_budget { + parts.push("compile_clean_over_budget".to_string()); + } + if !compile_clean_drift_receipt_ok { + parts.push("compile_clean_cost_drift_receipt_refused".to_string()); + } + scoped_wire_text(&parts.join(" ")) +} + /// Terminal fast-exit for the floor walk (CI floor endgame D2): the executor retains a /// ~16GB store (process-shared index, typed caches, interner) whose Drop walk at process /// end measured 2.5–3.1 minutes, twice-confirmed (Pi bench: swap grows DURING Drop; @@ -10989,13 +11030,10 @@ fn walk_exit_code(any_failed: bool) -> i32 { /// `run()`'s walk path — every plan walk (floor, plan-artifact, regen, falsifier) exits /// through it; every refusal/error path above returns normally. The exit CODE is exactly /// `walk_exit_code(any_failed)` — behavior-identical to the ExitCode return it replaces. -fn floor_terminal_fast_exit(code: i32) -> ! { +fn floor_terminal_fast_exit(code: i32, detail: &str) -> ! { use std::io::Write as _; let terminal_outcome = if code == 0 { "completed" } else { "failed" }; - let final_code = match write_floor_worker_terminal( - terminal_outcome, - &format!("walk terminal exit code {code}"), - ) { + let final_code = match write_floor_worker_terminal(terminal_outcome, detail) { Ok(()) => code, Err(msg) => { eprintln!("claim_executor: floor worker terminal receipt refusal: {msg}"); @@ -12060,6 +12098,43 @@ mod tests { assert_eq!(walk_exit_code(false), 0); } + #[test] + fn walk_terminal_detail_carries_located_refusal_not_bare_exit_code() { + let detail = walk_terminal_detail( + true, + &[ + "batch=3 fn=discovery-corpus detail=25 of 8158 discovery witness(es) failed" + .to_string(), + ], + &[], + false, + true, + ); + assert!( + detail.contains("batch=3 fn=discovery-corpus"), + "the terminal receipt must carry the located batch refusal, got: {detail}" + ); + assert!( + detail.contains("mode=WitnessRed"), + "the terminal receipt must carry the typed mode, got: {detail}" + ); + assert!( + !detail.trim().eq("walk terminal exit code 1"), + "a bare exit-code string is not a located refusal: {detail}" + ); + assert_eq!( + walk_terminal_detail(false, &[], &[], false, true), + "walk terminal exit code 0" + ); + } + + #[test] + fn walk_terminal_detail_surfaces_post_walk_compile_clean_refusals() { + let detail = walk_terminal_detail(true, &[], &[], true, false); + assert!(detail.contains("compile_clean_over_budget")); + assert!(detail.contains("compile_clean_cost_drift_receipt_refused")); + } + fn outcome(entry: &str, function: &str, o: ClaimOutcome) -> DiscoveryWitnessOutcome { DiscoveryWitnessOutcome { entry: entry.to_string(),