AI agents are taking real actions — deleting files, sending emails, merging code. When something goes wrong, the question is always: did a human actually authorize that, and can you prove it?
Oath is an open protocol for cryptographically signed human intent. Before an agent acts, it checks for an attestation:
If there's no attestation, the action is blocked. The interesting part: the absence of a signature is itself evidence. An agent can't claim it was authorized if there's no cryptographic proof that it was.
Security model: the private key never leaves your machine. The agent only calls verify, never attest. Attest is a human command. As secure as SSH key storage - same threat model, no central authority to compromise.
The repo has a working demo - an agent running 5 actions, 2 attested, 3 blocked — and a protocol spec at v1.0.0 (CC0, public domain). Anyone can implement the protocol in any language.
What's not there yet: multi-device sync and a Python package. Would appreciate feedback on the protocol design, especially the action class format (namespace:action:scope) and whether the signing model covers edge cases I haven't thought of.
The demo shows character-level sync, slash commands, a community Word Wall, and offline editing. Disconnect your network, keep typing, reconnect - it merges automatically.
Known limitations:
- SDK undo/redo not yet wired into the demo editor (browser native works)
- No E2E encryption yet
Security note on the demo: LocalWrite is a public collaborative space with no authentication. Rooms are accessible to anyone with the URL and so don't share sensitive or personal data. The server sees all content in plaintext. Rate limiting and input validation are in place, but there's no content moderation or identity verification. Treat it like a public whiteboard.
I've been obsessed with the Ink & Switch "Local-First Software" vision for some time now—apps that work offline, feel instant, and give users control of their data. But every time I tried to build a local-first app, I hit the same wall: integration complexity.
The existing CRDT libraries (Yjs, Automerge) are incredible—they pioneered the algorithms that make local-first work. Kevin's optimization work on Yjs is masterful, and Automerge changed how I think about distributed systems.
But they're designed as modular primitives. You compose networking, storage, and conflict resolution yourself. That flexibility is powerful for complex systems, but it creates what I call the "Day 1 problem" for local-first: you spend 3 days wiring infrastructure before writing features.
I built SyncKit to solve this.
Different philosophy: Where Yjs gives you powerful primitives (build your own local-first stack), SyncKit gives you a pre-wired local-first database. Persistence, sync, presence—built-in, not plugins.
The technical approach:
- Rust core with zero unsafe blocks (you can grep the codebase)
- TLA+ verified (explored 6.5M states to prove correctness)
- 154KB bundle (everything compiled together)
- 1,081 tests, 80 chaos tests
Performance: Competitive within 1-2ms of Yjs for standard ops. The win is local-first DX - one package that handles offline, sync, and conflict resolution.
What's included:
- Rich text editing (Fugue algorithm for non-interleaving edits)
- Live cursors & presence
- Undo/redo (CRDT-native)
- IndexedDB persistence
- React/Vue/Svelte adapters
Built this in Nairobi, 9pm-3am. v0.1.0 got 601 stars in 3 weeks which honestly shocked me.
That's a fair point. The description does assume some familiarity with local-first patterns. I'll think about how to make the "why you'd want this" clearer for people outside that space. I appreciate the honest feedback
That's actually a really cool idea! Notes are just documents, so the sync model would work well. Hadn't thought about Obsidian specifically but I like it.
Currently I am leaning more into P2P for the zero-effort user side setup, although I was considering if hybrid P2P/client-server approach is feasible: free lite P2P vs paid, managed SaaS for user convenience and improved performance.
"Zero data loss" means system-level guarantees (no corruption from network failures, crashes, etc), not that concurrent edits to the same field are preserved. LWW definitely clobbers one of the edits.
What v0.1.0 does give you is field-level granularity (edits to different fields don't conflict) and guaranteed convergence (all devices reach the same state). But yeah, same field = last write wins.
The Rust core already has better CRDTs (Text, Counter, Set) that handle concurrent edits properly. They just need to exposed in the TypeScript SDK for v0.2.0.
I should clarify this in the docs. Thanks for pointing it out.
Thanks! For native Android, not directly yet because v0.1.0 is Rust → WASM → TypeScript (web/Node/Deno/Bun).
But since the core sync engine is pure Rust, native Android bindings are definitely possible. The main paths would be:
1. JNI bindings directly from Rust
2. Or using the existing WASM core with a JVM WASM runtime
Haven't prioritized this yet since v0.1.0 focused on web/JS ecosystem, but if there's demand for Android, I could explore it. Are you working on something that needs offline sync on Android?
Thanks! Yeah, Realm's shift in direction left a gap in the offline-first space.
I didn't build Dart bindings yet (Rust → WASM → TypeScript for v0.1.0), but since the core is in Rust, Dart bindings via dart_rust_bridge are definitely feasible. Would actually be a great addition.
Are you actively looking for a Realm replacement for a Dart project? Curious what your offline sync requirements are. It might help me prioritize Dart support
I use Loro CRDT, which is written in Rust as well, on my Dart apps with flutter_rust_bridge and it works pretty well. For syncing I'm using their Loro protocol product although I used iroh before. However, the annoying thing about how the CRDT libraries work is that they're essentially key value NoSQL type storage, not relational. I would love something like SQLite or Postgres on both the server and client that can sync, which companies like ElectricSQL have, but no Dart bindings and also I'd prefer to be in the all Rust ecosystem as well as self host.
You've hit on the core limitation because SyncKit has the same issue. Document/key-value like Loro and Yjs. The relational model problem is fundamental to CRDTs. They guarantee conflict-free convergence because documents are independent, but that breaks with foreign keys and joins. Can't have arbitrary SQL queries and guaranteed convergence without coordination.
ElectricSQL and PowerSync solve it differently (full SQL but weaker offline guarantees). For SyncKit, document-based state is an architectural choice, not something v0.2.0 will change.
I'm curious to know how you're working around this with Loro. Are you building your own query layer or are you keeping everything denormalized?
Yeah I'm essentially writing my own ORM with functions like getFoo which queries the exact substructure of the CRDT to find the info I need. Apparently Postgres is getting a CRDT extension though but we'll see how it goes, typically it's not that fast.
Oath is an open protocol for cryptographically signed human intent. Before an agent acts, it checks for an attestation:
oath attest --action "database:delete_records:project_alpha" \
oath verify --action "database:delete_records:project_alpha"# → ATTESTED proof: a1b2c3d4
If there's no attestation, the action is blocked. The interesting part: the absence of a signature is itself evidence. An agent can't claim it was authorized if there's no cryptographic proof that it was.
Security model: the private key never leaves your machine. The agent only calls verify, never attest. Attest is a human command. As secure as SSH key storage - same threat model, no central authority to compromise.
The repo has a working demo - an agent running 5 actions, 2 attested, 3 blocked — and a protocol spec at v1.0.0 (CC0, public domain). Anyone can implement the protocol in any language.
What's not there yet: multi-device sync and a Python package. Would appreciate feedback on the protocol design, especially the action class format (namespace:action:scope) and whether the signing model covers edge cases I haven't thought of.