Skip to content

chore(deps): Update archlinux:latest Docker digest to 40ec92a - #4

Merged
lusoris merged 1 commit into
masterfrom
renovate/archlinux-latest
May 28, 2026
Merged

lusoris merged 1 commit into
masterfrom
renovate/archlinux-latest

Conversation

@renovate

@renovate renovate Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
archlinux final digest 1047e6e → 40ec92a

Configuration

📅 Schedule: (in timezone Europe/Vienna)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot requested a review from lusoris as a code owner May 28, 2026 10:53
@lusoris
lusoris merged commit 4539664 into master May 28, 2026
25 of 57 checks passed
@lusoris
lusoris deleted the renovate/archlinux-latest branch May 28, 2026 12:02
lusoris added a commit that referenced this pull request May 28, 2026
… v0.8 (#35)

Closes the Netflix backlog gap identified in Research-0732 item #4:
the fork's Python harness had `CambiFeatureExtractor.VERSION = '0.5'`
while upstream Netflix is at '0.8'. The version increment adds the
resolution-comparison validation rule + minor option-default updates.

C `cambi.c` extractor is NOT touched; this is a Python compat-layer
sync only. Netflix CPU golden assertions don't use CAMBI.

Per Research-0732 audit; references ADR-0709 (Phase 4b umbrella).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 6, 2026
…rpus expansion (ADR-0882) (#716)

* feat(fuzz): add fuzz_json_model + fuzz_dnn_sidecar harnesses (ADR-0882)

Closes deferred targets #3 (fuzz_model_load) and #4 (fuzz_sidecar) from
Research-0083 surface survey. Each harness binds a public parser entry
point (vmaf_read_json_model_from_buffer + collection variant for the SVM
model JSON parser; vmaf_dnn_sidecar_load for the tiny-AI sidecar loader),
ships a small seed corpus, and is wired into the nightly fuzz.yml matrix.

First run of fuzz_json_model surfaced a heap-buffer-overflow in
vmaf_model_destroy when parse_slopes outruns feature_names: ensure_feature
_capacity grows feature_cap without updating n_features, so destruction
walks past the initialised region. Reproducer committed under
json_model_known_crashes/. Per ADR-0404 the harness stays on until the fix
lands; tracked as T-JSON-MODEL-SLOPES-FEATURE-CAP-OOB-2026-05-30 in
docs/state.md. fuzz_dnn_sidecar ran 3.95M iterations clean in a 30-second
local smoke.

Notes:
- Internal (non-VMAF_EXPORT) entry points cannot be reached through
  libvmaf.so under ADR-0379's -fvisibility=hidden policy, so the
  harnesses compile parser sources directly into each binary, mirroring
  test_model / test_model_loader.
- b_lto=false is load-bearing: ASan + LTO together discard module-dtor
  sections at link time on the larger source set.
- Known-crash reproducer uses .bin extension to dodge the pre-commit
  check-json hook, which would otherwise refuse fuzzer-mutated payloads
  that are intentionally not valid JSON.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* test(fuzz): expand y4m_input_corpus with 7 missing chroma-path seeds

The existing y4m_input_corpus covered 420/420p10/422/411/mono but
left 7 distinct parser branches unreachable by the seed corpus:

- C420mpeg2  — y4m_convert_42xmpeg2_42xjpeg conversion path
- C420paldv  — y4m_convert_42xpaldv_42xjpeg conversion path
- C444       — y4m_convert_null path (missing entirely)
- C444alpha  — aux-buf allocated path for the discarded alpha plane
- C420p12    — 12-bit 4:2:0 (high-bitdepth branch)
- C422p10    — 10-bit 4:2:2
- C444p10    — 10-bit 4:4:4

Each seed is a minimal valid Y4M file (W4 H4, one all-zero frame).
libFuzzer will cover all chroma conversion callbacks and
depth-multiplier branches immediately instead of waiting for the
fuzzer to discover these header permutations by mutation.

Companion to the fuzz_json_model + fuzz_dnn_sidecar landing
(ADR-0882).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 8, 2026
…MCP, vmaftune, copyright, error paths, headers, magic numbers, docs) (#858)

* fix(ubsan): silence 5 UBSan-flagged production-code UB sites

1. pdjson.c/h: change stack_top from size_t to ptrdiff_t so that the
   -1 sentinel is a well-defined signed value; update all (size_t)-1
   comparisons to -1 and add casts on the depth/size comparisons to
   keep sign-clean arithmetic.

2. motion_avx512.c (×3 scalar tails): cast uint16_t filter[] operands
   to uint32_t before accumulation; the sum of all five taps at max
   pixel values (≈65536×65535) overflows signed int in the C default
   arithmetic promotions.

3. vif_avx512.c (all 4 sites): cast loop counter i to int before
   subtracting fwidth_half; unsigned − signed promotes to unsigned and
   the subsequent signed-int assignment is implementation-defined when
   the result wraps.

4. adm_avx2.c (10 sites): replace the unsigned hex literal
   0xFFFFFFFFFFFFFFFF passed to _mm256_set_epi64x() with -1LL;
   the hex form overflows long long and is UB per C99 §6.4.4.1.

5. integer_adm.c (both init loops): cast (1u << (shift_flt[idx] - 1))
   to int32_t before assigning to int32_t add_bef_shift_flt[]; the
   1u<<31 wrap is intentional per ADR-0155 (Netflix#955) and is now
   an explicit implementation-defined conversion rather than UB.
   NOLINT annotations cite ADR-0155 inline.

Build: clean (1010/1010 targets). Tests: 87/87 fast suite pass.
No Netflix golden assertion values changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(asan): null caller handles + unlock/destroy mutex on all error paths

ASan/LeakSan dangling-pointer UAF fixes across five init/create/destroy
functions in core/src/:

- vmaf_init (libvmaf.c): *vmaf is now NULLed on every failure path so
  the caller cannot read a freed pointer after a failed init.
- vmaf_feature_extractor_context_create (feature_extractor.c/.cpp):
  *fex_ctx NULLed on free_x/free_f labels and on the inline
  vmaf_fex_ctx_parse_options error path.
- vmaf_fex_ctx_pool_create (feature_extractor.c/.cpp): *pool NULLed on
  all failure paths; feature_extractor.c also gains a pthread_mutex_init
  return-value check (the .cpp already had it) and a free_fex_list label
  to match the new guard.
- vmaf_fex_ctx_pool_destroy (feature_extractor.c/.cpp):
  pthread_mutex_unlock + pthread_mutex_destroy now called before free(pool)
  per POSIX; freeing a locked mutex is UB and leaks glibc TSD resources.
- vmaf_feature_collector_init + feature_vector_init (feature_collector.c/
  .cpp): *feature_collector and *feature_vector NULLed on all failure
  paths.

All changes follow CERT MEM30-C. Local verify: meson test --suite=fast
87/87 pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ai): pin torchvision>=0.27.0 and add 13 missing script stubs

Three Python ABI / missing-script findings resolved:

1. ai/pyproject.toml: promote torchvision from a comment-explained
   implicit dep to a pinned direct dependency (>=0.27.0,<0.28.0).
   pytorch-lightning >= torchmetrics 1.9+ eagerly imports
   torchvision.transforms at module-load time; a stale torchvision 0.26.0
   wheel against torch 2.12.0 raises RuntimeError: operator
   torchvision::nms does not exist (not an ImportError), so pip's
   constraint resolution was the only reliable preventive fix.

2. ai/scripts/export_tiny_models.py: wrap the vmaf_train.models import
   (which triggers the pytorch_lightning -> torchvision chain) in a
   broad try/except so an ABI-mismatched venv produces a clear error
   message with the pip fix command instead of an opaque RuntimeError.

3. dev/Containerfile: add an explicit pip install torchvision>=0.27.0,<0.28.0
   step after the ai/ package install so freshly built container images
   never carry a stale torchvision wheel from a previous layer cache.

4. ai/scripts/: add 13 stub scripts that are referenced in docs/ADRs but
   were absent from the filesystem.  Each stub exits 0 with a short
   "not yet implemented" message and a pointer to the relevant doc.
   Stubs: build_calibration_set.py, eval_loso_fr_regressor_v2.py,
   external_benchmark_pvmaf.py, fetch_lsvq.py, gen_calibration.py,
   gen_dists_sq_placeholder_onnx.py, gen_mobilesal_placeholder_onnx.py,
   gen_ssimulacra2_eotf_lut.py, hdrsdr_vqa_to_corpus_jsonl.py,
   my_corpus_to_corpus_jsonl.py, quantize_int8.py,
   train_fr_regressor_v4.py, train_video_saliency_student.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(mcp): harden input validation — 5-finding wave (depth cap, frameNum, HTTP TypeError, n-cap, KeyError)

1. _nan_to_none: add depth cap (100 levels) via _nan_to_none_depth helper to
   prevent RecursionError on deeply nested JSON payloads from large vmaf runs.

2. _pick_worst_frames: wrap int(idx) in try/except (TypeError, ValueError) so
   non-numeric or dict frameNum values are logged and skipped instead of
   propagating and aborting describe_worst_frames.

3. http_transport._handle_score: add TypeError to the (ValueError, FileNotFoundError)
   catch so int(None) / int([...]) on non-integer width/height/bitdepth fields
   returns 400 instead of 500.

4. _call_tool describe_worst_frames: enforce schema maximum:32 on n server-side
   (raises ValueError for n < 1 or n > 32), not just in the JSON Schema hint.

5. _call_tool: extract dispatch into _call_tool_dispatch and wrap with
   KeyError -> ValueError conversion so missing required arguments produce a
   readable error message ("tool X missing required argument: 'ref'") instead
   of a bare KeyError.

22 new tests in test_mcp_hardening_wave1.py; no pre-existing test regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(vmaf-tune): 5 critical vmaftune bugs — proxy inputs, saliency height, saliency guard, profile source, test contract

Fix 1 (proxy.py): fr_regressor_v2.onnx was exported with two separate named
inputs ("features" [N,6] + "codec" [N,14]) matching FRRegressor.forward().
run_proxy was concatenating them into one 20-D tensor and feeding it as a
single input, so the codec port received nothing and fast-path production
mode produced wrong predictions. Now wires the two inputs separately for
two-input graphs; falls back to the legacy single-input path for older exports.

Fix 2 (saliency.py): compute_saliency_map crashed at runtime for any height
not divisible by 8 because the saliency_student_v1 encoder path requires
aligned tensor dims. Added an upfront ValueError with a clear hint showing
the next valid height rather than surfacing a cryptic onnxruntime error.

Fix 3 (cli.py): _run_recommend_saliency always invoked saliency_aware_encode
even when --saliency-aware was not set, because config=None caused the
function to silently create a default SaliencyConfig() and run the model.
Added an explicit guard: when saliency_aware is False, call run_encode directly.

Fix 4 (encoder_profile.py): build_encode_request raised AttributeError when
the profile "source" field was stored as a plain path string (written by
older vmaf-tune versions) instead of a metadata dict. Now normalises the
field to {"path": value} before accessing .get("path").

Fix 5 (test_fast.py): test_proxy_module_uses_lazy_import_seam was validating
the broken single-input 20-D contract. Updated to use a two-input fake session
(named "features" + "codec") and assert that run_proxy wires the inputs
separately, confirming the corrected behaviour from Fix 1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(copyright): sweep license/copyright drift across 303 fork-original files

Three categories fixed:

1. ffmpeg-patches/0007 and 0008: remove "and Claude (Anthropic)" from 3
   copyright lines; per project_copyright_lusoris_only.md, Anthropic is not
   a rights holder — Lusoris-only attribution required.

2. 66 fork-original SIMD files (AVX2/AVX-512/NEON in
   core/src/feature/x86/ and core/src/feature/arm64/): add
   "Copyright 2026 Lusoris" as a second copyright line immediately after
   the existing Netflix line (dual notice; Netflix line preserved as these
   files may include upstream-derived code).

3. 234 fork-original C/H files: replace wrong SPDX identifier
   "BSD-3-Clause-Plus-Patent" with correct "BSD-2-Clause-Patent" to
   match the LICENSE root (BSD+Patent / SPDX: BSD-2-Clause-Patent).

Verified: scripts/ci/check-copyright.sh exits 0 on all changed files;
grep for BSD-3-Clause-Plus-Patent and "Anthropic" in copyright positions
returns 0 hits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compat,mcp,vmaf-tune): cross-version-compat — 4 findings

1. vmaf-tune _write_compare_profile_report: write JSON artifact when
   format='both' (previously only .html + .md were written, silently
   dropping the .json sidecar). Regression tests in
   test_format_both_json.py now pass.

2. MCP HTTP test fixture scoping: token_client fixture in
   test_http_transport.py leaked the removal of VMAFX_MCP_HTTP_NO_AUTH
   because os.environ.pop() was called inside a patch.dict that did not
   track that key, so the pop was not reverted on fixture teardown.
   Replaced with an explicit save/restore approach that prevents
   cross-test env contamination.

3. test_vmaf_version_handles_version_timeout: _vmaf_version is an async
   coroutine; the test now uses @pytest.mark.asyncio so pytest-asyncio
   drives the event loop instead of calling the coroutine object
   synchronously (Python 3.14+ would raise on await of a non-awaitable).

4. compat/python-vmaf/tools/misc.py: SourceFileLoader.load_module() is
   deprecated since Python 3.4 and scheduled for removal in Python 3.15;
   imp.load_source() was removed in Python 3.12. Migrated to the modern
   importlib.util.spec_from_file_location / exec_module path that works
   on all supported Python versions (3.8+).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(error-path): check and propagate return values at 5 error-path sites

1. cambi.c set_contrast_arrays: free partial allocs on OOM and propagate
   error at call site instead of silently ignoring -ENOMEM.
2. integer_motion.c flush: capture and propagate both
   vmaf_feature_collector_append_with_dict return values.
3. cuda/integer_motion_v2_cuda.c flush: capture and propagate
   vmaf_feature_collector_append return value.
4. sycl/integer_vif_sycl.cpp flush_fex_sycl: capture and propagate
   vmaf_sycl_queue_wait return value; close_fex_sycl (void)-casts it
   as the teardown path must continue regardless.
5. sycl/integer_adm_sycl.cpp: same pattern as integer_vif_sycl.cpp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(model): 3 model-coverage fixes — vmaf_b log-level, tiny-model path guard, fr_regressor_v3 codec gate

Finding #1 (vmaf_phone_v0.6.1 absent): confirmed false positive — phone mode is a
score-transform on vmaf_v0.6.1.json, not a separate file. Docs and code already correct.

Finding #2 (vmaf_b_v0.6.3 spurious ERROR before fallback):
- model.c vmaf_model_load_from_path: demote "could not read model from path" from
  VMAF_LOG_LEVEL_ERROR to VMAF_LOG_LEVEL_WARNING. The CLI falls back to the collection
  loader when this call fails, so a bootstrap/collection JSON is not an error — it has
  a different top-level structure. The .pkl hard-error follow-up stays at ERROR since pkl
  is permanently unsupported.

Finding #3 (--tiny-model silently rejects .json path with -EBADMSG):
- configure_tiny_model (vmaf.c): add early extension check before vmaf_use_tiny_model.
  When the path does not end in ".onnx", emit a clear diagnostic explaining that sidecar
  .json files are loaded automatically alongside the .onnx, not passed directly. Previously
  the JSON bytes were scanned as protobuf by onnx_scan.c, producing the opaque -EBADMSG.

Finding #4 (fr_regressor_v3 out-of-range scores without --tiny-codec):
- dnn.h: add vmaf_dnn_is_codec_aware(ctx) public API.
- dnn_ctx.h: add vmaf_ctx_dnn_is_codec_aware bridge declaration.
- libvmaf.c: implement vmaf_ctx_dnn_is_codec_aware (checks sess, has_sidecar,
  codec_aware flag, and extra_in_width > 0).
- dnn_attach_api.c: implement vmaf_dnn_is_codec_aware public wrapper.
- configure_tiny_model (vmaf.c): after model load, if the model is codec-aware but no
  --tiny-codec / --tiny-preset / --tiny-crf was given, reject with a clear error message
  explaining that the conditioning block would contain only an "unknown" fallback slot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(headers): resolve 5 public/internal header leak findings

1. picture_v2.h: rename include guard from reserved C identifier
   __VMAF_PICTURE_V2_H__ (double-underscore prefix, undefined behaviour
   per ISO C 7.1.3) to LIBVMAF_PICTURE_V2_H_.

2. All public headers: convert bare quoted includes (#include "foo.h" /
   #include "libvmaf/foo.h") to angle-bracket form (#include <libvmaf/foo.h>)
   across all 9 affected installed headers (libvmaf.h, picture.h, picture_v2.h,
   feature.h, model.h, dnn.h, libvmaf_cuda.h, libvmaf_hip.h, libvmaf_metal.h,
   libvmaf_mcp.h, libvmaf_sycl.h). Quoted-path includes only resolve when the
   build root is on the include path, breaking pkg-config consumers who only
   have the installed prefix.

3. picture.h VmafPicture: add INTERNAL banners to the ref and priv fields,
   clarifying they are managed by libvmaf and must not be accessed externally.

4. libvmaf.h VMAF_POOL_METHOD_NB: add __attribute__((deprecated)) on GCC/Clang
   so external callers see a build-time warning. Gate the attribute on
   !VMAF_BUILDING_LIBVMAF so internal TUs (output.c) that legitimately iterate
   [0, NB) are not affected. Inject -DVMAF_BUILDING_LIBVMAF into
   vmaf_cflags_common in core/src/meson.build.

5. vmaf_assert.h: remove from the install_headers() list in
   core/include/libvmaf/meson.build. The header exposes VMAF_ASSERT_DEBUG which
   is gated on the internal VMAF_DEBUG build flag and has no defined semantics
   for external consumers. Internal .c files continue to include it from the
   source tree. Add an INTERNAL comment banner to the header itself.

Build-verified: meson setup + ninja (1010/1010 targets clean) +
meson test --suite=fast (87/87 pass, 0 failures).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(constants): extract 5 magic numbers to named constants

- CAMBI_WINDOW_DIVISOR=375 and CAMBI_MIN_WIDTH_HEIGHT=216 centralised in
  cambi_internal.h; local per-backend defines (CAMBI_CUDA_MIN_WIDTH_HEIGHT,
  CAMBI_HIP_MIN_WIDTH_HEIGHT) and the bare 375 divisor removed from
  cambi.c, integer_cambi_cuda.c, and integer_cambi_hip.c.

- DNN_SIDECAR_JSON_MAX=1u<<20 added to model_loader.h; three guard sites
  in model_loader.c now reference it instead of bare bit-shifts /
  integer literals.

- FEATURE_VECTOR_INITIAL_CAPACITY=8u added to feature_collector.h; three
  literal 8s in feature_collector.c replaced.

- DNN_MIN_BIT_DEPTH=9 added to tensor_io.h; bpc guard in tensor_io.c
  (two sites) and dnn_api.c now reference it.

Build: 1010/1010 ninja targets; 87/87 fast tests pass; pre-commit clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docs): round-4 docs-substance-audit — remove stale HIP scaffold note + mark vmafx CLI as planned + remove active Vulkan claims

Four targeted fixes from the round-4 docs-substance audit:

1. core/include/libvmaf/libvmaf_hip.h — remove the stale "Status: scaffold
   only. Every entry point returns -ENOSYS" Doxygen block. The HIP backend
   is fully implemented (ADR-0519 / ADR-0533 / ADR-0539); 21 feature
   extractors are registered and verified on AMD gfx hardware. Replace
   with an accurate status note pointing to the three unregistered legacy
   stubs and the no-HIP stubs.c contract.

2. docs/api/gpu.md — complete the vmaf_hip_import_state table entry: add
   the -ENOSYS return when built without HIP (matches the header Doxygen
   and stubs.c behaviour) alongside the already-documented -EINVAL case.

3. docs/usage/vmafx-cli.md — mark the vmafx symlink, --netflix-compat flag,
   and vmafx-* Python aliases as "planned — not yet implemented in master".
   Neither cli_parse.c nor the Python pyproject.toml entries have been
   updated yet (ADR-0690 / ADR-0696 specify the design). Add interim
   equivalents using the already-shipped --precision=max flag.

4. docs/usage/vmaf-tune.md — remove active Vulkan claims. The Vulkan
   backend was deleted in ADR-0726; --score-backend=vulkan no longer
   exists. Mark the Vulkan section REMOVED with a historical-reference
   notice; update six flag-table rows to drop vulkan from the accepted
   enum; fix the native-first-order example (vulkan was already absent
   from the auto probe order table at line 393).

No code changes; docs only. No golden assertions touched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 27, 2026
…t + vmaf-tune stderr + eval shape guard (T-BUGHUNT-MCP-2026-06-27)

Bug-hunt sweep (mcp subsystem), 4 fixed / 2 already-fixed-and-skipped:

- mcp #1 (high): the Go cmd/vmafx-mcp streamable-HTTP transport had no auth,
  no body limit, and bound all interfaces — the Python ADR-0967 hardening was
  never ported. New cmd/vmafx-mcp/http_security.go adds a bearer-token
  middleware (VMAFX_MCP_HTTP_TOKEN, crypto/subtle constant-time compare,
  VMAFX_MCP_HTTP_NO_AUTH=1 opt-out, refuse-all 401 when neither is set), a
  4 MiB body limit (http.MaxBytesReader + Content-Length pre-flight -> 413),
  and a loopback-only default bind (VMAFX_MCP_HTTP_BIND, default 127.0.0.1,
  applied when mcp.http.addr has no host); wired into main.go runMCPTransport.
- mcp #3 (med): unify the score-precision default to "legacy" (%.6f, the
  C-CLI default per ADR-0119). The Python HTTP /v1/score path and the Go
  direct-cgo->subprocess fallback both defaulted to "17", diverging from the
  stdio path and the documented default.
- mcp #4 (low): add the pred/target shape-mismatch guard to the Go
  eval_model_on_split inline script (parity with Python _eval_model_on_split).
- mcp #5 (low): the three Go vmaf-tune wrappers now fold subprocess stderr
  into the error via a shared runVmafTune helper
  ("vmaf-tune <sub> exited <rc>: <stderr>"), instead of discarding it with
  exec.Output().

Skipped (already fixed in-tree): mcp #2 (subsample forwarding on
vmaf_score_encoded — scoreExtras.subsample) and mcp #6 (HTTP /v1/score strict
serializer — http_transport.py uses _dumps_strict).

Golden safety: no Netflix golden assertAlmostEqual value touched (MCP servers
only).

Reproducer:
  go test ./cmd/vmafx-mcp/        # TestSecurityMiddleware*, TestApplyBindHost,
                                  # TestRunVmafTune_*
  gosec ./cmd/vmafx-mcp/          # 0 issues
  PYTHONPATH=mcp-server/vmaf-mcp/src python -m pytest mcp-server/vmaf-mcp/tests -q
                                  # 451 passed, 2 skipped
                                  # (incl. test_score_precision_defaults_to_legacy)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 27, 2026
…t + vmaf-tune stderr + eval shape guard (T-BUGHUNT-MCP-2026-06-27)

