Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

GIFScenarioSource
basic.gifScaffold config -> doctor -> check -> run -> state (≈25 s)basic.tape
plan-apply.gifPlan/Apply: sealed artifact + credential redaction (ADR-0005 PA9) (≈20 s)plan-apply.tape
reconcile-repair.gifChunked 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):

GIFScenarioSource
init-scaffold.gifrivet init + cat orders.yaml — what scaffolding produces (≈8 s)init-scaffold.tape
check-verdict.gifrivet check verdict block: strategy, verdict, suggestion (≈7 s)check-verdict.tape
inspect.gifPost-run inspection: state show + metrics + state files + state progression (≈15 s)inspect.tape

Mode / planner spots (embedded in docs/modes/, docs/reference/, docs/planning/):

GIFScenarioSource
chunked-progress.gifChunked 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.gifTwo-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.gifrivet init --discover + jq over the JSON artifact — ranked cursor + chunk candidates per table (≈8 s)discover-artifact.tape
plan-campaign.gifMulti-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.gifrivet 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:

GIFScenarioSource
doctor-gcs.gifrivet 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:

GIFScenarioSource
pool-detect.gifConnect-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:

GIFScenarioSource
cdc.gifScaffold 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.gifrivet 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.gifA 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-detect needs the pool docker-compose profile up so pgBouncer (6432) and ProxySQL (6033) are reachable: docker compose --profile pool up -d pgbouncer proxysql.
  • doctor-gcs needs gcloud auth application-default login and 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 Output paths only. VHS rejects absolute paths.
  • No multi-line Type heredocs. VHS parses every newline as a tape command. Fixture YAMLs are written to the workdir by the renderer before vhs runs (see fixture_chunked_setup).
  • Theme: Dracula, 14 pt; 1200 x 720 for basic / plan-apply and 1280 x 780 for reconcile-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

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.