Use this runbook when your app already ships Rindle from the pre-v1.4
image-only shape and you need to move onto the current AV-aware runtime
contract. Fresh installs should stay on README.md and the
greenfield deep guide in getting_started.md.
The generated package-consumer upgrade proof exercises the same public path this
guide teaches: explicit host plus packaged migrations, mix rindle.doctor,
optional mix rindle.runtime_status, then the repair verb that matches the
observed state.
1. Confirm Runtime Ownership And AV Prerequisites
Before you touch migrations, make sure the host app still owns the same runtime boundaries:
- Rindle persists through your adopter-owned Repo.
- Oban stays on the default
Obaninstance and the host app owns that supervision tree. - Install
FFmpeg >= 6.0before you enable AV variants or diagnose AV work.
If you are bumping the package version as part of the upgrade, fetch the new dependency first:
mix deps.get
If you only need the greenfield setup details again, return to
getting_started.md. This guide assumes the app already
owns its Repo, Oban config, and storage configuration.
2. Run Explicit Host And Packaged Migrations
Run your host migrations and the packaged Rindle migrations explicitly. The
canonical upgrade path stays on Application.app_dir(:rindle, "priv/repo/migrations"):
Application.ensure_all_started(:rindle)
{:ok, _pid} = MyApp.Repo.start_link()
host_path = Path.join([File.cwd!(), "priv", "repo", "migrations"])
rindle_path = Application.app_dir(:rindle, "priv/repo/migrations")
unless File.dir?(rindle_path) do
raise "Rindle migration path missing: #{rindle_path}"
end
{:ok, _, _} =
Ecto.Migrator.with_repo(MyApp.Repo, fn repo ->
for path <- [host_path, rindle_path] do
Ecto.Migrator.run(repo, path, :up, all: true)
end
end)Rindle still does not hide this behind a public install task. The host app owns the migration handoff.
3. Validate The Upgraded Runtime
Run the read-only environment check immediately after migrations:
mix rindle.doctor
mix rindle.doctor validates setup and drift. If it reports FFmpeg, Oban, or
migration issues, fix those before you attempt any repair command.
4. Inspect Degraded Upgraded Work When Needed
If a specific upgraded asset or variant looks wrong after the migration, inspect the bounded runtime report before you mutate anything:
mix rindle.runtime_status --format json
mix rindle.runtime_status is optional in the happy path. Use it when you need
to confirm whether the problem is failed asset-scoped work,
stale/missing drift, or broader runtime residue. Deep diagnostics and error
maps stay in operations.md and
troubleshooting.md.
5. Repair One Upgraded Asset Through The Public Facade
For one failed upgraded asset, use the asset-scoped repair surface:
asset_id = "..."
{:ok, report} =
Rindle.requeue_variants(asset_id, variant_names: ["web_720p"])Rindle.requeue_variants/2 is the sharp lane for one asset. It re-enqueues the
named failed variants without pulling ready, queued,
processing, stale, or missing siblings into the run.
6. Reserve Broad Drift Repair For Stale Or Missing Variants
Do not use asset-scoped requeue as a surrogate for profile drift or missing
storage objects. For broader derivative drift, stay on:
mix rindle.regenerate_variants
That command is the broad maintenance lane for stale or missing variants
after recipe, preset, or storage drift.
Next Reads
operations.mdfor the day-2 verb map and task boundariestroubleshooting.mdfor error-state recovery guidancegetting_started.mdfor the greenfield install path