Bug-hunt sweep (mcp subsystem), 4 fixed / 2 already-fixed-and-skipped:

- mcp #1 (high): the Go cmd/vmafx-mcp streamable-HTTP transport had no auth,
  no body limit, and bound all interfaces — the Python ADR-0967 hardening was
  never ported. New cmd/vmafx-mcp/http_security.go adds a bearer-token
  middleware (VMAFX_MCP_HTTP_TOKEN, crypto/subtle constant-time compare,
  VMAFX_MCP_HTTP_NO_AUTH=1 opt-out, refuse-all 401 when neither is set), a
  4 MiB body limit (http.MaxBytesReader + Content-Length pre-flight -> 413),
  and a loopback-only default bind (VMAFX_MCP_HTTP_BIND, default 127.0.0.1,
  applied when mcp.http.addr has no host); wired into main.go runMCPTransport.
- mcp #3 (med): unify the score-precision default to "legacy" (%.6f, the
  C-CLI default per ADR-0119). The Python HTTP /v1/score path and the Go
  direct-cgo->subprocess fallback both defaulted to "17", diverging from the
  stdio path and the documented default.
- mcp #4 (low): add the pred/target shape-mismatch guard to the Go
  eval_model_on_split inline script (parity with Python _eval_model_on_split).
- mcp #5 (low): the three Go vmaf-tune wrappers now fold subprocess stderr
  into the error via a shared runVmafTune helper
  ("vmaf-tune <sub> exited <rc>: <stderr>"), instead of discarding it with
  exec.Output().

