Instructional GIFs
Three short screencasts of Rivet’s core workflows, rendered from VHS tape scripts against the repository’s local Docker Compose stack.
Overview screencasts:
| GIF | Scenario | Source |
|---|---|---|
| basic.gif | Scaffold config -> doctor -> check -> run -> state (≈25 s) | basic.tape |
| plan-apply.gif | Plan/Apply: sealed artifact + credential redaction (ADR-0005 PA9) (≈20 s) | plan-apply.tape |
| reconcile-repair.gif | Chunked export + reconcile + targeted repair; committed boundary untouched per ADR-0009 RR4 (≈35 s) | reconcile-repair.tape |
Short, single-command spots (embedded next to each step of Getting Started):
| GIF | Scenario | Source |
|---|---|---|
| init-scaffold.gif | rivet init + cat orders.yaml — what scaffolding produces (≈8 s) | init-scaffold.tape |
| check-verdict.gif | rivet check verdict block: strategy, verdict, suggestion (≈7 s) | check-verdict.tape |
| inspect.gif | Post-run inspection: state show + metrics + state files + state progression (≈15 s) | inspect.tape |
Mode / planner spots (embedded in docs/modes/, docs/reference/, docs/planning/):
| GIF | Scenario | Source |
|---|---|---|
| chunked-progress.gif | Chunked export on 50 k rows / 10 chunks with RUST_LOG=info so per-chunk progress is visible; ends with the structured summary (≈14 s) | chunked-progress.tape |
| incremental-cursor.gif | Two-run cursor progression — first run exports 10 k rows and saves cursor, second run is skipped via skip_empty: true (≈14 s) | incremental-cursor.tape |
| discover-artifact.gif | rivet init --discover + jq over the JSON artifact — ranked cursor + chunk candidates per table (≈8 s) | discover-artifact.tape |
| plan-campaign.gif | Multi-export rivet plan: Priority / Prioritize block per export + Campaign block with shared_source_heavy_conflict warning on a shared source_group (≈9 s, needs 20 M + 15 M-row fixture) | plan-campaign.tape |
| parallel-cards.gif | rivet run --parallel-export-processes over four chunked exports: one card per export with live progress bar, ETA, rows, and final metrics in place; trailing aggregate Run summary (≈30 s) | parallel-cards.tape |
Destination-specific:
| GIF | Scenario | Source |
|---|---|---|
| doctor-gcs.gif | rivet doctor + rivet run against real Google Cloud Storage via Application Default Credentials; final gcloud storage ls confirms .rivet_doctor_probe + Parquet (≈18 s). Requires gcloud auth application-default login and write access to $GCS_DEMO_BUCKET (default rivet_data_test). | doctor-gcs.tape |
Operational warnings:
| GIF | Scenario | Source |
|---|---|---|
| pool-detect.gif | Connect-time pooler / proxy detection: direct PG (silent) → pgBouncer (transaction-mode warning) → direct MySQL (silent) → ProxySQL (MysqlProxyKind::ProxySql warning). Requires the pool docker-compose profile (docker compose --profile pool up -d pgbouncer proxysql); ≈18 s. | pool-detect.tape |
Change data capture:
| GIF | Scenario | Source |
|---|---|---|
| cdc.gif | Scaffold mode: cdc, capture MySQL binlog changes since a checkpoint into typed Parquet, read them back as typed rows (__op + columns) (≈15 s) | cdc.tape |
| cdc-parallel.gif | rivet run --parallel-exports with a full snapshot + a CDC stream of the same table, side by side — two cards, one aggregate summary (≈12 s) | cdc-parallel.tape |
| error-cdc-access.gif | A MySQL user missing the REPLICATION grant gets the exact requirement + a pointer to the grants doc, not a raw driver error (≈6 s) | error-cdc-access.tape |
They are linked from the user-facing guides (see “Where they appear” below)
and are intentionally terminal-only: no narration, no cursor movement, no UI
chrome. They show exactly what rivet prints.
Regenerating
Prereqs (one-off):
brew install vhs # pulls ttyd + ffmpeg as dependencies
docker compose up -d postgres mysql
cargo build --release --bin rivet --bin seed
cargo run --release --bin seed -- --target postgres # ~500 rows in public.orders
Render all three:
python3 -m dev.pytools.render_gifs
Or just one:
python3 -m dev.pytools.render_gifs basic
python3 -m dev.pytools.render_gifs plan-apply
python3 -m dev.pytools.render_gifs reconcile-repair
python3 -m dev.pytools.render_gifs init-scaffold
python3 -m dev.pytools.render_gifs check-verdict
python3 -m dev.pytools.render_gifs inspect
python3 -m dev.pytools.render_gifs chunked-progress
python3 -m dev.pytools.render_gifs incremental-cursor
python3 -m dev.pytools.render_gifs discover-artifact
python3 -m dev.pytools.render_gifs plan-campaign # creates ~35 M rows in rivet_gif.*
python3 -m dev.pytools.render_gifs parallel-cards # 4 chunked exports, parent-side cards UI
python3 -m dev.pytools.render_gifs pool-detect # connect-time pooler/proxy warnings; see below
python3 -m dev.pytools.render_gifs doctor-gcs # real GCS via ADC; see below
The default invocation (no args) renders the eleven “always
reproducible” scenarios against Docker Compose (setup per scenario is
ephemeral — tables live under a dedicated rivet_gif schema that is
dropped on teardown). Two scenarios are opt-in:
pool-detectneeds thepooldocker-compose profile up so pgBouncer (6432) and ProxySQL (6033) are reachable:docker compose --profile pool up -d pgbouncer proxysql.doctor-gcsneedsgcloud auth application-default loginand a writable bucket.
plan-campaign takes ~60 s because it seeds 35 M narrow rows so the
cost-class classifier triggers shared_source_heavy_conflict.
The renderer creates an ephemeral /tmp/rivet-gif-<name> workdir, seeds any
fixture the scenario needs (the reconcile-repair tape uses a dedicated
10,000-row rivet_gif.events schema that is dropped on exit), invokes
vhs, and moves the rendered .gif next to the tape.
Environment the tapes assume
Each tape inherits DATABASE_URL, RIVET_BIN_DIR, and PSQL_BIN from
the renderer. The first Hide block prepends them to PATH and sets a
clean PS1='rivet-demo $ ' prompt, so the rendered terminal is
deterministic regardless of the user’s shell rc.
Conventions
- Relative
Outputpaths only. VHS rejects absolute paths. - No multi-line
Typeheredocs. VHS parses every newline as a tape command. Fixture YAMLs are written to the workdir by the renderer beforevhsruns (seefixture_chunked_setup). - Theme: Dracula, 14 pt; 1200 x 720 for
basic/plan-applyand 1280 x 780 forreconcile-repair(wider table output). - Typing speed: 30–35 ms/char. Fast enough to keep GIFs short; slow enough to read command lines.
Where they appear
- README.md — top-level table of contents.
- docs/README.md — “Start here” section.
- docs/getting-started.md (current 4-step layout):
basic.gifin §3 “Preflight & run”.check-verdict.gifin §3 (right after therivet checkblock).inspect.gifin §4 “Inspect & iterate”.
- docs/reference/cli.md —
plan-apply.gifnext torivet plan,reconcile-repair.gifnext torivet reconcile,parallel-cards.gifnext torivet run --parallel-export-processes. - docs/destinations/gcs.md —
doctor-gcs.gifin the “Verify” section. - docs/modes/chunked.md —
chunked-progress.gifin “Progress bar (chunked exports)”. - docs/modes/incremental.md —
incremental-cursor.gifin “What happens”. - docs/reference/init.md —
init-scaffold.gifin “Single table”;discover-artifact.gifin “Discovery artifact”. - docs/reference/prioritization.md —
plan-campaign.gifin “Viewing the output”. - docs/pilot/pilot-walkthrough.md —
init-scaffold.gif(Step 1),plan-apply.gif(Step 3),inspect.gif(Step 5),reconcile-repair.gif(Steps 6–8). - docs/pilot/demo-quickstart.md —
plan-apply.gif(Step 3),reconcile-repair.gif(Step 4). - docs/pilot/production-checklist.md —
pool-detect.gifin “Connection poolers and proxies”.
If you update a tape, re-render, and commit both the .tape and the
.gif together. The tape is the source; the GIF is the build artifact.