# gizfs:volume

Files and objects are deterministic clients of the same committed range. This owner restores both catalogs at one snapshot cut and never exposes proposals.

```gizlang
import * as Volume from "gizfs:volume";
```

## Types

### `Observer`

```gizlang
type Observer = { term: i64; last: i64; after: bytes; rows: Catalog<Observation>; }
```

What a node has shown to each session: the sessions' tokens, generations and the position each saw.

- `term`: `i64`
- `last`: `i64`
- `after`: `bytes`
- `rows`: `_gizlang_lib_fs__catalog.Catalog<M43.Observation>`

### `Change`

```gizlang
type Change = { serial: i64; session: string; inode: i64; parent: i64; name: string; }
```

A change that a mount may hold in its cache (Client.changes): the attributes or bytes of an inode (inode >= 0), a
name of a directory (name !== ""), or a recall (inode < 0, name ""): session wants the names of directory parent,
which another session holds (FS.Op.delegate); the holder commits what it answered and gives them back. serial
numbers the changes of this node; session made it.

- `serial`: `i64`
- `session`: `string`
- `inode`: `i64`
- `parent`: `i64`
- `name`: `string`

### `Changes`

```gizlang
type Changes = { first: i64; next: i64; through: i64; items: Vec<Change>; }
```

A page of changes: first, the serial of the oldest this node still has (a mount that needs older ones lost them);
through, the last serial the page examined. The changes of the asking session are left out.

- `first`: `i64`
- `next`: `i64`
- `through`: `i64`
- `items`: `Vec<M43.Change>`

### `ObjectOperation`

```gizlang
type ObjectOperation = { id: string; digest: bytes; outcome: Object.Outcome; principal: Access.Principal; revision: i64; intents: Vec<Access.Intent>; requestTime: i64; }
```

An object request in flight: its id, digest, outcome, principal and intents.

- `id`: `string`
- `digest`: `bytes`
- `outcome`: `M42.Outcome`
- `principal`: `_gizlang_lib_fs__access.Principal`
- `revision`: `i64`
- `intents`: `Vec<_gizlang_lib_fs__access.Intent>`
- `requestTime`: `i64`

### `Message`

```gizlang
type Message = | { kind: "tick"; } | { kind: "incoming"; request: Protocol.Request; reply: Protocol.MailboxReply; known: Option<Store.Identity>; } | { kind: "outgoing"; serial: i64; result: Result<bytes, string>; }
```

A message to the actor of a range: a tick, a request that came in, or a peer's answer.

- `tick`
- `incoming`
- `outgoing`

### `Pending`

```gizlang
type Pending = { request: Protocol.Request; reply: Protocol.MailboxReply; known: Option<Store.Identity>; }
```

known: the identity of a stored write's bytes, hashed as the request arrived (Volume.arriving), or none.

- `request`: `_gizlang_lib_fs__protocol.Request`
- `reply`: `_gizlang_lib_fs__protocol.MailboxReply`
- `known`: `_gizlang_sdk_core.Option<_gizlang_lib_fs__store.Identity>`

### `Volume`

```gizlang
type Volume = { sys: System; raft: Raft.Node; fs: FS.State; objects: Object.State; objectOperations: Catalog<ObjectOperation>; lifecycle: Lifecycle.State; admitted: Task.Cell<Vec<Protocol.Endpoint>>; applied: i64; contact: i64; timeout: i64; mailbox: Task.Channel<Message>; pending: Vec<Pending>; serial: i64; rootIndex: Ref<Lifecycle.RootIndex>; objectOperationBytes: i64; objectOperationOldest: i64; collector: Option<Ref<CollectionSession>>; sessionRuntime: Ref<SessionRuntime>; authorization: Ref<Access.Authorization>; transportState: Ref<TransportState>; keys: Task.Cell<Vec<Access.Key>>; }
```

One replicated range of a volume on this node: its Raft node, its file system, objects, lifecycle and transport.

- `sys`: `gizlang_system.System`
- `raft`: `M40.Node`
- `fs`: `_gizlang_lib_fs__fs.State`
- `objects`: `M42.State`
- `objectOperations`: `_gizlang_lib_fs__catalog.Catalog<M43.ObjectOperation>`
- `lifecycle`: `_gizlang_lib_fs__lifecycle.State`
- `admitted`: `gizlang_task.Cell<Vec<_gizlang_lib_fs__protocol.Endpoint>>`
- `applied`: `i64`
- `contact`: `i64`
- `timeout`: `i64`
- `mailbox`: `gizlang_task.Channel<M43.Message>`
- `pending`: `Vec<M43.Pending>`
- `serial`: `i64`
- `rootIndex`: `Ref<_gizlang_lib_fs__lifecycle.RootIndex>`
- `objectOperationBytes`: `i64`
- `objectOperationOldest`: `i64`
- `collector`: `_gizlang_sdk_core.Option<Ref<M43.CollectionSession>>`
- `sessionRuntime`: `Ref<M43.SessionRuntime>`
- `authorization`: `Ref<_gizlang_lib_fs__access.Authorization>`
- `transportState`: `Ref<M43.TransportState>`
- `keys`: `gizlang_task.Cell<Vec<_gizlang_lib_fs__access.Key>>`

### `Client`

```gizlang
type Client = { sys: System; endpoints: Ref<Vec<Protocol.Endpoint>>; key: bytes; tenant: string; uid: i64; gid: i64; transport: Protocol.ConnectionPool; leader: Task.Cell<i64>; stored: Task.Cell<i64>; site: string; floor: Task.Cell<i64>; }
```

A client of a range. endpoints: the range's nodes as this client and its copies know them; a topology change
updates them (Client.learn). site: the site of this client ("" for none: every request goes to the leader).
floor: the highest applied position that this client saw (NEAR).

- `sys`: `gizlang_system.System`
- `endpoints`: `Ref<Vec<_gizlang_lib_fs__protocol.Endpoint>>`
- `key`: `bytes`
- `tenant`: `string`
- `uid`: `i64`
- `gid`: `i64`
- `transport`: `_gizlang_lib_fs__protocol.ConnectionPool`
- `leader`: `gizlang_task.Cell<i64>`
- `stored`: `gizlang_task.Cell<i64>`
- `site`: `string`
- `floor`: `gizlang_task.Cell<i64>`

### `Status`

