โ† Dashboard ยท Docs ยทConcepts

Grove Concepts

Terminology

Cell

A single Grove node โ€” one device running grove.py and web.py. Every cell has its own identity (keypair), storage, and dashboard. Your laptop, a Raspberry Pi, a VPS โ€” each is a cell.

Fleet

All the cells you're connected to. Your personal distributed network.

Peer

Another cell in your fleet. Peers sync files, relay messages, and back each other up.

Friend

A peer you've promoted to friend status. Friends can share files with you (via grants). Non-friend peers can still store your encrypted chunks but can't share files with you.

Observer

A person with portal browser access but no cell of their own. Observers are provisioned automatically when a friend visits a portal page โ€” no password required on first entry. They can view files and folders that the cell owner has explicitly shared ("Show in Portal"), and use GroveAI at the friends tier. Observers cannot push chunks, modify grants, or access files not shared with them.

Identity tiers (summary)

Tier Runs a cell? Shares files? Portal access?
Cell owner Yes Yes Yes (full admin)
Friend Yes Yes (mutual grant) Yes (friends tier)
Observer No No Yes (read-only, scoped)

Favorite

A peer marked as a preferred sync target. Your chunks will always be synced to favorite peers first, regardless of speed ranking.

Chunk

A 4MB piece of a file, encrypted with ChaCha20-Poly1305. Files are split into chunks for storage and transfer. Chunk filenames are their BLAKE2b hash (content-addressed).

Manifest

A JSON file describing a complete file: its chunk hashes, encryption metadata, and (in v1) encrypted-at-rest sensitive fields (filename, source path). On-disk filenames are opaque: .json, where the content hash is derived from signable manifest fields. Manifests live in ~/.grove/manifests/. The v1 format (ยง7) ensures that even the filename of a shared file is not visible to chunk-holding peers.

Grant

A cryptographic permission to access a shared file. When you share a file with a peer, you create a signed grant containing the manifest hash, the encrypted file key, and your signature. Grants are verified using Ed25519 signatures.

Placement

The system's record of which chunks live on which peers. Used to decide where to replicate, what's under-replicated, and what's at risk. Stored in ~/.grove/placement.db (SQLite).

Replication Factor

How many copies of each chunk exist across the fleet. Default desired factor: 2 (your cell + one peer). Configurable per-cell.

Relay

A WebSocket server that lets cells communicate when they can't reach each other directly (e.g., behind NAT). Cells connect to a relay and exchange messages through it. Relay operators can't read message contents (end-to-end encrypted).

Transport

How two cells communicate. Types:

Bounty