Skipped (already fixed in-tree): mcp #2 (subsample forwarding on
vmaf_score_encoded — scoreExtras.subsample) and mcp #6 (HTTP /v1/score strict
serializer — http_transport.py uses _dumps_strict).

Golden safety: no Netflix golden assertAlmostEqual value touched (MCP servers
only).

Reproducer:
  go test ./cmd/vmafx-mcp/        # TestSecurityMiddleware*, TestApplyBindHost,
                                  # TestRunVmafTune_*
  gosec ./cmd/vmafx-mcp/          # 0 issues
  PYTHONPATH=mcp-server/vmaf-mcp/src python -m pytest mcp-server/vmaf-mcp/tests -q
                                  # 451 passed, 2 skipped
                                  # (incl. test_score_precision_defaults_to_legacy)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 27, 2026
…t + vmaf-tune stderr + eval shape guard (T-BUGHUNT-MCP-2026-06-27) (#1046)

Bug-hunt sweep (mcp subsystem), 4 fixed / 2 already-fixed-and-skipped:

- mcp #1 (high): the Go cmd/vmafx-mcp streamable-HTTP transport had no auth,
  no body limit, and bound all interfaces — the Python ADR-0967 hardening was
  never ported. New cmd/vmafx-mcp/http_security.go adds a bearer-token
  middleware (VMAFX_MCP_HTTP_TOKEN, crypto/subtle constant-time compare,
  VMAFX_MCP_HTTP_NO_AUTH=1 opt-out, refuse-all 401 when neither is set), a
  4 MiB body limit (http.MaxBytesReader + Content-Length pre-flight -> 413),
  and a loopback-only default bind (VMAFX_MCP_HTTP_BIND, default 127.0.0.1,
  applied when mcp.http.addr has no host); wired into main.go runMCPTransport.
- mcp #3 (med): unify the score-precision default to "legacy" (%.6f, the
  C-CLI default per ADR-0119). The Python HTTP /v1/score path and the Go
  direct-cgo->subprocess fallback both defaulted to "17", diverging from the
  stdio path and the documented default.
