
<div class="callout callout-attn"><p><strong>Alpha.</strong> Via is under active development. APIs, operational flows, and host requirements may change between releases.</p></div>

Add-ons are Via-managed resources that apps use through named bindings. They let app code depend on platform resources without hard-coded host paths, long-lived credentials, or deployment scripts that know where the resource lives.

SQLite is the first add-on. It is not the add-on system. The same model is meant for other managed resources over time: queues, caches, object storage, search indexes, external service connectors, or other databases.

## Binding model

An app uses a stable name such as `DATABASE`. Via decides which resource backs that name for a specific app and release.

```mermaid
flowchart TB
    APP[App code] --> BINDING[Binding name]
    BINDING --> RELEASE[Release binding]
    RELEASE --> DESCRIPTOR[Via-authorized descriptor]
    DESCRIPTOR --> RESOURCE[Managed resource]
```

The binding name is app-facing. The add-on id, storage path, descriptor generation, credential material, snapshots, restore flow, and audit trail are Via-owned.

| Concept | What it means |
|---|---|
| Add-on | A Via-managed resource with lifecycle, storage, descriptor, and audit state. |
| Binding | The stable app-facing name for that resource, such as `DATABASE`. |
| Descriptor | Runtime connection material returned only to an authorized workload. |
| Generation | Versioned descriptor material used for rotation and revocation. |
| Release binding | The snapshot of bindings that a deployed release is allowed to use. |

Bindings are release-scoped. Creating or changing a binding affects a future deploy. A running release keeps the binding claims that were snapshotted when Via built and launched it.

## Readiness and repair

Operators can use `via addon ensure sqlite <name> --app <app> --bind <binding>` as the idempotent path for SQLite add-on readiness. The command creates missing metadata when allowed, confirms that the binding points at the requested app-facing name, and checks that provider storage is usable by the app runtime. `via addon status <name> --json` reports the same readiness layers for already-provisioned resources.

With ensure `--json`, the response includes the mutation summary fields `created`, `already_exists`, `changed`, `compatible`, and `warning`. Ensure and status JSON also include explicit readiness fields for automation:

| Field | What it means |
|---|---|
| `metadata_ready` | Control-plane add-on metadata exists and matches the request. |
| `storage_ready` | Provider storage exists and is usable. |
| `binding_ready` | The app binding points at the requested add-on. |
| `runtime_ready` | Runtime descriptor delivery can use the binding. |
| `usable_by_app` | All required readiness gates passed for app runtime use. |
| `blocking` | Stable blocker code when the add-on is not usable. |
| `owner` | Persona that can resolve the blocker. |
| `reason` | Human-readable reason for the current state. |
| `remediation` | Next command or action to repair the state. |

If storage is missing, JSON reports a stable blocker such as `storage_missing` and the remediation points to `via addon ensure ... --repair`. Repair is explicit so operators can distinguish compatible metadata from filesystem repair.

## Why add-ons matter

Via already owns the deploy path: source intake, clean checkout, typecheck, tests, artifact signing, runtime launch, config, routes, logs, backup, and audit. Add-ons extend that ownership to app dependencies.

That gives operators one place to manage resource lifecycle:

| Operator concern | Via behavior |
|---|---|
| Provisioning | Create resources with `via addon`. |
| App access | Bind resources to apps under stable names. |
| Runtime delivery | Serve descriptors through workload identity and the config server. |
| Rotation | Rotate or revoke descriptor generations without changing app source. |
| Recovery | Snapshot and restore through Via commands so state and audit stay consistent. |

It also keeps app code portable. The same source can ask for `DATABASE` in development, staging, and production while Via binds each environment to a different backing resource.

## SQLite as the first provider

Managed SQLite proves the add-on path end to end:

```bash
via addon create sqlite app-db --app api --bind DATABASE
vary app deploy api --target prod
```

At runtime, app code uses the binding name:

```vary
let db = Sql.connect("DATABASE")
```

Via owns the database file, descriptor authorization, proxy access, snapshots, restore, credential generation, and audit records. The app does not need to know where the SQLite file lives.

That pattern is the point. SQLite is one add-on provider using the same add-on contract.

## Operational shape

Add-ons should be managed through Via commands and APIs. Operators should not copy live add-on files by hand or put resource details into app source.

| Operation | Purpose |
|---|---|
| `via addon create` | Provision a managed resource. |
| `via addon bind` | Attach the resource to an app under a binding name. |
| `via addon snapshot` | Capture restorable add-on state. |
| `via addon restore` | Restore add-on state with explicit safety handling. |
| `via addon rotate-credentials` | Issue a new descriptor generation. |
| `via addon revoke-credentials` | Reject an older descriptor generation. |
| `via addon destroy` | Remove an unbound add-on. |

Destroy keeps the destroyed row inspectable by id for audit, but tombstones the
stored name as `NAME#destroyed#ADDON_ID`. That frees the original add-on name
for a clean recreate while keeping the historical resource explicit. Failed
provisioning records that never produced data-bearing storage are renamed to
`NAME#failed#ADDON_ID` on the next create, while failed records with SQLite
bytes still present keep blocking reuse until an operator chooses the retention
or repair path.

Continue to [Managed SQLite](/docs/via/managed-sqlite/) for the current concrete add-on provider, or [Secrets and config](/docs/via/secrets-and-config/) for the workload identity model that protects runtime descriptors.
