From 58bfb78db226ffb687a2b2a6bf046aa61254d3f1 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:33:04 +0530 Subject: [PATCH 1/7] ci: collect native Linux host checks and guard exclusions --- .github/workflows/no-gpu.yml | 26 +++++++-- CONTRIBUTING.md | 9 ++++ build.zig | 1 + tools/zig/host_tests_test.py | 102 +++++++++++++++++++++++++++++++++++ zig/build/host_tests.zig | 74 +++++++++++++++++++++++++ 5 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 tools/zig/host_tests_test.py create mode 100644 zig/build/host_tests.zig diff --git a/.github/workflows/no-gpu.yml b/.github/workflows/no-gpu.yml index 7a5064fb2a..2d63cf1d86 100644 --- a/.github/workflows/no-gpu.yml +++ b/.github/workflows/no-gpu.yml @@ -33,7 +33,7 @@ jobs: run: python -m unittest discover -s tools/tests -p "test_bench*.py" -v zig: runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 60 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: @@ -96,10 +96,26 @@ jobs: exit 0 fi python3 -m unittest discover -s tools/zig -p zig_cache_restat_test.py -v - # zig build test is the host unit tests. No GPU. The Python suite is not this check. - # A unit test that hangs fails by name after 10 minutes instead of holding the runner until the job's limit. - - name: zig build test - run: zig build -Dfixed-cpu test --test-timeout 10m + - name: Host test graph regressions + shell: bash + env: + BASE_REF: ${{ github.base_ref }} + PUSH_BASE: ${{ github.event.before }} + run: | + if [ -n "$BASE_REF" ]; then + base=$(git merge-base HEAD "origin/$BASE_REF" 2> /dev/null || true) + else + base=$(git rev-parse --verify "$PUSH_BASE^{commit}" 2> /dev/null || true) + fi + if [ -n "$base" ] && git diff --quiet "$base" HEAD -- \ + build.zig zig/build/host_tests.zig tools/zig/host_tests_test.py; then + echo "Host test graph inputs are unchanged." + exit 0 + fi + python3 -m unittest discover -s tools/zig -p host_tests_test.py -v + # Keep per-test timeouts while allowing the DeepSeek AOT enumeration to finish on hosted runners. + - name: zig build test-host + run: zig build -Dfixed-cpu test-host --test-timeout 20m # The kernel contract's limits gate: every registered launch against M1-M5 and sm_80/86/89/120/121, controls red. - name: zig build test-kernel-contract run: zig build -Dfixed-cpu test-kernel-contract diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 82cf12ca97..920cd18f29 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,6 +41,15 @@ zig build test-cuda-host This subset does not replace the complete `test` suite. +Native Linux no-GPU CI runs `zig build -Dfixed-cpu test-host --test-timeout 20m`. +It includes `test` and every configured `test-*` and `check-*` step, including compile-only checks. +New named checks join automatically, even when a build module registers them last. +The reviewed exclusions in `zig/build/host_tests.zig` cover the optional xgrammar tests, +the separately scheduled `check-release-paths` gate, and temporary failures tracked in #2031. +An empty named check, a stale exclusion, or an alias that brings excluded work back into the aggregate fails it. +When a fix lands, remove its temporary exclusion and the matching fixture entry in `tools/zig/host_tests_test.py`. +This aggregate is only registered for native Linux; other hosts keep their existing `test` and device steps. + HIP is an explicit build opt-in. Add `-Dhip=true` to enable its host tests and named HIP targets: ```sh diff --git a/build.zig b/build.zig index 3aa689962a..50616a2686 100644 --- a/build.zig +++ b/build.zig @@ -75,6 +75,7 @@ pub fn build(b: *std.Build) void { @import("zig/build/dsv41_draft.zig").steps(b); @import("zig/build/dsv41_assets.zig").steps(b); const target = b.standardTargetOptions(.{}); + defer @import("zig/build/host_tests.zig").wire(b, target); @import("zig/build/copy_source.zig").steps(b); @import("zig/build/checkpoint_io_host.zig").steps(b, target); const release_version = b.option([]const u8, "version", "Release version, exactly MAJOR.MINOR.PATCH"); diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py new file mode 100644 index 0000000000..0e8b5839f3 --- /dev/null +++ b/tools/zig/host_tests_test.py @@ -0,0 +1,102 @@ +"""Real Zig build graphs must include new host checks and keep reviewed external requirements outside CI.""" +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[2] +POLICY = ROOT / "zig/build/host_tests.zig" +EXCLUDED = ( + "test-grammar-budget", + "test-grammar-tools", + "check-release-paths", + "test-metal-residency-owners-host", + "test-exl3-prompt-host", + "test-qwen35-draft-frame-host", + "test-qwen35-frame-invalidation-host", + "test-gemma4-affine-host", + "test-gradient-serving", + "test-qwen-serving-host", +) + + +@unittest.skipUnless(sys.platform.startswith("linux"), "test-host is a native Linux CI aggregate") +class HostTestGraphTests(unittest.TestCase): + def setUp(self): + self.zig = os.environ.get("ZIG") or shutil.which("zig") + if not self.zig: + self.skipTest("no Zig compiler found (set ZIG, or put zig on PATH)") + temporary = tempfile.TemporaryDirectory(prefix="tensorfold-host-graph-") + self.addCleanup(temporary.cleanup) + self.root = Path(temporary.name) + shutil.copyfile(POLICY, self.root / "host_tests.zig") + + def build(self, extra="", omit=None, args=None): + excluded = "\n".join( + f' b.step("{name}", "external requirement").dependOn(&b.addFail("external gate ran").step);' + for name in EXCLUDED if name != omit + ) + source = '''const std = @import("std"); +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + defer @import("host_tests.zig").wire(b, target); +''' + excluded + "\n" + extra + "\n}\n" + (self.root / "build.zig").write_text(source) + return subprocess.run([self.zig, "build", *(args or ["test-host", "--summary", "all"])], + cwd=self.root, capture_output=True, text=True, timeout=120) + + def assert_failed_with(self, result, message): + self.assertNotEqual(result.returncode, 0, result.stdout + result.stderr) + self.assertIn(message, result.stdout + result.stderr) + + def test_new_named_host_test_is_included_after_the_collector_is_declared(self): + result = self.build(' b.step("test-new-host", "new host test").dependOn(&b.addFail("new host test reached").step);') + self.assert_failed_with(result, "new host test reached") + + def test_existing_unnamed_unit_tests_are_preserved(self): + result = self.build(' b.step("test", "existing units").dependOn(&b.addFail("existing units reached").step);') + self.assert_failed_with(result, "existing units reached") + + def test_new_compile_only_check_is_included(self): + (self.root / "broken.zig").write_text('comptime { @compileError("new compile check reached"); }\n') + result = self.build(''' const check = b.addObject(.{ .name = "compile-only", .root_module = b.createModule(.{ + .root_source_file = b.path("broken.zig"), .target = target, + }) }); + b.step("check-new-host", "compile only").dependOn(&check.step);''') + self.assert_failed_with(result, "new compile check reached") + + def test_reviewed_external_requirements_are_not_executed(self): + result = self.build() + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + self.assertNotIn("external gate ran", result.stdout + result.stderr) + + def test_alias_to_an_excluded_check_is_rejected(self): + result = self.build(''' b.step("test-alias", "alias").dependOn(&b.top_level_steps.get("test-grammar-budget").?.step);''') + self.assert_failed_with(result, "test-host reaches excluded test-grammar-budget") + self.assertNotIn("external gate ran", result.stdout + result.stderr) + + def test_direct_alias_to_an_excluded_action_is_rejected(self): + result = self.build(''' const external = b.top_level_steps.get("test-grammar-tools").?; + b.step("test-action-alias", "alias").dependOn(external.step.dependencies.items[0]);''') + self.assert_failed_with(result, "test-host reaches excluded test-grammar-tools") + self.assertNotIn("external gate ran", result.stdout + result.stderr) + + def test_empty_named_check_is_rejected(self): + result = self.build(' _ = b.step("test-empty", "accidentally disconnected");') + self.assert_failed_with(result, "named check test-empty has no build steps") + + def test_removed_external_step_requires_review_of_its_exclusion(self): + result = self.build(omit="test-grammar-tools") + self.assert_failed_with(result, "stale exclusion test-grammar-tools") + + def test_cross_target_does_not_acquire_a_native_host_aggregate(self): + result = self.build(args=["--help", "-Dtarget=x86_64-windows-gnu"]) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + self.assertNotIn("test-host", result.stdout) + + +if __name__ == "__main__": + unittest.main() diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig new file mode 100644 index 0000000000..2129b566b2 --- /dev/null +++ b/zig/build/host_tests.zig @@ -0,0 +1,74 @@ +//! Native Linux CI collects named host tests and compile checks after every build module has registered its steps. +const std = @import("std"); +const Step = std.Build.Step; +const Set = std.AutoHashMapUnmanaged(*Step, void); + +const Exclusion = struct { name: []const u8, reason: []const u8 }; +const exclusions = [_]Exclusion{ + .{ .name = "test-grammar-budget", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, + .{ .name = "test-grammar-tools", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, + .{ .name = "check-release-paths", .reason = "The release-paths CI job checks the separately built release server" }, + .{ .name = "test-metal-residency-owners-host", .reason = "red on main, #2031 (Qwen27 recording root lacks affine_mm, #2331)" }, + .{ .name = "test-exl3-prompt-host", .reason = "red on main, #2031 (missing b32 initializer, #2094)" }, + .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (uninitialized seg_fn in the recording fixture)" }, + .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, + .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, + .{ .name = "test-gradient-serving", .reason = "source pins awaiting re-baseline (#2031), gradient source identities drifted" }, + .{ .name = "test-qwen-serving-host", .reason = "source pins awaiting re-baseline (#2031), launch sequence drifted" }, +}; + +pub fn wire(b: *std.Build, target: std.Build.ResolvedTarget) void { + const host = b.graph.host.result; + if (host.os.tag != .linux or target.result.os.tag != host.os.tag or + target.result.cpu.arch != host.cpu.arch or target.result.abi != host.abi) return; + + const all = b.step("test-host", "Native Linux host tests and compile checks with reviewed exclusions"); + var rejected: std.ArrayList(*Step) = .empty; + for (b.top_level_steps.values()) |top| { + const name = top.step.name; + if (&top.step == all or !isCheck(name) or exclusion(name) != null) continue; + if (top.step.dependencies.items.len == 0) + reject(b, &rejected, b.fmt("test-host: named check {s} has no build steps", .{name})); + all.dependOn(&top.step); + } + + var included: Set = .empty; + collect(b.allocator, all, &included); + for (exclusions) |entry| { + const top = b.top_level_steps.get(entry.name) orelse { + reject(b, &rejected, b.fmt("test-host: stale exclusion {s}: {s}", .{ entry.name, entry.reason })); + continue; + }; + var visited: Set = .empty; + if (includedBoundary(b.allocator, &top.step, &included, &visited)) + reject(b, &rejected, b.fmt("test-host reaches excluded {s}: {s}", .{ entry.name, entry.reason })); + } + if (rejected.items.len != 0) all.dependencies = rejected; +} + +fn reject(b: *std.Build, rejected: *std.ArrayList(*Step), message: []const u8) void { + rejected.append(b.allocator, &b.addFail(message).step) catch @panic("OOM"); +} + +fn isCheck(name: []const u8) bool { + return std.mem.eql(u8, name, "test") or std.mem.startsWith(u8, name, "test-") or + std.mem.startsWith(u8, name, "check-"); +} + +fn exclusion(name: []const u8) ?Exclusion { + for (exclusions) |entry| if (std.mem.eql(u8, name, entry.name)) return entry; + return null; +} + +fn collect(a: std.mem.Allocator, root: *Step, seen: *Set) void { + if ((seen.getOrPut(a, root) catch @panic("OOM")).found_existing) return; + for (root.dependencies.items) |dep| collect(a, dep, seen); +} + +fn includedBoundary(a: std.mem.Allocator, root: *Step, included: *const Set, seen: *Set) bool { + if ((seen.getOrPut(a, root) catch @panic("OOM")).found_existing) return false; + if (included.contains(root)) return true; + if (root.tag != .top_level) return false; + for (root.dependencies.items) |dep| if (includedBoundary(a, dep, included, seen)) return true; + return false; +} From dd3e2f287c758e58a6b6cab51c08657b0a3cecc7 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:44:01 +0530 Subject: [PATCH 2/7] ci: track the pre-existing GLM snapshot fixture failure --- tools/zig/host_tests_test.py | 1 + zig/build/host_tests.zig | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index 0e8b5839f3..6da69fdaba 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -17,6 +17,7 @@ "test-exl3-prompt-host", "test-qwen35-draft-frame-host", "test-qwen35-frame-invalidation-host", + "test-glm-snapshots-host", "test-gemma4-affine-host", "test-gradient-serving", "test-qwen-serving-host", diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index 2129b566b2..7544e6d526 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -12,6 +12,7 @@ const exclusions = [_]Exclusion{ .{ .name = "test-exl3-prompt-host", .reason = "red on main, #2031 (missing b32 initializer, #2094)" }, .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (uninitialized seg_fn in the recording fixture)" }, .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, + .{ .name = "test-glm-snapshots-host", .reason = "red on main, #2031 (snapshot fixture copies module lacks core)" }, .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, .{ .name = "test-gradient-serving", .reason = "source pins awaiting re-baseline (#2031), gradient source identities drifted" }, .{ .name = "test-qwen-serving-host", .reason = "source pins awaiting re-baseline (#2031), launch sequence drifted" }, From 39b8903922d1c4bfeb86cc274c3e832a06de6602 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:07:55 +0530 Subject: [PATCH 3/7] ci: restore the repaired residency and GLM snapshot host checks --- tools/zig/host_tests_test.py | 2 -- zig/build/host_tests.zig | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index 6da69fdaba..c9ff600992 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -13,11 +13,9 @@ "test-grammar-budget", "test-grammar-tools", "check-release-paths", - "test-metal-residency-owners-host", "test-exl3-prompt-host", "test-qwen35-draft-frame-host", "test-qwen35-frame-invalidation-host", - "test-glm-snapshots-host", "test-gemma4-affine-host", "test-gradient-serving", "test-qwen-serving-host", diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index 7544e6d526..587f9590d8 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -8,14 +8,12 @@ const exclusions = [_]Exclusion{ .{ .name = "test-grammar-budget", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "test-grammar-tools", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "check-release-paths", .reason = "The release-paths CI job checks the separately built release server" }, - .{ .name = "test-metal-residency-owners-host", .reason = "red on main, #2031 (Qwen27 recording root lacks affine_mm, #2331)" }, .{ .name = "test-exl3-prompt-host", .reason = "red on main, #2031 (missing b32 initializer, #2094)" }, - .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (uninitialized seg_fn in the recording fixture)" }, + .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, - .{ .name = "test-glm-snapshots-host", .reason = "red on main, #2031 (snapshot fixture copies module lacks core)" }, .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, - .{ .name = "test-gradient-serving", .reason = "source pins awaiting re-baseline (#2031), gradient source identities drifted" }, - .{ .name = "test-qwen-serving-host", .reason = "source pins awaiting re-baseline (#2031), launch sequence drifted" }, + .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (gradient source identities drifted)" }, + .{ .name = "test-qwen-serving-host", .reason = "red on main, #2031 (serving source and launch pins drifted)" }, }; pub fn wire(b: *std.Build, target: std.Build.ResolvedTarget) void { From 0ee98bc0889675b48c34a8264c932253b65c6392 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:11:36 +0530 Subject: [PATCH 4/7] ci: track two Qwen host checks still failing on main --- tools/zig/host_tests_test.py | 2 ++ zig/build/host_tests.zig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index c9ff600992..36b37c1a6d 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -16,6 +16,8 @@ "test-exl3-prompt-host", "test-qwen35-draft-frame-host", "test-qwen35-frame-invalidation-host", + "test-qwen35-draft-trees-host", + "test-qwen27-prompt-rows-host", "test-gemma4-affine-host", "test-gradient-serving", "test-qwen-serving-host", diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index 587f9590d8..5f170bf5da 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -11,6 +11,8 @@ const exclusions = [_]Exclusion{ .{ .name = "test-exl3-prompt-host", .reason = "red on main, #2031 (missing b32 initializer, #2094)" }, .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, + .{ .name = "test-qwen35-draft-trees-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, + .{ .name = "test-qwen27-prompt-rows-host", .reason = "red on main, #2031 (over-cap fixture expects InvalidEnvironment)" }, .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (gradient source identities drifted)" }, .{ .name = "test-qwen-serving-host", .reason = "red on main, #2031 (serving source and launch pins drifted)" }, From 5cf22489dfc9a01f25bcbbd058be534ac3c37f52 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:17:35 +0530 Subject: [PATCH 5/7] ci: track the existing cluster loader fixture failure --- tools/zig/host_tests_test.py | 1 + zig/build/host_tests.zig | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index 36b37c1a6d..b9b657f12c 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -18,6 +18,7 @@ "test-qwen35-frame-invalidation-host", "test-qwen35-draft-trees-host", "test-qwen27-prompt-rows-host", + "test-cluster-loader-host", "test-gemma4-affine-host", "test-gradient-serving", "test-qwen-serving-host", diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index 5f170bf5da..1ed48c5462 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -13,6 +13,7 @@ const exclusions = [_]Exclusion{ .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, .{ .name = "test-qwen35-draft-trees-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, .{ .name = "test-qwen27-prompt-rows-host", .reason = "red on main, #2031 (over-cap fixture expects InvalidEnvironment)" }, + .{ .name = "test-cluster-loader-host", .reason = "red on main, #2031 (cluster loader fixture lacks canon)" }, .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (gradient source identities drifted)" }, .{ .name = "test-qwen-serving-host", .reason = "red on main, #2031 (serving source and launch pins drifted)" }, From 426c89fa73864a35f5f9636c9a2650c1d4e49928 Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Mon, 9 Nov 2026 22:28:35 +0530 Subject: [PATCH 6/7] ci: restore six repaired Linux host checks --- tools/zig/host_tests_test.py | 6 ------ zig/build/host_tests.zig | 10 ++-------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index b9b657f12c..249647fe03 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -13,15 +13,9 @@ "test-grammar-budget", "test-grammar-tools", "check-release-paths", - "test-exl3-prompt-host", "test-qwen35-draft-frame-host", "test-qwen35-frame-invalidation-host", - "test-qwen35-draft-trees-host", - "test-qwen27-prompt-rows-host", - "test-cluster-loader-host", - "test-gemma4-affine-host", "test-gradient-serving", - "test-qwen-serving-host", ) diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index 1ed48c5462..a37aad907a 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -8,15 +8,9 @@ const exclusions = [_]Exclusion{ .{ .name = "test-grammar-budget", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "test-grammar-tools", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "check-release-paths", .reason = "The release-paths CI job checks the separately built release server" }, - .{ .name = "test-exl3-prompt-host", .reason = "red on main, #2031 (missing b32 initializer, #2094)" }, - .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, + .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (recording fixture leaves seg_fn uninitialized)" }, .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, - .{ .name = "test-qwen35-draft-trees-host", .reason = "red on main, #2031 (draft tree node count now returns an error union)" }, - .{ .name = "test-qwen27-prompt-rows-host", .reason = "red on main, #2031 (over-cap fixture expects InvalidEnvironment)" }, - .{ .name = "test-cluster-loader-host", .reason = "red on main, #2031 (cluster loader fixture lacks canon)" }, - .{ .name = "test-gemma4-affine-host", .reason = "red on main, #2031 (reviewed Metal affine_mm source pin drifted)" }, - .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (gradient source identities drifted)" }, - .{ .name = "test-qwen-serving-host", .reason = "red on main, #2031 (serving source and launch pins drifted)" }, + .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (Flash Next hyper-connection source pin drifted)" }, }; pub fn wire(b: *std.Build, target: std.Build.ResolvedTarget) void { From 7b7e1118081c0bde74ac860ad2e32e8a5b45220a Mon Sep 17 00:00:00 2001 From: Garv Rao <241987901+garvrao80@users.noreply.github.com> Date: Mon, 9 Nov 2026 23:42:32 +0530 Subject: [PATCH 7/7] ci: keep large-state timing commands out of the Linux host gate --- CONTRIBUTING.md | 2 +- tools/zig/host_tests_test.py | 3 +++ zig/build/host_tests.zig | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 154f6e0a97..b2adc009fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,7 +45,7 @@ Native Linux no-GPU CI runs `zig build -Dfixed-cpu test-host --test-timeout 20m` It includes `test` and every configured `test-*` and `check-*` step, including compile-only checks. New named checks join automatically, even when a build module registers them last. The reviewed exclusions in `zig/build/host_tests.zig` cover the optional xgrammar tests, -the separately scheduled `check-release-paths` gate, and temporary failures tracked in #2031. +the separately scheduled `check-release-paths` gate, manual large-state timing commands, and temporary failures tracked in #2031. An empty named check, a stale exclusion, or an alias that brings excluded work back into the aggregate fails it. When a fix lands, remove its temporary exclusion and the matching fixture entry in `tools/zig/host_tests_test.py`. This aggregate is only registered for native Linux; other hosts keep their existing `test` and device steps. diff --git a/tools/zig/host_tests_test.py b/tools/zig/host_tests_test.py index 249647fe03..a728cdc76a 100644 --- a/tools/zig/host_tests_test.py +++ b/tools/zig/host_tests_test.py @@ -13,6 +13,9 @@ "test-grammar-budget", "test-grammar-tools", "check-release-paths", + "test-startup-states-timing", + "test-imprint-ops-timing", + "test-metal-residency-owners-host", "test-qwen35-draft-frame-host", "test-qwen35-frame-invalidation-host", "test-gradient-serving", diff --git a/zig/build/host_tests.zig b/zig/build/host_tests.zig index a37aad907a..ed6e7b1a4e 100644 --- a/zig/build/host_tests.zig +++ b/zig/build/host_tests.zig @@ -8,6 +8,9 @@ const exclusions = [_]Exclusion{ .{ .name = "test-grammar-budget", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "test-grammar-tools", .reason = "Requires the optional xgrammar checkout and -Dxgrammar=DIR" }, .{ .name = "check-release-paths", .reason = "The release-paths CI job checks the separately built release server" }, + .{ .name = "test-startup-states-timing", .reason = "Manual disk startup timing seeds up to 100,000 states" }, + .{ .name = "test-imprint-ops-timing", .reason = "Manual Imprint timing seeds up to 100,000 learned states" }, + .{ .name = "test-metal-residency-owners-host", .reason = "red on main, #2031 (Qwen27 recording fixture leaves Runner.kv unset)" }, .{ .name = "test-qwen35-draft-frame-host", .reason = "red on main, #2031 (recording fixture leaves seg_fn uninitialized)" }, .{ .name = "test-qwen35-frame-invalidation-host", .reason = "red on main, #2031 (same recording fixture as test-qwen35-draft-frame-host)" }, .{ .name = "test-gradient-serving", .reason = "red on main, #2031 (Flash Next hyper-connection source pin drifted)" },