A credit system for resource sharing. 1 bounty = 1 GB-month of chunk storage. Cells earn bounty daily by holding chunks for other peers; they spend bounty when peers hold their chunks. Tracked bilaterally in grove.db. "Blind bytes" (chunks held for unknown peers who haven't exchanged bilateral data) are also tracked and represent fleet contribution, not waste.

Drive modes

How extra storage drives attached to a cell contribute to Grove:

Plaintext-primary storage

Your files in ~/GroveHome are the primary copy โ€” they stay on disk in plaintext. Encrypted chunks are generated from plaintext and replicated to peers; if a chunk is missing but the plaintext source exists locally, Grove regenerates the chunk on demand. This means GroveHome = 1 full replica even without any remote peers.

Recycle Bin

A 24-hour soft-delete window. When you delete a file from Grove, the manifest is marked pending_delete_at and the item appears in the Recycle Bin. After 24 hours (or manual confirmation), the manifest and chunks are permanently removed. The dashboard shows a banner when items are in the bin, and warns loudly when the countdown is under an hour.

Files

The dashboard's ๐Ÿ“ Files tab โ€” your personal drive. Shows files you've uploaded to GroveHome, lets you browse folders, upload, download, share, and delete. Only your own files appear here; files shared by others appear in Feed.

Feed

The dashboard's ๐Ÿ“ก Feed tab โ€” incoming shares from friends. Shows files that friends have explicitly shared with you via grants. Feed is signal (what peers want you to see); Files is content (your drive).

Folder role / Renderer

A folder can carry a role that changes how Grove displays it instead of a plain file list. Roles: photos (gallery), notes (markdown reader), site (published web page), audio (music library), video (video library), and mixed (the default file list). Roles are inferred automatically โ€” a folder becomes audio or video when at least 3 of its files are that media type and they're at least half the folder โ€” and can be overridden manually ("show as music/video/files"). Overrides persist in folder_roles.json. The view that draws a role is its renderer; renderers run identically on the owner dashboard and the portal.

Media renderer

The shared renderer behind the audio and video roles. It presents a folder as a library + a single unified player (audio and video share one player), modeled on a music app's library tab. It is folder-derived: track titles come from the filename (a leading track-number prefix is stripped) and sub-folders become a nested tree โ€” there is no ID3/metadata tag reading. The player handles play/pause, seek, next/previous, shuffle, auto-advance, a lossless badge for FLAC/WAV/ALAC/AIFF, and fullscreen for video.

Streaming spine

The byte-range delivery path that lets large media start and seek instantly. When a player requests a byte range (HTTP Range), Grove decrypts only the 4MB chunks that cover that range rather than the whole file, so seeking into a large FLAC or movie costs one or two chunk decrypts. The same spine serves both the audio and video renderers.

Portal

Two related things:

1. Browser-only access for people who don't run a cell. A friend can visit a cell's portal URL, log in as an Observer, and access files the owner has shared ("Show in Portal").

2. Owner WAN remote access โ€” the cell owner can provision their own portal account on a gateway cell (Settings โ†’ Remote Access) to access their drive from outside Tailscale. Files in ~/GroveHome/Remote are auto-shared to the portal (the "Remote folder").

Gateway

A cell with a public domain name (e.g. grove.nook.li) that serves invite links, the portal, and the WebSocket relay. Typically a VPS or a home server with nginx and a TLS cert. Grove cells use gateway_url in config to point at their gateway.

GroveAI

Built-in AI chat powered by local LLM inference via llama.cpp. Selects the cheapest-capable local model first (Low/Mid/High/Auto tiers), then escalates to a friend's cell if needed. Image generation is available on capable nodes (where the stable-diffusion binary and a Flux model are installed). AI-trust model: local-first by default; peer queries require a mutual-friend relationship and are E2E-encrypted.

AI tiers

Opp Sync (Opportunistic Sync)

Background process that runs every ~5 minutes. Probes all peers, checks for missing chunks, pulls/pushes data to maintain replication targets, records speed measurements, and runs health checks.


File Lifecycle


1. Upload         โ†’ File saved to GROVE_HOME (your file tree)
2. Chunk           โ†’ Split into 4MB chunks, encrypted with ChaCha20
3. Manifest        โ†’ JSON manifest created describing the file
4. Local storage   โ†’ Chunks stored in ~/.grove/chunks/{hash[:2]}/{hash}
5. Sync            โ†’ Opp sync pushes chunks to peers (speed-ranked)
6. Placement       โ†’ Placement DB tracks which peers hold which chunks
7. Healing         โ†’ If a peer goes offline, chunks re-replicate elsewhere

Sharing Lifecycle


1. Select file     โ†’ Choose file(s) in Files tab (your drive)
2. Pick peers      โ†’ Select which friends to share with
3. Create grant    โ†’ Signed grant with encrypted file key
4. Push grant      โ†’ Grant sent to friend's cell
5. Friend sees it  โ†’ Appears in their ๐Ÿ“ก Feed tab (not their Files tab)
6. Friend downloadsโ†’ Chunks pulled from your cell (or other holders)

Directory Structure


~/.grove/                    # Runtime directory (GROVE_DIR)
โ”œโ”€โ”€ config.json              # Cell configuration
โ”œโ”€โ”€ node.key                 # Ed25519 private signing key
โ”œโ”€โ”€ node.pub                 # Ed25519 public key
โ”œโ”€โ”€ node_x25519.key          # X25519 private key (for chat encryption)
โ”œโ”€โ”€ node_x25519.pub          # X25519 public key
โ”œโ”€โ”€ .key                     # Master encryption key (256-bit)
โ”œโ”€โ”€ peer_secret              # Global shared secret for peer API auth (fallback)
โ”œโ”€โ”€ dashboard_auth           # Dashboard password hash
โ”œโ”€โ”€ placement.db             # SQLite: chunk placement tracking
โ”œโ”€โ”€ grove.db                 # SQLite: bounty, grants, milestones, stats
โ”œโ”€โ”€ peer_speeds.json         # Recorded route speeds
โ”œโ”€โ”€ peer_health.json         # Peer uptime tracking
โ”œโ”€โ”€ chunks/                  # Encrypted chunk storage
โ”‚   โ”œโ”€โ”€ ab/                  # First 2 hex chars of BLAKE2b hash
โ”‚   โ”‚   โ””โ”€โ”€ ab3f7c...       # Full hash filename
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ manifests/               # File manifests (opaque <content_hash>.json names)
โ”‚   โ””โ”€โ”€ a1b2c3d4e5f6....json
โ”œโ”€โ”€ invites/                 # Created invite tokens
โ”œโ”€โ”€ models/                  # AI model files (.gguf)
โ”œโ”€โ”€ assets/                  # Frontend HTML/CSS/JS assets
โ”œโ”€โ”€ grove.py                 # Core library
โ””โ”€โ”€ web.py                   # Web dashboard + API server

~/GroveHome/                 # User file tree (GROVE_HOME); plaintext primary replica
โ”œโ”€โ”€ Documents/
โ”œโ”€โ”€ Photos/
โ”œโ”€โ”€ Remote/                  # Auto-shared to portal (Remote folder feature)
โ””โ”€โ”€ ...                      # Your actual files

Network Topology


         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
         โ”‚  Relay   โ”‚  (WebSocket hub, optional)
         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚         โ”‚         โ”‚
โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”
โ”‚ Cell โ”‚ โ”‚ Cell โ”‚ โ”‚ Cell โ”‚
โ”‚ (Mac)โ”‚ โ”‚ (Pi) โ”‚ โ”‚ (VPS)โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ†•         โ†•         โ†•
 Tailscale / Yggdrasil / LAN / WAN

Cells find the best route to each peer automatically. Routes are benchmarked every 6 hours and scored by throughput + latency.