```gizlang
type Status = { node: i64; epoch: i64; commit: i64; applied: i64; role: i64; stored: i64; band: i64; inodes: i64; }
```

BAND and INODES: the band of the range's file system (FS.band) and its inodes, which Ranges.place balances.

- `node`: `i64`
- `epoch`: `i64`
- `commit`: `i64`
- `applied`: `i64`
- `role`: `i64`
- `stored`: `i64`
- `band`: `i64`
- `inodes`: `i64`

### `Mutation`

```gizlang
type Mutation = { receipt: FS.Receipt; observed: Journal.Position; inode: Option<FS.Inode>; }
```

inode: what the command made or changed (FS.changedInode), as its reply found it; none in a receipt read later.

- `receipt`: `_gizlang_lib_fs__fs.Receipt`
- `observed`: `gizlang_journal.Position`
- `inode`: `_gizlang_sdk_core.Option<_gizlang_lib_fs__fs.Inode>`

### `Reservation`

```gizlang
type Reservation = { sequence: i64; epoch: i64; }
```

A reserved request sequence of a session, and the epoch it belongs to.

- `sequence`: `i64`
- `epoch`: `i64`

### `Tracker`

```gizlang
type Tracker = { next: i64; floor: i64; accepted: i64; after: i64; rows: Map<i64, Tracked>; }
```

The requests of a session that are not yet known to be done: their sequences, and the floor below which all are
done.

- `next`: `i64`
- `floor`: `i64`
- `accepted`: `i64`
- `after`: `i64`
- `rows`: `_gizlang_sdk_collections.Map<i64, M43.Tracked>`

### `SessionClient`

```gizlang
type SessionClient = { client: Client; token: FS.SessionToken; mailbox: Task.Channel<ControlEvent>; stopped: Task.Cell<bool>; failed: Task.Cell<string>; worker: Task.Task<i64>; timer: Task.Task<i64>; closing: Task.Channel<bool>; }
```

A client of one filesystem session: it numbers its commands, renews the session and learns their receipts.

- `client`: `M43.Client`
- `token`: `_gizlang_lib_fs__fs.SessionToken`
- `mailbox`: `gizlang_task.Channel<M43.ControlEvent>`
- `stopped`: `gizlang_task.Cell<bool>`
- `failed`: `gizlang_task.Cell<string>`
- `worker`: `gizlang_task.Task<i64>`
- `timer`: `gizlang_task.Task<i64>`
- `closing`: `gizlang_task.Channel<bool>`

### `Maintenance`

```gizlang
type Maintenance = { cut: i64; checked: i64; changed: i64; next: string; workBytes: i64; unconfirmed: i64; }
```

One maintenance page: `checked` roots verified (`changed` of them repaired); `unconfirmed` roots could not be verified now.

- `cut`: `i64`
- `checked`: `i64`
- `changed`: `i64`
- `next`: `string`
- `workBytes`: `i64`
- `unconfirmed`: `i64`

### `Membership`

```gizlang
type Membership = { cut: i64; migrated: i64; total: i64; done: bool; }
```

One membership step: the cut, the roots copied so far of the total, and whether the change is done.

- `cut`: `i64`
- `migrated`: `i64`
- `total`: `i64`
- `done`: `bool`

### `Preparation`

```gizlang
type Preparation = { cut: i64; examined: i64; total: i64; roots: i64; done: bool; }
```

One step of a capture for a reclamation or a backup: the cut, the roots seen so far of the total, and whether it is
done.

- `cut`: `i64`
- `examined`: `i64`
- `total`: `i64`
- `roots`: `i64`
- `done`: `bool`

### `ReaderReclamation`

```gizlang
type ReaderReclamation = { revision: i64; examined: i64; released: i64; next: string; }
```

One page of object reader reclamation: the revision, the readers seen and released, and where the next page starts.

- `revision`: `i64`
- `examined`: `i64`
- `released`: `i64`
- `next`: `string`

### `HashJob`

```gizlang
type HashJob = { tenant: string; data: bytes; reply: Task.Channel<Option<Store.Identity>>; }
```

A stored write that arrived (arriving) and the channel for its identity.

- `tenant`: `string`
- `data`: `bytes`
- `reply`: `gizlang_task.Channel<_gizlang_sdk_core.Option<_gizlang_lib_fs__store.Identity>>`

### `Retained`

```gizlang
type Retained = { roots: i64; bytes: i64; copies: i64; next: string; }
```

The immutable bytes that the range retains, one page of identities at a time (each counted once, before copies).

- `roots`: `i64`
- `bytes`: `i64`
- `copies`: `i64`
- `next`: `string`

### `ReadReply`

```gizlang
type ReadReply = { data: bytes; stale: bool; }
```

The bytes of a handle, and whether the read should change the inode's access time (FS.accessStale).

- `data`: `bytes`
- `stale`: `bool`

### `PinnedVersion`

```gizlang
type PinnedVersion = { version: Object.Version; capability: bytes; }
```

An object version that a pin holds, and the capability that reads its bytes.

- `version`: `M42.Version`
- `capability`: `bytes`

### `PinnedUpload`

```gizlang
type PinnedUpload = { state: Object.State; capability: bytes; }
```

An upload that a pin holds, and the capability that reads its bytes.

- `state`: `M42.State`
- `capability`: `bytes`

### `RefMove`

```gizlang
type RefMove = | { kind: "moved"; version: i64; } | { kind: "conflict"; }
```

A move of a named ref: the new version of the ref object, or a conflict when the
ref no longer names `from` or another move came first.

- `moved`
- `conflict`

## Functions

### `changesReady`

```gizlang
function changesReady(request: bytes, page: bytes): bool
```

True when the CHANGES answer PAGE to the request REQUEST goes back now: a first request (after < 0), a page with
changes, or one that moved past the changes of the asking session. A bad body goes back too, as its error.

Effects: fail, read, write, console, io.

### `innerRequest`

```gizlang
function innerRequest(request: Protocol.Request): Protocol.Request
```

The request that a NEAR envelope carries, or REQUEST.

Effects: fail, read, write, console, io.

### `newClient`

```gizlang
function newClient(sys: System, endpoints: Vec<Protocol.Endpoint>, key: bytes, tenant: string, uid: i64, gid: i64): Result<Client, string>
```

Prepared in the caller's owning task, before any request deadline children.
The same transport and byte issuer serve FS, S3 and administrative requests.

