Appearance
About this article
- Audience: Operators and integrators who need the recording mental model before soak or playback work
- Goal: Understand how justified 60-second H.265 chunks are written, verified, and served through the proxy
- Type: Concept
Summary
Ghost Protocol records continuous H.265 in 60-second justified chunks with sidecar metadata and a rolling manifest. Playback time matches wall time—roughly 30 fps with linear PTS deltas—not a fast-forward slice. The edge stays sovereign; the proxy at PHANTOM_PROXY pulls, transcodes, and escalates clips to cloud analysis.
Prerequisites
- One shadow writing chunks (
site-role-aorsite-role-b) - Phantom proxy reachable — see API quick reference
Edge pipeline
Two cooperating processes run inside the edge app bundle container:
- ghost_core — 4K H.265 primary stream (VIDEO_FIFO) plus an independent 640×640 RF-DETR substream (NN_FIFO) for on-device detection
- ghost_agent_v2 — chunk recorder that rotates justified 60s archives under the recordings root
Each chunk writes chunk_*.h265 plus a JSON sidecar. A recent_manifest.jsonl lists the latest N chunks for playback context without scanning the full tree.
Sidecar and status contract
Sidecar fields (approximate on healthy runs):
| Field | Expected |
|---|---|
duration_s | ~60 |
keyframe_count | Aligned with 30 fps segment |
justified | true on continuous real-time recording |
rfdetr_stride_fps | 10.0 |
group | continuous |
.h265_status (v1.0.0) summarizes inventory: storage_health (OK / WARNING / CRITICAL), is_writing_data, chunks_inventory_count, and free space.
Justified means the depicted timeline equals wall time. Legacy overcount slices set justified false and fail playback calibration gates.
Playback verification
Confirm contract before promotion or cloud escalation:
- ffprobe PTS/pkt_pts deltas linear ~0.033s (30 fps)
- Sidecar
duration_smatches wall duration (~60s per chunk) - Proxy
/fleet/playback-readyreturns a play URL whose mp4 matches the above
bash
curl -s "$PHANTOM_PROXY/fleet/playback-ready?shadow=site-role-a&limit=3" | jq .Proxy surfaces
The proxy centralizes recording access—edge devices never hold cloud keys:
| Route | Role |
|---|---|
GET /fleet/playback-ready | Justified chunk list with cached mp4 play URLs |
POST /pull-recording | SFTP pull from shadow + ffmpeg remux |
GET /stream/snapshot | Live JPEG or graceful H.265 tail fallback |
/tools/call get_recording_status | Live storage, recent chunks, stall hints |
MQTT cache at /fleet/mqtt/latest complements MCP for ~10 Hz telemetry during soaks.
Storage and prune
Recording roots include internal overlay paths and optional external USB mounts. Overlay merged views can lag SSH df after prune—confirm on device when proxy numbers disagree.
Retention prune deletes oldest chunk_*.h265 files and sidecars while keeping the newest N per host. Run DRY_RUN=1 first. Orchestrator --prune-first applies relief before long soaks when storage_health is CRITICAL.
See Updates, prune & storage and USB extended storage.
Common failure modes
- Overlay lag — proxy still shows CRITICAL after prune; trust device
dfand restart recorder - Stall without restart — do not
pkill ghost_corealone; restart the full app - Wrong root — confirm active recordings directory before prune on fleets with external storage
Next steps
- Architecture overview — full stack tiers
- Cloud video escalation — proxy-owned Gemini and Video Intelligence path
- Gate interpretation — soak and playback QA failures
- API quick reference — playback-ready and pull-recording curls
Operator depth
Live fleet state and harness evidence live in private operator handoff (not published) (private).