{"id":"ba957eb7-66cb-4bf3-bf31-5f6636d73dd9","slug":"ffs","kind":"skill","name":"ffs","summary":"FFS is a Rust-based local substrate that stores signed, classified, bitemporal atoms in a single SQLite database, exposes them through a daemon over a Unix-domain-socket / Windows-named-pipe JSON-RPC","owner":"Fornado-Greenhouse","repoUrl":"https://github.com/Fornado-Greenhouse/ffs","license":"BlueOak-1.0.0","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-05-08T11:10:55.000Z","addedAt":"2026-10-21T21:10:03.048Z","logoUrl":"https://avatars.githubusercontent.com/u/219038475?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["databases"],"tags":[],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-22T03:56:10.302Z","sample":false,"url":"https://conduits.dev/tools/ffs","language":"Rust","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<!-- omit in toc -->\n# FFS — Foley File System\n\n![Status](https://img.shields.io/badge/status-pre--alpha-orange)\n![License](https://img.shields.io/badge/license-Blue_Oak_1.0.0-blue.svg)\n[![CI](https://github.com/Fornado-Greenhouse/ffs/actions/workflows/ci.yml/badge.svg)](https://github.com/Fornado-Greenhouse/ffs/actions/workflows/ci.yml)\n\n> **Records-shaped, not file-shaped.** A substrate where what your knowledge says, who said it, and who's allowed to see it are all first-class.\n\n> ⚠️ **Pre-alpha.** Not yet installable. The substrate's atom envelope, predicate-spec loader, and Cargo workspace are in. The daemon, CLI, plugin, and federation transport are not. See [Status](#status) for what's shipped and [`ARCHITECTURE.md`](ARCHITECTURE.md) for the full design.\n\n---\n\n## Why this exists\n\nThe SaaS-and-files era is good at neither of two things knowledge workers need: **ownership of their data**, and **sub-record access control**. CRMs, file shares, knowledge bases, contact managers each handle one or two of these concerns — and only inside walls the user does not control.\n\nFFS is a substrate that gives you both at the layer below applications. It treats knowledge as **records**, not files. Each record is a signed claim about something — a contact, a decision, a note — with provenance, bitemporal history, and tier-based classification. Records are content-addressed and capability-gated, so two FFS instances can federate bilaterally: \"I can see existence and work email for your contacts; you can see full notes for mine; either of us can revoke at any time.\"\n\nIn the iCloud Notes / Datomic lineage, not the Dropbox / OneDrive lineage.\n\n## What FFS gives you\n\n**Ownership.** FFS runs on your hardware, encrypted at rest with keys held by your OS keychain. There is no provider in the middle. There is no terms-of-service that changes. A `git clone` of your substrate produces a working FFS instance — your knowledge is portable in a way SaaS data never is.\n\n**Sub-record control.** A contact decomposes into atoms — existence, work email, personal email, notes — each classified independently. Tell one peer \"you can see existence and work email\"; tell another \"full access\"; revoke either at any time. Capabilities are themselves signed records, queryable and auditable.\n\n**Durable history.** Every claim is signed, timestamped, and immutable. Change happens through supersession; nothing is overwritten. You can ask \"what did I know about Sarah on April 15th, before she changed teams?\" and get a real answer.\n\n## A glimpse\n\nThe Sarah Chen contact below is what you'd see in `~/.ffs/contacts/by-name/S/Sarah_Chen.md`. Open it in Obsidian, vim, Notepad, VS Code — whatever. Edit it. The substrate absorbs the change.\n\n```markdown\n---\ndisplay_name: Sarah Chen\nwork_email: sarah@acme.com\ntier: introducible\n---\n\n## Notes\n- Met at distributed-systems conference, June 2025\n- Interested in records-shaped knowledge tools\n```\n\nThe file is a *projection* — rendered on demand from the underlying atoms. Here's one of the atoms behind it (the work-email claim, signed by Wes):\n\n```json\n{\n  \"v\": 1,\n  \"entity\": \"z6MkrSarahChen001...\",\n  \"predicate\": \"contact.person.work_email\",\n  \"claim\": {\"value\": \"sarah@acme.com\"},\n  \"author\": \"z6MkhaXgWesIdentity...\",\n  \"valid_from\": \"2026-05-09T00:00:00Z\",\n  \"valid_to\": null,\n  \"tx_time\": \"2026-05-09T14:23:11.421Z\",\n  \"classification\": \"work_email\",\n  \"supersedes\": null,\n  \"provenance\": [{\"kind\": \"ingest_file\", \"uri\": \"file:///.ffs/ingest/notes-2025-06-12.md\", \"hash\": \"z58s...\"}],\n  \"signature\": \"z58sQv...Ed25519signature...\"\n}\n```\n\nSarah's full contact is the head of supersession chains for several atoms like this — display name, work email, personal email, notes — each separately classifiable and shareable. The markdown file you see in the editor is the rendered view; the atoms are canonical.\n\n## Status\n\n| Component | Status | What it does |\n|---|---|---|\n| Cargo workspace + cross-platform CI | ✅ shipped | Seven Rust crates, Linux/macOS/Windows build matrix |\n| Atom envelope (signing, hashing, JCS) | ✅ shipped | The interoperability contract: Ed25519 + BLAKE3 + canonical JSON |\n| Predicate spec loader (TOML + JSON Schema + hot-reload) | ✅ shipped | The substrate's vocabulary, parsed and validated at load |\n| SQLite atom store with SQLCipher | ⏳ planned | Per-substrate encrypted storage with bitemporal indexes |\n| Capability evaluator | ⏳ planned | Action × scope × time → Allow/Deny |\n| Projection renderer (Tera templates) | ⏳ planned | Atoms → markdown for any editor |\n| Daemon JSON-RPC dispatcher (UDS / named pipe) | ⏳ planned | Long-running per-user process |\n| `ffs` CLI + `ffs://` URL resolver | ⏳ planned | Static binary for shell pipelines |\n| Filesystem watcher + fast-path classifier | ⏳ planned | Sub-200ms editor edits become atoms |\n| Skills host (scribe, librarian, auditor) | ⏳ planned | Python agents under daemon supervision |\n| Federation transport (mTLS pull-based) | ⏳ planned | Bilateral peer-to-peer, fingerprint-pinned |\n| MCP server (nine tools) | ⏳ planned | AARM-conformant boundary for AI agents |\n| Obsidian plugin | ⏳ planned | The end-user surface |\n\nThe full 23-task plan in dependency order: [`.compozy/tasks/ffs-mvp/_tasks.md`](.compozy/tasks/ffs-mvp/_tasks.md).\n\n## Architecture, briefly\n\n```\n        editors / CLI / MCP agents\n                   │\n                   ▼\n            ┌──────────────┐         mTLS HTTPS\n            │  ffs-daemon  │◀───────────────────────▶ peer FFS\n            │  (Rust)      │\n            └──────┬───────┘\n                   ▼\n            ┌──────────────┐\n            │ store.db     │  (SQLite + SQLCipher)\n            └──────────────┘\n```\n\nSeven Rust crates plus a Python skill bundle plus a TypeScript Obsidian plugin. The atom envelope (canonical JSON, BLAKE3 hash, Ed25519 signature) is the single substrate-interop contract; everything else composes around it.\n\nFull design: [`ARCHITECTURE.md`](ARCHITECTURE.md). Decision-by-decision history: [`adrs/`](.compozy/tasks/ffs-mvp/adrs/) (21 ADRs). Product spec: [`_prd.md`](.compozy/tasks/ffs-mvp/_prd.md). Implementation spec: [`_techspec.md`](.compozy/tasks/ffs-mvp/_techspec.md).\n\n## MCP agents\n\nFFS ships `ffs-mcp`, a Model Context Protocol server that any MCP-aware agent (Claude Code, ChatGPT desktop, framework-agnostic agents) can spawn as a subprocess. It exposes nine tools (six MVP tools per ADR-013, `ffs_search` and `ffs_list_path` per ADR-027's agent memory convention, and `ffs_accept_proposal` per ADR-035's morning read), each translating to a daemon JSON-RPC call with capability checks at the daemon boundary:\n\n| Tool | Purpose |\n|---|---|\n| `ffs_query` | List atoms about an entity (capability-filtered) |\n| `ffs_search` | Search entities by name/title before proposing new content — search-before-write (ADR-027) |\n| `ffs_list_path` | Enumerate a projection listing for progressive disclosure instead of scanning the substrate (ADR-027) |\n| `ffs_render_projection` | Render a projection path to markdown |\n| `ffs_resolve_url` | Resolve `ffs://` URLs (atom / entity / path) |\n| `ffs_author_atom` | Propose content into the ingest quarantine — a proposal, not a committed atom, until the user accepts it |\n| `ffs_inspect_predicate` | Return a predicate spec (schema + reverse-map rules) |\n| `ffs_audit_query` | Return recent auditor.daily_summary atoms |\n\nSample Claude Code `mcpServers` block:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"ffs\": {\n      \"command\": \"ffs-mcp\",\n      \"args\": [],\n      \"env\": {\n        \"FFS_DAEMON_SOCKET\": \"/Users/you/.ffs/run/ffs.sock\",\n        \"FFS_AGENT_KEY\": \"/Users/you/.ffs/keys/claude.ed25519\"\n      }\n    }\n  }\n}\n```\n\nPer ADR-013, capability checks live on the daemon side; the MCP server is a thin pass-through. A capability denial comes back as an MCP tool-level error (`isError: true`) with the typed reason in `details.kind`, not a JSON-RPC error — so the agent surfaces \"the substrate refused this\" cleanly without treating it as a transport break.\n\n## Philosophy: substrate, not application\n\nFFS doesn't tell you what your knowledge is *for*. It gives you the primitives — atoms, capabilities, federation, projection — and lets applications above the substrate inherit them. The first application planned on top is **Folodex**, a contact-graph tool that exercises FFS for the relationship-holder use case (salespeople, journalists, founders, community organizers who own networks they currently don't control).\n\nBut Folodex is one application. The same primitives handle general knowledge capture, AI-agent output absorption, and team collaboration. That breadth is intentional: tools that solve one of these concerns well already exist; what's missing is the substrate underneath that handles all of them coherently.\n\n**FFS aligns with [AARM](https://aarm.dev)** — Autonomous Action Runtime Management — an open specification for securing AI-driven actions at runtime. The mapping is by construction, not retrofit: capability-as-data is AARM's policy engine; atoms are the context accumulator; the proposal-quarantine flow is the approval service; signed-and-multihashed atoms are the receipt generator. See [`ARCHITECTURE.md` § Security model](ARCHITECTURE.md#security-model-aarm-conformant) for the component-by-component breakdown.\n\n## Onboarding\n\nThe MVP closes the loop on the technical-friend-onboarding-a-non-technical-peer scenario from the PRD. Three documents under [`docs/onboarding/`](docs/onboarding/) cover the full path from install to daily use:\n\n- [**Technical-friend checklist**](docs/onboarding/technical-friend-checklist.md) — install, keychain, identity, first run, federation handshake. ~45–60 minutes.\n- [**First-use guide**](docs/onboarding/first-use-guide.md) — capture, navigate, review, edit, federate. Audience is the end-user peer; no terminal use required.\n- [**Troubleshooting**](docs/onboarding/troubleshooting.md) — every known failure mode with symptoms and fixes (SQLCipher, Windows named-pipe, federation handshake, skill subprocess hangs, capability denials).\n\nAnnotated illustrations of the Obsidian-side surfaces live in [`docs/onboarding/screenshots/`](docs/onboarding/screenshots/).\n\n## Follow along\n\nThis project is being built in the open. There is nothing to install yet; the most useful things you can do today are:\n\n- ⭐ Star the repo — signals interest and helps surface it.\n- 👀 Watch for releases — first usable build is what we're heading toward.\n- 📖 Read [`ARCHITECTURE.md`](ARCHITECTURE.md) and the [PRD](.compozy/tasks/ffs-mvp/_prd.md). They're the substantive design.\n- 💬 Open a [Discussion](https://github.com/Fornado-Greenhouse/ffs/discussions) — especially with use-case signal: *\"here's the network I'd want to share — does FFS fit?\"*\n- 🐛 File an [Issue](https://github.com/Fornado-Greenhouse/ffs/issues) for design feedback, technical concerns, or \"I'd like to use this for X.\"\n\n`CONTRIBUTING.md` and `SECURITY.md` are forthcoming. For security concerns in the meantime, contact the maintainer directly. Operational norms for working in this repo (test runner, shell discipline, ADR numbering) are documented in [`CLAUDE.md`](CLAUDE.md).\n\n## License and credit\n\nFFS is licensed under the [Blue Oak Model License 1.0.0](LICENSE) — a modern, plain-English permissive license with an explicit patent grant. You may use, copy, modify, and redistribute it freely; please retain the license notice.\n\nProject lead: **Wes Foley**.\n\nBuilt with the records-not-files lineage of [Datomic](https://www.datomic.com/), [iCloud Notes](https://support.apple.com/en-us/HT205773), and the local-first community's push toward user-owned knowledge. The substrate's storage layer rests on [SQLite](https://www.sqlite.org/), and we carry forward its blessing:\n\n> *May you do good and not evil.*\n> *May you find forgiveness for yourself and forgive others.*\n> *May you share freely, never taking more than you give.*\n"}