# 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/<boot-stamp>/<binary-path>.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.
