Skip to content

fix: drive whole tree toward zero warnings and HISS - #1518

Merged
lusoris merged 203 commits into
masterfrom
integration/zero-warning-hiss21
Sep 22, 2026
Merged

lusoris merged 203 commits into
masterfrom
integration/zero-warning-hiss21

Conversation

@lusoris

@lusoris lusoris commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Integration train for the repository-wide zero-warning / zero-HISS cleanup. It makes warning and scan failures observable, removes concrete Python, native, SIMD, GPU, Rust, Go, MCP, and test findings without suppressions, retires .workingdir2 from public contracts, and keeps the README HISS claim mechanically checked.

Status update (2026-09-22). The DO-NOT-MERGE rationale below is discharged. The scanner reported 1,063 findings when this was written; it now reports 286, verified against a baseline re-recorded from a clean clone at the merged tip, with praetorctl audit and the managed README governance block both passing.

Since then this branch has absorbed twelve HISS burn-down slices and eleven bug-fix branches, the pinned governance engine has advanced to f41e74d8f (which stops counting extern "C" blocks and file-scope initialisers as functions, and measures a function's length from its opening brace rather than its signature), and the debt baseline plus the README block's recorded count move with it as one unit.

The release-please PR remains outside this train and must not be merged by this PR.

Known residue, stated rather than hidden: the GPU clang-tidy lanes still need a re-measure; core/src/feature/hip/integer_adm_hip.c carries a pre-existing use-after-free on the OOM path (init_fex_hip frees every buffer and then returns success), preserved verbatim here rather than fixed silently; and ADR-1289 is Proposed pending maintainer sign-off.

no docs needed: no user-visible delta. The Doc-Substance path mapping flags three surfaces here — core/src/feature/(feature_|integer_)*.c, the x86/arm64 SIMD paths and the CUDA feature kernels — because they were touched without a matching docs/metrics/ or docs/backends/cuda/ edit. Every one of those edits is structural: goto cleanup ladders replaced by acyclic unwind helpers and oversized functions split into static helpers in the same translation unit. No metric, option, flag, score or output schema changes, and the CUDA slice is proven bit-identical — all 19 CUDA extractors over 48 frames at --precision max, max |diff| = 0.0. The changes here that DO have a user-visible surface are documented: the engine bump and the SYCL tidy lane in docs/development/ci.md and ADR-1290, and the licence-identifier corrections in the files that carry them.

No Go package, file, command, API, behavior, or CI lane is removed. The diff deletes zero .go files and is net-positive in Go lines.

Type

  • fix — bug fix
  • refactor — no behavior change
  • docs — documentation
  • test — test coverage and gate fixes
  • build / ci — tooling / infra
  • sycl / cuda / simd — backend-specific

Checklist

  • Commits follow Conventional Commits.
  • make format && make lint is green locally — full configured-lint debt remains and blocks readiness.
  • Unit tests pass: meson test -C build — focused and fast suites are green; full final gate remains pending.
  • SIMD/GPU cross-backend final qualification — CUDA execution is pending an unshared device window.
  • New native files carry the required license header; the repository header gate passes.
  • Added ADR fragments and generated indexes pass the freshness gate.

Bug-status hygiene

  • docs/state.md and the branch state ledgers track the affected cleanup work.

Netflix golden-data gate

  • No Netflix golden assertAlmostEqual(...) value changed. An AST comparison across all 17 changed python/test files reports zero semantic assertion deltas.

Cross-backend numerical results

Final train-level cross-backend qualification is pending. Focused CUDA/SYCL/native builds and tests are recorded in the branch commits; no golden values were changed.

Deep-dive deliverables

  • Research digest — the branch includes focused digests under docs/research/, including 2074-hiss-21-replay-evidence.md, 2075-cppcheck-high-signal-noncuda.md, 2076-cuda-adm-signbit-warning.md, 2077-go-duplicate-implementation-cleanup.md, core-hiss-control-flow-cleanup-2026-09-21.md, python-warning-root-causes-2026-09-21.md, and the SYCL cleanup digests.
  • Decision matrix — captured in the accompanying ADRs and research digests; mechanical one-way warning fixes document their invariant directly.
  • AGENTS.md invariant note — relevant package notes are updated across ai/, core/, scripts/, Go packages, and backend subtrees.
  • Reproducer / smoke-test command — commands are listed below.
  • CHANGELOG fragment — focused fragments are present under changelog.d/changed/ and changelog.d/fixed/ for every integrated batch.
  • Rebase note — docs/rebase-notes.md carries the integrated cleanup entries.

Reproducer

praetorctl audit
make lint
meson test -C build --suite=fast
make test-netflix-golden
scripts/git-hooks/pre-push-mkdocs-strict.sh
python3 scripts/ci/ffmpeg_patch_stack.py --refresh --output-dir .workingdir/cache/ffmpeg-patch-stack/hooks

Current verified evidence

  • Exact pushed head: ba098d5f71e63fdd5de0e8e8128184e4f3de1301.
  • Full unskipped pre-push suite passed: formatting, Ruff, Black, ShellCheck, Semgrep, mypy, MkDocs strict, security, governance, and cumulative FFmpeg n9.0.1 patch replay.
  • Current HISS count: 1,063, down from 1,143 at integration start. This is not accepted debt; cleanup continues on this draft.
  • Go diff: 50 changed .go files, +1,969/-1,121 lines, zero deleted Go files.

Known follow-ups

  • Eliminate every remaining real HISS finding, then remove the baseline/on-touch mechanism instead of treating it as a waiver.
  • Land the Praetor scanner correction for structural false positives, install the exact merged binary, and rerun the inventory.
  • Integrate the warning-clean CUDA and Python batches after their complete gates pass.
  • Drive configured clang-tidy/cppcheck to zero across the whole tree; upstream/Netflix origin is not an exemption.
  • Run final full native, Python, Go, Rust, GPU parity, Netflix golden, release, and hosted exact-head gates before making this PR ready.

Breaking changes / migration

None intended. .workingdir is the sole private agent-state root; corpora remain under .corpus. Public docs and gates reject the retired .workingdir2 spelling.

…sing comments

Three defects an adversarial pass over `aa794eee4` found.

`helm lint + template` (helm-chart.yml) still merged red. It triggers on
`pull_request` with `paths: [deploy/helm/**, .github/workflows/helm-chart.yml]`
— the same path-filtered class as `FFmpeg Ubuntu gcc`, `Docker Image Build`,
`Dev Container Build`, `vmafx-sys CI` and `cargo-deny`, all of which that commit
gated under the explicit rationale that ADR-0313 absent-means-skip covers them.
It has four real failing paths and the chart is something people run
`helm install` on; helm-chart.yml's own header records that `helm lint` was
failing on master for an unknown length of time before that workflow existed,
and that the kind+kuttl lane is label-gated so it does not catch a broken chart
on the pull request that breaks it.

The reason it was missed is worth recording, because it is a method defect
rather than an oversight: that pass derived the ungated set from a single pull
request statusCheckRollup. A rollup can only contain workflows whose path
filters that pull request matched, and #1518 touches no `deploy/helm/**` file,
so the lane was invisible to the whole inventory. Re-derived here from the
workflow tree instead — parse every `*.yml`, keep the jobs whose `on:` carries
`pull_request`, and diff their names against `required[]`. That gives 64
pull-request-triggered jobs; `helm lint + template` was the only genuine gap,
the other 17 being matrix parents whose expanded row names are already required,
or the structurally-excluded set ADR-1297 already enumerates.

`scripts/ci/check-aggregator-names.sh` extracted `required[]` by matching
single-quoted literals across the whole array, comments included, so an ordinary
English apostrophe in a comment opened a spurious quoted run. Writing "one pull
request's rollup" above an entry made the checker report a multi-line blob as a
missing required name. It now strips whole-line `//` comments first; a probe
that re-inserts exactly that comment passes.

Also removes copy-paste triplication left by the same commit: the five-line
ADR-1297 paragraph appears three times in docs.yml and three times in build.yml,
and ten consecutive duplicate `# required-aggregator` markers (six in build.yml,
four in libvmaf-build-matrix.yml). The third copy of each paragraph says
"above" where the first two say "below" — the marker they describe is below all
three — which is the tell that an editor re-applied the same insert rather than
three deliberate emphases.

`bash scripts/ci/check-aggregator-names.sh` reports OK across 79 required
checks, each reported by exactly one job;
`python3 -B scripts/ci/test_fail_closed_ci.py` is 7 tests OK; all four touched
workflows parse under `yaml.safe_load`.
…train

Brings the branch level with master after #1507 (the ADM stack train) landed,
which `strict_required_status_checks_policy` requires before #1518 can merge.
Sixteen conflicts, all in files both sides worked for different reasons: #1507
rewrote the integer-ADM kernels for int64 DWT sums at 16 bpc, tiny-frame parity
and AdmBufferHip by pointer (ADR-0759), while this branch removed 49 CUDA gotos,
fixed three HIP init-failure paths that reported success after freeing every
buffer, and ran a whole-tree HISS burn-down. Both sets are kept.

Notable resolutions:

* `core/src/feature/hip/integer_adm_hip.c` — master's side. It had independently
  fixed the same use-after-free: its `init_fex_hip()` releases every tier and
  returns `-ENOMEM` on dictionary failure. The branch's fix for the other two
  paths lives in `ssimulacra2_hip.c`, which master never touched, so it
  survives.
* `core/src/feature/sycl/integer_adm_sycl.cpp` — master's side. Its
  anonymous-namespace refactor removes the very `NOLINTBEGIN(misc-use-anonymous-namespace,
  misc-use-internal-linkage)` the branch had re-cited, and had already removed
  the matching `NOLINTEND`; taking the branch's side would have left an
  unterminated `NOLINTBEGIN`.
* `core/src/feature/cuda/integer_adm/adm_cm.cu` — master's structure with the
  branch's `INT32_MIN` spelling restored per docs/research/2076, which rejected
  the explicit cast. Verified on CUDA 13.4: the bare `1u << 31` raises #68-D
  while the cast and `INT32_MIN` compile silently, and all three emit an
  identical fatbin.
* `core/src/feature/hip/AGENTS.md` — the branch's invariant note named five
  helpers master's rewrite had deleted and one under the wrong name. Rewritten
  against the helpers that exist, every rule kept, all nine names grepped back
  against the source. That is the exact failure ADR-0759's own history records:
  an AGENTS.md asserting a contract the kernels no longer hold.
* `docs/state.md` — union, checked both ways. 560 T- ids; all 552 from the
  branch and all 510 from master are present and nothing appears that was on
  neither side.

`.standards-baseline.json` re-recorded on the merged tree with the engine the
branch pins (`f41e74d8f9a3`, built from that ref and calibrated to reproduce the
branch's pre-merge 283 before use): **286 -> 279**, no `-allow-increase`. Two
findings genuinely arrived with master's code and both were cleared rather than
baselined — `ADM_CM_LINE` in `adm_cm.cu`, which was praetor reading a file-scope
macro invocation as a function signature and measuring the following anonymous
namespace, resolved by writing out the macro's single expansion (fatbin proven
byte-identical); and `i4_adm_cm_device_hip` at 61 LOC, split at a statement
boundary to 48.
`docs/state.md Gate` failed on the row T-DOCS-BUILD-GLOBAL-PAGES-CONCURRENCY-2026-09-22:

    Inserted lines in docs/state.md still carry a placeholder PR/commit
    reference. Per ADR-0334, state.md rows must cite the merged numeric PR
    (e.g. `PR #432`) or commit SHA, not a "this PR" / "this commit" / "TBD"
    placeholder.

The row did cite a concrete commit (`160ddfc3d`) and a concrete run
(35739609377), but wrote "the docs build for this PR" around them, which is the
banned phrase whatever sits next to it — and rightly so: the row outlives the
pull request that added it, and a reader three months from now cannot resolve
"this PR" from the ledger alone. Both occurrences now say PR #1518.
Merge origin/master into integration/zero-warning-hiss21. Eleven paths
conflicted; ten resolved mechanically. The one that mattered was
core/src/interop/pelorus_interop.c, where the two sides did opposite
things:

  master (#1515) bumped PELORUS_VENDOR_SHA 818d844 -> 93bef120 (v0.2.2)
  and re-vendored the mirror.

  this branch (#1518) left the pin at 818d844 and split pel_blob_pack,
  pel_blob_find_section, pel_qp_report_from_blocks and pel_x265_csv_parse
  in the mirror in place, for the HISS-21 burn-down.

ADR-1113 makes core/src/interop/pelorus_*.c a verbatim copy of
libpelorus/src/*.c at PELORUS_VENDOR_SHA; lint and standards fixes for
them belong upstream in VMAFx/pelorus followed by a --update re-vendor,
never in the mirror. The branch is therefore the side in violation, so
this merge takes master on both counts: the bumped pin and the
re-vendored mirror. docs/state.md has tracked this as
T-PELORUS-MIRROR-SOURCE-DRIFT-2026-09-22 and predicted the consequence.

The consequence landed as predicted. Restoring the verbatim mirror
reinstates nine recorded findings (three HISS-04 in pelorus_interop.c,
one HISS-02 and one HISS-04 in pelorus_qp_report_csv.c, four HISS-04 in
the test_pelorus_interop.c fixture), taking the debt total 279 -> 288.

Rather than raise the ratchet with an --allow-increase exception, twelve
real findings are cleared in the fork's own code to absorb them:

  core/src/model.c                   4 HISS-01
    vmaf_model_collection_append's cascading fail/fail_mc/fail_model
    unwind becomes model_collection_new(), which frees what it itself
    allocated on each early return, in the same order (mc->model before
    mc). The out-param is assigned only on success; the historical
    contract that a failed first append leaves the caller's handle NULL
    is kept explicitly.

  core/src/feature/float_adm.c       3 HISS-01 + 1 HISS-04
    init's three `goto fail` unwinds call a shared adm_state_release(),
    which close() now uses too. extract's four per-scale appends and
    eleven debug appends move into adm_append_scale_scores() and
    adm_append_debug_scores() verbatim: same appends, same order, same
    arguments.

  core/src/feature/integer_motion.c  1 HISS-01 + 2 HISS-04
    extract's forward `goto write_score` becomes an if-wrap around the
    SAD block. init's ISA dispatch chain moves into
    motion_select_pipeline() with the guards and their evaluation order
    intact, so the last matching ISA still wins. flush's per-index loop
    body moves into motion_flush_one(), with the loop-carried
    prev_processed threaded through a pointer so the moving-average
    recurrence is unchanged.

Every edited file is taken to zero HISS findings, per ADR-0141. No
arithmetic was rewritten anywhere; only whole statements moved, in the
same order.

Proof of behaviour-neutrality: all three Netflix golden pairs were
scored with --feature float_adm --feature motion --feature adm at
--precision max, before and after, from the same build directory. The
output JSON is byte-identical apart from the fps timing field. The
158-test CPU meson suite passes.

Net: .standards-baseline.json 279 -> 276, recorded with a plain
`praetorctl baseline -record` under the pinned f41e74d8 engine -- no
exception flag, no reason string, no policy carve-out. The README
praetor-managed governance block is reconciled to the new count. The
clang-tidy cpu baseline tightens for the two files that improved
(float_adm.c 5 -> 4, integer_motion.c 11 -> 9; total 742 -> 739), the
host measurement having been calibrated against four untouched files
first.

ssimulacra2.c's single goto was deliberately left alone: clearing it
would have obliged splitting picture_to_linear_rgb (111 LOC) and
create_recursive_gaussian (66 LOC), scalar colour math that four SIMD
ports must stay bit-exact against.

Still outstanding: the four splits want landing upstream in
VMAFx/pelorus, then a --update re-vendor and a pin bump, which would
drop the nine mirror entries from the baseline.

Refs: ADR-1113, ADR-0141, ADR-1298
The `vmaf` Python package could not be built by any setuptools older
than 77.0.1, and nothing in the tree said so.

ADR-1236 changed `python/pyproject.toml`'s `[project].license` from the
table form to the PEP 639 SPDX expression `"BSD-2-Clause-Patent"`.
setuptools learned that form in 77.0.0 (yanked, so 77.0.1 is the first
installable release); every earlier release rejects it with
`configuration error: project.license must be valid exactly by one
definition (2 matches found)` and exits 1 before running any command.
`[build-system].requires` listed a bare `setuptools`, so a PEP 517 build
happened to resolve a new enough backend while every direct `setup.py`
invocation inherited whatever the ambient interpreter had.

Ubuntu 24.04 ships setuptools 68.1.2 in `/usr/lib/python3/dist-packages`
and `pip install --user` leaves it there, which is exactly the Coverage
Gate runner. That lane first ran the Python suite to completion on PR
#1518 (job 106867166071) and reported
`python/test/setup_metadata_test.py::test_setup_metadata_version_matches_package_marker`
as a bare `CalledProcessError`: the helper used
`subprocess.run(check=True, capture_output=True)`, so setuptools' own
diagnosis was captured and then discarded.

Measured, not inferred - `setup.py --version` against `python/`:
setuptools 68.1.2 exits 1, 76.1.0 exits 1, 77.0.1 exits 0 and prints
3.2.1. Replayed end to end in an `ubuntu:24.04` container: stock 68.1.2
fails with the configuration error, and after
`pip install --user 'setuptools>=77.0.1'` the same command prints 3.2.1
from the user site that shadows dist-packages.

The floor is now declared where each consumer will honour it:

- `[build-system].requires` pins `setuptools>=77.0.1`.
- `make cythonize`'s `cythonize-deps` installs the same floor into the
  venv it then runs `setup.py` against, where there is no PEP 517
  isolation to fetch a newer backend on its own.
- The two `tests-and-quality-gates.yml` lanes that run `python/test/`
  against the ambient interpreter install it alongside the requirements.

Reverting to `license = { text = ... }` was rejected: setuptools 77+
deprecates that form with removal announced for 2027-02-18, so it would
trade this failure for a deprecation warning on every build, which is
the opposite of what this branch is for.

`setup_metadata_test.py` gains
`test_build_backend_floor_covers_the_license_metadata_form`, which
asserts the declared specifier admits 77.0.1 and excludes 76.1.0 and
68.1.2 for as long as the SPDX form is in use, and its `setup.py` helper
now raises with the subprocess's stdout and stderr, so the next such
break is one CI read instead of a bisect over setuptools releases.

Verified: 3 passed under setuptools 84.0.0; under a setuptools 68.1.2
venv the version test fails quoting setuptools verbatim. `praetorctl
audit` reports 276 active violations within the 276 baselined limit with
all seven touched files clean, so `.standards-baseline.json` is
unchanged. `pre-commit run --files` clean over every touched path.
core/test/dnn/test_tiny_model_verify.c restored the working directory
with `(void)chdir(cwd_save)`. glibc declares chdir warn_unused_result
under _FORTIFY_SOURCE and a `(void)` cast does not silence GCC's
-Wunused-result, so the release build the Tidy Changed lane configures
emitted the tree's only compiler warning there (job 106867169949,
line 250). The cast also discarded a result the test depends on: every
assertion after it, and every later test in the binary, runs relative to
that directory.

The restore is now checked with mu_assert. Reproduced by compiling the
TU from build-cpu/compile_commands.json with -O2 -D_FORTIFY_SOURCE=2:
one warning before, none after.
ruff 0.16.8 — the version .pre-commit-config.yaml pins — reports
`self.assertTrue(STRICT_CONTEXTS <= strict)` in
scripts/ci/tests/test_hiss_replay_contract.py as SIM300, a Yoda
condition: the constant stands on the left of the comparison. The
ruff-check hook runs with --fix, so in CI it rewrote the file and the
Pre-Commit job failed with 'files were modified by this hook' (job
106867169848). Local ruff 0.16.6 does not flag it, which is why it
landed.

The autofix is applied as ruff computes it. Subset and superset are the
same relation read from either end, so the assertion is unchanged.
Verified against the pinned 0.16.8 binary: SIM300 on the old line, clean
after.
Tidy Changed failed on PR #1518 with a single clang-diagnostic-error
(job 106867169949):

  core/test/test_integer_cambi_sycl.c:28:10: error: 'config.h' file not
  found [clang-diagnostic-error]

The lane's exclusion list already carries the SYCL family as
`^core/test/test_sycl`, and every other SYCL test matches it. This one
does not: it is the only member named test_<feature>_sycl.c rather than
test_sycl_<feature>.c. It is `#if HAVE_SYCL`-gated and meson compiles it
only under -Denable_sycl=true, so the CPU-only build the lane configures
has no compile command for it — build-cpu/compile_commands.json holds
zero entries for the path — and clang-tidy falls back to default flags,
which cannot find the generated config.h. Reproduced locally with
clang-tidy 22.1.8 against the same database. It surfaced now because
50657c9 touched the file for the first time, putting it in the
changed-file set.

Excluded by an exact path rather than a widened prefix, so a future
test_sycl-adjacent name does not inherit the exemption silently. Nothing
goes unmeasured: the file stays bounded by the ADR-1290 `sycl` ratchet
lane, the same posture the CUDA, HIP and eBPF families already have, and
the comment block above the list records why.
The Silent-Revert Guard reported ten undeclared findings for the
d9805a6 merge (job 106867169120). Each was adjudicated separately
against `git show origin/master:<path>` and the merge result; none is a
loss. origin/master is an ancestor of the branch head, so the merged
tree is the head tree and every claim below is a plain two-blob
comparison.

Six are HISS burn-down refactors, ADR-0141:

  core/src/feature/float_adm.c   the `goto fail` unwind moved into
  core/src/model.c               helpers; the "gone" lines stand in
  core/src/feature/integer_motion.c  them, re-indented. For these three
                                 master and the branch's own parent hold
                                 byte-identical blobs, so nothing of the
                                 target's was touched: the edits were
                                 authored inside the merge commit, and
                                 `dropped` subtracts only non-merge
                                 commits, which is why it fires.
  core/src/feature/integer_motion.c (resurrected) the same re-indent,
                                 seen from the other side.
  core/src/feature/cuda/integer_adm/adm_cm.cu  a single-expansion macro
                                 written out, plus INT32_MIN for the
                                 same bits (docs/research/2076).
  core/src/feature/hip/integer_adm_hip.c  region arithmetic lifted into
                                 i4_adm_cm_region_hip; `&x` became
                                 `&r.x`. Master has not touched either
                                 GPU file since the merge base.

Two are the ADR-1290 rename of the per-lane compilation-database hook,
TIDY_RATCHET_PREP_<lane> to TIDY_RATCHET_COMPDB_<lane>: `Makefile` and
its operator documentation in `docs/development/ci.md`, where the
paragraph was rewritten and re-wrapped. Both generators survive under
the new names; the six ci.md lines read as gone because "Without that
step the lane measures the host files only" is now "Without it those
lanes measure the host files only", and so on.

One is a merge-resolution artefact in `.github/workflows/lint-and-format.yml`:
the eBPF exclusion's trailing `|` moved to the end of the two families
7c4cd42 appended, and the pelorus_mirror filter still consumes the
list (ADR-1142 scope rule).

One is `changelog.d/fixed/hip-adm-buffer-by-pointer-reapplied.md`, where
two fragments were written independently for one change and collided on
the filename; the branch's names the four kernels, both commits and the
measured ROCm numbers, so it says everything master's said.

Each entry is keyed to one path and an evidence regex that every line of
its finding matches, per ADR-1291. The guard now exits 0 with all 26
findings declared.
An adversarial pass over `e4e269888` found it had turned `Tidy Changed` green by
removing `core/test/test_integer_cambi_sycl.c` from the gate, on the stated
grounds that the file "stays bounded by the ADR-1290 `sycl` ratchet lane". That
bound does not exist:

    $ grep -rn 'tidy-ratchet.py --lane' .github/workflows/
    lint-and-format.yml:444:  ... --lane cpu --build-dir build
    nightly.yml:66:           ... --lane cpu --build-dir build

Both invocations are `--lane cpu`, the Tidy Ratchet job configures
`-Denable_sycl=false`, and `scripts/ci/tidy-baseline-sycl.json` is a workstation
measurement rather than a CI gate. The other required lane, `Tidy SYCL`, selects
`core/test/test_sycl*.c` — and this file is the one member of the family without
that prefix, which is exactly why it needed its own exclusion line in the first
place. So it fell between the two jobs and was measured by neither.

Naming it in `Tidy SYCL`'s four selection globs closes that, rather than leaving
a file unmeasured. The exclusion in `Tidy Changed` stays — the file genuinely has
no compile command in the CPU-only build and clang-tidy dies on
`'config.h' file not found` — but its comment no longer claims a bound that is
not there.

Also tightens two `silent-revert-allowlist.json` evidence regexes. ADR-1291
makes the regex the bound on a declaration ("an entry written too loosely would
hide work"), and `allowed_by()` declares a finding when every evidence line
matches, so breadth is the whole bound. The two entries written for the
HISS-01 goto removals matched far more than their own findings: measured against
master's blobs, `core/src/model.c` matched 122 of 384 substantive lines and
`core/src/feature/integer_motion.c` 159 of 398. Both are now exact alternations
of the evidence the detector itself produces, derived by importing
`check-silent-revert.py` and replaying `diff_pair` / `branch_intent` rather than
by hand. `model.c` drops to 32/466 (6.9%). `integer_motion.c` only reaches
142/451 (31.5%) and that is structural, not slack: its finding genuinely spans
73 distinct lines, so any regex matching all of them is broad. Narrowing it
further needs a per-line mechanism rather than a regex, which is a change to the
gate rather than to this declaration.

`python3 scripts/ci/check-silent-revert.py` exits 0 with 24 declared and 0
undeclared findings.

Re-applies the `docs.yml` Pages-upload scoping, which was lost: it was an
uncommitted working-tree edit while sibling agents were running in the same
worktree, and one of them restored the file.
Every docs run that actually built documentation was failing, and the failure
mode disguised itself. Measured at job level:

    48300e3  19:29:21 -> 19:39:31  10m10s  cancelled
    d9805a6  18:05:31 -> 18:15:34  10m03s  cancelled
    2487da3  17:58:19 -> 17:58:39     20s  success

`timeout-minutes: 10`, and GitHub reports a timed-out job as `cancelled`. The
run that passed is a dependency bump whose diff touches no docs, so the ADR-1140
impact planner skipped the build -- it never ran mkdocs, so it proves nothing.
In the runs that did, mkdocs itself logged "Documentation built in 562.22
seconds", leaving about 38 s of the 600 s budget for checkout, setup-python,
`pip install -r docs/requirements.txt` and `make docs-fragments-check`. The site
is ~1300 ADRs and grows every time one lands, so the ceiling was going to be
crossed whatever else changed. 25 minutes is about 2.5x the measured build with
room for hosted-runner spread, which the Coverage Gate work measured at up to
2.3x on the same runner class.

This corrects the cause recorded in the previous commit. That one scoped the
Pages artifact upload to deploying runs and attributed the cancellations to an
artifact-name collision between concurrent pull-request builds. The scoping is
still right on its own terms -- only `deploy` consumes the artifact, `deploy`
runs on push to master, and not uploading it gives the build back a minute --
but it is not what was failing, and the comment now says so instead of asserting
a cause that does not hold. The ADR-1294 ref-scoped concurrency group stays
correct and unrelated.

Worth noting why this surfaced now: ADR-1297 made `Docs Site Build` a required
context. It had been timing out and reporting `cancelled` before that, where
nothing was gating on it.
`Coverage Gate` failed its Python suite on one test, twice:

    python/test/setup_metadata_test.py::test_setup_metadata_version_matches_package_marker
    AssertionError: `/usr/bin/python3 setup.py --version` exited 1
      `authors` defined outside of `pyproject.toml` is ignored
      ... setuptools CANNOT consider this value unless `authors` is listed as `dynamic`

`4f0bf1f12` declared a setuptools floor and improved that assertion's output,
which is what turned an opaque `CalledProcessError` into the message above, but
the cause was the metadata split itself. It was recorded at the time as "not a
gate failure today, warning noise on a zero-warning branch". It is a gate
failure: setuptools treats a `[project]` table as authoritative and a key passed
from setup.py that `[project]` neither declares nor lists as `dynamic` aborts the
invocation on the runner's setuptools.

`author` / `author_email` -> `[project].authors`, `url` -> `[project.urls]`,
`entry_points={"console_scripts": ...}` -> `[project.scripts]`. `description` and
`long_description` were already stated by `[project].description` and
`[project].readme`, so the setup.py copies are dropped rather than moved.

What stays in setup.py is only what PEP 621 cannot express: `package_dir`
pointing at the out-of-tree sources in compat/python-vmaf/ (ADR-0700), the
package list under that mapping, `package_data` for the py.typed marker, and the
lazily-built Cython extension. `version=get_version()` stays too, because
`[project].dynamic = ["version"]` is precisely how a dynamic version is supplied.

The wheel entry points were the risk in doing this, so they were checked rather
than assumed: the eight console scripts compare identical name for name and
target for target between the old `entry_points` dict and the new
`[project.scripts]` table.

Verified: `python3 setup.py --version` goes from exit 1 to exit 0 printing
`3.2.1` with no warnings at all, and `pytest python/test/setup_metadata_test.py`
is 3 passed.
…needs

The Coverage Gate still failed `setup_metadata_test` after `4f0bf1f12` declared
the setuptools floor, and after `36e24e877` moved the metadata into `[project]`.
Both were real fixes for real defects; neither was this one. The third cause,
read from the traceback rather than guessed:

    dist._finalize_license_expression()
      _canonicalize_license_expression(license_expr)
    ImportError: Cannot import `packaging.licenses`.
            Setuptools>=77.0.0 requires "packaging>=24.2" to work properly.

ADR-1236 made `[project].license` the PEP 639 SPDX expression
`"BSD-2-Clause-Patent"`. setuptools>=77 canonicalises that through
`packaging.licenses`, a module that first exists in packaging 24.2. The runner
has setuptools>=77 (because `4f0bf1f12` installs it) and an older `packaging`
from `/usr/lib/python3/dist-packages`, so raising the setuptools floor alone
moved the failure one layer down instead of ending it: every `setup.py`
invocation now dies in license canonicalisation before running any command.

Reproduced both ways in a throwaway venv, not inferred:

    setuptools 84.0.0 + packaging 24.0  -> exit 1,
      ImportError: Cannot import `packaging.licenses`
    setuptools 84.0.0 + packaging 26.3  -> exit 0, prints 3.2.1

`packaging>=24.2` now sits beside `setuptools>=77.0.1` in all four places that
floor is declared, because each has a different consumer and none of them sees
the others: `[build-system].requires` for PEP 517 frontends, `make cythonize`'s
`cythonize-deps` for the venv it runs `setup.py` against directly, and the pip
install steps of both the Coverage Gate and Coverage GPU lanes, where
`pip install --user` leaves the distro `packaging` in place exactly as it leaves
the distro setuptools.
@lusoris
lusoris merged commit 6475fa9 into master Sep 22, 2026
90 checks passed
@lusoris
lusoris deleted the integration/zero-warning-hiss21 branch September 22, 2026 23:39
lusoris added a commit that referenced this pull request Sep 22, 2026
Merge `origin/master` (6475fa9, #1518) into the Intel NEO 26.35 branch.
Nine paths conflicted; each was resolved on the merits.

`dev/scripts/fetch-intel-neo.py` -- branch side taken whole. Master's #1518
hunks are a HISS-21 shape cleanup of the pre-branch file: `resolve_and_fetch`
split into `fetch_release` / `select_asset` / `resolve_igc_urls` /
`resolve_packages` / `print_resolution` / `collect_expected_shas` /
`download_and_verify`, black-width reflow, and a `Dict[str, Any]` annotation.
Nothing in those hunks is behavioural. The branch had already rewritten the
same file into the same shape and further: `_resolve_stack`, `_first_asset`,
`_release_assets`, `_print_resolution`, `_parse_checksums`,
`_add_igc_checksums`, `_download_and_verify` and `_write_checksum_audit` are
all under the 60-LOC cap, the module is fully annotated in PEP 604 form, and
none of it exceeds the formatter width. Per resolved hunk, the branch keeps
the behaviour master's split preserved and adds to it: gmmlib still skips
only `.ddeb` while the ICD and level-zero selectors also reject `legacy`
(`_first_asset` `reject=` tuples, identical predicates to `select_asset`);
the checksum asset is still the first name ending `.sum` or containing
`sha256`; IGC debs are still resolved from the assets first and the release
body second; IGC sums are still merged in from the
intel-graphics-compiler release when the compute-runtime `.sum` omits them.
On top of that the branch keeps its own hardening -- HTTPS/host validation,
redirect handling that drops `Authorization` across hosts, bounded metadata
reads, asset-name validation against the URL basename, atomic retrying
downloads that replaced the `curl` subprocess, and removal of a deb whose
checksum fails. Verified clean under black 26.5.1 and ruff.

`scripts/ci/AGENTS.md` -- union. Master's `check_mypy_python_version`
paragraph continues the preceding `check-workflow-versions.py` section and
is placed there; the branch's new `### Dev-container GitHub build secret`
section follows it.

`docs/state.md` -- union, verified both ways: all 807 `T-` ids on
`origin/master` and all 748 on the branch survive, 808 in the merged file.

`docs/adr/by-tag/{build,ci,fork-local,index,security}.md` and `mkdocs.yml`
are generated: one side taken, then regenerated with
`scripts/docs/concat-adr-index.sh`, `generate-adr-by-tag.sh` and
`generate-adr-nav.sh`. `CHANGELOG.md` likewise regenerated from
`changelog.d/`. Their only delta against master is ADR-1271, which is this
branch's.

`.standards-baseline.json` is not re-recorded. praetorctl `f41e74d8`, the
ref `.github/workflows/standards-gate.yml` pins, reports 276 infractions on
untouched `origin/master` -- exactly what master commits -- and 276 with 0
new unbaselined on the merged tree. No file this branch touches carries a
baselined infraction.
lusoris added a commit that referenced this pull request Sep 22, 2026
…ead store

`docs/metrics/ms-ssim.md` advertised `float_ms_ssim_sycl`'s `enable_chroma` as
"yes — fully implemented (3 planes)", and said in prose that "SYCL computes it.
`n_planes` becomes 3 and `_cb` / `_cr` are produced on the GPU". Neither holds
on master.

Measured, not read off the issue — whose quoted line numbers predate #1518 and
no longer match:

    $ git show origin/master:core/src/feature/sycl/integer_ms_ssim_sycl.cpp \
        | grep -n n_planes
      79:    unsigned n_planes;
     412:    s->n_planes = (format == VMAF_PIX_FMT_YUV400P || !s->enable_chroma) ? 1U : 3U;

Two occurrences in the whole translation unit: the struct field and the one
assignment. Nothing reads it, so the kernel takes plane 0 whatever the option
says. The twin also advertises only `float_ms_ssim` and `float_ms_ssim_sycl` in
`provided_features`, so a model asking for `float_ms_ssim_cb` / `_cr` gets them
from the CPU twin by name. The score is correct; the chroma planes are not
GPU-accelerated — which is exactly the HIP row's wording, one line below.

The doc now says that. The underlying dead store is NOT fixed here and is
tracked as T-SYCL-MS-SSIM-CHROMA-DEAD-STORE-2026-09-23: either wire `n_planes`
through the kernel so the option does what it claims, or drop the field and
reject `enable_chroma` outright the way the CUDA twin does. A
computed-and-ignored option is what produced the false claim in the first place,
so closing the doc without tracking the cause would invite it back.

Closes #1519.
lusoris pushed a commit that referenced this pull request Sep 23, 2026
…10 (#1468)

Updates the dev container's Intel NEO compute runtime to `26.35.39758.10`, with
gmmlib 22.10.0 and IGC 2.41.5 derived from Intel's release metadata and every
package verified against the published SHA-256 set.

The same branch closes the fetcher's fail-open and credential-transport
defects. `dev/scripts/fetch-intel-neo.py` keeps GitHub credentials on
`api.github.com` and strips `Authorization` across a redirect, refuses
non-HTTPS or non-GitHub targets, bounds metadata reads, validates each asset
name against its own URL basename, downloads atomically with retries instead
of shelling out to `curl`, and removes a deb whose checksum or package
validation fails. Optional GitHub authentication now travels as an ephemeral
BuildKit secret across raw Docker, Compose, and CI rather than
`ARG GITHUB_TOKEN`; anonymous builds still work, and
`scripts/ci/check-dev-container-build-secret.py` plus native Docker/Compose
`--check` make a secret-in-ARG regression blocking. ADR-1271,
Research-2070, `T-DEV-CONTAINER-GITHUB-TOKEN-BUILD-ARG-2026-09-20`.

Reconciliation with master
--------------------------

The branch predated #1518, whose HISS-21 sweep had reformatted and split the
old `fetch-intel-neo.py`. Reconciling the two by merge produced a correct tree
but an invisible one: the merge discarded #1518's version of that file without
any hunk in the PR diff showing it, and `Silent-Revert Guard` reported it as
91 dropped lines. Per `docs/development/silent-revert-gate.md` the
PR-description declaration is reserved for a revert that is the point of the
pull request, not a reversal riding along inside a larger branch, so the
branch was rebased onto master instead — the gate's own first remedy. The
replacement is now visible in `fix(dev): harden Intel NEO release downloads`,
and the guard is clean.

No behaviour from #1518 was lost. Its hunks in that file were structural:
`resolve_and_fetch` split into helpers, a black-width reflow, and one added
annotation. The branch had already rewritten the same module into the same
shape and further — `_resolve_stack`, `_release_assets`, `_first_asset`,
`_parse_checksums`, `_add_igc_checksums`, `_download_and_verify`,
`_write_checksum_audit`, all under the 60-LOC cap and fully annotated — and
its 14-test suite pins those names, where #1518's helpers had no test at all.
Every selection predicate survives unchanged: gmmlib still rejects only
`.ddeb`, the ICD and level-zero selectors also reject `legacy`, the checksum
asset is still the first name ending `.sum` or containing `sha256`, IGC debs
still resolve from the assets first and the release body second, and IGC sums
are still merged in from intel-graphics-compiler when compute-runtime's `.sum`
omits them.

`docs/state.md` was union-merged and checked both directions: all 807 `T-` ids
on master and all 748 on the branch survive, 808 in the result. The generated
surfaces — `docs/adr/by-tag/`, the mkdocs ADR nav, `docs/adr/README.md`,
`CHANGELOG.md` — were regenerated rather than hand-resolved.

`.standards-baseline.json` is unchanged. praetorctl `f41e74d8`, the ref
`standards-gate.yml` pins, reports 276 infractions on untouched master and 276
with zero new unbaselined here.

Verification
------------

All 72 reporting checks pass on `eb66ec76f`, zero failures, 10 structurally
skipped; `Required Checks Aggregator` success; branch level with master.
Locally: `check-silent-revert.py` clean, `praetorctl audit` /
`hiss coverage --verify` / `dedupe scan` green, black and ruff clean on the
resolver, 14 resolver tests and 6 build-secret mutation tests pass.

Merged with admin bypass because the repository has a single collaborator who
cannot self-approve (ADR-1252).
lusoris added a commit that referenced this pull request Sep 23, 2026
Master's zero-warning sweep (#1518) reworked files this branch also
rewrote. Neither side is wholly right, so each is resolved on its own
terms rather than by picking a side.

test_lint_configured.py — master's version is kept. It carries fixtures
and a test this branch never had (the model-fixture install, the
CPPCHECK_FILESDIR stub, and clang-tidy warning promotion), and taking the
branch's file would have dropped them. The branch's contribution, routing
the fixture's own command runs through the bounded wrapper, is ported onto
it instead, and the Make sandbox now stages scripts/lib/safe_subprocess.py
so the copied driver can import it.

test_cppcheck_posix_model.py — `import subprocess` comes back. This branch
moved the test's own runs onto the wrapper and dropped the import with
them, but master's new case mocks write_cppcheck_posix_model.py's
subprocess.run and builds a CompletedProcess for it. That module is
outside this branch's adoption set, so the mock target is still subprocess.

test_agent_eligibility_precheck.py — the tracker raises CommandFailed now
rather than CalledProcessError, so the mock's side_effect follows. The
contract it feeds is unchanged: a gh query that could not run still blocks
dispatch. The branch's end-to-end CLI harness is kept and re-pointed at
that same contract; it previously asserted the opposite, which would have
turned two fail-closed dispatch guards into fail-open ones.

hw_encoder_corpus.py — the usage example moves off .workingdir2/, retired
while this branch was open, onto .corpus/ as master spells it.
lusoris added a commit that referenced this pull request Sep 23, 2026
Master's zero-warning sweep (#1518) reworked files this branch also
rewrote. Neither side is wholly right, so each is resolved on its own
terms rather than by picking a side.

test_lint_configured.py — master's version is kept. It carries fixtures
and a test this branch never had (the model-fixture install, the
CPPCHECK_FILESDIR stub, and clang-tidy warning promotion), and taking the
branch's file would have dropped them. The branch's contribution, routing
the fixture's own command runs through the bounded wrapper, is ported onto
it instead, and the Make sandbox now stages scripts/lib/safe_subprocess.py
so the copied driver can import it.

test_cppcheck_posix_model.py — `import subprocess` comes back. This branch
moved the test's own runs onto the wrapper and dropped the import with
them, but master's new case mocks write_cppcheck_posix_model.py's
subprocess.run and builds a CompletedProcess for it. That module is
outside this branch's adoption set, so the mock target is still subprocess.

test_agent_eligibility_precheck.py — the tracker raises CommandFailed now
rather than CalledProcessError, so the mock's side_effect follows. The
contract it feeds is unchanged: a gh query that could not run still blocks
dispatch. The branch's end-to-end CLI harness is kept and re-pointed at
that same contract; it previously asserted the opposite, which would have
turned two fail-closed dispatch guards into fail-open ones.

hw_encoder_corpus.py — the usage example moves off .workingdir2/, retired
while this branch was open, onto .corpus/ as master spells it.
lusoris added a commit that referenced this pull request Sep 23, 2026
Three findings from continuing to diff the ledger against master.

ADR links. 28 `adr/NNNN-slug.md` links in docs/state.md resolved to no file.
ADRs are cited by number -- the link text is `[ADR-NNNN]` -- but the slug is
part of the path, so an ADR rename silently breaks every link written against
the old one. ADR-0278 was linked as 0278-nolint-citation-closeout.md where the
file is 0278-t7-5-nolint-sweep.md; ADR-0214 and ADR-1142 were each linked under
several slugs, some real and some not. Repaired from the number, which is the
stable identifier, so the target follows the rename by construction. One
citation is different in kind: ADR-0846 has no file at all -- the tree jumps
0845 to 0848 -- so it is rendered as plain text with that stated, rather than
pointed at a 404. The same drift affects 73 links across 43 other files under
docs/ and is filed as T-DOCS-ADR-LINK-SLUG-DRIFT-2026-09-23 rather than widened
into this change; mkdocs --strict does not catch any of them.

T-CI-MYPY-PYTHON-VERSION-STALE-2026-09-19 closed. Its claim -- mypy pinned to
3.10 against a >=3.14 floor -- is no longer true: PR #1518 raised it, and
pyproject.toml now carries python_version = "3.14" with a comment binding it to
requires-python. Checked rather than assumed that the residual is a different
defect: mypy still stops before semantic analysis here, but now on module
resolution (163 errors in 102 files, all duplicate-module or missing
__init__.py), which T-CI-MYPY-JOB-CHECKS-NO-FILES-2026-09-21 already tracks and
the Makefile documents inline.

T-SPDX-INVALID-IDENTIFIER-2026-09-16 re-measured. The row states a residual of
92 files carrying the non-existent BSD-3-Clause-Plus-Patent identifier; master
has 66, and the single informal `BSD+Patent` occurrence it also names is gone.
Numbers corrected; the row stays open.
lusoris added a commit that referenced this pull request Sep 23, 2026
An ADR link carries the decision's identity twice, as a number and as a slug,
and either half can rot alone. 98 links under docs/ resolved to no file;
mkdocs --strict catches none of them, because it validates the nav and page
rendering, not the target of an inline relative link.

The two halves rot for different reasons, so they need different repairs:

  63 stale slug   the ADR was renamed. The number still names the right
                  decision, so the link is repaired from the number.

  35 wrong number an ADR collision sweep renumbered the file. The slug still
                  names the right decision, so the link is repaired from the
                  slug -- and so is the [ADR-NNNN] text, which carries the
                  wrong number too.

Root cause of the second group, read out of the history rather than guessed:
af227b0 (PR #310, 2026-05-03) and fb14bc3 (PR #752, 2026-05-10) were
collision sweeps for duplicate-numbered ADRs. The second renamed 50 files,
moving 0241-vmaf-tiny-v3-mlp-medium.md to 0389-vmaf-tiny-v3-mlp-medium.md and
27 others into the 0388-0415 band. Each sweep moved the file and its index
fragment and left every inbound citation on the old number.

Slug-before-number is the whole design, and it was got wrong first. Repairing
all 98 from the number was tried, and an independent two-pass review of the
result confirmed 39 sites where that silently repointed a citation at an
unrelated decision: [ADR-0241] in a tiny-AI evaluation digest became a link to
the HIP PSNR kernel-template ADR. Those links resolve, so they read as
authoritative and nothing complains afterwards -- strictly worse than the dead
link they replaced. The review also recovered the two sweep commits above,
which is what turned a plausible heuristic into a verified one: the slug is
the half those sweeps preserved.

One citation resolves by neither half. ADR-0846 is a number the tree skips
entirely, 0845 -> 0848, and no ADR carries the cpp23-wave8 slug either, so it
is now plain text rather than a link to a 404.

The gate is scripts/ci/check-adr-links.py, wired as the check-adr-links
pre-commit hook on any docs/ change. It reports rather than rewrites unless
asked, refuses to guess when neither half resolves or the halves disagree, and
carries 16 positive/negative/boundary cases (HISS-15) including one that
proves slug beats number when both could resolve. Documented in
docs/development/adr-workflow.md.

Deliberately out of scope: a citation whose number and slug agree and are both
the wrong decision. That needs review, not a parser --
T-STALE-ADR-CITATIONS-2026-09-16.

Also in this change, from the same pass over the ledger:
T-CI-MYPY-PYTHON-VERSION-STALE-2026-09-19 is closed (PR #1518 raised the pin
to 3.14; the residual is module resolution, which
T-CI-MYPY-JOB-CHECKS-NO-FILES-2026-09-21 already tracks), and
T-SPDX-INVALID-IDENTIFIER-2026-09-16's residual is re-measured from 92 to 66
with its BSD+Patent occurrence now gone.
lusoris added a commit that referenced this pull request Sep 25, 2026
…ment moot torch filters (BUG-048 A12)

Diagnose and resolve BUG-048 item A12 silent revert from commit 384d97d
over commit 993c0ef (#1559) across three areas:

1. Restore pythonpath = ["src"] in mcp-server/vmaf-mcp/pyproject.toml
   under [tool.pytest.ini_options], allowing pytest to discover vmaf_mcp
   without requiring an editable install. Add regression tests in
   mcp-server/vmaf-mcp/tests/test_pytest_pythonpath.py and
   scripts/ci/tests/test_pytest_pythonpath.py.
2. Restore _binary_supports_backend_flag() in
   tools/vmaf-tune/tests/test_adr_0543_backend_enforcement.py and wire it
   into _resolve_vmaf_binary(), preventing false test failures when a
   pre-fork legacy /usr/local/bin/vmaf binary on PATH lacks --backend.
   Update _vmaf_c_source() to inspect core/tools/vmaf.cpp (ADR-0700 rename)
   and add unit tests for probe and resolver behavior.
3. Verify PyTorch 2.10 deprecation filters are moot: PR #1518 (commit
   6475fa9, T-TINYAI-TORCH-214-WARNINGS-2026-09-22) already eliminated
   underlying warnings by migrating torch.onnx.export to dynamic_shapes under
   the repo-wide filterwarnings = ["error"] policy. Retaining zero-warning
   authority without re-introducing obsolete suppressions.

Update docs/rebase-notes.md, CHANGELOG.md, changelog.d fragment, and
docs/state.md (T-TEST-HARDENING-A12-SILENT-REVERT-2026-09-24). Keep BUG-048
open in .workingdir/BUGS.md while noting A12 completion.
lusoris added a commit that referenced this pull request Oct 4, 2026
…ils (#1982)

* fix(dev): exit non-zero again when a hardware-corpus quality point fails

scripts/dev/hw_encoder_corpus.py exited 0 when an encode, decode or
score failed or a quality point produced no canonical-6 row, so a failed
run looked like a complete corpus. #1518 added the non-zero exit,
main(argv) and its test; #1509, merged after it from an older base,
rewrote main() for executable resolution and dropped both. No CI job ran
the test, which failed every case.

main(argv) now returns 1 when any point fails and keeps the rows of the
points that succeeded. encode_hw is split into helpers (HISS-04 baseline
445 to 444) and builds the same commands. The test stubs ffmpeg and the
vmaf binary as executables and gains a one-failed-point and a
non-executable-binary control.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants