A reproducible, GPU-native quality gate for first-person video.
News · Features · Quickstart · Examples · Policy config · Status
Fenon Gate turns signed HTTPS or immutable R2 video inputs into typed QC reports and hash-verified evidence. Operators choose only a backend and policy. Model paths, TensorRT, NVDEC, and GPU selection stay in Docker Compose.
Important
The local Docker Compose backend is implemented and validated on an NVIDIA A10. Managed cloud is upcoming and is not a released production feature.
- 2026-09-15 — A10 canary passed. The HTTPS → NVDEC → TensorRTNative → policy → evidence path completed on Lambda Cloud without CPU or inference fallback. See the canary record.
- 2026-09 — Local preview available. The
fgateCLI, asynchronous API, minimal YAML configuration, versioned standard policy, and safe R2 batch lifecycle are implemented in the working tree.
- One small config. Select
localorcloudand a named policy. - GPU-only production path. Readiness requires TensorRTNative, NVDEC, the selected GPU, and the exact model.
- Typed QC checks. Every check returns structured measurements, limits, outcomes, and applicable temporal intervals.
- Verified evidence. Evidence is checked by byte size and SHA-256 before it is accepted locally or remotely.
- Safe batch processing. R2 sources are immutable, destinations are create-only, and local media is cleaned only after verified upload.
- No hidden fallback. A missing model, provider, decoder, or runtime fails readiness instead of changing execution semantics.
Create config.yaml:
version: 1
backend: local
policy: standardThis is the complete operator configuration. Model paths, inference backend,
video decoder, and GPU selection remain in docker-compose.yaml.
- Python 3.12 or newer and
uv - Docker with Compose
- NVIDIA driver and Container Toolkit
- FFmpeg with
h264_cuvidand a matchinglibnvcuvid.so.1 - approved dynamic hand model at the path mounted by docker-compose.yaml
uv venv --python 3.12 .venv
uv pip install -e '.[dev,cpu]'
source .venv/bin/activateexport FGATE_GPU_DEVICE=0
fgate deploy start config.yamlDeployment succeeds only after the API reports the expected GPU, model, TensorRTNative provider, NVDEC backend, and policy hashes.
fgate check config.yaml 'https://example.com/presigned-video.mp4'The command waits for completion, writes
fgate-results/<job-id>/report.json, downloads the evidence images, and
verifies every artifact.
fgate check config.yaml \
'https://example.com/shift-a.mp4' \
'https://example.com/shift-b.mp4'fgate status config.yaml JOB_IDfgate batch config.yaml examples/job.example.jsonThe example manifest freezes every source size and ETag and defines a create-only result destination.
fgate deploy stop config.yamlThe versioned standard policy configuration lives in policies/standard.yaml:
version: 1
name: standard
checks:
camera_covered:
reject_after_seconds: 5
hands_visible:
minimum_percent: 60
worker_idle:
maximum_percent: 50
minimum_segment_seconds: 10
camera_steadiness:
maximum_translation_percent: 3
maximum_rotation_degrees_per_second: 5
repetitive_motion:
maximum_score: 0.85
warnings:
blurry:
maximum_percent: 20
bad_exposure:
maximum_percent: 20| Signal | Standard limit | Result |
|---|---|---|
| Camera covered | Reject after 5 seconds | Hard check |
| Hands visible | At least 60% | Hard check |
| Worker idle | At most 50% in segments ≥10 seconds | Hard check |
| Camera translation | At most 3% | Hard check |
| Camera rotation | At most 5°/s | Hard check |
| Repetitive motion | Score at most 0.85 | Hard check |
| Blur | At most 20% | Warning |
| Bad exposure | At most 20% | Warning |
Covered footage makes hands, idle, repetition, blur, and exposure
not_applicable. When hands do not pass, idle and repetition also become
not_applicable. This prevents downstream conclusions from unreliable input.
Reports use the fgate-report-v1 schema and record the policy, model, provider,
GPU, and video backend identities used for the run.
{
"schema_version": "fgate-report-v1",
"status": "complete",
"human_calibrated": false,
"conditional_on_model": true,
"results": [
{
"verdict": "good",
"checks": [{"name": "hands_visible", "outcome": "pass"}],
"warnings": []
}
]
}The automated interval describes temporal sampling uncertainty conditional on the detector and sampled timeline. It is not a human-validated accuracy or confidence claim.
| Backend | State | Connection |
|---|---|---|
local |
Working; A10 validated | CLI → Docker Compose → local API |
cloud |
Upcoming; not released | CLI → authenticated HTTPS API |
The cloud client configuration reserves an endpoint and FGATE_API_TOKEN, but
the managed API, ingress, model publication, and production rollout gates are
not complete.
| Capability | Status |
|---|---|
| Local Compose backend | Available |
| Async API and CLI | Available |
| Standard YAML policy | Available |
| Immutable R2 workflow | Available |
| NVIDIA A10 provider parity | Validated |
| Human-labelled policy calibration | Blocked on ground truth |
| Immutable production image and model publication | Next |
| Managed cloud backend | Upcoming |
The A10 canary matched eight hand-positive frames between static TensorRT and
TensorRTNative with minimum IoU 0.997603 and maximum confidence delta
0.002270. That is an execution and provider-parity result, not
human-validated detector accuracy or a production SLA.
See TASKS.md for concrete work, owners, dependencies, and acceptance criteria. See RUNBOOK.md for deployment and GPU acceptance.
make verify
docker compose -f docker-compose.yaml config --quietmake verify runs formatting checks, Ruff, strict mypy, and the test suite.
GPU, model, CUDA, TensorRT, or decoder changes also require the canary and
provider-parity checks in the runbook.
- Minimal operator configuration: backend and policy in YAML; GPU and model mechanics in Compose.
- Explicit failure: readiness fails instead of silently degrading.
- Evidence before cleanup: outputs are verified before local media is released.
- Immutable identity: frozen manifests, source ETags, and create-only destinations keep reruns auditable.
- Honest uncertainty: sampling intervals are never presented as human-validated confidence.