Effects: fail, read, write, console, io.

### `formats`

```gizlang
function formats(): Vec<Codec.Format>
```

The on-disk formats of this module. A test opens a committed store sample of every version.

Effects: fail.

### `mutating`

```gizlang
function mutating(method: string): bool
```

Whether METHOD changes the file system (mutate or a batch).

### `innerMethod`

```gizlang
function innerMethod(request: Protocol.Request): string
```

The method of REQUEST, or of the request in its NEAR envelope.

Effects: fail, read, write, console, io.

### `open`

```gizlang
function open(sys: System, disk: Disk, local: Store.Local, id: i64, endpoints: Vec<Protocol.Endpoint>, voters: Vec<i64>, policy: Durability, key: bytes, history: string): Result<Volume, string>
```

Opens the range of this node on DISK: its log, its snapshot and its state.

Effects: fail, read, write, console, io.

### `snapshotSize`

```gizlang
function snapshotSize(volume: Volume): Result<i64, string>
```

Same encoded envelope, sized by its owners before allocation or proposal.

Effects: fail, read, write, console, io.

### `operationKey`

```gizlang
function operationKey(principal: Access.Principal, id: string): bytes
```

The key of an object operation in objectOperations: who asked and the operation id.

Effects: fail.

### `observe`

```gizlang
function observe(observer: mut Observer, state: FS.State, term: i64, leader: bool, now: i64, count: i64): Result<Vec<FS.Session>, string>
```

Derived observations use canonical session physical slots. Slot reuse replaces
an observation; history/incarnation/generation never transfer an old deadline.
The index is transient and bounded by the canonical session pool's peak size.

Effects: fail, read, write, console, io.

### `arriving`

```gizlang
function arriving(tenant: string, request: Protocol.Request, hashers: Task.Channel<HashJob>): Option<Store.Identity>
```

As a request arrives, before the actor takes it: the identity of the bytes of a stored write of at least
THREAD_HASH_BYTES, hashed on one of the node's hash threads (startHashers). The actor that commits the write then
does not hash it (resolveStored), and the requests of all connections hash at once. A 1 MiB hash was 0.6 ms of the
actor's 6 ms for each MiB written (2026-10-15). None for any other request.

Effects: fail, io.

### `startHashers`

```gizlang
function startHashers(count: i64): Task.Channel<HashJob>
```

COUNT threads that hash arriving stored writes while the node serves. They live as long as the calling task: a
thread for each write set up a runtime world each time, 2-3 ms, and a 256 MiB close sent 256 of them (0.6-1 s).

Effects: fail, read, write, console, io.

### `backupBlobs`

```gizlang
function backupBlobs(bundle: bytes): Result<Vec<Store.Identity>, string>
```

The blobs that a backup bundle of version 3 names (Volume.backup), read without its key: Client.backupTo copies
them, and the restore checks the bundle's signature and each blob.

Effects: fail, read, write, console, io.

### `accepted`

```gizlang
function accepted(outcome: Object.Outcome): Result<Object.Outcome, string>
```

OUTCOME, or its refusal (a status of 300 or more) as an error.

Effects: fail.

### `observePending`

```gizlang
function observePending(tracker: mut Tracker, sequence: i64, mutation: Mutation, history: string): Result<bool, string>
```

A still-pending read proves no terminal effect through this exact barrier.
A terminal status alone is not adapter acceptance of its result.

Effects: fail.

### `plannedMethod`

```gizlang
function plannedMethod(method: string): string
```

The planned method of METHOD, or "" when the actor answers it whole.

### `internalMethod`

```gizlang
function internalMethod(method: string): bool
```

Whether METHOD is planned work of the actor itself, which no client may call.

### `answerPlanned`

```gizlang
function answerPlanned(local: Store.Local, request: Protocol.Request, plan: bytes): Option<bytes>
```

The reply of REQUEST that the actor planned as PLAN; none when the actor answers it whole.

Effects: fail, read, write, console, io.

### `readPlanned`

```gizlang
function readPlanned(local: Store.Local, plan: bytes): Option<bytes>
```

The reply of a read that planRead planned, with LOCAL the node's store; none when a piece needs the actor.

Effects: fail, read, write, console, io.

## Methods

### `Volume.changeSignal`

```gizlang
function Volume.changeSignal(self: Volume): Task.Cell<i64>
```

The serial of the next change of this node (ChangeFeed.next), for the connections that hold a CHANGES request
until a change comes (node.giz answer): a mount learns of a change at once, with one request each CHANGES_WAIT_MS
when nothing changes.

Effects: fail, read.

### `Client.close`

```gizlang
function Client.close(self: Client): void
```

Closes the client's connections.

Effects: fail, read, write, console, io.

### `Volume.roots`

```gizlang
function Volume.roots(self: Volume, staged: bool): Result<Vec<Store.Identity>, string>
```

The roots that the range retains; STAGED adds the ones of writes not yet committed.

Effects: fail, read, write, console, io.

### `Volume.applyCommitted`

```gizlang
function Volume.applyCommitted(self: mut Volume): Result<bool, string>
```

Applies the committed log entries that are not yet applied.

Effects: fail, read, write, console, io.

### `Volume.peerDone`

```gizlang
function Volume.peerDone(self: mut Volume, serial: i64, result: Result<bytes, string>): void
```

Takes the answer RESULT of the peer work SERIAL.

Effects: fail, read, write, console, io.

### `Volume.tick`

```gizlang
function Volume.tick(self: mut Volume): Result<bool, string>
```

Runs the timers of the range: elections, heartbeats, leases and expiry. True when this node leads.

Effects: fail, read, write, console, io.

### `Volume.barrier`

```gizlang
function Volume.barrier(self: mut Volume): Result<i64, string>
```

A read barrier: the commit index that a read waits for. It fails unless this node leads with a quorum.

Effects: fail, read, write, console, io.

### `Volume.checkpoint`

```gizlang
function Volume.checkpoint(self: mut Volume): Result<Raft.Snapshot, string>
```

The byte files kept from the log (one syncfs) and the page files sync at the same time: neither depends on the other.

Effects: fail, read, write, console, io.

### `Volume.mutate`

```gizlang
function Volume.mutate(self: mut Volume, command: FS.Command): Result<FS.Outcome, string>
```

Commits COMMAND; its outcome.

Effects: fail, read, write, console, io.

### `Volume.mutateMany`

