{"id":47631027,"url":"https://github.com/craigwatt/vfo","last_synced_at":"2026-04-26T13:00:28.006Z","repository":{"id":178171792,"uuid":"564853616","full_name":"CraigWatt/vfo","owner":"CraigWatt","description":"Autonomous media optimization engine for video libraries: mezzanine→source→profile workflows with quality checks and observability.","archived":false,"fork":false,"pushed_at":"2026-04-26T00:24:59.000Z","size":13832,"stargazers_count":5,"open_issues_count":17,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-26T00:35:52.692Z","etag":null,"topics":["c","cli","dolby-vision","ffmpeg","ffprobe","hevc","media-pipeline","mkv","mp4","rule-engine","transcoding","video-encoding","video-streaming","vmaf","workflow-engine"],"latest_commit_sha":null,"homepage":"https://craigwatt.github.io/vfo/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CraigWatt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2022-11-11T16:51:48.000Z","updated_at":"2026-04-26T00:24:41.000Z","dependencies_parsed_at":"2024-04-28T21:29:49.677Z","dependency_job_id":"ddc52d83-4549-44ab-b87f-21d69558dde8","html_url":"https://github.com/CraigWatt/vfo","commit_stats":null,"previous_names":["craigwatt/vfo"],"tags_count":87,"template":false,"template_full_name":null,"purl":"pkg:github/CraigWatt/vfo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CraigWatt%2Fvfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CraigWatt%2Fvfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CraigWatt%2Fvfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CraigWatt%2Fvfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CraigWatt","download_url":"https://codeload.github.com/CraigWatt/vfo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CraigWatt%2Fvfo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32297898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T09:34:17.070Z","status":"ssl_error","status_checked_at":"2026-04-26T09:34:00.993Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cli","dolby-vision","ffmpeg","ffprobe","hevc","media-pipeline","mkv","mp4","rule-engine","transcoding","video-encoding","video-streaming","vmaf","workflow-engine"],"created_at":"2026-04-01T23:29:55.232Z","updated_at":"2026-04-26T13:00:28.000Z","avatar_url":"https://github.com/CraigWatt.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Validate](https://img.shields.io/github/actions/workflow/status/CraigWatt/vfo/on-push-test.yml?branch=main\u0026label=validate)\n![E2E (media)](https://img.shields.io/github/actions/workflow/status/CraigWatt/vfo/on-self-hosted-e2e.yml?branch=main\u0026label=e2e%20media)\n![Docs](https://img.shields.io/github/actions/workflow/status/CraigWatt/vfo/ci-docs-pages.yml?branch=main\u0026label=docs)\n![Latest Release](https://img.shields.io/github/v/release/CraigWatt/vfo?display_name=tag)\n![License](https://img.shields.io/github/license/CraigWatt/vfo)\n![GitHub all releases](https://img.shields.io/github/downloads/CraigWatt/vfo/total)\n\n# vfo\n\n`vfo` is an autonomous media optimization engine for video libraries.\n\nInstead of applying one preset to every file, `vfo` reads a configuration file, inspects each input video, and chooses an FFmpeg command based on matching profile rules (configured with `PROFILE=` entries). The project is aimed at media-library and streaming workflows where source files vary widely in codec, color space, bit depth, and resolution.\n\nAt a system level, vfo implements a repeatable loop:\n\n- detect media properties\n- decide the profile + scenario path\n- act by executing deterministic profile actions\n- verify outcomes through status observability and optional quality scoring\n\n## Why use vfo?\n\n- Turn heterogeneous libraries into consistent, target-shaped outputs.\n- Model output intent as rules (profiles + scenarios), not one-off encode scripts.\n- Keep playback-driven output families separated with explicit profile targets.\n- Preserve folder structure while generating variants across one or many storage locations.\n- Keep full FFmpeg flexibility through explicit profile action commands.\n- Validate readiness and outcomes with `doctor`, `status`, `status-json`, `visualize`, and optional PSNR/SSIM/VMAF gates.\n\n## Outcome framing\n\nToday, vfo is strongest when you need:\n\n- a deterministic, auditable decision path from mezzanine to delivery profile\n- repeatable profile behavior across large libraries\n- a balance between quality, compatibility, and throughput\n- observable pipeline state for local runs and CI lanes\n\nvfo does not yet claim:\n\n- real-device playback certification for every target\n- universal automatic tuning without operator profile choices\n- complete quality guarantees unless thresholds/gates are explicitly configured\n\n## Current project status\n\n- **Actively implemented today:** macOS support is the clearest documented path in the repository.\n- **Planned / incomplete:** Linux and Windows support are referenced in project docs, but are still marked as work in progress.\n- **Configuration-first workflow:** `vfo` does not do much without a `vfo_config.conf` file.\n\nThe repository also includes an in-progress sample config at `services/vfo/src/vfo_config.conf`, which is the best reference for how profiles and scenarios are currently expressed.\n\n## AI workflow memory\n\nThis repository keeps AI routing context in markdown files that live with the code:\n\n- `AGENTS.md`\n- `objectives.md`\n- `architecture.md`\n- `subsystems.md`\n- `testing.md`\n- `escalation.md`\n\nThese files define the cheap-first routing policy, subsystem map, verification bar, and Codex escalation rules for issue-driven automation.\n\nFor day-to-day Codex work, the repository also keeps a small packet format in `task-packets.md` and issue templates under `.github/ISSUE_TEMPLATE/` so requests stay scoped and context-light.\n\n## Terminology\n\n- `Mezzanine` = high-quality working library input\n- `Source` = normalized intermediate layer\n- `Profile` = delivery target definition\n\nRecommended pipeline modes:\n\n1. Default: `mezzanine -\u003e source -\u003e profile`\n2. Optional: `mezzanine -\u003e profile` (skip source if your library is already normalized)\n\n## How vfo works\n\nAt a high level, `vfo` works like this:\n\n1. Read `vfo_config.conf`.\n2. Discover your mezzanine/source locations and profile definitions.\n3. For each candidate input file, inspect its media properties.\n4. Match the file against profile criteria and scenario conditions.\n5. Run the FFmpeg command attached to the first matching scenario.\n6. Write output into the profile destination while keeping the source folder layout.\n7. Optionally score outputs against a reference layer (PSNR/SSIM and optional VMAF) and apply strict gates.\n8. Surface run/stage outcomes through status observability for operator and CI feedback.\n\nOptional hygiene stage (configurable):\n\n- Run `vfo mezzanine-clean` to audit or normalize mezzanine folder/file naming before encode stages.\n\nOptional quality scoring stage (configurable):\n\n- Run post-profile `PSNR`/`SSIM` checks (and optional `VMAF`) against the selected reference layer (`source`, `mezzanine`, or `auto`).\n- Surface per-profile scoring status in run observability output.\n\n### Core concepts\n\n#### Mezzanine and source folders\n\nThe sample configuration distinguishes between a `MEZZANINE_LOCATION` and a `SOURCE_LOCATION`. The code also supports a `KEEP_SOURCE` switch, which changes whether profile generation runs from the mezzanine set or from the source set.\n\n#### Profiles\n\nA profile represents a target output collection, such as a compatibility tier for a specific playback device or streaming profile.\n\nEach profile can define criteria such as:\n\n- codec\n- bit depth\n- color space\n- minimum resolution\n- maximum resolution\n- destination folder\n\n#### Scenarios\n\nEach profile can contain one or more scenarios. A scenario is effectively a condition-expression plus an FFmpeg command.\n\nExamples of scenario conditions visible in the sample config include:\n\n- `CODEC_JUST_RIGHT`\n- `RES_TOO_HIGH`\n- `FULL_HD_OR_HIGHER`\n- `NO_VALID_COLOR_SPACE_DETECTED`\n- `ELSE`\n\nWhen a scenario matches, `vfo` runs the FFmpeg command tied to that scenario.\n\n## Installation\n\n### Option 1: install from a release\n\nThe repository's release notes describe two macOS-oriented installation paths:\n\n1. Install the `.pkg` release asset.\n2. Download the static build zip and copy the bundled `bin/` commands plus config file.\n\nRelease notes: [RELEASE.txt](./RELEASE.txt)\n\n## Release channels\n\nvfo uses three delivery lanes:\n\n- Main snapshot artifacts (on `main` pushes) for internal/beta testing.\n- Beta prereleases from tags like `v1.2.3-beta.1`.\n- Stable releases from tags like `v1.2.3`.\n- Successful `main` push validations auto-create the next stable tag (`vX.Y.Z`) for that commit, which triggers the stable release workflow automatically.\n\nCI/CD test integration:\n\n- Validation workflow (`PR + main`) runs `make ci` with hosted synthetic e2e (`VFO_E2E_ASSET_MODE=synthetic`, `VFO_E2E_MAX_SEEDS=1`).\n- Tag release workflows (beta + stable) also run `make ci` on hosted runners before packaging/release.\n- Full media-backed e2e runs on the self-hosted runner workflow `.github/workflows/on-self-hosted-e2e.yml`.\n- The self-hosted full-media workflow runs automatically on same-repo PRs to `main` and on `main` pushes, and can also be triggered manually with custom `assets_dir`, `clip_duration`, `max_seeds`, and optional DV fixture inputs.\n- Use local run mode (`VFO_E2E_ASSET_MODE=local`) when you want to validate against your own mounted media library.\n- Every e2e run captures `vfo` + dependency versions under `tests/e2e/.reports/latest/` and uploads them as workflow artifacts.\n- AI routing + premium escalation lanes are available via:\n  - `.github/workflows/ci-issue-routing.yml` (issue open/label routing with `GPT-5.4 mini first` or `GPT-5.4 high now` recommendation)\n  - `.github/workflows/ci-codex-autonomous-loop.yml` (premium Codex sweep + `agent-ready` issue trigger, opt-in only)\n  - `.github/workflows/ci-codex-pr-autofix.yml` (bounded premium CI autofix for Codex-owned PRs only, opt-in only)\n  - premium lane guardrails doc: `infra/docs/codex-autonomous-loop.md`\n  - task packet guide: `task-packets.md`\n- Docs site build + Pages deploy is available via:\n  - `.github/workflows/ci-docs-pages.yml` (PR build validation + `main` Pages deploy)\n- GHCR package lane is available via:\n  - `.github/workflows/ci-package-ghcr.yml` (publishes `ghcr.io/\u003cowner\u003e/vfo` on `main` and tag pushes)\n- Release publication jobs use explicit deployment environments:\n  - stable: `release-stable`\n  - beta: `release-beta`\n- Delivery model overview:\n  - `infra/docs/github-delivery-lanes.md`\n- Deployment/runtime strategy:\n  - `infra/docs/deployment-runtime-strategy.md`\n\nPackage quickstart:\n\n```bash\ndocker pull ghcr.io/craigwatt/vfo:main\ndocker run --rm ghcr.io/craigwatt/vfo:main --version\n```\n\n### Toolchain mode (CLI)\n\n`vfo` now supports runtime toolchain mode selection via environment variable:\n\n- `TOOLCHAIN_MODE=system` (default): use host PATH tools.\n- `TOOLCHAIN_MODE=auto`: currently falls back to host PATH tools (managed lane reserved).\n- `TOOLCHAIN_MODE=managed`: currently hard-fails with a clear message (managed CLI lane not active yet).\n\nExamples:\n\n```bash\nTOOLCHAIN_MODE=system vfo doctor\nTOOLCHAIN_MODE=auto vfo status-json\n```\n\n### Option 2: build from source\n\nPrerequisites:\n\n- `gcc`\n- `make`\n- a reasonably recent `ffmpeg`\n- `zsh` available as `/bin/zsh` or `zsh` in your shell environment, since the `Makefile` sets `SHELL := zsh`\n\nBuild the binary:\n\n```bash\nmake all\n```\n\nThe compiled executable is written to:\n\n```text\nservices/vfo/bin/vfo\n```\n\n#### Install target\n\nThe repository includes an install target:\n\n```bash\nmake install\n```\n\nBy default this copies the binary under `/usr/local/bin` and copies `services/vfo/src/vfo_config.conf` into `/usr/local/bin/vfo_conf_folder`.\nIt also copies stock profile-action scripts (`*.sh`, for example `transcode_*_profile.sh`, `profile_guardrail_skip.sh`) into `/usr/local/bin`.\n\n## Quick start\n\n1. Install FFmpeg and MKVToolNix (`mkvmerge`).\n2. Build or download `vfo`.\n3. Ensure `vfo_config.conf` exists at `/usr/local/bin/vfo_conf_folder/vfo_config.conf`.\n4. Edit the config file so the folder paths match your machine.\n5. Define at least one profile (`PROFILE=`) and one scenario.\n6. Run `vfo doctor` to validate environment + config.\n7. Run `vfo status` for a high-level readiness snapshot.\n8. Run `vfo visualize` for a local workflow view (HTML + JSON + Mermaid).\n9. Run `vfo mezzanine-clean` to preview mezzanine hygiene changes (or apply if enabled).\n10. Run `vfo run` for the default end-to-end pipeline.\n11. Run `vfo` with individual stage commands or a specific profile name when needed.\n\nExample starter flow:\n\n```bash\nsudo mkdir -p /usr/local/bin/vfo_conf_folder\nsudo cp services/vfo/src/vfo_config.conf /usr/local/bin/vfo_conf_folder/vfo_config.conf\n$EDITOR /usr/local/bin/vfo_conf_folder/vfo_config.conf\nvfo --help\nvfo doctor\nvfo status\nvfo status-json\nvfo visualize\nvfo mezzanine-clean\nvfo run\nvfo profiles\n```\n\n## Command-line usage\n\nThe help text in the repository currently documents this shape:\n\n```text\nvfo [argument] || [options]\n```\n\n### Options\n\n- `-h`, `--help` — print help text\n- `-v`, `--version` — print version information\n- `--no-color` — disable colored output\n\n### Common arguments\n\n- `mezzanine`\n- `source`\n- `show`\n- `wizard`\n- `config`\n- `doctor`\n- `status`\n- `status-json`\n- `visualize`\n- `run`\n- `mezzanine-clean`\n- `profiles`\n- `wipe`\n- any profile name defined in `vfo_config.conf` (via `PROFILE=`)\n\nA useful mental model is:\n\n- use `profiles` to run every configured profile\n- use a specific profile name to run only that profile\n- use `wipe` together with profile-oriented commands when you want profile outputs removed\n- use `doctor` before first run (or after machine/config changes)\n- use `status` to view a component-level readiness summary before execution\n- use `status-json` in automation/tests when you need machine-readable status\n- use `visualize` for local workflow artifacts (`status.json`, Mermaid, HTML)\n- use `mezzanine-clean` for optional mezzanine filename/folder hygiene and recommendations\n- use `run` for the default pipeline (mezzanine -\u003e source if enabled -\u003e profiles -\u003e optional quality scoring)\n- use `wizard` as onboarding: choose `quickstart` for recommended defaults or `advanced` for full tuning\n- use `config` to open the active config in `vim`, then fall back to `$EDITOR`\n\nWizard behavior highlights:\n\n- preflight checks for required tools and config-path write permissions\n- step-based onboarding flow with explicit review before write\n- safe config writes (temporary file + atomic replace + timestamped backup)\n- stock preset multi-select across the current shipped packs, including:\n  - `balanced_open_audio`\n  - `roku_family_all_sub_convert_audio_conform`\n  - `fire_tv_family_all_sub_convert_audio_conform`\n  - `chromecast_google_tv_family_all_sub_convert_audio_conform`\n  - `apple_tv_family_all_sub_convert_audio_conform`\n  - `fire_tv_stick_4k_dv_all_sub_convert_audio_conform`\n  - `device_targets_open_audio` (legacy compatibility)\n  - `craigstreamy_hevc_selected_english_subtitle_preserve`\n  - `craigstreamy_hevc_all_sub_preserve`\n  - `craigstreamy_hevc_smart_eng_sub_audio_conform`\n  - `craigstreamy_hevc_all_sub_audio_conform`\n  - `craigstreamy_hevc_smart_eng_sub_subtitle_convert`\n  - `craigstreamy_hevc_smart_eng_sub_subtitle_convert_audio_conform`\n  - `craigstreamy_hevc_smart_eng_sub_aggressive_vmaf`\n  - `craigstreamy_hevc_smart_eng_sub_audio_conform_aggressive_vmaf`\n\n## Configuration guide\n\nThe sample `services/vfo/src/vfo_config.conf` is long, but the structure is consistent.\n\nFor hardware-aware profile actions (for example Apple Silicon encode with CPU fallback), see:\n\n- `services/vfo/actions/`\n- `services/vfo/docs/profile-action-schema.md`\n- `services/vfo/examples/vfo_config.profile_actions.conf`\n\nFor stock shipping profile packs, see:\n\n- `services/vfo/presets/`\n\nFor device compatibility conformance checks, see:\n\n- `services/vfo/docs/device-conformance.md`\n- `tests/e2e/validate_device_conformance.sh`\n- `services/vfo/docs/mezzanine-clean.md`\n- `services/vfo/docs/quality-scoring.md`\n\nFor engine readiness and observability status output, see:\n\n- `services/vfo/docs/status-observability.md`\n- `services/vfo/docs/workflow-visualization.md`\n- `services/vfo/docs/workflow-engine.bpmn`\n- `services/vfo/docs/workflow-decisions.dmn`\n\n### 1. Set required paths\n\nStart by updating the top-level locations:\n\n- `MEZZANINE_LOCATION`\n- `MEZZANINE_LOCATIONS` (semicolon-separated, optional but recommended for multi-drive)\n- `MEZZANINE_LOCATION_MAX_USAGE_PCT` (semicolon-separated caps aligned to `MEZZANINE_LOCATIONS`)\n- `SOURCE_LOCATION`\n- `SOURCE_LOCATIONS` (semicolon-separated, optional but recommended for multi-drive)\n- `SOURCE_LOCATION_MAX_USAGE_PCT` (semicolon-separated caps aligned to `SOURCE_LOCATIONS`)\n- `SOURCE_AS_LOCATION`\n\nFor profile outputs, you can now also define:\n\n- `\u003cPROFILE\u003e_LOCATION`\n- `\u003cPROFILE\u003e_LOCATIONS`\n- `\u003cPROFILE\u003e_LOCATION_MAX_USAGE_PCT`\n\nWhen multiple locations are configured, `vfo` selects destinations by projected post-write utilization and available free space, honoring each location cap and keeping a reserve so near-full volumes are avoided.\n\n### 2. Decide global behavior\n\nExamples from the sample file include:\n\n- `KEEP_SOURCE`\n- `SOURCE_TEST_ACTIVE`\n- `SOURCE_TEST_TRIM_START`\n- `SOURCE_TEST_TRIM_DURATION`\n- `SOURCE_AS_ACTIVATE`\n- `MEZZANINE_CLEAN_ENABLED`\n- `MEZZANINE_CLEAN_APPLY_CHANGES`\n- `MEZZANINE_CLEAN_APPEND_MEDIA_TAGS`\n- `MEZZANINE_CLEAN_STRICT_QUALITY_GATE`\n- `QUALITY_CHECK_ENABLED`\n- `QUALITY_CHECK_INCLUDE_VMAF`\n- `QUALITY_CHECK_STRICT_GATE`\n- `QUALITY_CHECK_REFERENCE_LAYER`\n- `QUALITY_CHECK_MIN_PSNR`\n- `QUALITY_CHECK_MIN_SSIM`\n- `QUALITY_CHECK_MIN_VMAF`\n- `QUALITY_CHECK_MAX_FILES_PER_PROFILE`\n\n### 3. Define custom folders\n\nThe sample uses repeated `CUSTOM_FOLDER=\"name,type\"` entries, where the type is one of the approved values used in code today:\n\n- `films`\n- `tv`\n\n### 4. Define a profile\n\nA minimal profile pattern looks like this:\n\n```text\nPROFILE=\"queen\"\nQUEEN_LOCATION=\"/path/to/output\"\nQUEEN_LOCATIONS=\"/path/to/output;/Volumes/Media-2/path/to/output\"\nQUEEN_LOCATION_MAX_USAGE_PCT=\"90;95\"\nQUEEN_CRITERIA_CODEC_NAME=\"h264\"\nQUEEN_CRITERIA_COLOR_SPACE=\"bt709\"\nQUEEN_CRITERIA_RESOLUTION_MIN_WIDTH=\"352\"\nQUEEN_CRITERIA_RESOLUTION_MIN_HEIGHT=\"240\"\nQUEEN_CRITERIA_RESOLUTION_MAX_WIDTH=\"1920\"\nQUEEN_CRITERIA_RESOLUTION_MAX_HEIGHT=\"1080\"\n```\n\n### 5. Add scenarios and FFmpeg commands\n\nEach scenario is paired with one FFmpeg command:\n\n```text\nQUEEN_SCENARIO=\"RES_TOO_HIGH\"\nQUEEN_FFMPEG_COMMAND=\"ffmpeg ... $vfo_input ... $vfo_output\"\n```\n\nUse these placeholders in your command strings:\n\n- `$vfo_input`\n- `$vfo_output`\n\nThat lets `vfo` substitute the actual source and destination file paths at runtime.\n\n## Example use cases\n\n### Build a 1080p H.264 compatibility tier\n\nCreate a profile for older TVs, low-end streamers, or browser playback. Set the max resolution to 1920x1080, prefer `h264`, and add scenarios that:\n\n- remux compliant files\n- downscale larger files\n- reject files that are too small\n\n### Build multiple output targets from one library\n\nDefine separate profiles for:\n\n- a high-quality archive copy\n- a 1080p SDR streaming tier\n- a smaller mobile-friendly tier\n\nThen run:\n\n```bash\nvfo profiles\n```\n\n### Test your workflow on short clips first\n\nThe sample config includes source test settings so you can generate trimmed outputs while checking that your profile and FFmpeg logic behaves as expected.\n\n## Development\n\n### Repository layout\n\n```text\ninfra/\n  packaging/\n    macos/\nplatform/\n  docs-site/\n  vfo-desktop/\n    src-tauri/\n    web/\n    contracts/\n  vfo-contracts/\nservices/\n  vfo/\n    src/\n      ...\n    test/\ntests/\n  e2e/\n```\n\nTesting convention:\n\n- Service tests live beside each service in `services/\u003cservice-name\u003e/test/`.\n- Platform component tests live beside each component in `platform/\u003ccomponent\u003e/test/`.\n- Infra validation tests live in `infra/test/`.\n- Cross-service end-to-end tests live in `tests/e2e/`.\n\nNaming conventions and terminology policy:\n\n- canonical policy: `AGENTS.md`\n- latest audit snapshot: `infra/docs/naming-conventions-audit.md`\n\n### Build commands\n\n```bash\nmake all\nmake tests\nmake e2e\nmake ci\nmake clean\nmake clean_tests\n```\n\nNote that `make tests` links against `cmocka`, so you may need to install that dependency first.\n\nFor full local-media e2e:\n\n```bash\nVFO_E2E_ASSET_MODE=local VFO_E2E_ASSETS_DIR=\"/absolute/path/to/open-source-media\" VFO_E2E_MAX_SEEDS=4 make e2e\n```\n\n### Docs site\n\nThe monorepo docs site source is in `platform/docs-site/`.\n\nKey visual docs include:\n\n- `platform/docs-site/docs/pipeline-end-to-end.md`\n- `platform/docs-site/docs/flow-levels.md` (interactive React Flow canvases)\n- `platform/docs-site/docs/profile-visual-standard.md`\n- `platform/docs-site/docs/e2e-toolchain-latest.md`\n- generated stock profile sheets under `platform/docs-site/docs/profiles/generated/`\n\n### Desktop scaffold\n\nThe monorepo now includes a desktop-app scaffold intended for:\n\n- `services/vfo/` as the standalone processing engine\n- `platform/vfo-desktop/` as Tauri runtime + React UI shell (with React Flow web scaffold)\n- `platform/vfo-contracts/` as machine-readable schema contracts shared across UI/automation integrations\n\nSee:\n\n- `platform/vfo-desktop/README.md`\n- `platform/vfo-desktop/web/README.md`\n- `platform/vfo-desktop/contracts/allowed-cli-commands.json`\n- `platform/vfo-contracts/status-json.schema.json`\n\nLocal docs workflow:\n\n```bash\nmake docs-generate\nmake docs-build\n```\n\nOptional local preview:\n\n```bash\nmake docs-serve\n```\n\nPublished docs (when GitHub Pages is enabled for the repository):\n\n- `https://craigwatt.github.io/vfo/`\n\n## Known rough edges\n\n- Some documentation in the repository is still marked as work in progress.\n- The install path for `vfo_config.conf` appears inconsistent between the `Makefile` and the runtime error/help text.\n- The sample configuration contains roadmap comments and experimental notes alongside active settings.\n\n## Contributing\n\nContributions that improve documentation, example configs, portability, and installation behavior would all make the project easier to adopt.\n\n- Ask broader questions in [GitHub Discussions](https://github.com/CraigWatt/vfo/discussions/27)\n- Report bugs or feature ideas in [GitHub Issues](https://github.com/CraigWatt/vfo/issues)\n\n## Support\n\nIf the project is useful to you, consider starring the repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigwatt%2Fvfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcraigwatt%2Fvfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigwatt%2Fvfo/lists"}