coverage-gap stage 2: utils/preflight — run CI's gates locally#3102
Merged
Conversation
One command, two tiers. Fast (default, ~7s): formatter --verify on tracked .das (mirrors the pre-push hook), lint on changed .das, and a clang syntax-only pass on changed C++ — chunked across cores via utils/common/parallel_workers. --full adds dasgen freshness, the CI-only-das compile sweep (ci_only_das.txt: dasOpenGL today), the six doc.yml gates run individually (das2rst, stub grep, Uncategorized, untracked RST, sphinx latex+html with the doctree cache deleted first), ctest -L small (--no-tests=error so an unbuilt target can't 0-tests- pass), the interp/JIT/AOT suites, and the sequence smoke (with $BIN injected for multi-config layouts). --only/--skip select subsets; --list-gates shows the menu; exit 1 on any FAIL. Cross-platform per COVERAGE_GAP.md stage 2: every subprocess goes through popen_argv (no shell, no quoting trap, stderr merged); the syntax pass is clang-cl /Zs on Windows and clang -fsyntax-only elsewhere; daslang/build-dir discovery handles multi-config and single-config layouts; a missing host tool or module-disabled binary reports SKIP with an install/rebuild hint, never a silent pass. Build gates triage LNK1104: a foreign daslang process locking bin outputs is the make_pr §3 trap (FAIL + hint); a DLL-flavor daslang pinning its own libDaScriptDyn*.dll — where preflight's host blocks the relink by construction — is SKIP with a build-from-plain-shell-once hint. Windows clang discovery prefers the VS-bundled clang-cl (via vswhere) — the binary CI's ClangCL toolset uses. Proven necessary: standalone LLVM 22 rejects vecmath volatile-union passing that VS clang 19 (and CI) accept. Fallbacks: PATH, then the clang-cl the dasLLVM prebuilt package ships next to LLVM.dll (/Zs needs no linker). Gate verification on this repo: fast tier green end-to-end; FAIL paths proven live (lint caught 11 real warnings in this tool's first draft; an injected bit-field reference bind — the exact tests-cpp incident class from #3095 — flagged by cpp-syntax in 1.1s); dasgen, ci-das (11 dasOpenGL files), all six docs gates, tests-cpp, and sequence exercised. ci_only_das.txt deliberately excludes examples/games/sequence: its requires resolve against a gitignored daspkg install that only the smoke script refreshes — a stale copy produced phantom errors against a green master. The sequence smoke machinery runs end-to-end locally (fresh install, release, artifact checks) up to a bundle-exe loader failure that reproduces without preflight — recorded with triage evidence in COVERAGE_GAP.md's new follow-ups section, alongside the .das_package-needs-clean-install question and a binary-staleness-warning idea. Also fixed in place (probe-verified): skills/filesystem.md claimed optional-returning temp_directory()/create_temp_* forms that do not exist — the real surface is error-out-param + _result variants. skills/preflight.md + skills/make_pr.md gain the tool pointer; the manual mirror tables remain the per-step reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new utils/preflight utility to run (most of) the repo’s CI “gates” locally, aligning local developer workflows with CI enforcement and documenting the mapping in the existing skills/preflight.md process docs.
Changes:
- Introduces
utils/preflight/main.dasimplementing fast/full tiers plus gate selection (--list-gates,--only,--skip). - Adds
utils/preflight/ci_only_das.txtto define the in-repo-only.dassurface compiled by theci-dasgate. - Updates process/docs to reference the new one-command workflow and correct filesystem temp-dir API usage docs.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/preflight/README.md | Documents how to run the new preflight tool and its tiers/options. |
| utils/preflight/main.das | Implements the preflight gate runner (format/lint/cpp-syntax + full tier gates). |
| utils/preflight/ci_only_das.txt | Defines CI-only .das compile sweep inputs and module-based skip policy. |
| skills/preflight.md | Updates the lane↔mirror reference to point to the automated utils/preflight tool. |
| skills/make_pr.md | Adds a “shortcut” pointing to utils/preflight while preserving the checklist authority. |
| skills/filesystem.md | Fixes temp directory/file API documentation to match actual signatures/behavior. |
| COVERAGE_GAP.md | Records Stage 2 follow-ups discovered while building preflight. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…caping The "no shell" claim in the header and README now names its one exception (the sequence gate runs CI's own smoke scripts under pwsh/bash by design), and the Windows -Command string escapes embedded single quotes in bin_dir/cwd by doubling. Follow-up note updated with a stronger data point: a fully fresh one-shot rebuild still loads 0xC0000139, ruling out artifact staleness. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gate timing kept t0 as double(ref_time_ticks()) and cast back to int64 for get_time_usec — lossy past 2^53 ticks, and "now_seconds" was a misnomer for raw ticks anyway. t0 is now int64 ticks end-to-end; seconds_since(int64) is the only conversion point. docs/untracked treated any empty `git ls-files` output as PASS, even when git itself failed — now a non-zero rc is FAIL with the git output surfaced, matching the tool's no-silent-pass rule. Verified: fast tier green; --only docs all six gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rning Persist per-gate wall times locally; warn when a gate runs far off its baseline (~10% = noise, ~2x = regression signal). Diff-scaled gates need per-file normalization or exclusion from the baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…is SKIP tests-jit: an unwritable probe file now SKIPs with the real reason instead of falling through to the misleading no-dasLLVM hint; the probe failure detail points at the attached output first. tests-aot: the root CMakeLists gates tests/aot out on DAS_AOT_EXAMPLES_DISABLED and 32-bit Windows — an unknown test_aot target (MSB1009 / unknown target / No rule to make target, probe- verified on MSBuild) is now SKIP, not FAIL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uard The system temp dir is shared across checkouts, so the fixed preflight_fmt_list.txt / preflight_jit_probe.das names let concurrent preflights clobber each other — both now go through unique_temp_path (ref_time_ticks suffix). The docs gate deleted doc/sphinx-build without checking the outcome; a cache that survives deletion (locked files) would make the sphinx gates an untrustworthy PASS. Now stat() confirms the dir is gone, and if not both sphinx gates SKIP with a remove-and-re-run hint — SKIP rather than FAIL per the gate taxonomy: a local environment obstacle, not something CI would be red on. Verified: fast tier green (lint caught a dropped reserve in the new skip helper first); --only docs all six gates green through the new guard path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xvfb-run is a wrapper script; --version is unrecognized. WSL probe on Ubuntu 24.04 showed it ACCIDENTALLY exits 0 anyway (prints the unrecognized-option error and proceeds), so the old probe worked there — but other Debian-family versions exit non-zero on unknown options, which would wrongly SKIP the sequence gate on headless linux with xvfb installed. tool_available gains a probe-flag overload; xvfb-run is probed with its documented -h (exit 0 verified in the CI-mirror distro). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Headers-only changes: the SKIP note now says plainly that this gate did NOT validate them and what does (compile their includers via cmake --build, or CI's clang lanes) — not the old passive "validated in full builds". Deliberately NOT pointing at --full as suggested: the full tier doesn't guarantee a C++ compile either, that would re-overclaim. Out-of-scope C++: dropped "covered by full clang-cl build" — preflight runs no clang-cl build gate; it's CI's clang-cl lane that compiles module/util TUs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 2 of
COVERAGE_GAP.md(#3097 plan, #3098 process docs). One command, two tiers:Cross-platform by construction (the stage-2 requirement)
popen_argv— no shell anywhere, no quoting trap, stderr merged into the capture.clang-cl /Zson Windows,clang -fsyntax-onlyon mac/Linux; parallel via the existingutils/common/parallel_workersrail (files chunked, one clang per worker).ctestgets--build-configonly when the generator is multi-config; the sequence smoke gets$BINinjected for multi-config layouts.SKIPwith the install/rebuild hint, never a silent pass.ctestruns with--no-tests=errorso an unbuilt tests-cpp-small can't 0-tests-pass.Verified live on this repo, including the failure paths
cpp-syntaxin 1.1s./Zsneeds no linker).libDaScriptDyn*.dll(preflight's host blocks the relink by construction — CI's static daslang doesn't have this) → SKIP with a build-once-from-plain-shell hint.Scope decisions + follow-ups (recorded in COVERAGE_GAP.md, per review)
ci_only_das.txtcovers in-repo-only surfaces (dasOpenGL).examples/games/sequenceis excluded: its requires resolve against a gitignored daspkg install that only the smoke script refreshes — a stale local copy produced phantom compile errors against a green master. New follow-ups section captures the.das_package-needs-clean-install question (leaning: separate CI job, preflight stays read-only — discussable), the bundle-exe loader failures (uses_sqlitectest 0xC0000135 + sequence bundle 0xC0000139, with triage: trivial-exe+ colocated DLLs runs clean,.jitted_scriptsnot the cause), and a binary-staleness warning idea.examples/games/sequence/modules); the smoke now does a genuinely fresh install — verified, full daspkg install → release → artifact checks pass up to the pre-existing bundle-exe loader issue.Also fixed in place (probe-verified):
skills/filesystem.mdclaimed optional-returningtemp_directory() ?? ""/ short-argcreate_temp_*forms that don't exist — real surface is error-out-param +_resultvariants.🤖 Generated with Claude Code