```gizlang
function Volume.mutateMany(self: mut Volume, given: Vec<FS.Command>): Vec<Result<FS.Outcome, string>>
```

Group commit: each command projects on the ones before it, the leader proposes all of them,
and one replication round commits them with one log sync on each node.

Effects: fail, read, write, console, io.

### `Volume.mutateObject`

```gizlang
function Volume.mutateObject(self: mut Volume, principal: Access.Principal, id: string, payload: bytes): Result<Object.Outcome, string>
```

Commits the object request ID of PRINCIPAL with PAYLOAD; its outcome.

Effects: fail, read, write, console, io.

### `Volume.changeAuthorization`

```gizlang
function Volume.changeAuthorization(self: mut Volume, principal: Access.Principal, change: Access.RuleChange): Result<i64, string>
```

Commits the authorization change CHANGE; the new revision.

Effects: fail, read, write, console, io.

### `Volume.changeKey`

```gizlang
function Volume.changeKey(self: mut Volume, principal: Access.Principal, change: Access.KeyChange): Result<bytes, string>
```

Issue the next key of a principal (its credential key in the reply), or revoke its key (an empty reply).

Effects: fail, read, write, console, io.

### `Volume.retained`

```gizlang
function Volume.retained(self: mut Volume, after: string, count: i64): Result<Retained, string>
```

One page of COUNT retained roots after AFTER.

Effects: fail, read, write, console, io.

### `Volume.mutateLifecycle`

```gizlang
function Volume.mutateLifecycle(self: mut Volume, command: Lifecycle.Command): Result<i64, string>
```

Commits the lifecycle command COMMAND; its cut.

Effects: fail, read, write, console, io.

### `Volume.reclaimObjectReaders`

```gizlang
function Volume.reclaimObjectReaders(self: mut Volume, principal: Access.Principal, revision: i64, after: string, count: i64): Result<ReaderReclamation, string>
```

Reclaim only capabilities already invalidated by a committed ACL generation.
A lost token, disconnected reader or local clock alone grants no deletion.
The existing lifecycle catalog and release command remain the sole roots.

Effects: fail, read, write, console, io.

### `Volume.upload`

```gizlang
function Volume.upload(self: mut Volume, tenant: string, data: bytes): Result<Vec<Store.Receipt>, string>
```

Stores DATA of TENANT on its owners; the receipts of its copies.

Effects: fail, read, write, console, io.

### `Volume.scrub`

```gizlang
function Volume.scrub(self: mut Volume, after: string, count: i64): Result<Maintenance, string>
```

Checks one page of COUNT roots after AFTER, and repairs the copies that are missing or bad.

Effects: fail, read, write, console, io.

### `Volume.prepareGC`

```gizlang
function Volume.prepareGC(self: mut Volume, id: string, count: i64): Result<Preparation, string>
```

Captures one page of COUNT roots for the reclamation ID.

Effects: fail, read, write, console, io.

### `Volume.prepareBackup`

```gizlang
function Volume.prepareBackup(self: mut Volume, id: string, count: i64): Result<Preparation, string>
```

Captures one page of COUNT roots for the backup ID.

Effects: fail, read, write, console, io.

### `Volume.beginGC`

```gizlang
function Volume.beginGC(self: mut Volume): Result<i64, string>
```

Whole-operation convenience. Bounded maintenance calls prepareGC repeatedly
instead, then collect with its opaque per-node native cursor.

Effects: fail, read, write, console, io.

### `Volume.collect`

```gizlang
function Volume.collect(self: mut Volume, node: i64, after: string, count: i64): Result<Maintenance, string>
```

Reclaims on NODE one page of COUNT roots after AFTER that the reclamation cut no longer retains.

Effects: fail, read, write, console, io.

### `Volume.membership`

```gizlang
function Volume.membership(self: mut Volume, endpoints: Vec<Protocol.Endpoint>, target: Vec<i64>, count: i64): Result<Membership, string>
```

Moves the range one step toward the nodes TARGET at ENDPOINTS, copying up to COUNT roots.

Effects: fail, read, write, console, io.

### `Volume.backup`

```gizlang
function Volume.backup(self: mut Volume, id: string, budget: i64): Result<bytes, string>
```

The signed backup bundle of the current cut (version 3): the metadata image and the names of its blobs, which stay
pinned (backup:ID) until Client.unpin. The bytes go apart (Client.backupTo), so a backup has no bound but the
metadata. Kept small writes go to their blob files first, so every named blob is a file of a node.

Effects: fail, read, write, console, io.

### `Volume.importBackup`

```gizlang
function Volume.importBackup(self: mut Volume, data: bytes, sourceKey: bytes): Result<bool, string>
```

Restores a backup bundle into this empty range. Version 3 (Volume.backup) names its blobs, and the restore reads
each one from this node's blob folder (copied there from the backup: Client.backupTo), one at a time, and checks
its identity. Version 2 holds the bytes of its blobs.

Effects: fail, read, write, console, io.

### `Client.backupTo`

```gizlang
function Client.backupTo(self: Client, id: string, dir: Dir): Result<i64, string>
```

A backup of this range into the folder DIR: each blob that DIR lacks (Store.fileName: named by its identity, so a
later backup into the same folder copies only new blobs), then BACKUP_MANIFEST, the signed bundle of the cut
(Volume.backup), and the pins of the backup ID go. To restore, copy MANIFEST to a new node's RESTORE and the blob
files to its bytes/. Returns the count of blobs it copied.

Effects: fail, read, write, console, io.

### `Volume.gather`

```gizlang
function Volume.gather(self: mut Volume): Result<bool, string>
```

Takes the messages already in the mailbox, without waiting. Requests join the pending queue, so a mutation commits
with those queued behind it: a sole voter receives no messages during its commit (it has no replication round), so
before this each of its commands had its own log sync. A probe task receives while this task yields; a probe that
still waits then is cancelled. A tick runs once at the end.

Effects: fail, read, write, console, io.

### `Volume.settle`

```gizlang
function Volume.settle(self: mut Volume): void
```

A follower acknowledges an append of new entries as soon as its log is durable, and applies the commits it
learned after the reply: its apply is not on the leader's commit path. A commit-only append (a barrier)
is applied before the reply, so a barrier still proves that the acknowledging followers applied. A failed apply stops
the range (reopen required), as an uncertain sync does.

Effects: fail, read, write, console, io.