- mcp #4 (low): add the pred/target shape-mismatch guard to the Go
  eval_model_on_split inline script (parity with Python _eval_model_on_split).
- mcp #5 (low): the three Go vmaf-tune wrappers now fold subprocess stderr
  into the error via a shared runVmafTune helper
  ("vmaf-tune <sub> exited <rc>: <stderr>"), instead of discarding it with
  exec.Output().

Skipped (already fixed in-tree): mcp #2 (subsample forwarding on
vmaf_score_encoded — scoreExtras.subsample) and mcp #6 (HTTP /v1/score strict
serializer — http_transport.py uses _dumps_strict).

Golden safety: no Netflix golden assertAlmostEqual value touched (MCP servers
only).

Reproducer:
  go test ./cmd/vmafx-mcp/        # TestSecurityMiddleware*, TestApplyBindHost,
                                  # TestRunVmafTune_*
  gosec ./cmd/vmafx-mcp/          # 0 issues
  PYTHONPATH=mcp-server/vmaf-mcp/src python -m pytest mcp-server/vmaf-mcp/tests -q
                                  # 451 passed, 2 skipped
                                  # (incl. test_score_precision_defaults_to_legacy)

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@lusoris lusoris added this to the 1.0.0 — First release milestone Sep 4, 2026
lusoris added a commit that referenced this pull request Sep 5, 2026
…-AV1-HDR knobs

