> ## Documentation Index
> Fetch the complete documentation index at: https://microsanbox-staging-toks-cloud-snapshot-contracts.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Snapshots

> TypeScript SDK - Snapshot API reference

Capture the disk state of a stopped sandbox through the active backend, then
boot fresh sandboxes from it. Local snapshots are portable artifacts; cloud
snapshots use managed storage or the organization's host volume.

```typescript theme={null}
import { Sandbox, Snapshot, SnapshotHandle } from "microsandbox";
import type { SaveOpts, SnapshotScope, SnapshotVerifyReport } from "microsandbox";
```

<Note>
  Snapshots are **disk-only** and require a sandbox that is not running (stopped or crashed).
  `listDir`, `reindex`, `save`/`saveTo`, `load`, and `verify` keep the same API
  on every backend, but currently reject with `UnsupportedError` in cloud.
</Note>

## Capture and boot

These entry points live on `SandboxBuilder` and `SandboxHandle`; they are the bridge between sandboxes and snapshot artifacts.

#### <span className="msb-recv">.</span><span className="msb-hn">fromSnapshot()</span>

```typescript theme={null}
fromSnapshot(snapshot: string | Snapshot | SnapshotHandle): SandboxBuilder
```

<Accordion title="Example">
  ```typescript theme={null}
  const sb = await Sandbox.builder("worker")
    .fromSnapshot("after-pip-install")
    .create();
  ```
</Accordion>

