Skip to main content

qc-skill

Deterministic media quality control / validation. Measures and checks video, audio, subtitle, and delivery artifacts - a single file, or (kind=delivery_package) N named artifacts (video + subtitle + thumbnail + metadata, ...) validated together as one delivery - against caller-supplied rules, and returns structured PASS/WARN/FAIL/UNKNOWN results with evidence. Use when you need to know facts about a media file (resolution, fps, codec, loudness, silence, black/freeze frames, subtitle timing/coverage) or whether it meets an explicit spec (expected resolution/fps/codec, loudness target+tolerance, subtitle sync tolerance, required companion artifacts). Do NOT use this skill to decide whether media may ship, to edit/re-render/repair media, to generate or rewrite subtitles, or to transcribe/understand content semantically - those belong to video-production-agent (decisions), audio-production-skill / video-editing-skill (execution), subtitle-skill (generation), and transcription-skill (ASR).

Source facts

Repository
kajisho5/qc-skill
Last source activity
November 5, 2026 at 19:09
Detected SKILL.md language
English
Stars
4
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
qc-skill
description
Deterministic media quality control / validation. Measures and checks video, audio, subtitle, and delivery artifacts - a single file, or (kind=delivery_package) N named artifacts (video + subtitle + thumbnail + metadata, ...) validated together as one delivery - against caller-supplied rules, and returns structured PASS/WARN/FAIL/UNKNOWN results with evidence. Use when you need to know facts about a media file (resolution, fps, codec, loudness, silence, black/freeze frames, subtitle timing/coverage) or whether it meets an explicit spec (expected resolution/fps/codec, loudness target+tolerance, subtitle sync tolerance, required companion artifacts). Do NOT use this skill to decide whether media may ship, to edit/re-render/repair media, to generate or rewrite subtitles, or to transcribe/understand content semantically - those belong to video-production-agent (decisions), audio-production-skill / video-editing-skill (execution), subtitle-skill (generation), and transcription-skill (ASR).
# qc-skill ## Commands ```bash qc contract --json qc doctor --json qc run <request.json | -> --json [--workspace DIR] [--allowed-input-root DIR]... ``` ## Request parameters | Field | Type | Meaning | |---|---|---| | `operation` | `inspect` \| `check` \| `validate` | measure only, or measure+evaluate rules | | `kind` | `video` \| `audio` \| `subtitle` \| `delivery` \| `delivery_package` | what `input` (or `artifacts`) is | | `input` | string | path to the primary artifact (not accepted for `kind: delivery_package`) | | `subtitle` | string, optional | companion subtitle path (`kind: delivery` only) | | `reference_video` | string, optional | companion video path, for duration comparison (`kind: subtitle` only) | | `artifacts` | array, optional | `[{artifact_id, artifact_type, path}, ...]` - N named artifacts validated together as one delivery (`kind: delivery_package` only, required and non-empty for it) | | `parameters` | object, optional | detection sensitivity overrides (e.g. `silence_threshold_db`) | | `rules` | object, optional | typed expectations: `{video, audio, subtitle, delivery, delivery_package}` (see `src/qc_skill/rules.py`) | | `cache_policy` | `use` \| `bypass` \| `only` | default `use` | | `timeout` | number, optional | seconds of wall clock for the whole request; when it runs out every running ffprobe/ffmpeg is killed with its process group and the call fails with `TIMEOUT` (exit 15, retryable) - ADR-019 | Never send `command`, `argv`, `args`, `shell`, `cmd`, `exec`, `executable`, `filter`, `filter_complex`, or `env` - the request schema rejects all of them outright, at any nesting depth. For `kind: "delivery_package"`, `rules.delivery_package.cross_artifact` adds typed relationship checks across the named artifacts: `duration_consistency` (durations must agree within a tolerance) and `dependencies` (if artifact A is present, artifact B must be too) - never a string comparison or semantic/LLM judgment. See `docs/checks.md`. `rules.subtitle.timeline_integrity` (also reachable via `delivery`'s and `delivery_package`'s nested `subtitle` sub-rule) checks whether a subtitle's delivery-timeline cue timing still matches a caller-supplied source-to-delivery `timeline` mapping after a trim/concat/speed edit - qc-skill never constructs that mapping itself, only compares against one the caller supplies. See `docs/checks.md`. `VideoRule.max_single_luminance_excursion_sec`/ `max_total_luminance_excursion_sec` check for video signal outside the legal 8-bit range (default 16-235) via ffmpeg's `signalstats` (a literal per-frame pixel readout, not a heuristic classifier). See `docs/checks.md`. Three opt-in `VideoRule` checks (each measured only when asked, ADR-016/017/018): - `check_photosensitivity: true` - ITU-R BT.1702 general flash (20 cd/m2 changes, darker side < 160 cd/m2, > 25% of the screen, more than `max_flashes_per_second` (default 3) in any 1 s) -> `VIDEO_FLASH_RISK`. Red flash is not defined by the standard and is reported UNKNOWN. - `expected_cuts: [seconds]` - compares scdet cut times with your cut list (`max_cut_error_frames` default 1, `allow_extra_cuts` default true) -> `VIDEO_CUT_MISMATCH`, with matched/missing/extra in evidence. - `text_regions: [{t, box: [x, y, w, h], role: hook|cta|caption|term}]` - WCAG contrast ratio (`min_contrast_ratio` default 4.5) and ink height at a 1080 px short side (`min_text_height_px` per role, no default) -> `TEXT_ILLEGIBLE`. Measured facts only; no OCR. One opt-in full-reference comparison (ADR-021), `kind: video` or `rules.delivery.video`, against the top-level `reference_video`: - `reference_metrics: ["vmaf", "ssim", "psnr"]` (any subset) -> `video.vmaf_meets_minimum` (`min_vmaf` default 93), `video.ssim_meets_minimum` (`min_ssim` default 0.95), `video.psnr_meets_minimum` (`min_psnr_db` default 31). A smaller input is upscaled to the reference's size; a different frame rate or a length more than one frame apart is refused (checks UNKNOWN, reason in `video.reference_alignment`). Without libvmaf in the host's ffmpeg (see doctor `filter:libvmaf`) VMAF is UNKNOWN and SSIM/PSNR still run. ## Example ```json { "operation": "check", "kind": "audio", "input": "/workspace/mix.wav", "rules": {"audio": {"integrated_loudness_target_lufs": -16, "integrated_loudness_tolerance_lu": 1.0, "max_true_peak_dbfs": -1.0}} } ``` Response: `{"status": "completed", "report": {"overall_status": "PASS"|"WARN"|"FAIL"|"UNKNOWN", "checks": [...], "measurements": [...], "findings": [...]}, "provenance": {...}}`. ## Workflow hints for an agent 1. Call `doctor --json` once per environment to confirm ffmpeg/ffprobe and the filters you need (`blackdetect`, `freezedetect`, `ebur128`, `astats`, `silencedetect`) are `AVAILABLE`, not just installed-in-theory. Before asking for VMAF, check `checks["filter:libvmaf"].status`. 2. Use `inspect` first when you don't yet know what to expect (e.g. before you have a delivery spec) - it returns pure measurements you can reason over yourself. 3. Use `check`/`validate` with explicit `rules` once you know the target spec. Never assume a default target (loudness, resolution, fps) - if the caller doesn't supply one, the corresponding check is simply not run, and `qc-skill` will not guess. 4. Treat `report.overall_status: "FAIL"` as **information**, not failure of your own operation - `status: "completed"` means the QC run itself succeeded. React to `findings[].code` to decide what to do next (that decision is yours, not qc-skill's). 5. A response `status: "failed"` (with an `error.code`) means the QC run itself could not complete - handle it like any other tool error. ## Boundaries qc-skill never: makes a publish/block/re-render decision, edits or re-encodes media, generates or rewrites subtitles, transcribes audio, performs semantic/scene understanding, executes a caller-supplied filter graph or shell command, or fabricates a measurement it could not actually take (an unmeasurable value is `null` with a note, or the check is `UNKNOWN` with a `reason` - never a guess).
View on GitHub