Research-2079: SYCL Clang-Tidy Required Gate Verification and Hardening¶
- Status: Active
- Workstream: ADR-1297, ADR-0623
- Last updated: 2026-09-24
Scope¶
This research digest documents post-promotion verification and hardening of pre-RC1 state item T-SYCL-CLANG-TIDY-DISABLED. Commit 6475fa9ea had already made Tidy SYCL a required, non-advisory CI merge gate under ADR-1297. This follow-up records the audit of live master GitHub Actions runs, reconciles the stale state row, remediates header-pattern coverage gaps, makes non-reporting fail closed, and adds mutation-tested contract infrastructure on one shared aggregator harness.
Context and Reactivation Criteria¶
ADR-0623 (docs/adr/0623-scaffold-audit-p2-half-finished.md) re-enabled the clang-tidy-sycl CI job using scripts/ci/gen-sycl-compile-commands.py (which synthesises compilation database entries for Meson's CUSTOM_COMMAND SYCL translation units) and the scripts/ci/clang-tidy-sycl.sh icpx-aware wrapper. The job was deliberately configured with continue-on-error: true (advisory status) pending at least one green master run confirming that the toolchain synthesis and header include resolution held without false positives.
ADR-1297 (docs/adr/1297-ci-gate-every-reporting-check.md) established the repository-wide merge gate policy: every check reporting on pull requests must be a required context in required-aggregator.yml. Commit 6475fa9ea implemented that policy for this lane: Tidy SYCL (advisory) dropped its suffix, lost continue-on-error: true, and joined the aggregator's required array.
However, state item T-SYCL-CLANG-TIDY-DISABLED remained open in docs/state.md, changed-file detection in lint-and-format.yml omitted .h files, and no dedicated contract test guarded against silent relaxation or workflow decoupling.
Live Master GitHub Actions Audit¶
On 2026-09-24 we re-read the live run and job pages for this bounded sequence of master pushes. The run page supplies the exact head and conclusion; the Tidy SYCL job page supplies each step conclusion. The squash-commit subject supplies the merged PR number.
| Run ID | Exact head | PR | Event | Tidy SYCL result |
|---|---|---|---|---|
| 35914295017 | 5b1bb866f08455b48f34d05401b30b99cfa588b5 | #1529 | push | Job success; wrapper step skipped (no matching SYCL path) |
| 35904645958 | 737430956f2141a81dd9ac4ce0bb52b21b37f21f | #1528 | push | Job success; wrapper step skipped (no matching SYCL path) |
| 35898349474 | b1f22066d46e38305ce589897ff3b3b028025d0f | #1527 | push | Job success; install, compile-database, and wrapper steps all success for the changed SYCL SpEED twins |
| 35868533022 | 961662ba302624f78dec8e8e31966ba78b09d553 | #1524 | push | Job success; wrapper step skipped (no matching SYCL path) |
| 35861745563 | 7f1005915fe16c2f329ae0cf80dd5e590b1e828d | #1516 | push | Job success; wrapper step skipped (no matching SYCL path) |
| 35857035653 | 2718263cb34a900799bbb9c1f295cff18b63b173 | #1523 | push | Job success; install, compile-database, and wrapper steps all success for integer_ms_ssim_sycl.cpp |
| 35839197106 | 301c2b5f04a6af1cfaba0fa4d430ecb6ad5c700f | #1522 | push | Job success; wrapper step skipped (no matching SYCL path) |
| 35833239963 | a6e3faad489d147124784ede58eccc093d36b718 | #1430 | push | Job success; wrapper step skipped (no matching SYCL path) |
Findings:
- Zero Failures in the bounded sample: all eight
Tidy SYCLjobs reportedsuccess. - Two real executions verified: runs 35857035653 and 35898349474 installed the toolchain, generated the compilation database, ran
clang-tidy-sycl.sh, and succeeded. The earlier draft incorrectly labelled 35898349474 as a clean skip. - Name Stability: The check name is stably reported as
Tidy SYCLacross all runs, matching the declaration inrequired-aggregator.yml.
File Pattern Gap Analysis and Remediation¶
In .github/workflows/lint-and-format.yml, the changed-file detection step for clang-tidy-sycl previously matched:
-- 'core/src/sycl/*.cpp' 'core/src/sycl/*.hpp' \
'core/src/feature/sycl/*.cpp' \
'core/src/feature/sycl/*.hpp' \
'core/test/test_sycl*.c' 'core/test/test_sycl*.cpp' \
'core/test/test_integer_cambi_sycl.c'
However, the codebase contains SYCL header files with .h extensions:
core/src/sycl/picture_sycl.hcore/src/feature/sycl/sycl_compat.h
Changes modifying only these .h headers would have resulted in files="" and skipped the job body entirely.
Remediation: Expanded file patterns across pull-request, push, and dispatch triggers in .github/workflows/lint-and-format.yml to include 'core/src/sycl/*.h' and 'core/src/feature/sycl/*.h'. Note that core/include/libvmaf/libvmaf_sycl.h is a public C API header and is already analyzed by the CPU clang-tidy job.
Contract Test Infrastructure¶
To ensure that the required, non-advisory gate is permanent and protected against regression, we implemented scripts/ci/test_sycl_tidy_workflow_contract.py.
The contract test asserts:
lint-and-format.ymldeclares jobclang-tidy-syclwith exactname: Tidy SYCLand# required-aggregator.- No
continue-on-erroror normalized constant-false job guard exists in the job. - Every pull-request, push-fallback, normal-push, and dispatch selection independently tracks all SYCL source and header patterns.
- Execution step uses
scripts/ci/clang-tidy-sycl.shand exits 1 if/tmp/tidy-sycl.failis created. required-aggregator.ymlregisters'Tidy SYCL'in bothrequiredandstrictMustReport; the job has no path filter, so absence is never a legitimate path skip.- Real Node.js execution of the aggregator script proves:
- A
failureconclusion onTidy SYCLblocks the aggregator (Tidy SYCL: failure). - A
successconclusion passes cleanly. - A
skippedor unreported run blocks under the strict-required contract. - Red mutation tests confirm that injecting
continue-on-error: true, renaming to(advisory), omitting the marker comment, using normalized constant-false job guards, dropping either header pattern from any one event branch, or removingTidy SYCLfrom either aggregator array raises an assertion failure. scripts/ci/required_aggregator_harness.pyowns the Node driver shared by the Go and SYCL contract suites, eliminating the HISS-19 duplication that allowed their simulations to drift.
Integration Surfaces¶
The contract is wired into:
- CI:
.github/workflows/rule-enforcement.ymlunderdeep-dive-checklist. - Local hooks:
.pre-commit-config.yaml(test-sycl-tidy-workflow-contract). - Shared execution seam:
scripts/ci/required_aggregator_harness.py, reused by the Go and SYCL workflow contracts. - Strict-set replay contract:
scripts/ci/tests/test_hiss_replay_contract.py, which pinsTidy SYCLas a fail-closed ADR-1297 context. - Documentation:
scripts/ci/AGENTS.md(Workflow coupling table & SYCL custom-command section). - State ledger:
docs/state.md(T-SYCL-CLANG-TIDY-DISABLEDclosed and moved to## Recently closed). - Rebase notes:
docs/rebase-notes.md. - Changelog:
changelog.d/fixed/sycl-clang-tidy-required-gate.mdand syncedCHANGELOG.md.