GIT-AV — DOCS

Reference

Sprint coverage matrix, architectural decisions that shaped the system, the seven-domain timeline model, server topology, and the v0.4 GA punch list. For diagrams see the Diagrams tab. Press \ to cycle themes, 1/2/3 for tabs.

VERSION0.4.0-dev (S8)
UPDATED2026-05-12
TESTS306 + 28 vitest
Sprint coverage matrix
SprintTagOutcomeStatus
S1 Skeletonv0.4.0-s1-skeletonCargo workspace, CLI scaffold, sharded vault, atomic symlink swizzle✓ shipped
S2 Core portv0.4.0-s2-corerusqlite ledger, branch manager, refs, snapshot/revert/checkout/log/diff✓ shipped
S3 C2PAv0.4.0-s3-c2paAuto-generate manifests on snapshot/revert; verify; inspect; audit (v1)✓ shipped
S4 Timelinev0.4.0-s4-timelineOTIO import/export, domain-split, V1–V10 validator, diff, three-way merge✓ shipped
S5 Serverv0.4.0-s5-serverJSON-RPC 2.0 + WebSocket + REST blob; bearer-token auth; in-process embed✓ shipped
S6 Foundationv0.4.0-s6-foundationFrontend design tokens, three view shells, TypeScript client✓ shipped
S6.1v0.4.0-s6.1Tauri embed, OpenRPC codegen, cursor pagination, Radix wrappers, a11y CI✓ shipped
S7 Timeline Diffv0.4.0-s7-timeline-diffSplit-player, synced playback, structured change list, CMX 3600 EDL✓ shipped
S7.5 AAFv0.4.0-s7.5-aafAAF change-list export (capability-gated via --features aaf-python)✓ shipped
S8 Viewsv0.4.0-s8-viewsBranch Graph + Provenance Inspector + Article 50 PDF audit; c2pa.audit/v3✓ shipped
S9 PackagingSigned bundles (.dmg/.msi/AppImage), R2 auto-updater, bundle-size CI gatesdeferred — budget gate
S10 LAN polishv0.4.0Producer-tablet capability gating, mDNS advertise, touch targets, GAV012 finalplanned
v0.5 Syncgav remote/push/pull, NLE adapters, CAI cert pathpost-GA
Architectural decisions that mattered

The ten calls behind the system shape

  • Symlinks over copy-on-write (S1). Branch switching is unlink + symlink per file inside an atomic temp+rename swizzle. Media bytes don't move; only the pointers flip. Windows works via the developer-mode symlink permission.
  • rusqlite, not sqlx (S2). The original plan (GAV007 §121, GAV008 §27) called for sqlx with compile-time SQL checks. By S2 the team switched to rusqlite (sync, bundled) — the engine is single-process, async overhead of sqlx was net negative at this scale, and bundled removes the libsqlite3 system-library dependency.
  • OTIO domain-split (S4). Storing one 12 MB OTIO file as a single blob means every grade change rewrites the whole timeline. Splitting into six per-domain JSON files plus a manifest of their hashes gets free dedupe — a colorist's grade change touches color.json only. Three-way merge becomes per-domain; conflict detection becomes per-clip-per-domain.
  • Hand-rolled OpenRPC, not generated (S5). Neither schemars nor okapi has a published crate that ships an end-to-end JSON-RPC + OpenRPC pipeline in 2026. We hand-maintain the OpenRPC document at crates/gav-server/src/schema/, use schemars 1.0 for type-only schema fragments, and rely on a CI drift check (regenerated methods.gen.ts must equal committed) to catch mismatches.
  • In-process Tauri embed, not sidecar (S6). GAV019 §1.1 #2 chose to spawn gav-server on a dedicated tokio task from a Tauri setup hook rather than ship it as an externalBin sidecar process. Branch checkout is the latency-sensitive operation — cross-process RPC marshalling between webview and sidecar would have measurable cost.
  • React Flow + dagre, not D3 (S8). Node positioning is dagre's job, edge routing is React Flow's, viewport culling + pan + zoom are free, and the prefers-reduced-motion gating is a one-line config. Hand-coded D3 would have shipped slower and been harder to ship accessibility coverage against.
  • Server-side sort + filter for the audit grid (S8). The Provenance Inspector renders blob-level rows at 100k+ scale. Sorting client-side breaks at that volume. c2pa.audit/v3 introduced server-applied sort key (hash / manifested / signature / ai_disclosed) and three filter axes, with cursor format c2:<sort>:<rank>:<hash> that pins to the active sort — switching mid-stream rejects with InvalidRef.
  • printpdf for the Article 50 PDF (S8 T2). Pure-Rust, PDF core fonts (Helvetica, no embedding), 8 kB per A4 page — small enough to email. Caveat: the crate uses a random XObjectId per document, so byte-identical reproducibility across runs isn't guaranteed (content is identical; bytes differ). Two-run byte-length parity is what we test instead.
  • Self-signed Ed25519 test cert (S3). Auto-generated under .gav/c2pa/. Manifests validate as untrusted; a real CAI-issued cert produces trusted. Ships a working cert path on day one; defers real-cert-loading to v0.5 when a studio actually asks.
  • CLI parity as a contract (every sprint). Anything the GUI shows, the CLI prints. AAF export → gav timeline diff --aaf; PDF audit → gav c2pa audit --pdf; capability probe → gav schema. Keeps the product accessible to AI agents and CI pipelines; makes the resilience gate the canonical integration test; prevents UI-only features from drifting away from the data model.
The seven-domain timeline model

What "domain split" buys you

gav timeline import file.otio writes 6 per-domain JSON workspace files plus a 7th manifest file listing the six blob hashes. Each is snapshotted into the vault and gets a C2PA manifest. Domain JSON edits are versioned independently — colorist edits color.json, sound designer edits audio.json, neither touches the other; gav merges automatically.

  • cuts.json — the edit decision list. CutChange::{Trimmed, Extended, Slipped, Moved, Rippled, Inserted, Removed} using Avid-cultural verbs.
  • color.json — per-clip ColorGrade (one version per clip in v0.4; Resolve local-versions deferred to v0.5).
  • audio.json — level/pan automation, channel maps, fader writes; the surface a re-recording mixer cares about.
  • effects.json — transitions, plug-in effects, speed ramps (annotated with curve type rather than misleading linear pct).
  • markers.json — the producer's notes and chapter heads.
  • metadata.json — everything else: scene/take, color tags, custom fields. Lossless extras catch-all so OTIO roundtrips bit-for-bit.
  • .gav-timeline.json — the manifest blob containing the six blob hashes. This is what gets snapshotted and shared.

Three-way merge runs per-domain with MergeStrategy::Auto (default) / Ours / Theirs. Conflicts are reported with CrossDomainConflict records that name the clip and the colliding domains; gav timeline merge exits 1 on conflict so CI scripts can set -e. The V1–V10 validator catches orphans, sync drift, overlap, out-of-range — exits 0/1/2 for clean/warnings/errors.

C2PA provenance layer

What ships, what's untrusted, what's the upgrade path

  • Manifest generation is auto on snapshot/revert when c2pa_auto_generate=true in .gav/config.toml (default true). The signing cert is auto-generated as a self-signed Ed25519 cert under .gav/c2pa/ with one-year validity.
  • Manifests validate as signed + valid + untrusted until a CAI-issued cert is loaded. untrusted is a chain-of-trust statement, not a structural-validity one — the JUMBF and COSE_Sign1 layers are spec-compliant from day one.
  • Action vocabulary maps to IPTC digital-source-type codes: humanEdits / algorithmicMedia / trainedAlgorithmicMedia / compositeWithTrainedAlgorithmicMedia. These surface in aurora_audit_summary.ai_disclosed and drive the EU AI Act Article 50 status badge (GREEN/AMBER/RED).
  • Sidecars live at .gav/manifests/<aa>/<bb>/<rest>.c2pa — mirrors the vault's sharded layout. Idempotent inserts via ON CONFLICT … DO UPDATE; same blob can be re-manifested without duplicate rows.
  • Server-side audit (c2pa.audit/v3) applies sort + filter via named-param SQL only. SQL injection surface reviewed (S8-R9): enum values map to &'static str slices; no user string interpolates. The cursor format c2:<sort>:<rank>:<hash> pins to the active sort; switching mid-stream returns InvalidRef so the client refetches from page 0.
  • PDF rendering uses printpdf 0.9.1 with PDF core fonts (Helvetica, no embedding) for byte-stable output across platforms. Cover page maps to Article 50 disclosure categories; paginated asset table with consistent column headers; --article-50-only filter trims the report to assets requiring disclosure.
  • The CAI upgrade path is a one-page section in GAV012 — load the studio's CAI-issued cert chain into .gav/c2pa/cert.pem, manifests now validate as trusted. Currently documented but not exercised end-to-end; a real studio's first install will surface whatever's missing.
Server topology (S5)

How gav serve fits

  • One axum 0.8 router serving POST /rpc (JSON-RPC 2.0, 24 methods), GET /ws (WebSocket event bus), and GET /blob/<hash> (REST blob stream with C2PA verify-default).
  • Bearer-token auth. OS keychain (keyring 3.x) with .gav/server/token file fallback. Default bind is loopback 127.0.0.1:7777. Non-loopback bind requires --cors-origin AND a token — the CLI refuses to start otherwise.
  • In-process embed. Server::start_in_process(...) exposes the same router on a dedicated thread + tokio runtime so Tauri can embed without Windows event-loop conflicts. The Tauri app gets the full RPC surface without spawning a sidecar process.
  • Capability gating (S10 T1). A new server.capabilities RPC will return the set of methods the current token can call; producer-tablet read-tokens will hide write buttons in the UI. Currently planned, not shipped.
  • OpenRPC drift CI is clean. Hand-maintained OpenRPC document at crates/gav-server/src/schema/; regenerated methods.gen.ts in packages/api-client must equal committed or CI fails.
  • The CLI never depends on the server. gav-cli links gav-core directly. No daemon required for any CLI op. The resilience gate (tests/cli/full_workflow.sh) runs end-to-end without ever starting the server.
v0.4 GA punch list (S10)
  1. Capability atom + producer-tablet capability gating. New server.capabilities RPC; ~15-component audit; read-token tokens hide write buttons. The producer-with-iPad scenario lights up end-to-end.
  2. Touch-target spacing. @media (pointer: coarse) → 44×44 px button minimum, 36 px row height. Frame.io's actual moat is iPad UX; this is the answer.
  3. mDNS advertise. gav serve --mdns makes the server findable as _gav._tcp.local on the LAN. Producer's tablet finds the editor's machine on the next-door studio Wi-Fi.
  4. CLAUDE.md S10-line correction + GAV012 finalization. Deployment-mode walkthroughs with screenshots; CAI procurement note.
  5. Repo-commands.html refresh + RELEASE_NOTES.md + full README rewrite. The README still says "S6.1 shipped, S7 in progress" because nothing forced a rewrite. S10 T5 forces it.
  6. GAV027 sprint report + tag v0.4.0. No sprint suffix — GA.
What's still open

Honest list of unresolved questions

  • S9 cert + R2 + secrets decision. Plumbing ready; certificates and DNS are the operational gate. Estimated half-day of work once the budget call gets made — ~$219/yr (Apple Developer ID + Azure Trusted Signing).
  • CAI cert procurement path. Documented in GAV012 but not exercised end-to-end. A real studio's first install will surface whatever's missing in the procurement walk.
  • NLE auto-snapshot hooks. GAV017 specifies the NleAdapter trait; no NLE adapter crates exist in the workspace (the gav-nle-* placeholder feature flags in gav-cli are stubs — flagged in GAV028 §M6). Adoption depends on at least one of Resolve / Premiere / FCP / Avid having a transparent auto-snapshot hook by v0.5.
  • Sync wire protocol (v0.5). Three candidates per GAV026 §10: custom JSON-RPC, git smart-HTTP, WebSocket delta. The right answer is partly determined by whether the eventual SaaS mode wants to ride the same protocol.
  • Production data scale. Vault tests through S8 use synthesized fixtures. A real studio with 50 TB of media and 18 months of branches will reveal the next-order performance constraints. The Trust Ladder + sharded vault was designed for that scale; testing it is empirical, not architectural.
  • i18n. English-only is fine for v0.4 (post-production audience is ~95% English-readable). v0.5 wires it; v1.0 might localize to JP/KR/FR/DE based on actual installs.
  • Resolve grade-versions (≤6 per clip). The flat ColorGrade model in v0.4 doesn't capture Resolve's local-versions feature. A ColorGrade::versions: Vec<NodeGraph> extension is a clean v0.5 timeline-model addition.
  • Playwright coverage for S8. Plan called for 6 specs; 0 landed in the compressed S8 timeline. The data path is verified via typecheck + build + resilience gate; full E2E coverage is an S8.x fast-follow alongside the 100k-row perf gate.
Internal documentation

Planning docs, sprint reports, audits, and design briefs maintained alongside the source tree under docs/gav/. Not currently published; listed here so stakeholders know what exists.

DocTitleType
GAV007v0.4 ArchitecturePlan
GAV008Rust Core MigrationPlan
GAV009Timeline Domain ModelPlan
GAV010Frontend Design SystemPlan
GAV011API ReferenceReference
GAV012Deployment ModesPlan
GAV013NLE Adapter CookbookPlan
GAV014CLI-First ResiliencePlan
GAV015S2 Core Port PlanPlan
GAV016S3 C2PA PlanPlan
GAV017S4 Timeline Plane PlanPlan
GAV018S5 Server PlanPlan
GAV019S6+ Frontend PlanPlan
GAV020S6 W11-W12 Sprint ReportReport
GAV021S6.1 Sprint ReportReport
GAV022S7 Sprint ReportReport
GAV023S7.5 AAF Sprint ReportReport
GAV024S8 Sprint ReportReport
GAV025S9 Prep NotesPrep
GAV026S10 PlanPlan
GAV028Post-S8 Repo AuditAudit
GAV029Product Design BriefBrief