# The danos file-system hierarchy danos is not unix, and its tree does not follow the unix FHS. Paths are the system's universal namespace — files, the device inventory, and protocol endpoints all live in one tree — but what a path *yields* differs by subtree: bytes, facts, or a connection. Root path resolution is provided by the kernel-resident VFS root (`fs_resolve`, `system/kernel/vfs.zig`); mounted backends serve the subtrees they own. Naming follows the codebase conventions: kebab-case, full words, no abbreviations. Every top-level name says what its subtree *is*. ## The tree | Path | What it is | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| | `/` | The root of the one namespace. | | `/applications` | Installed applications, one directory per application — the directory is the identity, the same rule as source sub-projects. *(Planned; empty today.)* | | `/protocol` | The contract namespace: one protocol node per contract, grouped into directories by domain (`/protocol/display`, `/protocol/networking/ip`). Synthetic — no bytes; opening a name yields a connection to the current provider. See [protocol-namespace.md](../os-development/protocol-namespace.md). | | `/system` | The operating system — what danos *is*. Its program subtrees mirror the source tree exactly. | | `/system/kernel` | The kernel image. | | `/system/drivers` | Driver binaries, one per sub-project (`/system/drivers/pci-bus`, `/system/drivers/ps2-bus`). | | `/system/services` | System-service binaries (`/system/services/init`, `/system/services/fat`). | | `/system/devices` | The device inventory: every node hardware discovery found, with its resources and parent — the structures of the devices module, as a browsable virtual tree. Informational only; you *read about* hardware here and *talk to* it through `/protocol`. *(Planned; served by device-manager.)* | | `/system/configuration` | Machine configuration (`init.csv`, `devices.csv`). Writable, served from the boot volume. | | `/system/logs` | Per-boot logs: `/system/logs//.log`. Writable, served from the boot volume. | | `/test` | Test fixtures for the QEMU integration suite. Read-only and initrd-backed like the program subtrees of `/system`, mirroring the repo's `test/` directory. Present on development and test images; a volume without it still boots. | | `/volumes` | Attached storage volumes, one directory per volume (`/volumes/usb`). A volume's own tree appears beneath its name. | Read-only and writable halves of `/system`: the program subtrees (`kernel`, `drivers`, `services`) and the future `devices` are immutable at runtime — initrd-backed or synthetic — while `configuration` and `logs` are mutable machine state served by the boot-volume FAT backend. The kernel's reserved-prefix rule (no mount may shadow `/system`, `/test`, or `/protocol`) needs a carve-out for exactly these two writable subtrees; that lands with the path migration below. Deliberately not defined yet: a temporary-files location and per-application mutable storage. Both belong to the `/applications` design and will be specified there, not guessed at here. ## Node kinds What a path resolves to. These fill `FileStatus.kind` and `DirectoryEntry.kind` in the [vfs protocol](vfs-protocol.md) (`library/protocol/vfs/vfs-protocol.zig`); enum values are append-only. | Kind | Meaning | |--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| | `regular` | An ordinary file: an uninterpreted byte stream, positional reads and writes, grows on demand. | | `directory` | A container mapping names to nodes; modified only through directory operations. | | `character_device` | A node whose read/write have **stream semantics**: unseekable, reads block until bytes exist, size is meaningless. The console and every tty-shaped node ([character-devices-and-tty.md](../character-devices-and-tty.md)); what a POSIX layer's `isatty` detects. | | `block_device` | A node addressed in fixed-size sectors — a raw volume. Reserved: recognized, nothing serves one yet. | | `symbolic_link` | Reserved: a recognized value, not implemented by any backend. | | `fifo` | Reserved for the future pipe object (wanted by the POSIX compatibility layer); not implemented. | | `protocol` | A node naming a contract: `open` yields an IPC connection (an endpoint capability) instead of a file id — the kind of every leaf under `/protocol`. *(Being added; see protocol-namespace.md.)* | Note the layering: `protocol` says what *opening the name* does (you get a conversation); `character_device`/`block_device` say what *read and write mean* on a node a provider serves you. The two compose — `/protocol/console` is a protocol node in the registry, and the node opened over that connection reports `character_device`, which is what gives it stream semantics. Only `socket` is retired (its value stays reserved for wire stability): a named rendezvous point is exactly what a protocol node is. ## What is deliberately absent There is no `/bin`, `/boot`, `/dev`, `/etc`, `/home`, `/lib`, `/mnt`, `/sbin`, `/srv`, `/tmp`, `/usr`, or `/var`. These encode unix history — the binary/library split of small disks, configuration-as-scattered-text, devices as magic files — that danos does not carry. A POSIX compatibility layer (the Python track's mini-libc) may *present* whichever of these its programs expect, mapped onto the real tree; the tree itself stays danos-native. ## Migration The tree above is the specification; some code still writes the unix paths it replaced. The flag-day converting them: | Today (in code) | Becomes | Where | |------------------------------------------|-------------------------------------------|-----------------------------------------------------------------| | `/etc/init.csv` | `/system/configuration/init.csv` | `system/services/init/init.zig` | | `/etc/devices.csv` | `/system/configuration/devices.csv` | `system/services/device-manager/device-manager.zig` | | `/var/log/...` | `/system/logs/...` | `system/services/logger/logger.zig`, the FAT server's `/var` mount | | `/mnt/usb` | `/volumes/usb` | `system/services/fat/fat.zig`, the fat/vfs tests | | `ServiceId` lookup | resolve + open under `/protocol` | every service and client; [protocol-namespace.md](../os-development/protocol-namespace.md) | The boot-image builder and the on-volume directory layout move in the same change, so a freshly written image and the paths the services expect never disagree.