- Land profile report audit findings #2-#10 in report.py and cli.py:
  - #2: Unify bitrate axis labels and tick formatting (Mbps/kbps).
  - #3: Render em-dash for failed rows with 0.0 values in HTML/Markdown.
  - #4: Assign VideoToolbox encoders to distinct palette slots (15-17).
  - #5 & #8: Deduplicate pareto annotations to lowest-bitrate point with bitrate.
  - #6: Add --json-sidecar CLI flag and ReportData.from_dict round-trip.
  - #7: Add picked CRF label to scatter plot and deduplicate legend entries.
  - #9: Strip timestamp and pin svg.hashsalt for byte-identical rendering.
  - #10: Add failed target markers and failure annotations to sweep chart.
- Document SVT-AV1-HDR tuning knobs and libsvtav1@svt-av1-hdr runtime variant
  in docs/usage/vmaf-tune.md and docs/usage/vmaf-tune-codec-adapters.md.
- Add comprehensive regression tests in tools/vmaf-tune/tests/test_report.py.
- Update docs/state.md, docs/rebase-notes.md, and changelog fragments.
lusoris added a commit that referenced this pull request Sep 5, 2026
…-AV1-HDR knobs

- Land profile report audit findings #2-#10 in report.py and cli.py:
  - #2: Unify bitrate axis labels and tick formatting (Mbps/kbps).
  - #3: Render em-dash for failed rows with 0.0 values in HTML/Markdown.
  - #4: Assign VideoToolbox encoders to distinct palette slots (15-17).
  - #5 & #8: Deduplicate pareto annotations to lowest-bitrate point with bitrate.
  - #6: Add --json-sidecar CLI flag and ReportData.from_dict round-trip.
  - #7: Add picked CRF label to scatter plot and deduplicate legend entries.
  - #9: Strip timestamp and pin svg.hashsalt for byte-identical rendering.
  - #10: Add failed target markers and failure annotations to sweep chart.