### `Volume.handle`

```gizlang
function Volume.handle(self: mut Volume, request: Protocol.Request): Protocol.Response
```

The answer to REQUEST.

Effects: fail, read, write, console, io.

### `Volume.handleKnown`

```gizlang
function Volume.handleKnown(self: mut Volume, request: Protocol.Request, known: Option<Store.Identity>): Protocol.Response
```

The answer to REQUEST, whose stored write's bytes have the identity KNOWN when it is some (Volume.arriving).

Effects: fail, read, write, console, io.

### `Client.inSite`

```gizlang
function Client.inSite(self: Client, site: string): Client
```

The same client in SITE: its reads go to the nodes of SITE first, and the leader counts its writes for SITE (NEAR).

### `Client.status`

```gizlang
function Client.status(self: Client): Result<Status, string>
```

The status of the range, from the node that answers.

Effects: fail, read, write, console, io.

### `Client.nodeStatus`

```gizlang
function Client.nodeStatus(self: Client, node: i64): Result<Status, string>
```

The status of the range from NODE.

Effects: fail, read, write, console, io.

### `Client.nodeUsage`

```gizlang
function Client.nodeUsage(self: Client, node: i64): Result<Usage.NodeUsage, string>
```

The storage usage of NODE.

Effects: fail, read, write, console, io.

### `Client.offerSession`

```gizlang
function Client.offerSession(self: Client): Result<FS.SessionOffer, string>
```

An offer to begin a filesystem session.

Effects: fail, read, write, console, io.

### `Client.sessionStatus`

```gizlang
function Client.sessionStatus(self: Client, token: FS.SessionToken): Result<FS.Session, string>
```

The session of TOKEN.

Effects: fail, read, write, console, io.

### `Client.requestCeiling`

```gizlang
function Client.requestCeiling(self: Client, token: FS.SessionToken): Result<i64, string>
```

The highest request sequence that the session of TOKEN may use.

Effects: fail, read, write, console, io.

### `Client.authorize`

```gizlang
function Client.authorize(self: Client, token: FS.SessionToken): Result<Journal.Position, string>
```

Checks the session of TOKEN; the journal position that it may read from.

Effects: fail, read, write, console, io.

### `Client.receipt`

```gizlang
function Client.receipt(self: Client, token: FS.SessionToken, sequence: i64): Result<Mutation, string>
```

The receipt of request SEQUENCE of the session of TOKEN.

Effects: fail, read, write, console, io.

### `Client.lockStatus`

```gizlang
function Client.lockStatus(self: Client, token: FS.SessionToken, sequence: i64): Result<Mutation, string>
```

The lock request SEQUENCE of the session of TOKEN, when it is still waiting.

Effects: fail, read, write, console, io.

### `Client.mutate`

```gizlang
function Client.mutate(self: Client, command: FS.Command): Result<Mutation, string>
```

Epoch resolution is once per call. A caller with an uncertain transport result
retains its resolved command; neither its token nor sequence is regenerated.

Effects: fail, read, write, console, io.

### `Client.mutateBatch`

```gizlang
function Client.mutateBatch(self: Client, commands: Vec<FS.Command>): Result<Vec<Result<Mutation, string>>, string>
```

COMMANDS in order in one request (MUTATE_BATCH): one round trip and one commit. Each has its mutation or the error
that the volume gave it.

Effects: fail, read, write, console, io.

### `Client.changes`

```gizlang
function Client.changes(self: Client, after: i64, own: FS.SessionToken): Result<Changes, string>
```

The changes of the volume after serial AFTER (Change) that the session OWN did not make; AFTER < 0 gives none and
where they start.

Effects: fail, read, write, console, io.

### `Client.resumedSession`

```gizlang
function Client.resumedSession(self: Client, source: FS.SessionToken): Result<FS.Resume, string>
```

The session that resumed the session SOURCE, and how its handles map.

Effects: fail, read, write, console, io.

### `Client.sessionPage`

```gizlang
function Client.sessionPage(self: Client, after: bytes, count: i64): Result<FS.SessionPage, string>
```

One page of COUNT sessions after AFTER.

Effects: fail, read, write, console, io.

### `Client.branchResume`

```gizlang
function Client.branchResume(self: Client, offer: FS.SessionOffer, nonce: string, source: FS.SessionToken, expected: i64, uid: i64, gid: i64, duration: i64): Result<FS.Resume, string>
```

Caller retains the offered raw target capability across uncertain replies;
the historical selection stays canonical and cannot authorize ordinary I/O.

Effects: fail, read, write, console, io.

### `Client.lookup`

```gizlang
function Client.lookup(self: Client, token: FS.SessionToken, parent: i64, name: string): Result<FS.Inode, string>
```

The inode of NAME in the folder PARENT.

Effects: fail, read, write, console, io.

### `Client.stat`

```gizlang
function Client.stat(self: Client, token: FS.SessionToken, inode: i64): Result<FS.Inode, string>
```

The inode INODE.

Effects: fail, read, write, console, io.

### `Client.fstat`

```gizlang
function Client.fstat(self: Client, token: FS.SessionToken, handle: i64): Result<FS.Inode, string>
```

The inode of the open handle HANDLE.

Effects: fail, read, write, console, io.

### `Client.getxattr`

```gizlang
function Client.getxattr(self: Client, token: FS.SessionToken, inode: i64, name: string): Result<bytes, string>
```

The value of the extended attribute NAME of INODE.

Effects: fail, read, write, console, io.

### `Client.listxattr`

```gizlang
function Client.listxattr(self: Client, token: FS.SessionToken, inode: i64): Result<Vec<string>, string>
```

The names of the extended attributes of INODE.

Effects: fail, read, write, console, io.

### `Client.getlock`

```gizlang
function Client.getlock(self: Client, token: FS.SessionToken, handle: i64, owner: i64, profile: string, start: i64, length: i64, exclusive: bool): Result<Option<FS.Lock>, string>
```

A lock of another owner that conflicts with the lock of OWNER on START and LENGTH of HANDLE, or none.

Effects: fail, read, write, console, io.

### `Client.list`

```gizlang
function Client.list(self: Client, token: FS.SessionToken, parent: i64, revision: i64, after: string, count: i64): Result<FS.Listing, string>
```

One page of COUNT entries of the folder PARENT after AFTER, at REVISION.

Effects: fail, read, write, console, io.