Boot a fresh sandbox from a snapshot. Mutually exclusive with
[`.image()`](/sdk/typescript/sandbox#image); the snapshot already pins the
image. Passing a `Snapshot` or `SnapshotHandle` preserves its backend-relative
reference automatically.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>snapshot</code><span className="msb-type">string | Snapshot | SnapshotHandle</span></div>
    <div className="msb-param-desc">Backend-relative string or snapshot object returned by this SDK.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="/sdk/typescript/sandbox#sandboxbuilder">SandboxBuilder</a></div>
    <div className="msb-param-desc">The same builder, for chaining.</div>
  </div>
</div>

#### <span className="msb-recv">handle.</span><span className="msb-hn">snapshot()</span>

```typescript theme={null}
snapshot(name: string): Promise<Snapshot>
```

Snapshot this sandbox under a bare name. The local backend uses its default
snapshot directory; cloud uses managed storage. The sandbox must be stopped or
crashed.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Snapshot name. Local stores it in the default snapshot directory; cloud creates a managed snapshot.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshot-instance">Promise\<Snapshot></a></div>
    <div className="msb-param-desc">The created snapshot artifact.</div>
  </div>
</div>

<Accordion title="Example">
  ```typescript theme={null}
  const h = await Sandbox.get("baseline");
  await h.stop();
  const snap = await h.snapshot("after-pip-install");
  ```
</Accordion>

***

## Snapshot static methods

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">builder()</span>

```typescript theme={null}
static builder(name: string): SnapshotBuilder
```

Begin building a new snapshot named `name` through the active backend. With no
destination, local uses its default snapshot directory and cloud uses managed
storage. [`.destDir()`](#destdir) selects a local parent or cloud host-volume
directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Snapshot name. Its storage location is selected by the active backend.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotbuilder">SnapshotBuilder</a></div>
    <div className="msb-param-desc">Builder for configuring the snapshot.</div>
  </div>
</div>

<Accordion title="Example">
  ```typescript theme={null}
  const snap = await Snapshot.builder("after-pip-install")
    .fromSandbox("baseline")
    .label("stage", "post-deps")
    .recordIntegrity()
    .create();
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">open()</span>

```typescript theme={null}
static open(pathOrName: string): Promise<Snapshot>
```

<Accordion title="Example">
  ```typescript theme={null}
  const snap = await Snapshot.open("after-pip-install");
  console.log(snap.digest);
  ```
</Accordion>

Open an existing snapshot through the active backend. Locally, bare names
resolve under the default snapshot directory and other values are artifact
paths. In cloud, bare values identify managed snapshots and path-like values
identify host-volume artifacts. Cheap metadata validation only; use
[`verify()`](#snap-verify) for content checks where supported.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>pathOrName</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Backend-relative snapshot name, ID, or path.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshot-instance">Promise\<Snapshot></a></div>
    <div className="msb-param-desc">The opened snapshot.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">get()</span>

```typescript theme={null}
static get(nameOrDigest: string): Promise<SnapshotHandle>
```

<Accordion title="Example">
  ```typescript theme={null}
  const h = await Snapshot.get("after-pip-install");
  console.log(h.digest, h.createdAt);
  ```
</Accordion>

Look up a snapshot through the active backend and return a lightweight
[`SnapshotHandle`](#snapshothandle-class).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>nameOrDigest</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Public identifier understood by the active backend, such as a local name/digest or cloud snapshot ID.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle-class">Promise\<SnapshotHandle></a></div>
    <div className="msb-param-desc">Lightweight handle returned by the active backend.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">list()</span>

```typescript theme={null}
static list(): Promise<SnapshotHandle[]>
```

<Accordion title="Example">
  ```typescript theme={null}
  for (const h of await Snapshot.list()) {
    console.log(h.name ?? h.digest, h.sizeBytes);
  }
  ```
</Accordion>

List snapshots visible through the active backend. Cloud lists managed
snapshots; host-volume artifacts are opened explicitly by reference.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle-class">Promise\<SnapshotHandle\[]></a></div>
    <div className="msb-param-desc">All indexed snapshot handles.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">listDir()</span>

```typescript theme={null}
static listDir(dir: string): Promise<Snapshot[]>
```

Walk a local directory and parse each subdirectory's manifest. Does not touch
the local index, which makes it useful for inspecting external snapshot
collections that were never loaded. Skips entries that don't look like
snapshot artifacts. Cloud returns `UnsupportedError`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Directory to scan for artifact subdirectories.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshot-instance">Promise\<Snapshot\[]></a></div>
    <div className="msb-param-desc">Parsed snapshots found in the directory.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">remove()</span>

```typescript theme={null}
static remove(pathOrName: string, opts?: { force?: boolean }): Promise<void>
```

<Accordion title="Example">
  ```typescript theme={null}
  await Snapshot.remove("after-pip-install", { force: true });
  ```
</Accordion>

Remove a snapshot through the active backend. Locally, the string may be a
path, name, or digest and removal refuses indexed children unless `force` is
set. In cloud, the string identifies a managed or host-volume snapshot.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>pathOrName</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Path, name, or digest of the snapshot to remove.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts.force</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Remove even if the snapshot has indexed children. Defaults to <code>false</code>.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">reindex()</span>

```typescript theme={null}
static reindex(dir?: string): Promise<number>
```

<Accordion title="Example">
  ```typescript theme={null}
  const count = await Snapshot.reindex();
  console.log(`reindexed ${count} snapshots`);
  ```
</Accordion>

Walk a local snapshots directory (default: the configured snapshots dir) and
rebuild the local index. Returns the number of artifacts indexed. Cloud
returns `UnsupportedError`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Directory to scan. Defaults to the configured snapshots dir.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise\<number></span></div>
    <div className="msb-param-desc">Count of artifacts indexed.</div>
  </div>
</div>

***

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">save()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```typescript theme={null}
static save(nameOrPath: string, out: string, opts?: SaveOpts): Promise<void>
```

Bundle a local snapshot into a `.tar.zst` archive. The recorded manifest is
archived as-is, so create the snapshot with
[`recordIntegrity()`](#recordintegrity) if receivers must verify content. See
[`SaveOpts`](#saveopts-interface) for bundling options. Cloud returns
`UnsupportedError`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>nameOrPath</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Name or path of the snapshot to bundle.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>out</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Output archive path.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#saveopts-interface">SaveOpts</a></div>
    <div className="msb-param-desc">Bundling options. All fields default to <code>false</code>.</div>
  </div>
</div>

<Accordion title="Example">
  ```typescript theme={null}
  await Snapshot.save("after-pip-install", "./baseline.tar.zst", {
    withImage: true,
  });
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot.</span><span className="msb-hn">load()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```typescript theme={null}
static load(archive: string, dest?: string): Promise<SnapshotHandle>
```

Unpack a snapshot archive (`.tar.zst` or `.tar`) into the local snapshots
directory. Structural and archive-entry checks run during import; recorded
payload integrity is preserved for explicit [`verify()`](#snap-verify).
Compression is detected from magic bytes. Cloud returns `UnsupportedError`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>archive</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Path to the archive to unpack.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>dest</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Destination directory. Defaults to the snapshots directory.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle-class">Promise\<SnapshotHandle></a></div>
    <div className="msb-param-desc">Handle to the loaded snapshot.</div>
  </div>
</div>

<Accordion title="Example">
  ```typescript theme={null}
  const h = await Snapshot.load("./baseline.tar.zst");
  console.log("loaded", h.digest);
  ```
</Accordion>

***

<h2 id="snapshot-instance">
  Snapshot instance members
</h2>

A `Snapshot` represents a backend-neutral disk snapshot and retains the backend
that created or opened it. Returned by [`Snapshot.builder().create()`](#snapshotbuilder),
[`Snapshot.open()`](#snapshot-open), and [`handle.snapshot()`](#handle-snapshot).

#### <span className="msb-recv">snap.</span><span className="msb-hn">reference</span>

```typescript theme={null}
get reference(): string
```

Stable value accepted by `SandboxBuilder.fromSnapshot()`.

#### <span className="msb-recv">snap.</span><span className="msb-hn">referenceKind</span>

```typescript theme={null}
get referenceKind(): "id" | "path"
```

How the selected backend resolves `reference`. Most callers can pass the
snapshot object directly and never inspect this value.

#### <span className="msb-recv">snap.</span><span className="msb-hn">digest</span>

```typescript theme={null}
get digest(): string
```

Canonical content digest (`sha256:hex`). The snapshot's identity.

#### <span className="msb-recv">snap.</span><span className="msb-hn">sizeBytes</span>

```typescript theme={null}
get sizeBytes(): bigint
```

Backend-reported stored payload size in bytes.

#### <span className="msb-recv">snap.</span><span className="msb-hn">imageRef</span>

```typescript theme={null}
get imageRef(): string
```

Image reference the snapshot was taken from.

#### <span className="msb-recv">snap.</span><span className="msb-hn">imageManifestDigest</span>

```typescript theme={null}
get imageManifestDigest(): string
```

OCI manifest digest of the pinned image.

#### <span className="msb-recv">snap.</span><span className="msb-hn">format</span>

```typescript theme={null}
get format(): "raw" | "qcow2"
```

On-disk format of the upper layer.

***

#### <span className="msb-recv">snap.</span><span className="msb-hn">scope</span>

<div className="msb-tags"><span className="msb-tag is-instance">getter</span></div>

```typescript theme={null}
get scope(): SnapshotScope
```

Snapshot scope: `"disk"` for a disk-only snapshot, `"resumable"` once resumable snapshots land. Always `"disk"` today. See [`SnapshotScope`](#snapshotscope-type).

***

#### <span className="msb-recv">snap.</span><span className="msb-hn">fstype</span>

```typescript theme={null}
get fstype(): string
```

Filesystem type inside the upper (e.g. `"ext4"`).

#### <span className="msb-recv">snap.</span><span className="msb-hn">parent</span>

```typescript theme={null}
get parent(): string | null
```

Manifest digest of the parent snapshot, or `null` for a root.

#### <span className="msb-recv">snap.</span><span className="msb-hn">createdAt</span>

```typescript theme={null}
get createdAt(): string
```

RFC 3339 timestamp when the snapshot was created.

#### <span className="msb-recv">snap.</span><span className="msb-hn">labels</span>

```typescript theme={null}
get labels(): ReadonlyArray<readonly [string, string]>
```

User-supplied labels (sorted by key in canonical form), as `[key, value]` pairs.

#### <span className="msb-recv">snap.</span><span className="msb-hn">sourceSandbox</span>

```typescript theme={null}
get sourceSandbox(): string | null
```

Best-effort source-sandbox name, if recorded. `null` when the manifest has no source recorded.

#### <span className="msb-recv">snap.</span><span className="msb-hn">saveTo()</span>

```typescript theme={null}
saveTo(out: string, opts?: SaveOpts): Promise<void>
```

Bundle this snapshot into an archive through the backend retained when it was
created or opened. This avoids resolving its reference through a possibly
different current default backend. Cloud returns `UnsupportedError`.

```typescript theme={null}
await snap.saveTo("./baseline.tar.zst", { withImage: true });
```

#### <span className="msb-recv">snap.</span><span className="msb-hn">verify()</span>

```typescript theme={null}
verify(): Promise<SnapshotVerifyReport>
```

<Accordion title="Example">
  ```typescript theme={null}
  const report = await snap.verify();
  if (report.upper.kind === "verified") {
    console.log(`hash matches: ${report.upper.digest}`);
  } else {
    console.log("no integrity hash recorded");
  }
  ```
</Accordion>

Recompute the upper layer's recorded content integrity and compare against the descriptor. Current BLAKE3 Merkle integrity skips known all-hole subtrees and hashes allocated leaves in batches; released SHA descriptors retain their exact, potentially O(logical size), verifier. The report's `upper.kind` is `"notRecorded"` when no integrity was recorded. The cloud backend currently rejects this operation with `UnsupportedError`.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotverifyreport-union">Promise\<SnapshotVerifyReport></a></div>
    <div className="msb-param-desc">Verification result.</div>
  </div>
</div>

## SnapshotBuilder

Fluent builder for a snapshot, returned by [`Snapshot.builder(name)`](#snapshotbuilder). Every setter mutates in place and returns `this`, so calls chain. The source sandbox is required: call [`.fromSandbox()`](#fromsandbox) before [`.create()`](#create).

***

#### <span className="msb-recv">.</span><span className="msb-hn">fromSandbox()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript theme={null}
fromSandbox(sourceSandbox: string): this
```

Set the sandbox to capture. Required; [`.create()`](#create) fails without it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>sourceSandbox</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Name of the stopped sandbox to capture.</div>
  </div>
</div>

***

#### <span className="msb-recv">.</span><span className="msb-hn">destDir()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript theme={null}
destDir(destDir: string): this
```

Create the artifact under this parent directory instead of the default snapshots store. The artifact directory is `destDir/<name>`; the name stays the snapshot's identity either way.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>destDir</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Parent directory to create the artifact in (e.g. a larger volume).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">label()</span>

```typescript theme={null}
label(key: string, value: string): this
```

Add a `key=value` label to the snapshot manifest. May be called repeatedly.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>key</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Label key.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Label value.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">force()</span>

```typescript theme={null}
force(): this
```

Overwrite an existing artifact with the same name instead of failing on conflict.

#### <span className="msb-recv">.</span><span className="msb-hn">recordIntegrity()</span>

```typescript theme={null}
recordIntegrity(): this
```

Compute and record a content-integrity hash of the upper layer at creation time, so the snapshot can be verified later or across a trust boundary.

***

#### <span className="msb-recv">.</span><span className="msb-hn">resumable()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript theme={null}
resumable(): this
```

Request a `"resumable"` snapshot (disk plus VM state). Accepted by the builder, but [`.create()`](#create) currently returns an `Unsupported` error; resumable snapshots have not landed yet.

***

#### <span className="msb-recv">.</span><span className="msb-hn">create()</span>

```typescript theme={null}
create(): Promise<Snapshot>
```

<Accordion title="Example">
  ```typescript theme={null}
  const snap = await Snapshot.builder("baseline-v2")
    .fromSandbox("baseline")
    .force()
    .recordIntegrity()
    .create();
  ```
</Accordion>

Capture the configured snapshot and return the resulting artifact.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshot-instance">Promise\<Snapshot></a></div>
    <div className="msb-param-desc">The created snapshot artifact.</div>
  </div>
</div>

## Types

### SnapshotHandle <span className="msb-tag is-type">class</span>

Lightweight handle returned by the active backend. Values are snapshotted at
construction time; call [`Snapshot.get()`](#snapshot-get) again for a fresh
reading if needed. Handles from [`Snapshot.list()`](#snapshot-list) are
read-only; fetch a live handle via `Snapshot.get()` for lifecycle methods.

<p className="msb-backref">Returned by <a href="#snapshot-get">Snapshot.get()</a>, <a href="#snapshot-list">Snapshot.list()</a>, <a href="#snapshot-load">Snapshot.load()</a></p>

| Member               | Type                                          | Description                                                                |
| -------------------- | --------------------------------------------- | -------------------------------------------------------------------------- |
| `digest`             | `string`                                      | Manifest digest (`sha256:hex`), the canonical identity.                    |
| `name`               | `string \| null`                              | Convenience name; `null` for digest-only entries.                          |
| `parentDigest`       | `string \| null`                              | Parent snapshot's manifest digest, or `null` for a root.                   |
| `scope`              | [`SnapshotScope`](#snapshotscope-type)        | Snapshot payload scope (`"disk"` today).                                   |
| `imageRef`           | `string`                                      | Image reference the snapshot was taken from.                               |
| `format`             | `"raw" \| "qcow2"`                            | On-disk format of the upper layer.                                         |
| `sizeBytes`          | `bigint \| null`                              | Backend-reported stored payload size, when known.                          |
| `createdAt`          | `Date`                                        | Snapshot creation time (from manifest).                                    |
| `reference`          | `string`                                      | Stable backend-relative restore reference.                                 |
| `referenceKind`      | `"id" \| "path"`                              | How the selected backend resolves the reference.                           |
| `open()`             | `Promise<`[`Snapshot`](#snapshot-instance)`>` | Open and metadata-validate the underlying artifact.                        |
| `remove(opts?)`      | `Promise<void>`                               | Remove the artifact and its index row; refuses on children unless `force`. |
| `saveTo(out, opts?)` | `Promise<void>`                               | Bundle through the backend retained by this handle.                        |

<p className="msb-label" id="snapshothandleopen">snapshotHandle.open()</p>

```typescript theme={null}
open(): Promise<Snapshot>
```

Open and metadata-validate the underlying artifact. Throws if this handle is read-only (came from [`Snapshot.list()`](#snapshot-list)); fetch a live handle via [`Snapshot.get()`](#snapshot-get) first.

<p className="msb-label" id="snapshothandleremove">snapshotHandle.remove()</p>

```typescript theme={null}
remove(opts?: { force?: boolean }): Promise<void>
```

Remove the artifact and its index row. Refuses if the snapshot has indexed children unless `force` is set. Throws if this handle is read-only.

```typescript theme={null}
const h = await Snapshot.get("after-pip-install");
const snap = await h.open();          // metadata-validated
await h.remove({ force: false });     // refuse if it has children
```

<p className="msb-label" id="snapshothandlesaveto">snapshotHandle.saveTo()</p>

```typescript theme={null}
saveTo(out: string, opts?: SaveOpts): Promise<void>
```

Bundle the referenced snapshot through the backend retained by the handle.
Handles returned by `Snapshot.list()` are metadata-only; fetch a live handle
with `Snapshot.get()` first. Cloud returns `UnsupportedError`.

***

### SaveOpts <span className="msb-tag is-type">interface</span>

Bundle options for [`Snapshot.save()`](#snapshot-save) and instance `saveTo()` methods. All fields default to `false`.

<p className="msb-backref">Used by <a href="#snapshot-save">Snapshot.save()</a> and instance <code>saveTo()</code> methods</p>

| Field         | Type      | Description                                                     |
| ------------- | --------- | --------------------------------------------------------------- |
| `withParents` | `boolean` | Walk the parent chain and include each ancestor in the archive. |
| `withImage`   | `boolean` | Include the OCI image cache so the archive boots offline.       |
| `plainTar`    | `boolean` | Skip zstd compression and write a plain `.tar`.                 |

***

### SnapshotScope <span className="msb-tag is-type">type</span>

Scope of what a snapshot captures. Every snapshot today is `"disk"`; `"resumable"` (disk plus VM state) is reserved for resumable snapshots.

<p className="msb-backref">Returned by <a href="#snap-scope">snap.scope</a> · <a href="#snapshothandle">SnapshotHandle.scope</a></p>

```typescript theme={null}
type SnapshotScope = "disk" | "resumable";
```

***

### SnapshotVerifyReport <span className="msb-tag is-type">union</span>

Result of [`snap.verify()`](#snap-verify). The `upper` discriminant is `"notRecorded"` when no integrity hash was stored at create time, or `"verified"` when the recorded hash matched the recomputed one.

<p className="msb-backref">Returned by <a href="#snap-verify">snap.verify()</a></p>

```typescript theme={null}
type SnapshotVerifyReport =
  | {
      readonly digest: string;
      readonly path: string;
      readonly upper: { readonly kind: "notRecorded" };
    }
  | {
      readonly digest: string;
      readonly path: string;
      readonly upper: {
        readonly kind: "verified";
        readonly algorithm: string;
        readonly digest: string;
      };
    };
```

| Field             | Type                          | Description                                         |
| ----------------- | ----------------------------- | --------------------------------------------------- |
| `digest`          | `string`                      | Snapshot's manifest digest.                         |
| `path`            | `string`                      | Artifact directory path.                            |
| `upper.kind`      | `"notRecorded" \| "verified"` | Whether an integrity hash was recorded and checked. |
| `upper.algorithm` | `string`                      | Hash algorithm (`"verified"` only).                 |
| `upper.digest`    | `string`                      | Recomputed upper-layer digest (`"verified"` only).  |
