419 lines
38 KiB
Markdown
419 lines
38 KiB
Markdown
---
|
|
name: video-editing-config-and-flags
|
|
description: Load when inspecting, setting, adding, renaming, reviewing, or debugging video-clipping.*, Spring profiles, scheduler/render guards, adapter selectors, filesystem paths, retention, local CV or local asset worker settings, their environment-variable mappings, or configuration-default drift. Use before any configuration or production-default change.
|
|
---
|
|
|
|
# Video Editing Configuration and Flags
|
|
|
|
Use this runbook to determine the effective configuration before starting the service or changing behavior. Treat every value below as repository state verified on **2026-07-21**, not as a production endorsement.
|
|
|
|
## Scope and routing
|
|
|
|
Use this skill for property ownership, precedence, defaults, environment mappings, validation, and flag-change review.
|
|
|
|
Do **not** use it to:
|
|
|
|
- start or operate a workflow; use `video-editing-run-and-operate`;
|
|
- rebuild local environments or provision models; use `video-editing-build-and-env`;
|
|
- diagnose a failed render or worker; use `video-editing-debugging-playbook` and `video-editing-diagnostics-and-tooling`;
|
|
- decide whether a behavior change may ship; use `video-editing-change-control`;
|
|
- judge output quality; use `video-editing-validation-and-qa`.
|
|
|
|
Definitions used here:
|
|
|
|
| Term | Meaning |
|
|
|---|---|
|
|
| Java default | Field initializer in `VideoClippingProperties`; applies when no higher-precedence source supplies the key. |
|
|
| Packaged effective default | Value obtained from packaged `application.properties` plus `application.yml` with no profile and no environment override. This is what a plain service start sees. |
|
|
| Guard | Spring condition or runtime test that enables a component or destructive action. |
|
|
| Adapter selector | String property used by `@ConditionalOnProperty` to choose one implementation. |
|
|
| Pre-provisioned | Dependency, executable, model, and licensed asset already present in the runtime image/filesystem; startup must not fetch it. |
|
|
| Fail-closed | Missing or invalid required capability prevents processing or promotion; it must not silently substitute lower-quality output. |
|
|
|
|
## Non-negotiable configuration policy
|
|
|
|
Enforce these user-supplied constraints for every environment:
|
|
|
|
1. Prohibit automatic dependency or model downloads, external AI services, network access, unlicensed assets, placeholder silence or tones, and unapproved rendering.
|
|
2. Do not change a production-facing default without `video-editing-change-control`, an ADR-style decision record, tests, rollback instructions, and environment impact analysis.
|
|
3. Provision local models and dependencies before runtime. Pin their identity and checksum outside behavioral configuration, then verify them before accepting work.
|
|
4. Production startup now fails under `strict-runtime=true` when Piper, MusicGen, AudioGen, their local paths, or the Python stack are absent. Keep that behavior and add license/checksum manifest verification before calling the runtime certified.
|
|
5. Keep all automatic render controls disabled and require an approval artifact at the render boundary.
|
|
6. Do not run `tools/run_local_cv_worker.sh` or `tools/run_local_asset_worker.sh` with their current default `BOOTSTRAP_MODE=auto` in a network-prohibited runtime. Both scripts can create virtualenvs and invoke `pip`; the CV script can also make Ultralytics resolve/download `yolov8n.pt`.
|
|
|
|
## Resolve the effective value
|
|
|
|
Use Spring Boot precedence: command-line arguments and environment-derived properties override packaged config; profile files override non-profile packaged files. This repository also embeds explicit `${CUSTOM_ENV:default}` placeholders in `application.yml`.
|
|
|
|
Follow this procedure:
|
|
|
|
1. Record active profiles and all `VIDEO_EDITING_*`, `FOLDER_SCHEDULER_*`, `LOCAL_ASSET_*`, and `LOCAL_CV_*` variables without exposing secrets.
|
|
2. Locate the key in `application-<profile>.*`, then `application.yml`, then `application.properties`, then the Java initializer.
|
|
3. Check the component guard below. A bound value can exist while its component is absent.
|
|
4. Check whether Java and packaged defaults differ. Packaged configuration wins in a normal application start.
|
|
5. For a generic Spring environment override, convert dots and hyphens to underscores and uppercase, for example `video-clipping.cleanup.enabled` to `VIDEO_CLIPPING_CLEANUP_ENABLED`. Prefer an explicit placeholder already present in `application.yml`; it documents the supported operational name.
|
|
|
|
Read configuration without starting the service:
|
|
|
|
```bash
|
|
sed -n '1,220p' src/main/resources/application.properties
|
|
sed -n '1,220p' src/main/resources/application.yml
|
|
sed -n '1,220p' src/main/resources/application-jpa.properties
|
|
sed -n '1,160p' src/main/resources/application-cinematic-editing-local.yml
|
|
sed -n '1,160p' src/main/resources/application-folder-scheduler-local.yml
|
|
sed -n '1,220p' src/test/resources/application.properties
|
|
```
|
|
|
|
## Critical drift: plain startup is unsafe
|
|
|
|
The packaged effective defaults activate multiple independent consumers and local bootstrap paths:
|
|
|
|
| Axis | Java default | Packaged effective default | Risk/status |
|
|
|---|---:|---:|---|
|
|
| folder scheduler enabled | `false` | `true` | Consumes files under `./input/source`. Unsafe for an exploratory start. |
|
|
| editing enabled | `true` | `true` | Creates editing components and starts runtime checks. |
|
|
| local director enabled | `true` | `true` | Polls editing input. Auto-render remains off in base config. |
|
|
| highlight scheduler enabled | `true` | `true` | Polls and moves highlight sources. |
|
|
| highlight render enabled | `false` | `false` | Render scan is fail-closed by default. |
|
|
| highlight approval required | `true` | `true` | Requires the configured flag when rendering is explicitly enabled; the bare flag is not production authorization. |
|
|
| visual provider | `heuristic` | `local-cv` | Packaged YAML selects the local HTTP adapter. |
|
|
| visual heuristic fallback | `true` | `true` | Quality may degrade without failing. Not production-ready. |
|
|
| local CV auto-start | `false` | `true` | Launches bootstrap script, which may install/download. Prohibited at runtime. |
|
|
| local asset auto-start | `false` | `true` | Runs resident-runtime verification at application startup; it no longer invokes the bootstrap script. |
|
|
| local asset strict runtime | `false` | `true` | Throws at startup when required local binaries, Python imports, model paths, or adjacent model-license sidecars are missing. |
|
|
| local director auto-render | `false` | `false` | Safe in base config. |
|
|
| local director approval required | `true` | `true` | Approval applies only if auto-render is enabled. |
|
|
|
|
The `cinematic-editing-local` profile sets local-director auto-render to `true` while requiring `approved.flag`. Treat the profile as a local workflow convenience, not a production profile. The `folder-scheduler-local` profile enables folder segmentation. Never activate either without checking the input directories.
|
|
|
|
## Complete application property catalog
|
|
|
|
Notation: `J` is the Java default; `P` is the packaged effective default when it differs. `@Min` is the only bean-validation constraint currently declared. Values without `@Min` generally lack startup validation.
|
|
|
|
### API, adapters, S3, queue, and processing
|
|
|
|
| Property | J / P default | Meaning, values, guard |
|
|
|---|---|---|
|
|
| `video-clipping.max-file-size-bytes` | `53687091200` | Max declared source size; `@Min(1)`. |
|
|
| `video-clipping.multipart-part-size-bytes` | `104857600` | Multipart chunk size; `@Min(5242880)`. |
|
|
| `video-clipping.upload-url-ttl-minutes` | `60` | Upload URL lifetime; `@Min(1)`. |
|
|
| `video-clipping.download-url-ttl-minutes` | `15` | Download URL lifetime; `@Min(1)`. |
|
|
| `video-clipping.allowed-content-types` | `video/mp4`, `video/quicktime`, `video/webm` | Boundary allow-list; no non-empty validation. |
|
|
| `video-clipping.repository` | no Java field / `memory` | Conditional selector only: `memory` (also match-if-missing) or `jpa`. It is present in packaged properties but absent from `VideoClippingProperties`. |
|
|
| `video-clipping.storage` | `memory` | `memory` (also match-if-missing) or `s3`; other values leave no storage adapter. |
|
|
| `video-clipping.queue` | `memory` | `memory` (also match-if-missing) or `db`; `db` enables polling and queue metrics. |
|
|
| `video-clipping.processing` | `stub` | `stub` (also match-if-missing) or `ffmpeg`; `stub` is not production output. |
|
|
| `video-clipping.s3.region` | `us-east-1` | S3 client region. |
|
|
| `video-clipping.s3.bucket` | `video-clipping-dev` | Object bucket; development name is not a production default. |
|
|
| `video-clipping.s3.endpoint` | unset | Optional endpoint override. |
|
|
| `video-clipping.s3.path-style` | `true` | Path-style addressing. |
|
|
| `video-clipping.database-queue.poll-interval-ms` | `1000` | Database queue scheduled delay; `@Min(100)`. |
|
|
| `video-clipping.database-queue.batch-size` | `5` | Max messages claimed per poll; `@Min(1)`. |
|
|
| `video-clipping.database-queue.visibility-timeout-ms` | `900000` | Expired-claim threshold; `@Min(1000)`. |
|
|
| `video-clipping.database-queue.max-attempts` | `3` | Dead-letter threshold; `@Min(1)`. |
|
|
| `video-clipping.database-queue.retry-backoff-ms` | `5000` | Retry delay; `@Min(0)`. |
|
|
| `video-clipping.quotas.max-active-jobs-per-tenant` | `5` | Active-job admission cap; `0` is permitted and rejects all new active work; `@Min(0)`. |
|
|
|
|
`application-jpa.properties` selects `repository=jpa`, `queue=db`, and `processing=stub`, then configures an H2 database in PostgreSQL compatibility mode with Flyway and Hibernate validation. It is not a PostgreSQL production profile.
|
|
|
|
Packaged Spring/platform settings are also configuration axes:
|
|
|
|
| Property | Packaged value | Status |
|
|
|---|---|---|
|
|
| `spring.application.name` | `video-clipping-service` | Service identity. |
|
|
| `spring.mvc.problemdetails.enabled` | `true` | Enables Spring Problem Details handling. |
|
|
| `management.endpoints.web.exposure.include` | `health,info,metrics,prometheus` | Exposure is not the same as authorization; production must secure management endpoints. |
|
|
| `spring.jpa.open-in-view` | `false` | Deliberate persistence boundary. |
|
|
| `logging.level.org.example.videoclips.folder` | `INFO` | Base YAML; explicit env `FOLDER_SCHEDULER_LOG_LEVEL`. |
|
|
| `spring.datasource.url/driver-class-name/username/password` | H2 memory URL / H2 driver / `sa` / empty | `application-jpa.properties` only; development/test convenience. |
|
|
| `spring.jpa.hibernate.ddl-auto` / `spring.jpa.show-sql` | `validate` / `false` | JPA profile schema validation and SQL logging. |
|
|
| `spring.flyway.enabled` | `true` | JPA profile migration control. |
|
|
|
|
Classify selectors and modes conservatively:
|
|
|
|
| Classification | Current values |
|
|
|---|---|
|
|
| Development/test only | `repository=memory`, `storage=memory`, `queue=memory`, `processing=stub`, H2 JPA profile, heuristic analysis, all local convenience profiles. |
|
|
| Experimental/unsafe for promoted output | heuristic fallback, network-capable local-CV auto-bootstrap, named/defaulted YOLO analysis, non-strict asset readiness, and any explicitly enabled render path whose approval is not authenticated and digest-bound. Historical Python/Java placeholder-audio fallbacks are removed in the 2026-07-21 working tree. |
|
|
| Production candidates requiring evidence | `repository=jpa` with real PostgreSQL, `storage=s3`, `queue=db`, `processing=ffmpeg`, pre-provisioned local CV/assets/director. Candidate means not certified by this repository. |
|
|
|
|
### API FFmpeg workspace, cleanup, and retention
|
|
|
|
| Property | J / P default | Meaning and validation |
|
|
|---|---|---|
|
|
| `video-clipping.ffmpeg.ffmpeg-binary` | `ffmpeg` | API clipper executable. |
|
|
| `video-clipping.ffmpeg.input-directory` | `./tmp/ffmpeg-input` | Materialized source workspace. |
|
|
| `video-clipping.ffmpeg.output-directory` | `./tmp/ffmpeg-output` | Generated clip workspace. |
|
|
| `video-clipping.ffmpeg.exact-preset` | `veryfast` | FFmpeg encoding preset used by the API clipper; absent from packaged config, so the Java default applies. |
|
|
| `video-clipping.ffmpeg.cleanup-local-files` | `true` | Per-job worker cleanup control. |
|
|
| `video-clipping.cleanup.enabled` | `true` | Runtime check inside both scheduled cleanup jobs; jobs still wake when false. |
|
|
| `video-clipping.cleanup.local-artifact-poll-interval-ms` | `300000` | Local cleanup delay; `@Min(30000)`. |
|
|
| `video-clipping.cleanup.local-artifact-retention-hours` | `24` | Age for FFmpeg and fixed temporary roots; `@Min(1)`. |
|
|
| `video-clipping.cleanup.retention-poll-interval-ms` | `3600000` | storage/repository cleanup delay; `@Min(30000)`. |
|
|
| `video-clipping.cleanup.source-retention-hours` | `168` | Expiry assigned to new source assets; `@Min(1)`. |
|
|
| `video-clipping.cleanup.clip-retention-hours` | `168` | Expiry assigned to clips; `@Min(1)`. |
|
|
|
|
Local artifact cleanup also targets fixed `tmp/in-memory-storage` and `tmp/stub-output`; those roots are not configurable. Relative paths resolve from the process working directory. Validate mount ownership, capacity, backups, retention, and path separation on macOS, Linux/VPS, and cloud runtimes.
|
|
|
|
### Folder segmentation scheduler
|
|
|
|
| Property | J / P default | Meaning and validation |
|
|
|---|---|---|
|
|
| `video-clipping.folder-scheduler.enabled` | J `false`; P `true` | Creates initializer, validator, clipper, and poller. |
|
|
| `.input-directory` | J `/input/source`; P `./input/source` | Inbox; scheduler moves candidates. Env: `FOLDER_SCHEDULER_INPUT_DIRECTORY`. |
|
|
| `.output-directory` | J `/output/clips`; P `./output/clips` | Segmented output. Env: `FOLDER_SCHEDULER_OUTPUT_DIRECTORY`. |
|
|
| `.processed-directory` | J `/input/processed`; P `./input/processed` | Successful source destination. Env: `FOLDER_SCHEDULER_PROCESSED_DIRECTORY`. |
|
|
| `.rejected-directory` | J `/input/rejected`; P `./input/rejected` | Failed source destination. Env: `FOLDER_SCHEDULER_REJECTED_DIRECTORY`. |
|
|
| `.working-directory` | J `/input/working`; P `./input/working` | Claimed source directory. Env: `FOLDER_SCHEDULER_WORKING_DIRECTORY`. |
|
|
| `.poll-interval-ms` | `5000` | Initial/fixed delay; `@Min(1000)`. Env: `FOLDER_SCHEDULER_POLL_INTERVAL_MS`. |
|
|
| `.segment-duration-seconds` | `8` | Segment target; `@Min(1)`; no explicit env placeholder. |
|
|
| `.ffmpeg-binary` / `.ffprobe-binary` | `ffmpeg` / `ffprobe` | Executables; no explicit env placeholders. |
|
|
| `.output-container` / `.exact-preset` | `mp4` / `veryfast` | FFmpeg output choices; no enum/allow-list validation. |
|
|
| `.preserve-input-quality` | `true` | Selects preservation behavior. Env: `FOLDER_SCHEDULER_PRESERVE_INPUT_QUALITY`. |
|
|
|
|
`FOLDER_SCHEDULER_ENABLED` controls the packaged guard; `FOLDER_SCHEDULER_LOG_LEVEL` controls only `org.example.videoclips.folder` logging.
|
|
|
|
### Editing, render, analysis, and assets
|
|
|
|
All keys below start with `video-clipping.editing`.
|
|
|
|
| Suffix | J / P default | Meaning / explicit environment variable |
|
|
|---|---|---|
|
|
| `.enabled` | `true` | Master component guard; `VIDEO_EDITING_ENABLED`. |
|
|
| `.project-directory` | `./output/edit-projects` | Multi-clip projects; `VIDEO_EDITING_PROJECT_DIRECTORY`. |
|
|
| `.highlight-project-directory` | `./output/highlight-projects` | Single-source projects; `VIDEO_EDITING_HIGHLIGHT_PROJECT_DIRECTORY`. |
|
|
| `.ffmpeg-binary` / `.ffprobe-binary` | `ffmpeg` / `ffprobe` | Editing executables; `VIDEO_EDITING_FFMPEG_BINARY`, `VIDEO_EDITING_FFPROBE_BINARY`. |
|
|
| `.thumbnail-count-per-clip` / `.contact-sheet-columns` | `5` / `5` | Inspection density; each `@Min(1)`; matching `VIDEO_EDITING_*` variable. |
|
|
| `.proxy-enabled` / `.proxy-width` | `true` / `640` | Proxy generation and width; width `@Min(1)`; matching `VIDEO_EDITING_*` variable. |
|
|
| `.scene-detection-threshold` | `0.35` | FFmpeg scene threshold; no range validation; `VIDEO_EDITING_SCENE_DETECTION_THRESHOLD`. |
|
|
| `.minimum-scene-duration-seconds` | `1.0` | Segment merge threshold; no validation; `VIDEO_EDITING_MINIMUM_SCENE_DURATION_SECONDS`. |
|
|
| `.silence-threshold-db` / `.silence-minimum-duration-seconds` | `-35.0` / `0.5` | Source audio analysis; no validation; matching `VIDEO_EDITING_*` variable. |
|
|
| `.target-duration-seconds` | `600` | Multi-clip target; `@Min(1)`; `VIDEO_EDITING_TARGET_DURATION_SECONDS`. |
|
|
| `.output-width` / `.output-height` / `.output-frame-rate` | `1920` / `1080` / `30` | Render geometry/rate; each `@Min(1)`; matching `VIDEO_EDITING_*` variable. |
|
|
| `.audio-sample-rate` | `48000` | Render audio rate; `@Min(1)`; `VIDEO_EDITING_AUDIO_SAMPLE_RATE`. |
|
|
| `.video-bitrate` / `.audio-bitrate` | `12000k` / `192k` | FFmpeg bitrate strings; no format validation; matching `VIDEO_EDITING_*` variable. |
|
|
| `.voiceover-provider` | `local` | Bound and tested but not consumed by main Java code; it is not a working remote-provider selector. Env: `VIDEO_EDITING_VOICEOVER_PROVIDER`. External AI is prohibited. |
|
|
| `.loudness-target-i` / `.loudness-true-peak` / `.loudness-range` | `-16.0` / `-1.5` / `11.0` | `loudnorm` parameters; no range validation; matching `VIDEO_EDITING_*` variable. |
|
|
| `.music-ducking-threshold` / `.music-ducking-ratio` | `0.045` / `8.0` | `sidechaincompress` parameters; no range validation; matching `VIDEO_EDITING_*` variable. |
|
|
| `.music-ducking-attack-ms` / `.music-ducking-release-ms` | `20` / `250` | Ducking timing; each `@Min(1)`; matching `VIDEO_EDITING_*` variable. |
|
|
| `.assets.music-folder` | `./input/highlights/assets/music` | Intended location for approved, licensed local music; directory membership is not license proof. `VIDEO_EDITING_ASSETS_MUSIC_FOLDER`. |
|
|
| `.assets.sfx-folder` | `./input/highlights/assets/sfx` | Intended location for approved, licensed local SFX; directory membership is not license proof. `VIDEO_EDITING_ASSETS_SFX_FOLDER`. |
|
|
| `.assets.fonts-folder` | `./input/highlights/assets/fonts` | Intended location for approved, licensed local fonts; directory membership is not license proof. `VIDEO_EDITING_ASSETS_FONTS_FOLDER`. |
|
|
| `.assets.luts-folder` | `./input/highlights/assets/luts` | Intended location for approved, licensed local LUTs; directory membership is not license proof. `VIDEO_EDITING_ASSETS_LUTS_FOLDER`. |
|
|
| `.assets.voiceover-folder` | `./output/highlight-projects/_voiceover-cache` | Generated voiceover cache; `VIDEO_EDITING_ASSETS_VOICEOVER_FOLDER`. |
|
|
|
|
Treat render, loudness, ducking, scene, and duration changes as output behavior changes. Require objective measurements and representative media evidence; configuration binding tests alone are insufficient.
|
|
|
|
Exact environment names for grouped editing rows:
|
|
|
|
| Property suffixes | Environment variables, in the same order |
|
|
|---|---|
|
|
| `.thumbnail-count-per-clip`, `.contact-sheet-columns` | `VIDEO_EDITING_THUMBNAIL_COUNT_PER_CLIP`, `VIDEO_EDITING_CONTACT_SHEET_COLUMNS` |
|
|
| `.proxy-enabled`, `.proxy-width` | `VIDEO_EDITING_PROXY_ENABLED`, `VIDEO_EDITING_PROXY_WIDTH` |
|
|
| `.silence-threshold-db`, `.silence-minimum-duration-seconds` | `VIDEO_EDITING_SILENCE_THRESHOLD_DB`, `VIDEO_EDITING_SILENCE_MINIMUM_DURATION_SECONDS` |
|
|
| `.output-width`, `.output-height`, `.output-frame-rate` | `VIDEO_EDITING_OUTPUT_WIDTH`, `VIDEO_EDITING_OUTPUT_HEIGHT`, `VIDEO_EDITING_OUTPUT_FRAME_RATE` |
|
|
| `.video-bitrate`, `.audio-bitrate` | `VIDEO_EDITING_VIDEO_BITRATE`, `VIDEO_EDITING_AUDIO_BITRATE` |
|
|
| `.loudness-target-i`, `.loudness-true-peak`, `.loudness-range` | `VIDEO_EDITING_LOUDNESS_TARGET_I`, `VIDEO_EDITING_LOUDNESS_TRUE_PEAK`, `VIDEO_EDITING_LOUDNESS_RANGE` |
|
|
| `.music-ducking-threshold`, `.music-ducking-ratio` | `VIDEO_EDITING_MUSIC_DUCKING_THRESHOLD`, `VIDEO_EDITING_MUSIC_DUCKING_RATIO` |
|
|
| `.music-ducking-attack-ms`, `.music-ducking-release-ms` | `VIDEO_EDITING_MUSIC_DUCKING_ATTACK_MS`, `VIDEO_EDITING_MUSIC_DUCKING_RELEASE_MS` |
|
|
|
|
### Visual analysis and local CV worker
|
|
|
|
All keys start with `video-clipping.editing.visual-analysis`.
|
|
|
|
| Suffix | J / P default | Meaning / explicit environment variable |
|
|
|---|---|---|
|
|
| `.provider` | J `heuristic`; P `local-cv` | Recognized routing is `local-cv`; any other value uses heuristic. Env: `VIDEO_EDITING_VISUAL_ANALYSIS_PROVIDER`. |
|
|
| `.endpoint` | `http://127.0.0.1:8091/v1/analyze-visuals` | Current local HTTP endpoint. Loopback is network, so this is a noncompliant implementation gap, not an approved certified path. Env: `VIDEO_EDITING_VISUAL_ANALYSIS_ENDPOINT`. |
|
|
| `.timeout-ms` | `30000` | Total HTTP call timeout; `@Min(1)`. Env: `VIDEO_EDITING_VISUAL_ANALYSIS_TIMEOUT_MS`. |
|
|
| `.fallback-to-heuristic` | `true` | On local-CV failure, return weaker heuristic analysis. Must be false in the fail-closed production target. Env: `VIDEO_EDITING_VISUAL_ANALYSIS_FALLBACK_TO_HEURISTIC`. |
|
|
| `.local-cv-worker.auto-start` | J `false`; P `true` | Starts `script` only when provider is `local-cv`. Runtime auto-start/bootstrap is prohibited. Env: `VIDEO_EDITING_LOCAL_CV_WORKER_AUTO_START`. |
|
|
| `.local-cv-worker.script` | `./tools/run_local_cv_worker.sh` | Launched executable. Env: `VIDEO_EDITING_LOCAL_CV_WORKER_SCRIPT`. |
|
|
| `.local-cv-worker.startup-wait-ms` | `0` | `0` skips health waiting; otherwise timeout; `@Min(0)`. Env: `VIDEO_EDITING_LOCAL_CV_WORKER_STARTUP_WAIT_MS`. |
|
|
| `.local-cv-worker.health-path` | `/health` | Health URI path. Env: `VIDEO_EDITING_LOCAL_CV_WORKER_HEALTH_PATH`. |
|
|
| `.local-cv-worker.health-check-interval-ms` | `1000` | Readiness poll and per-call cap; `@Min(1)`. Env: `VIDEO_EDITING_LOCAL_CV_WORKER_HEALTH_CHECK_INTERVAL_MS`. |
|
|
|
|
Worker-only environment variables are not Spring properties:
|
|
|
|
| Variable | Default/source | Effect and policy |
|
|
|---|---|---|
|
|
| `LOCAL_CV_HOST`, `LOCAL_CV_PORT` | `127.0.0.1`, `8091`; manager derives both from endpoint | Uvicorn bind address/port. Keep local to the service trust boundary. |
|
|
| `LOCAL_CV_BOOTSTRAP_MODE` | `auto` | `always` or first-use `auto` invokes pip. Runtime must use a pre-provisioned path/mode that cannot install. |
|
|
| `LOCAL_CV_PRELOAD_ONLY` | `false` | Exit after bootstrap/model preload. Preload can still download. |
|
|
| `LOCAL_CV_YOLO_MODEL` | `yolov8n.pt` | Ultralytics model path/name. A name can trigger model retrieval; production must supply a verified local path. |
|
|
| `LOCAL_CV_DISABLE_YOLO` | `false` | Skips YOLO and returns weaker/default labels. Experimental/debug only, never production-quality success. |
|
|
| `LOCAL_CV_LOG_LEVEL` | `INFO` | Python worker logging level. |
|
|
|
|
The worker health response reports library availability but returns HTTP 200 even if OpenCV or YOLO is absent. Do not equate `/health` success with production analysis readiness.
|
|
|
|
### Local asset runtime
|
|
|
|
All keys start with `video-clipping.editing.local-asset-worker`.
|
|
|
|
| Suffix | J / P default | Meaning / explicit environment variable |
|
|
|---|---|---|
|
|
| `.auto-start` | J `false`; P `true` | Runs bootstrap verification, not a persistent asset server. Must be false at production runtime under the no-download rule. Env: `VIDEO_EDITING_LOCAL_ASSET_WORKER_AUTO_START`. |
|
|
| `.strict-runtime` | J `false`; P `true` | Makes startup fail when the pre-provisioned local asset runtime is incomplete. It requires adjacent nonblank model-license sidecars but does not verify authenticity, origin, checksums, or allowed use. Env: `VIDEO_EDITING_LOCAL_ASSET_WORKER_STRICT_RUNTIME`. |
|
|
| `.bootstrap-script` | `./tools/run_local_asset_worker.sh` | Startup verifier command; `VIDEO_EDITING_LOCAL_ASSET_BOOTSTRAP_SCRIPT`. |
|
|
| `.script` | `./tools/local_asset_worker.py` | Per-asset CLI worker; `VIDEO_EDITING_LOCAL_ASSET_WORKER_SCRIPT`. |
|
|
| `.startup-wait-ms` | `0` | Bound and tested but not consumed by current asset verifier/synthesizer; `@Min(0)`. Env: `VIDEO_EDITING_LOCAL_ASSET_WORKER_STARTUP_WAIT_MS`. |
|
|
| `.health-path` | `/health` | Bound and tested but no local asset HTTP server consumes it. Env: `VIDEO_EDITING_LOCAL_ASSET_WORKER_HEALTH_PATH`. |
|
|
| `.health-check-interval-ms` | `1000` | Bound and tested but unused; `@Min(1)`. Env: `VIDEO_EDITING_LOCAL_ASSET_WORKER_HEALTH_CHECK_INTERVAL_MS`. |
|
|
| `.python-binary` | `./.venv-local-asset/bin/python` | Python used for import readiness and worker invocation; `VIDEO_EDITING_LOCAL_ASSET_PYTHON_BINARY`. |
|
|
| `.piper-binary` | `piper` | Voice model executable; `VIDEO_EDITING_LOCAL_ASSET_PIPER_BINARY`. |
|
|
| `.piper-model-path` | empty | Required in practice for Piper; `VIDEO_EDITING_LOCAL_ASSET_PIPER_MODEL_PATH`. |
|
|
| `.music-model` | `musicgen-small` | AudioCraft model name; `VIDEO_EDITING_LOCAL_ASSET_MUSIC_MODEL`. A short name is normalized to `facebook/<name>` and may download. |
|
|
| `.sfx-model` | `audiogen-medium` | AudioCraft model name; `VIDEO_EDITING_LOCAL_ASSET_SFX_MODEL`. A short name may download. |
|
|
|
|
Worker-only environment variables:
|
|
|
|
| Variable | Current behavior |
|
|
|---|---|
|
|
| `LOCAL_ASSET_BOOTSTRAP_MODE` | Script default `auto`; `auto`/`always` invokes pip. The Java verifier forcibly sets `auto`, overriding an inherited safer value. This blocks compliant runtime auto-start today. |
|
|
| `LOCAL_ASSET_PRELOAD_ONLY` | Java verifier sets `true`; script exits after dependency bootstrap. |
|
|
| `LOCAL_ASSET_PIPER_BINARY` | Java verifier passes configured binary; Python CLI also reads it by default. |
|
|
| `LOCAL_ASSET_PIPER_MODEL_PATH` | Java verifier exports it when nonblank; generation passes the configured model explicitly. |
|
|
| `LOCAL_ASSET_HOST`, `LOCAL_ASSET_PORT` | Script reads defaults `127.0.0.1:8092` but never uses them; there is no HTTP asset server. |
|
|
|
|
The Python and Java fallback success paths were removed in the 2026-07-21 working tree. Continue rejecting any generated asset whose production provenance, local model identity, checksum, license, and semantic fit are not verified; an audible WAV alone is insufficient.
|
|
|
|
### Local director and highlight scheduler
|
|
|
|
| Property suffix | Default | Meaning / explicit environment variable |
|
|
|---|---|---|
|
|
| `.local-director.enabled` | `true` | With editing enabled, polls multi-clip inbox; `VIDEO_EDITING_LOCAL_DIRECTOR_ENABLED`. |
|
|
| `.local-director.source/working/processed/rejected-directory` | `./input/editing/<state>` | Move-based lifecycle; matching `VIDEO_EDITING_LOCAL_DIRECTOR_*_DIRECTORY`. |
|
|
| `.local-director.poll-interval-ms` | `5000` | Initial/fixed delay; `@Min(1000)`; `VIDEO_EDITING_LOCAL_DIRECTOR_POLL_INTERVAL_MS`. |
|
|
| `.local-director.director-prompt-file-name` | `ai-director-prompt.md` | Prompt artifact; `VIDEO_EDITING_LOCAL_DIRECTOR_PROMPT_FILE_NAME`. |
|
|
| `.local-director.expected-plan-file-name` | `edit-plan.json` | Plan inbox filename; `VIDEO_EDITING_LOCAL_DIRECTOR_EXPECTED_PLAN_FILE_NAME`. |
|
|
| `.local-director.auto-render-when-plan-appears` | `false` | Enables render after plan scan; `VIDEO_EDITING_LOCAL_DIRECTOR_AUTO_RENDER`. Keep false unless explicitly approved. |
|
|
| `.local-director.require-approval-before-render` | `true` | Requires approval file when auto-rendering; `VIDEO_EDITING_LOCAL_DIRECTOR_REQUIRE_APPROVAL`. |
|
|
| `.local-director.approval-file-name` | `approved.flag` | Approval artifact name; `VIDEO_EDITING_LOCAL_DIRECTOR_APPROVAL_FILE_NAME`. |
|
|
| `.highlight-scheduler.enabled` | `true` | With editing enabled, enables both source and plan/render scanners; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_ENABLED`. |
|
|
| `.highlight-scheduler.source/working/processed/rejected-directory` | `./input/highlights/<state>` | Move-based source lifecycle; matching `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_*_DIRECTORY`. |
|
|
| `.highlight-scheduler.poll-interval-ms` | `5000` | Shared by source and render scanners; `@Min(1000)`; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_POLL_INTERVAL_MS`. |
|
|
| `.highlight-scheduler.render-enabled` | `false` | Runtime render scan gate; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_RENDER_ENABLED`. Keep false until the approval workflow is proven. |
|
|
| `.highlight-scheduler.require-director-approval` | `true` | Requires director approval file before flow; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_REQUIRE_DIRECTOR_APPROVAL`. The bare file is not digest-bound authorization. |
|
|
| `.highlight-scheduler.approval-file-name` | `approved.flag` | Approval artifact under director directory; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_APPROVAL_FILE_NAME`. |
|
|
| `.highlight-scheduler.max-highlights-per-source` | `3` | Plan item cap; `@Min(1)`; `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_MAX_HIGHLIGHTS_PER_SOURCE`. |
|
|
| `.highlight-scheduler.highlight-min-duration-seconds` | `8.0` | Lower duration clamp; `@Min(1)`; matching environment variable. |
|
|
| `.highlight-scheduler.highlight-max-duration-seconds` | `35.0` | Upper duration clamp; `@Min(1)`; matching environment variable. No validation ensures max >= min. |
|
|
|
|
Exact environment names for grouped scheduler rows:
|
|
|
|
| Property suffixes | Environment variables, in the same order |
|
|
|---|---|
|
|
| `.local-director.source/working/processed/rejected-directory` | `VIDEO_EDITING_LOCAL_DIRECTOR_SOURCE_DIRECTORY`, `VIDEO_EDITING_LOCAL_DIRECTOR_WORKING_DIRECTORY`, `VIDEO_EDITING_LOCAL_DIRECTOR_PROCESSED_DIRECTORY`, `VIDEO_EDITING_LOCAL_DIRECTOR_REJECTED_DIRECTORY` |
|
|
| `.highlight-scheduler.source/working/processed/rejected-directory` | `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_SOURCE_DIRECTORY`, `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_WORKING_DIRECTORY`, `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_PROCESSED_DIRECTORY`, `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_REJECTED_DIRECTORY` |
|
|
| `.highlight-scheduler.highlight-min/max-duration-seconds` | `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_HIGHLIGHT_MIN_DURATION_SECONDS`, `VIDEO_EDITING_HIGHLIGHT_SCHEDULER_HIGHLIGHT_MAX_DURATION_SECONDS` |
|
|
|
|
## Guards and coupled settings
|
|
|
|
| Behavior | Required condition | Additional gate |
|
|
|---|---|---|
|
|
| Folder segmentation | `folder-scheduler.enabled=true` | None beyond input eligibility; it moves files. |
|
|
| Editing API/core | `editing.enabled=true` or missing | Many editing beans use `matchIfMissing=true`. |
|
|
| Multi-clip director polling | editing and local-director enabled | Directory candidate rules. |
|
|
| Multi-clip auto-render | above plus `auto-render-when-plan-appears=true` | Approval file only when `require-approval-before-render=true`. |
|
|
| Highlight ingestion | editing and highlight scheduler enabled | Moves one eligible video at a time. |
|
|
| Highlight plan rendering | same | `render-enabled=true`; approval only when `require-director-approval=true`. |
|
|
| Local CV process | editing enabled | provider exactly `local-cv` and worker auto-start true. |
|
|
| Local CV fallback | provider `local-cv` fails | Returns heuristic only when fallback is true; otherwise throws. |
|
|
| Local asset readiness check | editing enabled | Local asset auto-start true; strict mode fails startup when readiness is incomplete. The bootstrap script is not invoked by this verifier. |
|
|
| Cleanup | scheduled unconditionally | Work skipped when cleanup enabled is false. |
|
|
| DB queue poller | `queue=db` | Requires JPA repository/infrastructure coherence. |
|
|
|
|
Before changing one setting, inspect all settings in its row. In particular, enabling an approval boolean without disabling render during rollout leaves a race window unless deployment/configuration is atomic.
|
|
|
|
## Profiles and tests
|
|
|
|
| Source | Overrides | Classification |
|
|
|---|---|---|
|
|
| `application.properties` | API defaults, adapters, S3, DB queue, FFmpeg workspace, quotas, cleanup, actuator exposure | Packaged base; currently development-oriented. |
|
|
| `application.yml` | Folder scheduler and complete editing tree | Packaged base; current all-on behavior is unsafe. |
|
|
| `application-jpa.properties` | JPA/db queue/stub plus H2, Flyway, Hibernate validation | Local/integration convenience, not production PostgreSQL. |
|
|
| `application-folder-scheduler-local.yml` | Enables local folder scheduler paths | Local only. |
|
|
| `application-cinematic-editing-local.yml` | Disables folder scheduler; enables editing/director auto-render with approval | Local only; rendering side effects. |
|
|
| `src/test/resources/application.properties` | Disables folder scheduler, director, highlight scheduler, CV auto-start, asset auto-start; sets asset strict false | Test safety override. |
|
|
| `src/test/resources/application-test.properties` | Disables folder scheduler only | Narrow test-profile override; do not assume it disables other consumers. |
|
|
|
|
`VideoClippingPropertiesTest` verifies most editing Java defaults and representative binding overrides. It does not exhaustively assert every top-level, folder, cleanup, queue, or highlight setting. Profile tests parse YAML values but do not prove safe runtime composition.
|
|
|
|
## Production target, not current implementation
|
|
|
|
For macOS development, Linux/VPS production, and cloud infrastructure, converge through change control on this behavior:
|
|
|
|
- Ship one immutable, platform-neutral application artifact, then create signed platform-specific runtime/model/image bundles. Promote the same bundle unchanged between environments for the same OS/CPU target; inject paths and secrets externally.
|
|
- Disable every scheduler, worker auto-start, and render path by default. Enable only the deployed capability.
|
|
- Run local model workers as pre-provisioned supervised processes or explicit adapters with no installation/download code in the request/startup path.
|
|
- Replace model-worker HTTP with in-process calls or explicitly designed non-network IPC. Deny model/media inference networking, including loopback. Treat API, database, storage, and telemetry as separately approved production integrations.
|
|
- Require verified local model paths, checksums, licenses, writable/output mounts, capacity limits, and health that validates model readiness.
|
|
- Make missing FFmpeg, FFprobe, Python stack, Piper model, AudioCraft model, CV model, or licensed asset fail startup/readiness for any enabled dependent capability.
|
|
- Disable heuristic, silence, tone, macOS `say`, and `espeak` substitutions for production results.
|
|
- Require approval for every render path and record the approver/artifact; a bare filesystem flag is a current mechanism, not sufficient Fortune 500 authorization evidence.
|
|
- Use distinct durable/shared project storage or enforce single-instance scheduling. Current filesystem queues/projects and move-based inboxes are not automatically horizontally scalable.
|
|
|
|
Do not silently implement this target by editing defaults. Record each gap as a controlled change with migration and rollback.
|
|
|
|
## Add or change a property
|
|
|
|
Complete every checkbox:
|
|
|
|
- [ ] State the requirement, owner, consumers, supported values/units, safe default, production classification, expiry/revisit condition, and whether it changes output or side effects.
|
|
- [ ] Search for an existing property before adding one; avoid aliases and speculative flags.
|
|
- [ ] Add the typed field under `VideoClippingProperties`; use an immutable value type where practical and add Jakarta validation for every meaningful range, nonblank path, enum, URI, or cross-field invariant.
|
|
- [ ] Decide whether omission must fail. Never give production-critical model, license, secret, endpoint, or approval settings an insecure fallback.
|
|
- [ ] Add the packaged property exactly once. If operations need an explicit environment name, use a documented placeholder and preserve Spring relaxed-binding consistency.
|
|
- [ ] Classify the default change through `video-editing-change-control`. Treat enabling a scheduler/worker/render, changing an adapter, endpoint, path, retention, quality threshold, model, codec, or fallback as production-facing.
|
|
- [ ] Map environment impact for macOS, Linux/VPS, and cloud: paths/mounts, permissions, filesystem persistence, process supervision, network policy, resources, secrets, rollout ordering, backward compatibility, and rollback value.
|
|
- [ ] Check coupled guards and all profiles. Make production fail closed; keep runtime downloads, external AI, network fetching, unlicensed assets, placeholders, and unapproved renders impossible.
|
|
- [ ] Add default, valid-override, invalid-value, and application-context guard tests. Add a cross-field test for min/max or mutually dependent settings.
|
|
- [ ] Add behavior tests proving the consumer uses the property. For output changes, add objective QA evidence; binding alone is not proof.
|
|
- [ ] Update this catalog and the configuration reference/documents of record. Explain every deliberate Spring Boot default deviation.
|
|
- [ ] Run the focused tests, full clean build prescribed by `video-editing-validation-and-qa`, configuration drift scans, and `git diff --check`.
|
|
- [ ] Provide rollout order, observable signals, rollback command/value, and removal date for temporary flags. Do not leave permanent dual paths without ownership.
|
|
|
|
## Review a proposed environment
|
|
|
|
Reject the configuration if any answer is “no”:
|
|
|
|
- [ ] Are only the intended scheduler and adapter beans enabled?
|
|
- [ ] Are model/dependency downloads impossible after image/build promotion?
|
|
- [ ] Do all model identifiers resolve to verified local artifacts rather than remote names?
|
|
- [ ] Are external AI and arbitrary remote worker endpoints impossible?
|
|
- [ ] Are all input, working, processed, rejected, project, cache, and temporary paths distinct, mounted, permissioned, capacity-limited, and retained intentionally?
|
|
- [ ] Does any missing model or asset fail closed without heuristic, silence, tone, `say`, or `espeak` substitution?
|
|
- [ ] Is every render disabled until authenticated approval is present?
|
|
- [ ] Are queue/repository/storage selectors coherent and production adapters, not `memory`/`stub`/H2 conveniences?
|
|
- [ ] Are cleanup and retention consistent with recovery, audit, and legal requirements?
|
|
- [ ] Are local worker health checks capability-aware, and are timeout/resource limits proven?
|
|
- [ ] Is the same application artifact and same signed runtime bundle used without rebuild across environments for each platform target, with auditable external configuration?
|
|
|
|
## Provenance and maintenance
|
|
|
|
Primary sources: `VideoClippingProperties`, packaged/profile/test configuration, all `@ConditionalOnProperty`/`@ConditionalOnExpression` guards, scheduler annotations, local worker managers, shell launchers, Python workers, and configuration/profile tests. Re-verify volatile facts after any configuration, worker, or dependency change.
|
|
|
|
```bash
|
|
# List declared Java defaults and validation annotations.
|
|
rg -n '^ public static class|^[[:space:]]+@(Min|Max|NotBlank|NotNull|Pattern)|^[[:space:]]+private ' src/main/java/org/example/videoclips/config/VideoClippingProperties.java
|
|
|
|
# Regenerate the packaged/profile/test key inventory.
|
|
rg -n '^[[:space:]]*[A-Za-z0-9_.-]+[=:]' src/main/resources src/test/resources
|
|
|
|
# Find configuration consumers and guards.
|
|
rg -n '@ConditionalOn(Property|Expression)|@Scheduled|video-clipping\.' src/main/java src/test/java
|
|
|
|
# Regenerate explicit environment mappings and worker-only variables.
|
|
rg -n '\$\{[A-Z][A-Z0-9_]*:|LOCAL_(ASSET|CV)_[A-Z0-9_]+' src/main/resources tools src/main/java
|
|
|
|
# Recheck fallback and download hazards without executing them.
|
|
rg -n 'pip install|get_pretrained|YOLO\(|fallback|write_silence|write_fallback_tone|strictRuntime|strict-runtime' tools src/main/java src/main/resources
|
|
|
|
# Run focused binding/profile tests only after confirming test resources disable side effects.
|
|
mvn -o -Dtest=VideoClippingPropertiesTest,CinematicEditingLocalProfileTest,FolderSchedulerLocalProfileTest,FolderSchedulerSpringContextTest test
|
|
|
|
# Check documentation formatting and the repository diff without mutation.
|
|
wc -l .claude/skills/video-editing-config-and-flags/SKILL.md
|
|
git diff --check -- .claude/skills/video-editing-config-and-flags
|
|
```
|