### `Client.read`

```gizlang
function Client.read(self: Client, token: FS.SessionToken, handle: i64, offset: i64, count: i64): Result<bytes, string>
```

COUNT bytes of HANDLE at OFFSET.

Effects: fail, read, write, console, io.

### `Client.readRelatime`

```gizlang
function Client.readRelatime(self: Client, token: FS.SessionToken, handle: i64, offset: i64, count: i64): Result<ReadReply, string>
```

COUNT bytes of HANDLE at OFFSET, and whether the access time should change.

Effects: fail, read, write, console, io.

### `Client.readInode`

```gizlang
function Client.readInode(self: Client, token: FS.SessionToken, inode: i64, offset: i64, count: i64): Result<ReadReply, string>
```

Reads the file INODE with no open handle (FS.readInode): a mount's read-only open.

Effects: fail, read, write, console, io.

### `Client.upload`

```gizlang
function Client.upload(self: Client, data: bytes): Result<Vec<Store.Receipt>, string>
```

Stores DATA of the client's tenant; the receipts of its copies.

Effects: fail, read, write, console, io.

### `Client.uploadFile`

```gizlang
function Client.uploadFile(self: Client, token: FS.SessionToken, handle: i64, data: bytes): Result<Vec<Store.Receipt>, string>
```

Stores DATA for a write to HANDLE; the receipts of its copies.

Effects: fail, read, write, console, io.

### `Client.writeOp`

```gizlang
function Client.writeOp(self: Client, token: FS.SessionToken, handle: i64, offset: i64, data: bytes): Result<FS.Op, string>
```

The operation that writes data at offset: up to the range's stored limit (Client.stored) the bytes ride in the
command (one commit makes them durable on a quorum); larger data goes to its owners first (Client.place).

Effects: fail, read, write, console, io.

### `Client.objectState`

```gizlang
function Client.objectState(self: Client): Result<Object.State, string>
```

Read-only policy projection: the master receipt/peer key never crosses the wire.
Pagination tokens use the gateway's bound client key. Publication verification
remains exclusively at the authoritative volume with its master policy.

Effects: fail, read, write, console, io.

### `Client.objectPage`

```gizlang
function Client.objectPage(self: Client, q: Object.Query): Result<Object.Page, string>
```

One page of the object query Q.

Effects: fail, read, write, console, io.

### `Client.objectView`

```gizlang
function Client.objectView(self: Client, bucket: string, key: string, version: i64, uploadId: string, actions: i64): Result<Object.State, string>
```

The object catalog view that ACTIONS on KEY of BUCKET need: the version, or the upload UPLOADID.

Effects: fail, read, write, console, io.

### `Client.pinObject`

```gizlang
function Client.pinObject(self: Client, bucket: string, key: string, version: i64, pinId: string): Result<PinnedVersion, string>
```

Pins VERSION of KEY in BUCKET under PINID, so its bytes stay until it is released.

Effects: fail, read, write, console, io.

### `Client.pinUpload`

```gizlang
function Client.pinUpload(self: Client, bucket: string, key: string, uploadId: string, nonce: string): Result<PinnedUpload, string>
```

Pins the upload UPLOADID of KEY in BUCKET.

Effects: fail, read, write, console, io.

### `Client.fetchPinned`

```gizlang
function Client.fetchPinned(self: Client, token: bytes, blob: Store.Identity): Result<bytes, string>
```

The bytes of BLOB through the pin capability TOKEN.

Effects: fail, read, write, console, io.

### `Client.releaseObject`

```gizlang
function Client.releaseObject(self: Client, token: bytes): Result<i64, string>
```

Releases the pin of TOKEN; the cut.

Effects: fail, read, write, console, io.

### `Client.authorization`

```gizlang
function Client.authorization(self: Client): Result<Access.Authorization, string>
```

The access rules and keys of the range.

Effects: fail, read, write, console, io.

### `Client.reclaimObjectReaders`

```gizlang
function Client.reclaimObjectReaders(self: Client, revision: i64, after: string, count: i64): Result<ReaderReclamation, string>
```

Releases one page of COUNT object readers after AFTER that REVISION no longer allows.

Effects: fail, read, write, console, io.

### `Client.changeAuthorization`

```gizlang
function Client.changeAuthorization(self: Client, change: Access.RuleChange): Result<i64, string>
```

Commits the authorization change CHANGE; the new revision.

Effects: fail, read, write, console, io.

### `Client.changeKey`

```gizlang
function Client.changeKey(self: Client, change: Access.KeyChange): Result<bytes, string>
```

Commits the key change CHANGE; the issued key, or none.

Effects: fail, read, write, console, io.

### `Client.retained`

```gizlang
function Client.retained(self: Client, after: string, count: i64): Result<Retained, string>
```

One page of COUNT retained roots after AFTER.

Effects: fail, read, write, console, io.

### `Client.uploadObject`

```gizlang
function Client.uploadObject(self: Client, bucket: string, key: string, data: bytes): Result<Vec<Store.Receipt>, string>
```

Stores DATA as the object KEY of BUCKET; the receipts of its copies.

Effects: fail, read, write, console, io.

### `Client.mutateObject`

```gizlang
function Client.mutateObject(self: Client, id: string, payload: bytes): Result<Object.Outcome, string>
```

Commits the object request ID with PAYLOAD; its outcome.

Effects: fail, read, write, console, io.

### `Client.objectResult`

```gizlang
function Client.objectResult(self: Client, id: string): Result<Option<Object.Outcome>, string>
```

The outcome of the object request ID, when it is known.

Effects: fail, read, write, console, io.

### `Client.changeObject`

```gizlang
function Client.changeObject(self: Client, command: Object.Command): Result<Object.Outcome, string>
```

One object mutation under a new operation id, with its outcome whatever its status.
A lost reply is resolved through the outcome of the same id.

Effects: fail, read, write, console, io.

### `Client.stageObject`

```gizlang
function Client.stageObject(self: Client, bucket: string, key: string, data: bytes): Result<Vec<Store.Chunk>, string>
```

`data` as immutable chunks on their durable owners, ready for a put of the object.

Effects: fail, read, write, console, io.

### `Client.objectSummary`

```gizlang
function Client.objectSummary(self: Client, bucket: string, key: string): Result<Option<Object.Summary>, string>
```

The current version of the object, if the bucket has it.

