---
title: Snapshots
description: TypeScript SDK - Snapshot API reference
---

Create and manage disk-only snapshots of stopped sandboxes. See [Snapshots](/sandboxes/snapshots) for usage and lifecycle concepts.

## SandboxBuilder

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

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

```typescript
fromSnapshot(pathOrName: string): SandboxBuilder
```

<Accordion title="Example">

```typescript
const sb = await Sandbox.builder("worker")
  .fromSnapshot("after-pip-install")
  .create();
```

</Accordion>

Boot a fresh sandbox from a snapshot artifact. Mutually exclusive with [`.image()`](/sdk/typescript/sandbox#image); the snapshot already pins the image. Documented in full on the [Sandbox](/sdk/typescript/sandbox#fromsnapshot) page.

<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">Bare name (resolved under the default snapshots directory) or filesystem path to an artifact 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="/sdk/typescript/sandbox#sandboxbuilder">SandboxBuilder</a></div>
    <div className="msb-param-desc">The same builder, for chaining.</div>
  </div>
</div>

## SandboxHandle

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

```typescript
snapshot(name: string): Promise<Snapshot>
```

Snapshot this sandbox under a bare name in the default snapshots directory (`~/.microsandbox/snapshots/<name>/`). Called on a [`SandboxHandle`](/sdk/typescript/sandbox#sandboxhandle). The sandbox must be stopped or crashed; running sandboxes are rejected with a `SnapshotSandboxRunning` error. To place the artifact elsewhere, use [`Snapshot.save()`](#snapshot-save) / [`Snapshot.load()`](#snapshot-load) or move the self-contained artifact 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">Bare name; becomes the artifact directory under the default snapshots dir.</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&lt;Snapshot&gt;</a></div>
    <div className="msb-param-desc">The created snapshot artifact.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
const h = await Sandbox.get("baseline");
await h.stop();
const snap = await h.snapshot("after-pip-install");
```

</Accordion>

---

## Snapshot

<p className="msb-member-group">Instance properties</p>

A `Snapshot` is a snapshot artifact on disk. The artifact directory is the source of truth; the local database index is a rebuildable cache.

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

```typescript
get path(): string
```

Path to the artifact directory.

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

```typescript
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
get sizeBytes(): bigint
```

Apparent size of the captured upper layer in bytes (sparse on disk).

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

```typescript
get imageRef(): string
```

Image reference the snapshot was taken from.

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

```typescript
get imageManifestDigest(): string
```

OCI manifest digest of the pinned image.

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

```typescript
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
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
get fstype(): string
```

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

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

```typescript
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
get createdAt(): string
```

RFC 3339 timestamp when the snapshot was created.

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

```typescript
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
get sourceSandbox(): string | null
```

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

<p className="msb-member-group">Static methods</p>

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

```typescript
static builder(name: string): SnapshotBuilder
```

Begin building a new snapshot named `name`, resolved under the default snapshots directory (`~/.microsandbox/snapshots/<name>/`) or under [`.destDir()`](#destdir) when set. The fluent builder is what powers the CLI internally. The source sandbox is set with [`.fromSandbox()`](#fromsandbox), which is required. See [`SnapshotBuilder`](#snapshotbuilder) for all setters.

<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">Bare snapshot name; becomes the artifact directory under the default snapshots dir.</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
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
static open(pathOrName: string): Promise<Snapshot>
```

<Accordion title="Example">

```typescript
const snap = await Snapshot.open("after-pip-install");
console.log(snap.digest);
```

</Accordion>

Open an existing snapshot artifact. Bare names resolve under the default snapshots directory; anything else is treated as a path. Cheap metadata validation only; it does not read the upper file. Use [`verify()`](#snap-verify) for content checks.

<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">Bare name (resolved under the default snapshots dir) or filesystem 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&lt;Snapshot&gt;</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
static get(nameOrDigest: string): Promise<SnapshotHandle>
```

<Accordion title="Example">

```typescript
const h = await Snapshot.get("after-pip-install");
console.log(h.digest, h.createdAt);
```

</Accordion>

Look up an indexed snapshot by digest, name, or path. Returns a lightweight [`SnapshotHandle`](#snapshothandle-class) backed by the local index row.

<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">Name, digest (<code>sha256:...</code>), or path of an indexed 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="#snapshothandle-class">Promise&lt;SnapshotHandle&gt;</a></div>
    <div className="msb-param-desc">Index-backed handle.</div>
  </div>
</div>

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

```typescript
static list(): Promise<SnapshotHandle[]>
```

<Accordion title="Example">

```typescript
for (const h of await Snapshot.list()) {
  console.log(h.name ?? h.digest, h.sizeBytes);
}
```

</Accordion>

List indexed snapshots from the local DB cache.

<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&lt;SnapshotHandle[]&gt;</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
static listDir(dir: string): Promise<Snapshot[]>
```

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

<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&lt;Snapshot[]&gt;</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
static remove(pathOrName: string, opts?: { force?: boolean }): Promise<void>
```

<Accordion title="Example">

```typescript
await Snapshot.remove("after-pip-install", { force: true });
```

</Accordion>

Remove a snapshot by path, name, or digest. Refuses if the snapshot has indexed children unless `force` is set.

<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
static reindex(dir?: string): Promise<number>
```

<Accordion title="Example">

```typescript
const count = await Snapshot.reindex();
console.log(`reindexed ${count} snapshots`);
```

</Accordion>

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

<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&lt;number&gt;</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
static save(nameOrPath: string, out: string, opts?: SaveOpts): Promise<void>
```

Bundle a 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.

<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
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
static load(archive: string, dest?: string): Promise<SnapshotHandle>
```

Unpack a snapshot archive (`.tar.zst` or `.tar`) into the 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.

<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&lt;SnapshotHandle&gt;</a></div>
    <div className="msb-param-desc">Handle to the loaded snapshot.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
const h = await Snapshot.load("./baseline.tar.zst");
console.log("loaded", h.digest);
```

</Accordion>

---

<p className="msb-member-group">Instance methods</p>

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

```typescript
verify(): Promise<SnapshotVerifyReport>
```

<Accordion title="Example">

```typescript
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.

<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&lt;SnapshotVerifyReport&gt;</a></div>
    <div className="msb-param-desc">Verification result.</div>
  </div>
</div>

## SnapshotHandle

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


A metadata and lifecycle handle for an existing snapshot.

<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>

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

`string`

Manifest digest (`sha256:hex`), the canonical identity.

#### <span className="msb-recv">snapshotHandle.</span><span className="msb-hn">name</span>

`string \| null`

Convenience name; `null` for digest-only entries.

#### <span className="msb-recv">snapshotHandle.</span><span className="msb-hn">parentDigest</span>

`string \| null`

Parent snapshot's manifest digest, or `null` for a root.

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

[`SnapshotScope`](#snapshotscope-type)

Snapshot payload scope (`"disk"` today).

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

`string`

Image reference the snapshot was taken from.

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

`"raw" \| "qcow2"`

On-disk format of the upper layer.

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

`bigint \| null`

Apparent size of the upper file at index time.

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

`Date`

Snapshot creation time (from manifest).

#### <span className="msb-recv">snapshotHandle.</span><span className="msb-hn">path</span>

`string`

Local artifact directory path.

#### <span className="msb-recv">snapshotHandle.</span><span className="msb-hn">open()</span> {#snapshothandleopen}

```typescript
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.

#### <span className="msb-recv">snapshotHandle.</span><span className="msb-hn">remove()</span> {#snapshothandleremove}

```typescript
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
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
```

## 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">snapshot.</span><span className="msb-hn">fromSandbox()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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">snapshot.</span><span className="msb-hn">destDir()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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">snapshot.</span><span className="msb-hn">label()</span>

```typescript
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">snapshot.</span><span className="msb-hn">force()</span>

```typescript
force(): this
```

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

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

```typescript
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">snapshot.</span><span className="msb-hn">resumable()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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">snapshot.</span><span className="msb-hn">create()</span>

```typescript
create(): Promise<Snapshot>
```

<Accordion title="Example">

```typescript
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&lt;Snapshot&gt;</a></div>
    <div className="msb-param-desc">The created snapshot artifact.</div>
  </div>
</div>

## Types

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

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

<p className="msb-backref">Used by <a href="#snapshot-save">Snapshot.save()</a></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
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
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). |
