284 lines
20 KiB
Markdown
284 lines
20 KiB
Markdown
---
|
|
name: video-editing-diagnostics-and-tooling
|
|
description: "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.
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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 `outputPath` resolution;
|
|
- 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
|
|
|
|
```bash
|
|
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.duration` with 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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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.properties` is 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:
|
|
|
|
- `UP` proves 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 `/health` handling 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 from `qa-report.json` alone.
|
|
|
|
## Provenance and maintenance
|
|
|
|
Re-verify volatile facts from the repository root; none of these commands starts the application or accesses the network:
|
|
|
|
```bash
|
|
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
|
|
```
|