The projection model
Every provider omnifs ships answers the same question: what does this service look like as a directory tree? The answer is a path. cat, ls, grep, find, tail, and every other tool that already lives in your shell work without modification because the kernel cannot tell the difference between a real directory and a FUSE mount.
That is the projection model: external services projected into local paths, one surface instead of one SDK per vendor.
One surface, many services
Section titled “One surface, many services”Without omnifs, reading a GitHub issue title, checking a container’s state, and fetching an arXiv paper are three separate programs with three separate auth flows and three separate pagination APIs. With omnifs, all three are path reads:
cat /github/acme/api/_issues/_open/2853/titlecat /docker/containers/by-name/postgres/statecat /arxiv/papers/1706.03762/metadata.jsonThe path is the entire operation. There is no client to initialize, no token to thread through function arguments, no response to deserialize. The host runtime handles all of that; your shell just opens a file.
The projection chain
Section titled “The projection chain”A single read() on a path descends this chain:
your shell (cat / ls / grep / any tool) │ │ read() or readdir() ▼kernel │ routes to the omnifs FUSE mount ▼FUSE │ passes the path to the host runtime ▼host runtime │ resolves path segments, checks bounded cache, │ selects the matching provider │ │ WIT: lookup-child / list-children / read-file ▼provider (wasm32-wasip2 component) │ interprets path segments as API parameters, │ asks the host to make an HTTPS callout ▼service (github, docker, arxiv, linear, dns, ...) │ └── bytes travel back up the same chainEach step in the chain is a well-defined boundary. The kernel issues standard POSIX calls. FUSE translates them to the host. The host speaks a three-operation WIT interface to the provider. The provider never opens its own socket: it calls back into the host, which holds the credentials and makes the outbound request.
On a cache hit, the request never leaves the machine. The host maintains a capacity-bounded cache invalidated by upstream events, not TTLs. An issue stays the same issue; inodes survive upstream renames.
Why this matters
Section titled “Why this matters”A path encodes the full intent of an operation. /github/acme/api/_issues/_open/2853/title tells you the provider, the account, the repository, the collection, the filter, the object, and the field, without any ambient context. Pipe it, redirect it, xargs it, write it to a shell script. Every POSIX tool that understands a path already understands omnifs.
The flip side: because the path is the full operation, the provider only needs to answer three read ops to expose its entire surface. There is no general-purpose query language, no pagination cursor, no partial-response contract. The host routes path segments; the provider maps them to API calls. Five live providers implement exactly this interface today. Thirteen more are in progress.
What the sub-pages cover
Section titled “What the sub-pages cover”- Paths and the WIT contract goes into the path grammar (provider / account / collection / filter / object / field) and the WIT interface (
omnifs:provider@1.0.0) the provider component must implement. - Runtime, cache, and identity covers how the host resolves paths, how the bounded cache works, why inodes are stable, and how upstream events drive invalidation.
- Capabilities and security explains why providers never open sockets directly: all external calls are explicit, capability-gated callouts routed through the host, which holds credentials and enforces scope.
- Mutations describes the planned write model: writes stage in a draft namespace and apply as a single transaction. This is not shipped; the page describes the design.