- Document SVT-AV1-HDR tuning knobs and libsvtav1@svt-av1-hdr runtime variant
  in docs/usage/vmaf-tune.md and docs/usage/vmaf-tune-codec-adapters.md.
- Add comprehensive regression tests in tools/vmaf-tune/tests/test_report.py.
- Update docs/state.md, docs/rebase-notes.md, and changelog fragments.
lusoris added a commit that referenced this pull request Sep 6, 2026
…-AV1-HDR knobs

- Land profile report audit findings #2-#10 in report.py and cli.py:
  - #2: Unify bitrate axis labels and tick formatting (Mbps/kbps).
  - #3: Render em-dash for failed rows with 0.0 values in HTML/Markdown.
  - #4: Assign VideoToolbox encoders to distinct palette slots (15-17).
  - #5 & #8: Deduplicate pareto annotations to lowest-bitrate point with bitrate.
  - #6: Add --json-sidecar CLI flag and ReportData.from_dict round-trip.
  - #7: Add picked CRF label to scatter plot and deduplicate legend entries.
  - #9: Strip timestamp and pin svg.hashsalt for byte-identical rendering.
  - #10: Add failed target markers and failure annotations to sweep chart.
- Document SVT-AV1-HDR tuning knobs and libsvtav1@svt-av1-hdr runtime variant
  in docs/usage/vmaf-tune.md and docs/usage/vmaf-tune-codec-adapters.md.