Effects: fail, read, write, console, io.

### `Client.moveRef`

```gizlang
function Client.moveRef(self: Client, bucket: string, key: string, name: string, from: i64, to: i64): Result<RefMove, string>
```

Points ref `name` (draft, review, published) of object `key` from version `from` (0:
no ref yet) to version `to`. The ref is the object `KEY/.refs/NAME`, and its body is
the decimal version it names; the versions of that object are the ref's history. The
move is one put conditional on the ref object's version, after its ETag shows `from`.
The caller names a version of `key` that exists.

Effects: fail, read, write, console, io.

### `Client.ref`

```gizlang
function Client.ref(self: Client, bucket: string, key: string, name: string): Result<i64, string>
```

The version of `key` that ref `name` names, or 0 when the ref does not exist.

Effects: fail, read, write, console, io.

### `Client.put`

```gizlang
function Client.put(self: Client, bucket: string, key: string, data: bytes, contentType: string): Result<i64, string>
```

DATA as the new latest version of `key` (Client.putFrom). Gives that version.

Effects: fail, read, write, console, io.

### `Client.putFrom`

```gizlang
function Client.putFrom(self: Client, bucket: string, key: string, size: i64, contentType: string, piece: (offset: i64, count: i64) => Result<bytes, string>, done: (bytes: i64) => void): Result<Object.Outcome, string>
```

SIZE bytes as the new latest version of `key`. PIECE(offset, count) gives them one PART at a time, so at most one
part is in memory; DONE(bytes) follows the progress. An object above PART is a multipart upload, which keeps the
matching parts of an unfinished upload of the key: a retry sends only the rest. Gives the outcome of the
publication (its version and ETag); a refusal is an error.

Effects: fail, read, write, console, io.

### `Client.get`

```gizlang
function Client.get(self: Client, bucket: string, key: string, version: i64): Result<bytes, string>
```

The bytes of version `version` of `key` (0: the latest). The read pin is released
on every path.

Effects: fail, read, write, console, io.

### `Client.fetchChecked`

```gizlang
function Client.fetchChecked(self: Client, capability: bytes, blob: Store.Identity): Result<bytes, string>
```

One chunk of a pinned version, checked against its identity.

Effects: fail, read, write, console, io.

### `Client.rows`

```gizlang
function Client.rows(self: Client, first: Object.Query, most: i64): Result<Vec<Object.Summary>, string>
```

The rows of every page of a query until a page is not truncated. More than `most`
rows is an error, so that a large bucket cannot fill memory.

Effects: fail, read, write, console, io.

### `Client.fetch`

```gizlang
function Client.fetch(self: Client, blob: Store.Identity): Result<bytes, string>
```

The bytes of BLOB, from a node that holds a valid copy.

Effects: fail, read, write, console, io.

### `Client.topology`

```gizlang
function Client.topology(self: Client): Result<Vec<Protocol.Endpoint>, string>
```

The nodes of the range.

Effects: fail, read, write, console, io.

### `Client.scrub`

```gizlang
function Client.scrub(self: Client, after: string, count: i64): Result<Maintenance, string>
```

Volume.scrub on the range.

Effects: fail, read, write, console, io.

### `Client.beginGC`

```gizlang
function Client.beginGC(self: Client): Result<i64, string>
```

Starts a reclamation; its cut.

Effects: fail, read, write, console, io.

### `Client.prepareGC`

```gizlang
function Client.prepareGC(self: Client, id: string, count: i64): Result<Preparation, string>
```

Volume.prepareGC on the range.

Effects: fail, read, write, console, io.

### `Client.prepareBackup`

```gizlang
function Client.prepareBackup(self: Client, id: string, count: i64): Result<Preparation, string>
```

Volume.prepareBackup on the range.

Effects: fail, read, write, console, io.

### `Client.cancelCapture`

```gizlang
function Client.cancelCapture(self: Client): Result<bool, string>
```

Cancels the capture in progress.

Effects: fail, read, write, console, io.

### `Client.collect`

```gizlang
function Client.collect(self: Client, node: i64, after: string, count: i64): Result<Maintenance, string>
```

Volume.collect on the range.

Effects: fail, read, write, console, io.

### `Client.pin`

```gizlang
function Client.pin(self: Client, id: string, roots: Vec<Store.Identity>): Result<i64, string>
```

Pins ROOTS under ID, so they stay until Client.unpin; the cut.

Effects: fail, read, write, console, io.

### `Client.unpin`

```gizlang
function Client.unpin(self: Client, id: string): Result<i64, string>
```

Releases the pin ID; the cut.

Effects: fail, read, write, console, io.

### `Client.backup`

```gizlang
function Client.backup(self: Client, id: string, budget: i64): Result<bytes, string>
```

The backup ID, at most BUDGET bytes.

Effects: fail, read, write, console, io.

### `Client.membership`

```gizlang
function Client.membership(self: Client, endpoints: Vec<Protocol.Endpoint>, target: Vec<i64>, count: i64): Result<Membership, string>
```

Volume.membership on the range.

Effects: fail, read, write, console, io.

### `Client.cancelMembership`

```gizlang
function Client.cancelMembership(self: Client): Result<i64, string>
```

Cancels the membership change in progress; the cut.

Effects: fail, read, write, console, io.

### `Client.checkpoint`

```gizlang
function Client.checkpoint(self: Client): Result<i64, string>
```

Writes a snapshot of the range and trims its log; the cut.

Effects: fail, read, write, console, io.

### `Client.beginSession`

```gizlang
function Client.beginSession(self: Client, offer: FS.SessionOffer, nonce: string, duration: i64): Result<FS.SessionToken, string>
```

Begin is a caller-held CAS identity until authority answers; no offer or nonce
is regenerated after an uncertain transport result.

Effects: fail, read, write, console, io.

### `Client.retireSession`

```gizlang
function Client.retireSession(self: Client, token: FS.SessionToken): Result<bool, string>
```

Retires the session of TOKEN, which its process left with no end (a mount that starts again after a crash): its
delegations, locks and opens go now, not at the end of its lease. An administrator drops the outcomes it did not
accept: no process takes them. A session that is gone already is no error.

Effects: fail, read, write, console, io.

### `Client.sibling`

```gizlang
function Client.sibling(self: Client): Result<Client, string>
```

A client of the same principal with its own connections, and the same in-process routes (Protocol.LocalRoute).

