Skip to content

The WIT interface

Every provider in omnifs implements exactly one WIT interface. The runtime loads the provider as a wasm32-wasip2 component, calls these functions, and handles everything else: FUSE mounting, caching, inode assignment, credential injection. The interface is small by design.

package omnifs:provider@1.0.0;
interface provider {
lookup-child: func(parent: node, name: string) -> option<node>;
list-children: func(dir: node) -> list<node>;
read-file: func(file: node) -> list<u8>;
}

Three functions. No more. The read surface of the entire filesystem is covered by lookup-child, list-children, and read-file. Mutations are a planned separate concern and are not part of this version of the interface.

A node is the unit of identity in the projected filesystem. It carries enough information for the provider to resolve a path segment or return file contents, and for the host to assign a stable inode.

The host owns inode assignment. A provider returns nodes; the runtime maps them to kernel inodes. If an upstream resource is renamed, the inode survives as long as the node’s identity is stable. Providers should use an identity that is stable across renames: a repository’s numeric ID rather than its slug, a container’s ID rather than its name, a paper’s arXiv ID rather than its URL.

When a user runs ls /omnifs/github/ollama/ollama/_issues/_open, the kernel issues a readdir syscall on the FUSE mount. The runtime resolves the path to a node and calls list-children on that node. The returned list of nodes becomes the directory entries.

Terminal window
ls /omnifs/github/ollama/ollama/_issues/_open
# runtime calls: list-children(node for _open)
# provider returns: [node("12301"), node("12345"), ...]
# shell sees: 12301 12345 ...

When a user runs cat /omnifs/github/ollama/ollama/_issues/_open/12345/title, the kernel issues a read syscall. The runtime resolves the path to a leaf node and calls read-file on it. The returned bytes are what the shell prints.

Terminal window
cat /omnifs/github/ollama/ollama/_issues/_open/12345/title
# runtime calls: read-file(node for "title" under issue 12345)
# provider returns: bytes of "Crash on long context with quantized model\n"

read-file returns list<u8>: raw bytes. The provider decides the encoding. Most providers return UTF-8 text for human-readable leaves (title, state, body) and binary for structured leaves (inspect.json, paper.pdf, source.tar.gz). Nothing in the interface enforces this; it is a convention.

Every intermediate segment in a path resolves via lookup-child. Given a parent node and a segment name, the function returns option<node>: some(node) if the child exists, none if it does not. The runtime chains these calls as it walks the path.

Terminal window
cat /omnifs/docker/containers/by-name/postgres/state
# runtime calls, in order:
# lookup-child(root, "containers") -> some(node)
# lookup-child(node, "by-name") -> some(node)
# lookup-child(node, "postgres") -> some(node)
# lookup-child(node, "state") -> some(node, kind=file)
# read-file(node for "state") -> b"running\n"

The option return type is what produces ENOENT. If lookup-child returns none, the runtime surfaces a “no such file or directory” error to the caller, with no further calls into the provider.

The host maintains a capacity-bounded cache in front of all three ops. The runtime does not call list-children on every readdir if the result is already cached. Cache invalidation is event-driven: the runtime listens for upstream events (webhook, polling, daemon event) and evicts the relevant entries. There are no TTLs.

From the provider’s perspective, any of the three functions may be called at any time, in any order. A provider must not assume it will be called in a particular sequence or that results from a prior call are still current when the next call arrives.

A provider component has no ambient authority. It cannot open a socket, read a file, or call an HTTP endpoint on its own. All external access is an explicit capability granted by the host at mount time. The host holds credentials; the provider receives only what the host passes through the capability interface.

This means a provider is sandboxed by construction: the WIT interface is the only surface it can use. A rogue or buggy provider cannot exfiltrate credentials it was never given, and cannot make network calls outside the scope the host permits.

The three ops are the complete read surface for omnifs:provider@1.0.0:

Shell operationSyscallomnifs op
ls <dir>readdirlist-children
cat <file>readread-file
Path segment resolutioninternallookup-child

Every find, grep, tail -f, jq, and pipe the user runs against an omnifs mount reduces to some combination of these three calls. The host handles FUSE protocol, caching, and inode management; the provider handles data retrieval.