ADR-2828: Every CI build lane spells warnings as errors where praetor's build-warnings gate reads it¶
- Status: Accepted
- Date: 2026-10-09
- Deciders: lusoris
- Tags: ci, build, governance, standards
Context¶
ADR-2170 turned warnings into errors leg by leg through one script, scripts/ci/werror-args.sh, called as $(...), through a step output or from a matrix value. Praetor's build-warnings gate (HISS-10, in the pin 3a766f2d56ad) reads the switch only as a literal on the build command, so ADR-2784 found 47 lanes in 16 workflows it read as ungated and declared each workflow in .config/lint-exceptions.d/HISS-10.toml until RC4 WP14 (#2438).
Measured on the last completed master runs (2026-10-08) and on this branch:
| Lanes | What they were | Measured |
|---|---|---|
| 11 | gated by werror-args.sh, unread by the gate | the gated legs |
| 22 | Meson builds without the switch (golden, DNN, MCP smoke, coverage, coverage GPU, sanitizer matrix, Tidy Changed, Tidy SYCL, Cppcheck, Tidy Metal, CodeQL, nightly TSan and benchmark, fuzz, retrain CLI, Arc parity, the consumer comparison, the Rust-extractor build, Linux Intel LLVM, macOS Clang+Metal) | no compiler warning in the logs that compiled, except four -Wreorder-init-list in integer_vif_metal.mm and float_ssim_metal.mm (macOS) |
| 1 | Windows MSVC+SYCL (icx-cl) | two deprecated CRT calls in test headers (fopen, _open) |
| 5 | CMake builds of the third-party Level Zero loader | none; v1.34.0 builds with -Wall -Werror under gcc 16 |
| 1 | the static pkg-config link smoke (${CC:-cc}) | none with -Wall -Wextra -Werror under gcc 13, 15 and 16 |
| 2 | cgo steps without -Werror | pkg/libvmaf compiles with -Wall -Werror |
| 5 | cargo build, test and run without -D warnings | both workspaces check with RUSTFLAGS=-D warnings --all-features --all-targets |
Decision¶
Spell the switch on every lane the gate reads (maintainer decision Q-316, option a):
- Meson:
-Dwerror=trueonmeson setup, beside$(scripts/ci/werror-args.sh true)(or themsvcstep output), which stays the one place that knows each linker's fatal-warnings switch. On thecmdlegs the literal sits on the first line of the command, because the gate does not read a^continuation. - CMake:
-DCMAKE_COMPILE_WARNING_AS_ERROR=ONon the five Level Zero configures. - Direct compile: the static link smoke names its compiler in the step's
env(ccache gcc-14, checked against the row's) and compiles with-Wall -Wextra -Werror. Linking the LTO archive under those flags surfaced three-Wmaybe-uninitializedsites the library's own links never print:float_vif.candspeed.cignored the result ofvif_get_scaling_method()(validated at init, now checked), andssim.cleft the low-pass kernel'sbnd_constunset (unused byKBND_SYMMETRIC, now 0). No computed value changes. - Go:
CGO_CFLAGS: -O2 -g -Wall -Werroron thego-cijob. - Cargo:
RUSTFLAGS: -D warningson therust-cijob. - Windows MSVC+SYCL:
werror: msvc;_open()inowner_only_file.hbecomes_sopen_s(..., _SH_DENYNO, ...), and everyfopen()icx-cl reported in the tests (master job 113791454832:vmafx_fixture_util.h,conversion_target_model.h,test_compat_conformance_scoring.c,test_vmafx_report.c,vmafx_score_contract.c) goes throughcore/test/test_fopen.h,_fsopen(..., _SH_DENYNO)on Windows, for tests that cannot linkcompat/path_utf8.c. - Metal: the two initialisers follow the struct's declaration order. On macOS
werror-args.shadds-no_warn_duplicate_librariesto the C++ link arguments: Meson's C++ standard-library probe of the Objective-C++ build links with-lc++, which clang++ adds again, and under-Wl,-fatal_warningsld64's duplicate warning stoppedmeson setup("Could not detect either libc++ or libstdc++") on the gated macOS Metal leg of master (run 37839768622) and on the newly gated macOS Clang+Metal leg ofbuild.yml.core/src/metal/meson.buildalready gives the project's own links the switch (ADR-2170). - Meson configure: the FFmpeg Windows MSVC job's configure printed eight pkg-config warnings, "Library target 'vmafx' has 'name_suffix' set. Compilers may not find it from its '-lvmafx' linker flag" (and
name_prefix, and the same forvmaf, for the installed and the-uninstalled.pcfiles), because the static MSVC names of ADR-2752 are set throughname_prefix/name_suffix, which Meson's pkg-config module always reports. Meson's ownnamingscheme=platformdoes not rename static libraries in Meson 1.12.1 (measured with a Windows cross build), socore/src/meson.buildhands the module the flags-L${vmafx_libdir} -lvmafx/-lvmaffor that build, withvmafx_libdirset to${libdir}in the installed files and to the build directory in the uninstalled ones; theLibsa consumer reads are unchanged.check_msvc_library_names.py --meson-logfails a configure log that holds the warning, on the FFmpeg MSVC job and the static MSVC legs. - Analysers:
scripts/ci/write-compile-commands.pydrops-Werrorfrom the database clang-tidy and cppcheck read; the build of those lanes keeps it.
HISS-10.toml is removed; praetorctl audit passes with 50 lanes gated (49, plus the FFmpeg Windows MSVC job that #2642 added) and no exception. T-CI-PRAETOR-HISS10-LANES-2026-10-08 and T-CI-WARNINGS-MSVC-LEGS-2026-10-07 close.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
| Keep the 16 entries until praetor reads a declared wrapper (cordanaLLM/praetor#924) | no workflow change | 36 lanes stay ungated meanwhile; entries renew every 90 days | Q-316 asked for both; this is option (a), #924 is option (c) |
Move the switch out of werror-args.sh (literal only) | no duplicate -Dwerror=true | the linker switch per OS needs a home; ADR-2170's test contract changes | the duplicate is harmless (Meson takes the last value) |
| Replace the five Level Zero builds by one script | HISS-19 | the gate does not read a script, so the lane would pass unread | the gate must see the switch |
Keep -Werror in the analysis database | one flag set | clang-tidy would turn clang's diagnostics on gcc's flags into errors | the database is read, not compiled |
| Gate release and tester image builds too | uniform | a newer compiler would stop a release (ADR-2170) | only the tester bundle's Level Zero build is a lane the gate reads, and it is gated |
Consequences¶
- Positive: a warning in any lane the gate reads fails the pull request that adds it, and the audit proves the switch is present; the exception list is empty.
- Negative: a toolchain or third-party (Level Zero) update that adds a diagnostic fails the lane until it is fixed;
upstream-consumers.ymlbuilds the base commit with-Werror, which a base older than the gate could fail. - Neutral / follow-ups: legs proven only on CI are listed in
docs/development/ci.md; the dev container's third-party build stays outside the gate (T-CI-WARNINGS-NON-MSVC-LEGS-2026-10-07).
References¶
- Q-316: both options; (a) one follow-up pull request that writes the switch literally on every lane next to
werror-args.sh, gates the 36 ungated lanes, fixes the warnings that surface without weakening anything, and removes the HISS-10 entries; (c) a praetor issue asking for a declared wrapper (orchestrator ledger, 2026-10-09). - Q-061: warnings are errors in every language (ADR-2342, RC4 WP14, #2438).
- ADR-2170, ADR-2784; cordanaLLM/praetor#924.