Skip to content

Repository files navigation

ontodag-fs

tests PyPI license

Browse your knowledge, not your folders. ontodag-fs presents an OntoDAG category lattice as a real, mountable filesystem, with file content stored on Ethereum Swarm via swarmfs.

It is a modern descendant of Gifford's Semantic File System (SOSP '91): directory names are interpreted as queries, not locations — but with a concept lattice instead of flat attributes, and content-addressed storage instead of a local disk.

$ odag-fs tree /
/
├── animal/
│   ├── dog/
│   │   └── rex.txt
│   ├── pet/
│   │   └── rex.txt
│   └── spider/
│       ├── document/
│       │   └── web-study.md
│       └── charlotte.txt
└── document/
    ├── spider/
    │   └── web-study.md
    ├── DESIGN_DECISIONS.md
    └── SPEC.md

The same file appears under every path it belongs to — web-study.md is both a spider thing and a document, so it lives at /animal/spider/document/, /document/spider/, and every reordering of those. No copies, no symlinks: one object, several true names.

The lattice can also carry typed values, and then paths can query them: ls '/parcel/weight(..5kg)/.all' lists everything filed at 3 kg, 4.5 kg, … — a virtual directory that exists for any well-formed bound without anyone creating it, computed exactly (rational arithmetic, no floats, nothing rounded). Friendly units resolve (weight(3kg)weight(3000g)); geohash prefixes (/geo(u2)) and fits-inside sizes work the same way. See User Guide §"Typed values in paths".

The ideas in five lines

  • Paths are queries. /pet/dog means "everything that is a pet AND a dog". Order never matters: /dog/pet is the same place.
  • Directories are concepts. Subdirectories are the categories that meaningfully refine what you're looking at.
  • Files are classified objects. A file's identity is its Swarm content address; its name is just a display label.
  • The ontology does the work. File something under dog and it is automatically under mammal, animal, pet — subsumption is free.
  • References cannot dangle. Content addressing means a classification can never point at a file that "moved" — there is nowhere to move to. (Tag filesystems on top of paths fight this forever; here it is structurally impossible.)

Quick start

$ pip install "ontodag[swarm]" ontodag-fs
$ odag-fs set store swarm:my-store     # once — the same setting odag uses
$ odag-fs tree /
$ odag-fs cat /pet/dog/rex.txt
$ odag-fs                              # interactive: cd/ls/cat with a > prompt
$ odag-fs --as-of 8e637ecc6ad6 tree /  # the store as it was (odag history lists roots)
$ pip install "swarmfs[fuse]" && odag-fs mount ~/mnt   # + libfuse2; add --rw to file by cp

New here? Read the User Guide — a tutorial that takes you from an empty machine to a mounted, browsable ontology, with worked examples of every capability.

Status

v0.1 — browse and file. Browsing (ls, tree, cat, info, FUSE mount) is complete and tested, and --as-of ROOT browses any past version of a store that keeps them (rs:/swarm:) — a version is a root, so this only hydrates from a different one. Filing works through the fsspec surface: fs.put_file(local, "/dessert/italian/tiramisu.md") stores the bytes on Swarm and classifies them in one step, rm retracts a classification (an object left with none waits in /.unfiled/), mv reclassifies or relabels, cp within the view is an intent union, and cp /.swarm/<ref> /<concept>/<name> classifies existing Swarm content without re-uploading. Bytes never move; identical content filed twice is one object. odag-fs mount --rw does the same from any shell or tool: cp report.pdf ~/mnt/finance/2026/ files it, rm retracts, mv reclassifies. The lattice itself (creating categories) is edited through OntoDAG's own API, never through the view — mkdir is refused. See ROADMAP.md.

Architecture

            FUSE mount (fsspec.fuse — a deployment mode, not architecture)
                 │
        OntoDAGFileSystem (this repo: fsspec AbstractFileSystem, stateless glue)
           │                │
        OntoDAG           swarmfs
     (classifier/index)  (bytestore: fsspec backend for Swarm)
           │                │
       recordstore        Bee node
     (persistence of the DAG)

This repo owns no state: classifications live in OntoDAG, the DAG persists through recordstore, bytes live on Swarm. OntoDAGFileSystem is a pure fsspec backend, so besides the CLI and FUSE you also get the whole fsspec ecosystem (pandas, pyarrow, DuckDB, …) for free.

Repo Role
ontodag the category DAG — index and classifier
swarmfs fsspec backend for Swarm — the bytestore (REFERENCE, test-pinned)
recordstore versioned key→record store over Swarm — DAG persistence (REFERENCE, test-pinned)
mdl-fca MDL/FCA learning over the same DAG (upstream, not a dependency)

Documentation

  • User Guide — tutorial, setup, worked examples
  • Reference — definition-first lookup tables (exports, options, path grammar, errors), pinned against the code by tests/test_reference.py; the document to hand to an AI agent
  • SPEC.md — the precise v0/v0.1 contract, method by method
  • DESIGN_DECISIONS.md — prior art and every decision, with reasoning
  • ROADMAP.md — what's in scope now vs later
  • CHANGELOG.md — what each release changed

Development

$ git clone https://github.com/petfold/ontodag-fs && cd ontodag-fs
$ python3 -m venv .venv && .venv/bin/pip install -e ".[test]"
$ .venv/bin/pytest                 # 315 tests

The test suite runs entirely offline — no Bee node, no FUSE — and every test runs against both the in-memory reference index and the real OntoDAG adapter, so the two cannot drift apart. Path-resolution invariants are property-based (hypothesis); see SPEC §6 for the invariant list.

About

Browse knowledge, not folders: an OntoDAG concept lattice as a real filesystem, with file content on Ethereum Swarm

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages