The kernel
Every capability your program does not compute itself arrives from outside: a model, a speech recognizer, a mailbox, a phone line. The industry ships each of them as an SDK — a library per vendor, linked into every application that wants it, carrying its own credential, its own retry policy and its own idea of what a stream is.
An operating system already solved this, for hardware. A capability outside the process is a device: opened by name, read and written as a stream, closed. The program says what it wants, never who provides it, and never holds the secret that makes the provider answer.
BentOS holds external capability the same way. Inference is a device.
$ llm models
/dev/llm/anthropic/claude-sonnet-4 — unavailable: BentosException(eacces) in open: /dev/llm/anthropic/claude-sonnet-4
/dev/llm/openai/gpt-4o-mini — unavailable: BentosException(eacces) in open: /dev/llm/openai/gpt-4o-mini
/dev/llm/fixture/weather 200000 ctx · out 8192 · reasoning budget · functions · image/png
/dev/llm/fixture/two-cities 200000 ctx · out 8192 · reasoning budget · functions · image/png
/dev/llm/fixture/echo 200000 ctx · out 8192 · reasoning budget · functions · image/png
Five devices on a machine that has never seen an API key. Three of them answer anyway — the userland ships fixture devices so that the shape of the thing can be learned before any account exists. The other two are present, enumerable, and refuse to open.
/dev/llm/... is a device path, not a file
It is the kernel’s namespace, and the kernel runs inside your process — there is no daemon anywhere in this, and nothing was mounted onto your filesystem. ls /dev/llm/ will show you nothing, and POSIX open() will not find it; the enumeration you have is llm models, which says so itself:
Note: stopgap — the canonical form is `ls /dev/llm/`, pending kernel namespace enumeration.
A real node under a real /dev, reachable by any program on the machine through the host’s own filesystem, is the design and not the state designed. A separate kernel daemon is the same: designed, unbuilt, and today unnecessary — the kernel is a library, every coreutil carries it, and each process opens its own devices and takes them with it when it exits.
What is real today is the semantics: a name, an open that can be refused, a stream, a close, and an errno vocabulary that survives all the way up to the shell.
$ echo hi | llm -d /dev/llm/anthropic/claude-sonnet-4
llm: BentosException(eacces) in open: /dev/llm/anthropic/claude-sonnet-4
$ echo $?
1
eacces on open — permission, named the way a kernel names it, before a single byte of application logic ran.
The credential is the driver’s, and your program cannot reach it
That failure is the whole argument, stated as a mechanism rather than a policy. The device was refused because the driver had no key. llm has no flag for a key, no configuration file that holds one, no environment variable it reads and forwards; llm config holds a default device and aliases and nothing else, and its own help says it plainly:
$ llm help config
Show or modify the default device and aliases. No key management — credentials belong to the driver.
An application that cannot hold a secret cannot leak one, cannot log one, and cannot be audited for one. The secret lives once, on the machine, at the layer that talks to the vendor — which is where every other operating system has kept the connection to the outside world for fifty years.
Three layers, and the middle one is where the meaning lives
The runtime gives mechanics. Open, read, write, close, and the errno vocabulary. It knows nothing about inference, audio or mail — only about streams and file handles. This is the ABI, and it is the same for every class of device there will ever be.
The subsystem gives meaning. One per class of device: what a chat turn is, what a function call is, what a committed transcript line is. It owns the wire types, and it is the reason a program written against the class survives a change of vendor.
The provider gives translation. One per vendor: this vendor’s HTTP, this vendor’s streaming dialect, this vendor’s authentication, mapped onto the subsystem’s types. It is the small layer, and deliberately so.
One subsystem per class of device, never per vendor.
That line is the difference between an operating system and an SDK zoo, and it is visible in what ships: chat-inference-dart is the subsystem, openai-chat-driver and anthropic-chat-driver are two providers under it. Point -d at either and the program above does not change — the vendor is a driver, not an integration.
The same shape holds for speech, and there it does something an SDK arrangement cannot: openai-stt-driver and openai-live-stt-driver are two providers from the same vendor under one stt subsystem, because bounded transcription and live capture are two different devices, not two different companies. The device path carries the verb: /dev/stt/<vendor>/<model>/<verb>.
What a driver author has to know
The provider is the small layer because the subsystem already did the hard part — so the honest measure of this design is how little is left for the person adding a vendor. There is a driver SDK, and the drivers above are what it was proven against. Adding a vendor to a class that already has a subsystem is the highest-leverage contribution the platform accepts, and it is where to start.
The catalogue is the point
chat is the class that is finished enough to build on, and the one with fixture devices under it. stt and tts are packaged with providers beneath them, and they open only against a real vendor device, since no fixture stands in for audio.
Beyond them the list is designed and unbuilt designed: vision, embed — and then, deliberately, out of AI entirely: im, email, voip. Each of those is today a swamp of one SDK per application, one credential per application, one retry policy per application. Each of them is a class of device with drivers underneath, and every application on the machine that wants a mailbox opens one.
That is the wager this floor is making. Not that inference deserves a device — that AI was only the first capability obvious enough to force the question.