20 KiB
| name | description |
|---|---|
| video-editing-diagnostics-and-tooling | Load this skill when you need a read-only measurement tool: inventory edit/highlight project state, verify a render manifest or QA report against media, run FFprobe/FFmpeg probes, lexically audit runtime hazards/defaults, inspect existing logs/metrics/health captures, or rerun an existing benchmark harness offline. Do not load it for interactive symptom-to-branch triage or for causal proof after triage. |
Video Editing Diagnostics and Tooling
Use measurement before changing code. Treat every passed field, health response, log line, and benchmark document as a claim with a known evidence boundary.
Verified against the repository on 2026-07-21.
Do not use this skill when
| Need | Load this sibling instead |
|---|---|
| Classify, approve, implement, or promote a behavior change | video-editing-change-control |
| Start schedulers, workers, or the service; deploy or recover it | video-editing-run-and-operate |
| Look up a configuration property or add a flag | video-editing-config-and-flags |
| Choose acceptance thresholds or certify a render/release | video-editing-validation-and-qa |
| Triage a known symptom interactively | video-editing-debugging-playbook |
| Explain a settled failure or rejected fix | video-editing-failure-archaeology |
| Prove a new algorithm or quality mechanism | video-editing-proof-and-analysis-toolkit |
Do not use a diagnostic result to bypass change control. Diagnostics may falsify a claim; they do not authorize a render, default change, dependency installation, model acquisition, or production promotion.
Diagnostic safety boundary
The canonical prohibitions are in video-editing-change-control; the configuration catalog is video-editing-config-and-flags, and acceptance evidence is defined by video-editing-validation-and-qa. Never perform these actions from a diagnostic session:
- Download a dependency or model automatically.
- Call an external AI service or use network transport for model/media work, including loopback.
- use an asset without recorded license/provenance evidence.
- Accept silence, a generated tone, or an OS speech fallback as production voiceover/music/SFX.
- Trigger rendering without recorded approval.
- change a production-facing default.
- Start the application merely to inspect project files. Current defaults enable the folder scheduler, editing, local director, highlight ingestion, and two local-worker auto-start paths; highlight rendering itself defaults off.
The local worker shell scripts are not safe diagnostic commands. tools/run_local_asset_worker.sh and tools/run_local_cv_worker.sh run pip install in their default auto bootstrap mode. The CV script also constructs an Ultralytics YOLO model from the default yolov8n.pt, which may initiate model acquisition when the file is absent. The asset runtime verifier no longer calls its bootstrap script and strict readiness now fails startup when resident model paths are missing.
Start here
Run these from the repository root. They are offline and read-only.
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/audit_runtime_safety.py --repo . --fail-on never
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/inventory_projects.py --repo . --fail-on never
Then verify a specific render:
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/verify_render.py \
--repo . \
--project-dir output/edit-projects/PROJECT_ID
For a per-highlight render, point --project-dir to its directory:
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/verify_render.py \
--repo . \
--project-dir output/highlight-projects/PROJECT_ID/highlights/HIGHLIGHT_ID \
--deep
--deep reads the entire media file three times through FFmpeg. Run it on a production copy or isolated worker, not on a latency-sensitive service volume.
Shipped tools
| Tool | Question answered | Dependencies | Exit codes |
|---|---|---|---|
scripts/inventory_projects.py |
Which edit/highlight projects are partial, inconsistent, stale, or backed only by asserted QA? | Python 3 standard library | 0 no finding at selected threshold; 2 findings; 3 invocation/read error |
scripts/verify_render.py |
Does a manifest agree with the real output duration and streams? Were QA checks measured or asserted? | Python 3, ffprobe; ffmpeg with --deep |
0 no error finding; 2 verification error; 3 tool/input error |
scripts/audit_runtime_safety.py |
Where do forbidden downloads, placeholders, auto-start, auto-render, approval bypass, or asset-license gaps remain? | Python 3 standard library | 0 no selected-severity finding; 2 finding; 3 invocation/read error |
All output ordering is deterministic. JSON mode is suitable for later CI integration:
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/inventory_projects.py \
--repo . --stale-hours 24 --format json --fail-on warning
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/audit_runtime_safety.py \
--repo . --format json
--stale-hours compares file modification times with the invocation time. Omit it when reproducibility across dates matters. An asset request count means request JSON files exist; it does not prove that every request remains unresolved.
Interpret project state
The edit project root defaults to output/edit-projects; the highlight project root defaults to output/highlight-projects. Override either root explicitly when diagnosing a mounted production copy:
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/inventory_projects.py \
--repo . \
--edit-root /mounted-copy/edit-projects \
--highlight-root /mounted-copy/highlight-projects \
--format table --fail-on error
The tool only treats a child as a project when project.json exists. It ignores caches such as _voiceover-cache.
| Observation | Meaning | Next discriminating check |
|---|---|---|
RENDERED_OUTPUT_MISSING |
Persisted state claims completion, but final.mp4 is absent. |
Inspect storage/copy logs; do not repair state by hand. |
OUTPUT_STATUS_MISMATCH |
A final file exists while project state is nonterminal/failed. | Verify the file and manifest, then inspect the state-transition failure. |
MANIFEST_OUTPUT_MISSING |
Provenance exists for an absent local output. | Resolve whether cleanup, relocation, or failed publication occurred. |
DIRECTOR_PLAN_MISSING |
A planned/rendering/rendered highlight has no director plan at the folder-contract path. | Check move/copy history and highlight_render_scan_* events. |
HIGHLIGHT_QA_ASSERTED |
A highlight QA report exists but did not run FFmpeg media probes. | Run verify_render.py --deep; do not certify from the report. |
NONTERMINAL_STALE |
No project file changed inside the chosen time window. | Identify the expected scanner/worker and correlate its last event. |
RENDERED_QA_MISSING |
A render has no persisted QA report. | Verify it independently; absence is not a pass or failure by itself. |
Statuses are CREATED, ANALYZING, ANALYZED (edit only), WAITING_FOR_DIRECTOR, PLANNING (edit only), PLANNED, RENDERING, RENDERED, and FAILED. Only RENDERED and FAILED are terminal for stale detection.
Separate measured QA from asserted QA
This distinction is load-bearing.
| Renderer | Current report behavior | Evidence actually present |
|---|---|---|
FfmpegEditRenderer |
Runs blackdetect, silencedetect, and astats; also checks files, timeline arithmetic, assets, overlays, command recording, and configured mastering filters. |
Media probes plus structural assertions. A warning does not make overall passed false; only failed ERROR checks do. |
HighlightFfmpegRenderer |
Marks duration, assets, overlays, and mastering checks true from plan/file assumptions; runs no black/silence/peak probe in buildQaReport. |
Assertions only. Its passed: true is not measured cinematic, visual, or audio quality. |
The older edit duration check compares the edit plan to the duration value passed into report construction. It does not probe the rendered container duration. Always compare render-manifest.json.durationSeconds with FFprobe independently.
verify_render.py checks:
- manifest
outputPathresolution; - FFprobe readability;
- manifest duration versus container duration, default tolerance
0.10s; - presence of video and audio streams;
- codec, dimensions, pixel format, frame-rate expression, sample rate, channels, and file size;
- declared QA failure and measured-versus-asserted classification;
- optionally, black ranges, silence ranges, and audio peaks using the repository's current thresholds.
It does not prove that highlights are correctly selected, pacing is cinematic, speech is intelligible, music/SFX are appropriate or licensed, overlays are readable, colors are intentional, or source-to-output continuity is correct. Load video-editing-validation-and-qa for certification.
Direct media measurements
Use an explicit input path. These commands read media and write only standard output/error.
Container and streams
ffprobe -v error -show_streams -show_format -of json -- path/to/final.mp4
Interpretation checklist:
- Confirm exactly the stream topology required by the acceptance contract; this project normally emits H.264 video and optional/expected AAC audio depending on the flow.
- Compare
format.durationwith the manifest and planned timeline. Container duration, stream duration, and planned duration can differ. - Confirm dimensions, pixel format, average frame rate, audio sample rate, channels, and codec rather than inferring them from a filename/profile string.
- Treat successful decode metadata as structural evidence, not creative-quality evidence.
Black, silence, clipping, freeze, and loudness
Repository-equivalent probes:
ffmpeg -hide_banner -v info -i path/to/final.mp4 -vf 'blackdetect=d=0.5:pic_th=0.98' -an -f null -
ffmpeg -hide_banner -v info -i path/to/final.mp4 -af 'silencedetect=noise=-45dB:d=2' -vn -f null -
ffmpeg -hide_banner -v info -i path/to/final.mp4 -af 'astats=metadata=1:reset=1' -vn -f null -
Additional investigative probes, not current application gates:
ffmpeg -hide_banner -v info -i path/to/final.mp4 -vf 'freezedetect=n=-60dB:d=2' -an -f null -
ffmpeg -hide_banner -v info -i path/to/final.mp4 -af 'ebur128=peak=true' -vn -f null -
Interpret the event timestamps, not just whether a word appears. Intentional fades can trigger black detection; pauses can trigger silence detection; a static composition can trigger freeze detection. Compare each interval with the edit plan and source. astats peaks at or above -0.1 dBFS fail the older renderer's audio-peak predicate. The configured mastering targets are integrated loudness -16 LUFS, true peak -1.5 dBTP, and loudness range 11 LU; the renderer invokes loudnorm, but only measurement can show the result.
Logs: event IDs and correlation
Application logs are SLF4J messages containing stable-looking event=<id> key/value tokens. They are not configured as JSON in the repository. Do not call them machine-readable structured logs until a formatter/parser contract is implemented and tested.
Search source-defined IDs without guessing:
rg -o 'event=[a-zA-Z0-9_{}-]+' src/main/java | sed 's/.*event=//' | sort -u
| Investigation | Start events | Completion/failure events | Correlation fields present in relevant paths |
|---|---|---|---|
| Edit analysis | edit_analysis_started |
edit_analysis_completed |
project_id, elapsed/count fields |
| Edit render | edit_render_started |
edit_render_completed, edit_render_failed |
project_id, elapsed, output, duration, size/error |
| Highlight ingest/analysis | highlight_scan_started, highlight_analysis_started |
highlight_scan_completed, highlight_processing_failed, highlight_analysis_completed |
scan_id, project_id, source/candidate fields vary by event |
| Highlight render flow | highlight_flow_started, highlight_render_started |
highlight_flow_completed, highlight_render_completed |
flow_id, scan_id, project_id, highlight_id across relevant events |
| Local CV | local_cv_request_started, local_cv_worker_starting |
local_cv_visual_analysis_completed, local_cv_visual_analysis_failed, worker lifecycle events |
clip/endpoint/status/elapsed fields vary |
| Local assets | local_asset_runtime_check_started, local_asset_generation_started |
local_asset_generation_completed, local_asset_generation_failed |
project/type/model/target/strategy fields vary |
Discriminating searches:
rg 'event=highlight_(flow|render|asset)|event=local_asset_' path/to/application.log
rg 'project_id=PROJECT_ID|flow_id=PROJECT_ID:' path/to/application.log
rg 'fallback|degraded|pending|failed|silence|ffmpeg-sine' path/to/application.log
Do not assume trace correlation exists. The build has no Micrometer Tracing/OpenTelemetry/Brave dependency and source has no tracer instrumentation as of the verification date. Documentation says traceId “if available”; that is not implementation evidence.
Never put media paths containing sensitive names, prompt bodies, transcript/voiceover text, tokens, tenant/user IDs, or exception payloads into newly added broad logs. Existing logs include paths and failure messages; assess redaction before production use.
Metrics, dashboards, and alerts
Actuator exposes health, info, metrics, and prometheus. Prometheus metric names translate dots to underscores.
| Metric family in code | Type | Interpretation |
|---|---|---|
video.clipping.queue.pending, .processing, .dlq, .oldest.pending.age.seconds |
DB-queue-only gauges | Backlog state; absent when queue mode is not db. |
video.clipping.edit.projects.created |
Counter | Process-local project creations since restart. |
video.clipping.edit.analysis.duration |
Timer | Analysis attempts that reached analysisCompleted; failures before it may be absent. |
video.clipping.edit.analysis.clip.count, .error.count |
Distribution summaries | Per-completed-analysis counts, not current gauges. |
video.clipping.edit.render.duration |
Timer | Both completed and failed renders record duration. |
video.clipping.edit.render.failures |
Counter | Render exceptions observed by instrumented renderers. |
video.clipping.edit.render.output.duration.seconds, .size.bytes |
Distribution summaries | Completed render output claims passed to observability, not FFprobe measurements. |
video.clipping.edit.director.prompt.tokens, .asset.generation.cost.usd |
Distribution summaries | Estimates, not tokenizer/provider invoices. |
The checked-in Grafana dashboard currently covers DB queue depth/age/DLQ/processing, API request rate and p95, CPU, and heap. It does not visualize edit/highlight render metrics or creative/business quality. The checked-in alert document covers queue age, DLQ, API 5xx, target down, and process CPU. It explicitly records missing job-failure, FFmpeg-exit, storage-failure, signed-URL, and disk metrics.
Do not invent a render success ratio: there is no render-success counter. A candidate alert such as increase(video_clipping_edit_render_failures_total[15m]) > 0 can detect recorded exceptions, but it misses silent audio/preview fallbacks and needs change-control approval, deployment labels, threshold evidence, and a linked runbook before adoption.
Cardinality rules
- Never tag metrics with
project_id,highlight_id,flow_id,scan_id, file path, prompt, model path, tenant/user ID, request ID, trace ID, or raw exception message. - Put per-project correlation in logs/traces; use metrics only for bounded dimensions such as workflow, outcome, stage, or a reviewed error class.
- Enumerate every allowed tag value in the design review. Reject free-form strings.
- Verify emitted series count and actual Prometheus names in a production-like scrape before adding panels or alerts.
- Do not expose health/details or Prometheus publicly. Exposure in
application.propertiesis endpoint availability, not proof of authorization or network policy.
Health is not readiness proof
RepositoryHealthIndicator, QueueHealthIndicator, and ObjectStorageHealthIndicator always return UP with adapter/capability details. They do not execute a repository query, publish/claim a message, access object storage, invoke FFmpeg/FFprobe, verify disk capacity, or check local models. Consequently:
UPproves only that Spring constructed those adapter beans and called the indicator.- The DB-queue gauges query repository state, but their presence is not an end-to-end queue test.
- Local asset/CV worker
/healthhandling is separate from Actuator health. - No repository evidence establishes distinct liveness/readiness groups or an authenticated actuator policy.
Treat a health response as one signal. Correlate it with queue age, real project progress, dependency metrics, logs, and an approved synthetic transaction.
Benchmark harnesses
These Maven tests are reproducible local planning harnesses. They write reports under target/benchmarks; they are not read-only and they are not production load tests.
| Command | What it measures | What it does not prove |
|---|---|---|
mvn -q -o -Dtest=FfmpegPresetBenchmarkHarness test |
Real FFmpeg preset wall time/output bytes on generated 16s 720p input | Production throughput or highlight quality |
mvn -q -o -Dtest=WorkerBenchmarkHarness test |
Synchronous stub worker CPU/wall/local/uploaded bytes for modeled 600s input | Real FFmpeg or object-store behavior |
mvn -q -o -Dtest=ObjectStorageBandwidthBenchmarkHarness test |
Local copy and throttled transfer throughput | Live S3/network performance |
mvn -q -o -Dtest=CostModelBenchmarkHarness test |
Formula output using checked-in assumptions | Current vendor pricing or invoice forecast |
Run a harness only after confirming it cannot trigger forbidden model/dependency acquisition in the prepared environment. Record hardware, OS, Java, Maven, FFmpeg, source commit, warmup, sample count, input, and raw report. Never compare current output to checked-in numbers without normalizing those variables. No checked-in load generator or executed production-like end-to-end load result exists as of 2026-07-21.
Evidence checklist for a diagnostic report
- Record repository commit and dirty-worktree state without mutating Git.
- Record OS/architecture, Java, Maven, FFmpeg, and FFprobe versions.
- State whether files are originals or read-only copies and identify the project/highlight IDs.
- Attach inventory JSON and render-verifier JSON.
- Distinguish an asserted application field from an independently measured value.
- State thresholds before running the measurement.
- Preserve negative observations and failed commands.
- Redact secrets, personal data, transcripts, voiceover text, signed URLs, and sensitive paths.
- Route every proposed behavior/config/instrumentation change through
video-editing-change-control. - Route certification through
video-editing-validation-and-qa; never certify by eye or fromqa-report.jsonalone.
Provenance and maintenance
Re-verify volatile facts from the repository root; none of these commands starts the application or accesses the network:
rg -n 'auto-start:|render-enabled:|require-director-approval:|fallback-to-heuristic:' src/main/resources/application*.yml
rg -n 'pip install|YOLO\(' tools src/main/java
rg -n 'fallbackTone|writeSilence|anullsrc|ffmpeg-sine|strategy=silence' src/main/java tools
rg -n 'RenderQaCheck|blackdetect|silencedetect|astats' src/main/java/org/example/videoclips/editing/{FfmpegEditRenderer,HighlightFfmpegRenderer}.java
rg -n 'registry\.(counter|timer|summary)|Gauge.builder' src/main/java
rg -n 'micrometer-tracing|opentelemetry|zipkin|brave|ObservationRegistry|Tracer' pom.xml src/main || true
rg -n 'management.endpoints.web.exposure.include' src/main/resources
jq -r '.panels[]? | [.title,.type] | @tsv' dashboards/video-clipping-overview-grafana.json
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/inventory_projects.py --help
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/verify_render.py --help
python3 .claude/skills/video-editing-diagnostics-and-tooling/scripts/audit_runtime_safety.py --help