ADR-1315: Drive libvmaf public C API Doxygen warnings to zero and fail closed¶
- Status: Accepted
- Date: 2026-09-25
- Deciders: lusoris
- Tags:
docs,ci,api,public-surface,doxygen
Context¶
ADR-0953 created core/doc/Doxyfile.public-api and the .github/workflows/doxygen-public-api.yml CI workflow to establish a clean documentation baseline for the public C headers under core/include/libvmaf/. While ADR-1297 promoted the Doxygen Public API workflow to a required status check in required-aggregator.yml, the check was configured with DOXYGEN_WARNING_CEILING: "228" rather than failing closed, and WARN_AS_ERROR remained disabled in the Doxyfile.
On 2026-09-22, state item T-DOXYGEN-PUBLIC-API-WARNINGS-REGRESSED-2026-09-22 recorded that the public API had accumulated 228 warning lines in build/doxygen-public-api/warnings.log. A complete inventory and classification of the 228 warnings revealed three underlying causes:
- Vendored Pelorus interop mirror (159 warnings):
core/include/libvmaf/pelorus/(interop.h,denoise.h,deband.h) was vendored in ADR-1113 as a byte-identical read-only mirror of externalVMAFx/pelorus.scripts/sync-pelorus-interop.shstrictly enforces zero git tree drift against the upstream tag. Furthermore, these headers are internal plugin interop definitions and are not installed bycore/include/libvmaf/meson.build. Modifying them locally violates tree sync parity, while leaving them in scope produced 17 undocumented compounds and 142 undocumented struct members. - Syntax and command mismatches (47 warnings):
@fieldtags in struct doc comments (libvmaf.h,libvmaf_cuda.h,model.h) are not recognized by Doxygen (which requires inline/**< ... */), causing the members to be flagged as undocumented.@thread-safetyannotations indnn.handpicture_v2.h(headers containing@filedirectives) triggeredwarning: Found unknown command '@thread'.- Multi-variable member declarations (e.g.
unsigned w, h;inlibvmaf.h,libvmaf_cuda.h,libvmaf_sycl.h,picture_v2.h, andmodel.h) attach inline comments only to the final symbol, leaving preceding symbols undocumented. - Cross-symbol
@reflinks in struct doc comments cannot be resolved across translation units by Doxygen from struct scope, emitting unresolvable reference warnings. - Missing public struct field documentation (22 warnings):
- All 11 members of
VmafPicture2inpicture_v2.h(ADR-0928) lacked member documentation. - Anonymous nested sub-struct variables (
pic_paramsinlibvmaf.h,libvmaf_cuda.h,libvmaf_sycl.h) lacked doc comments on the variable itself. - Nested confidence-interval and bootstrap score members (
ci,p95,bootstrapinmodel.h) were undocumented.
Decision¶
We will eliminate all 228 public-API Doxygen warnings, enforce a zero-warning contract at both the Doxyfile and workflow levels, and guard the contract with executable tests:
- Scope Doxyfile.public-api to installed public headers: Add
*/pelorus/*toEXCLUDE_PATTERNSincore/doc/Doxyfile.public-api. Pelorus headers are external vendored mirrors not installed by meson. - Remediate all public C headers:
- Split all multi-variable member declarations into individual single-variable declarations with dedicated
/**< ... */comments. - Remove deprecated
@fielddoc blocks and replace them with inline/**< ... */comments. - Document all nested sub-struct instances and
VmafPicture2members. - Convert struct-scope
@reflinks to backtick literals (`...`) per ADR-0953. - Standardize all
@thread-safetyannotations acrosscore/include/libvmaf/*.hto@note Thread safety: .... - Fail closed at zero warnings:
- Set
WARN_AS_ERROR = YESincore/doc/Doxyfile.public-api. - Set
DOXYGEN_WARNING_CEILING: "0"in.github/workflows/doxygen-public-api.yml. - Source-level regression guards: Add
PublicHeaderDoxygenContractTesttocore/test/test_gpu_public_header_docs.py(in meson'sfastsuite) to assert no@fieldor@threadtags return, ensure the Doxyfile and workflow keepWARN_AS_ERROR = YESand ceiling 0, and run Doxygen to verify zero warnings whenever the binary is present.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
| Zero warnings, fail-closed, and fast-suite regression test (chosen) | Eliminates all warnings; prevents regression at developer and CI time; respects vendored mirror boundary | Requires touching public header comments and splitting multi-declarations | Restores intended ADR-0953 / ADR-1297 posture without weakening docs |
| Keep warning ceiling at 228 | Zero code changes | Allows future documentation regressions to accumulate silently; masks genuine bugs | Violates fail-closed quality policy |
Modify pelorus/*.h in-tree | Documents pelorus structs | Breaks scripts/sync-pelorus-interop.sh and byte-parity with upstream pelorus repo | Pelorus headers are vendored read-only mirrors not installed by libvmaf |
Enable EXTRACT_ALL = YES | Hides undocumented member warnings | Masks missing documentation behind empty stubs | Weakens public API documentation rigor |
Consequences¶
- Positive:
doxygen core/doc/Doxyfile.public-apiruns with 0 warnings andWARN_AS_ERROR = YES.- CI workflow
doxygen-public-api.ymlfails closed on any warning (DOXYGEN_WARNING_CEILING: "0"). - Fast-suite test
core/test/test_gpu_public_header_docs.pycatches syntax regressions before push. - Vendored pelorus mirror remains byte-identical to upstream.
- Negative:
- Developers adding new public C symbols or structs must provide complete Doxygen comments or the build fails.
- Neutral / follow-ups:
- Closes state item
T-DOXYGEN-PUBLIC-API-WARNINGS-REGRESSED-2026-09-22.