dumont

Architecture

The conformance spine, honest capabilities, and composable decorators.

dumont is a stateless CLI: each invocation routes a URI to a backend and exits. The design rests on three ideas.

The package map

cmd/dumont          CLI entrypoint
internal/cli/       cobra commands + cross-remote copy / walk / sync / remove helpers
internal/config/    config.yaml + env:/file:/keychain: credential resolver
pkg/vfs/            FileSystem/File interfaces, Caps, typed errors, paths, io/fs adapter
pkg/uri/            location parser + scheme → backend Router
pkg/conformance/    the behavioral contract every backend must pass
pkg/cache/          transparent metadata + content caching decorator
pkg/emulate/        read-modify-write decorator (random write over object stores)
pkg/archivefs/      shared read-only FS over a flat archive entry list
backend/            mem · local · s3 · bunnystorage · bunnystream · httpfs · zipfs · tarfs

1. The conformance suite is the spine

One table-driven battery defines what "correct" means — write/read, stat & mtime, readdir, mkdir, remove semantics, exclusive create, rename, random read/write, path safety, context cancellation, and more. mem and local are the reference implementations; every other backend is measured against the same invariants. The suite is the executable definition of the filesystem contract.

2. Capabilities are honest

Every backend advertises a Caps struct:

type Caps struct {
    RandomRead    bool // opened files implement ReaderAtFile
    RandomWrite   bool // native random write — NOT emulated
    Append        bool // O_APPEND honored natively
    Truncate      bool // in-place truncate / O_TRUNC honored
    AtomicRename  bool // Rename is atomic
    Directories   bool // real directories vs. synthesized-from-prefix
    MTime         bool // reports meaningful modification time
    CaseSensitive bool // names are case-sensitive
}

The conformance suite cross-checks Caps against observed behavior — a backend can't claim atomic rename or random write it doesn't actually have. An operation a backend can't perform correctly returns ErrNotSupported; it is never silently faked in a way that could corrupt data.

Inspect it at runtime:

dumont caps aws

3. Behavior is composed, not baked in

Capabilities are added by wrapping a backend in decorators rather than complicating the backend itself:

  • pkg/cache — a transparent metadata + content cache that cuts repeated listing and stat round-trips. Network remotes get it automatically.
  • pkg/emulate (RMW) — read-modify-write random write, append, and in-place truncate over a whole-object backend. On a writable open it stages the object in a temporary local file, applies the writes, and re-uploads on Close/Sync. Correct but non-atomic and O(filesize), so it's opt-in via emulate: true. If the wrapped backend already supports native random write, RMW passes writable opens straight through.

Not in scope

  • A FUSE mount / daemon — dumont stays a stateless CLI. (The interfaces stay mount-ready for later.)
  • Graph/API backends projected as a lossy tree (Gmail, Notion, Slack…). Bunny Stream is the one deliberate, clearly-labelled exception.
  • Bidirectional / conflict-resolving syncsync is one-way by design.

On this page