Effects: fail, read, write, console, io.

### `Client.openSession`

```gizlang
function Client.openSession(self: Client, nonce: string, duration: i64): Result<SessionClient, string>
```

Begins a session for NONCE that lasts DURATION milliseconds, and starts its client.

Effects: fail, read, write, console, io.

### `Client.startSession`

```gizlang
function Client.startSession(self: Client, token: FS.SessionToken): Result<SessionClient, string>
```

Starts the client of the new session TOKEN.

Effects: fail, read, write, console, io.

### `SessionClient.command`

```gizlang
function SessionClient.command(self: SessionClient, op: FS.Op): Result<FS.Command, string>
```

The command of OP, with the session's next sequence.

Effects: fail, io.

### `SessionClient.accept`

```gizlang
function SessionClient.accept(self: SessionClient, sequence: i64, mutation: Mutation): Result<bool, string>
```

Records that the command SEQUENCE committed as MUTATION.

Effects: fail, io.

### `SessionClient.mutate`

```gizlang
function SessionClient.mutate(self: SessionClient, op: FS.Op): Result<Mutation, string>
```

Runs op as the next command of this session. A stale epoch changes nothing (ESTALE): the controller
learns the new one, and one new command is tried. A fenced session is ESTALE. The mutation also gives the inode
the command made or changed (Mutation.inode).

Effects: fail, read, write, console, io.

### `SessionClient.change`

```gizlang
function SessionClient.change(self: SessionClient, op: FS.Op): Result<FS.Outcome, string>
```

Commits OP; its outcome.

Effects: fail, read, write, console, io.

### `SessionClient.mutateMany`

```gizlang
function SessionClient.mutateMany(self: SessionClient, ops: Vec<FS.Op>): Result<Vec<Result<Mutation, string>>, string>
```

OPS in order as commands of this session in one batch (Client.mutateBatch): one round trip and one commit. Each has
its mutation or its error. A lost reply sends the same commands again (the volume applies a sequence once); a command
that the volume did not settle goes again alone (settle), so no sequence stays reserved. A stale epoch runs its op again.

Effects: fail, read, write, console, io.

### `SessionClient.write`

```gizlang
function SessionClient.write(self: SessionClient, handle: i64, offset: i64, data: bytes): Result<FS.Outcome, string>
```

Writes DATA at OFFSET as the next command (Client.writeOp). A range that grew past its copies takes no stored write
above FS.STORED_WRITE_BYTES (EINVAL): the client then learns that limit, and the write goes again by upload.

Effects: fail, read, write, console, io.

### `SessionClient.store`

```gizlang
function SessionClient.store(self: SessionClient, handle: i64, pieces: Vec<FS.StorePiece>, data: bytes): Result<FS.Outcome, string>
```

DATA as PIECES of the file of HANDLE in one stored write (FS.StorePiece): the small writes a flush holds. EINVAL
when the range takes smaller stored writes (FS.storedLimit); later writes then take that limit.

Effects: fail, read, write, console, io.

### `SessionClient.close`

```gizlang
function SessionClient.close(self: SessionClient): Result<bool, string>
```

Stops the session's tasks and ends the session.

Effects: fail, io.

### `Volume.networkResources`

```gizlang
function Volume.networkResources(self: Volume): ResourceContext
```

The resource context of the range's network buffers.

Effects: fail, read.

### `Volume.fetch`

```gizlang
function Volume.fetch(self: Volume, blob: Store.Identity): Result<bytes, string>
```

The bytes of BLOB.

Effects: fail, read, write, console, io.

### `Volume.localStore`

```gizlang
function Volume.localStore(self: Volume): Store.Local
```

The node's store of local blobs, which its connections read (readPlanned).

Effects: fail, read.

### `Client.scrubOnce`

```gizlang
function Client.scrubOnce(self: Client, after: string, count: i64): Result<Maintenance, string>
```

One admitted endpoint/attempt for paced background work. Ordinary callers
retain their explicit authority discovery path.

Effects: fail, read, write, console, io.

## Constants

### `CHANGES`

```gizlang
const CHANGES = "changes"
```

The method name of the change feed (Client.changes).

### `CHANGES_WAIT_MS`

```gizlang
const CHANGES_WAIT_MS = 1000
```

How long a changes request waits for a change before its answer goes back, in milliseconds.

### `NEAR_MISS`

```gizlang
const NEAR_MISS = "Raft read: the near node cannot answer"
```

The error of a read that the near node cannot answer; the client then asks the leader.

### `PART`

```gizlang
const PART = 8388608
```

The largest object that one put takes; a larger one is a multipart upload of parts of this size.

### `MAX_VOLUME_SNAPSHOT_BYTES`

```gizlang
const MAX_VOLUME_SNAPSHOT_BYTES = 33554432
```

The most bytes of a volume snapshot.

### `MUTATE_BATCH`

```gizlang
const MUTATE_BATCH = "mutateBatch"
```

The commands of one session in order (Client.mutateBatch): they commit together, with one log sync on each node. A
mount sends what it answered under its delegations this way (fuse.giz, Adapter.drain). Every answer to a mutation
comes after its commit.

### `LEASE_MS`

```gizlang
const LEASE_MS = 1250
```

How long a leader serves reads alone after a quorum heard it, in milliseconds.

### `MAX_RETAINED_PAGE`

```gizlang
const MAX_RETAINED_PAGE = 4096
```

The most roots of one page of Volume.retained.

### `MIGRATION_PAGE`

```gizlang
const MIGRATION_PAGE = 4
```

The most retained roots that one membership step copies to the new nodes (Volume.membership).

### `READ_PLAN`

```gizlang
const READ_PLAN = "readPlan"
```

A node's connections read for a mount (plannedMethod): the actor resolves the file and the pieces of the read, and
gives the bytes of holes and of blob pages in memory; the connection reads the other pieces from the local pages,
checked by their sums (readPlanned), in parallel with other reads and while the actor syncs its log. A piece that is
not in the local pages, or fails its sums, sends the whole read to the actor ("read"), which checks blob identities.

### `PUT_PLAN`

```gizlang
const PUT_PLAN = "putFilePlan"
```

A putFile goes the same way: the actor admits it (PUT_PLAN), and the connection hashes and publishes the bytes
(putPlanned), so the owners of a write take its puts in parallel; each was 45-53 ms of a follower's actor for 1 MiB.