- Add comprehensive regression tests in tools/vmaf-tune/tests/test_report.py.
- Update docs/state.md, docs/rebase-notes.md, and changelog fragments.
lusoris added a commit that referenced this pull request Sep 6, 2026
…-AV1-HDR knobs

- Land profile report audit findings #2-#10 in report.py and cli.py:
  - #2: Unify bitrate axis labels and tick formatting (Mbps/kbps).
  - #3: Render em-dash for failed rows with 0.0 values in HTML/Markdown.
  - #4: Assign VideoToolbox encoders to distinct palette slots (15-17).
  - #5 & #8: Deduplicate pareto annotations to lowest-bitrate point with bitrate.
  - #6: Add --json-sidecar CLI flag and ReportData.from_dict round-trip.
  - #7: Add picked CRF label to scatter plot and deduplicate legend entries.
  - #9: Strip timestamp and pin svg.hashsalt for byte-identical rendering.
  - #10: Add failed target markers and failure annotations to sweep chart.
- Document SVT-AV1-HDR tuning knobs and libsvtav1@svt-av1-hdr runtime variant
  in docs/usage/vmaf-tune.md and docs/usage/vmaf-tune-codec-adapters.md.
- Add comprehensive regression tests in tools/vmaf-tune/tests/test_report.py.
- Update docs/state.md, docs/rebase-notes.md, and changelog fragments.
lusoris added a commit that referenced this pull request Sep 6, 2026
…-AV1-HDR knobs (#1296)

* fix(vmaf-tune): address report audit findings #2-#10 and document SVT-AV1-HDR knobs

- Land profile report audit findings #2-#10 in report.py and cli.py:
  - #2: Unify bitrate axis labels and tick formatting (Mbps/kbps).
  - #3: Render em-dash for failed rows with 0.0 values in HTML/Markdown.
  - #4: Assign VideoToolbox encoders to distinct palette slots (15-17).
  - #5 & #8: Deduplicate pareto annotations to lowest-bitrate point with bitrate.
  - #6: Add --json-sidecar CLI flag and ReportData.from_dict round-trip.
  - #7: Add picked CRF label to scatter plot and deduplicate legend entries.
  - #9: Strip timestamp and pin svg.hashsalt for byte-identical rendering.
  - #10: Add failed target markers and failure annotations to sweep chart.
- Document SVT-AV1-HDR tuning knobs and libsvtav1@svt-av1-hdr runtime variant
  in docs/usage/vmaf-tune.md and docs/usage/vmaf-tune-codec-adapters.md.
- Add comprehensive regression tests in tools/vmaf-tune/tests/test_report.py.
- Update docs/state.md, docs/rebase-notes.md, and changelog fragments.

* docs(vmaf-tune): correct SVT-AV1-HDR knob defaults against upstream Parameters.md

The first cut of the knob table carried three defaults that contradict
juliobbv-p/svt-av1-hdr Docs/Parameters.md @ 0033340 (tune=1 not 0,
sharp-tx=1 not 0, noise-adaptive-filtering=2 not 0) and omitted twelve
documented keys. Rebuild the table from the upstream parameter reference,
state the three injection points for the -svtav1-params string and the
ADR-0294 CRF/preset window the variant inherits, and drop the
'this PR' placeholders from docs/state.md so the ADR-0165 touch gate
accepts the rows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(state): drop the duplicate rows a keep-both rebase created

Each dropped row restates one origin/master already carries; master is the
authoritative record. Verified with scripts/ci/check-state-md-rows.sh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant