WIP: SPEC-047 — Loro canonical store + zetld P2P sync daemon (crypto-review vehicle) #79

Draft
anuna-02 wants to merge 60 commits from spec/047-loro-p2p into main
anuna-02 commented 2026-07-20 12:00:29 +00:00 (Migrated from codeberg.org)

Orientation

Intent: SPEC-047 — a persistent zetld daemon owning each vault's canonical CRDT state (Loro, one doc per note + a namespace manifest), with roster-gated P2P realtime sync over iroh QUIC, MLS group keys, and did:crdt member identity. Markdown on disk becomes a deterministic export of the canonical store; external edits fold back in via a guarded import that never silently discards either side.

DO NOT MERGE — Tier-1 gate open. The auth-core surface (src/p2p/: SPAKE2 pairing, MLS group, roster, revocation, transport; plus src/daemon/p2p.rs wiring) is implemented and tested but UNREVIEWED (see the module banners). Merging is gated on the human crypto review per plans/IMPL-047.spl:

hence task assert '(given verified-crypto-review-hoc-signed)' plans/IMPL-047.spl --agent hugo

Also pending before merge: the DESIGN-047 cross-model review (non-Anthropic model) and spec approval (SPEC-047 is at 0.22.0-strawman, status Draft). This PR is the review vehicle, not a merge request.

What's in the branch (60 commits)

  • M1 substrate: zetl daemon {start,stop,status,materialise,reimport} lifecycle (idempotent, crash-recovering, flock-serialised startup, Unix-only via cfg(unix)); Loro canonical store (crdt::loro_store, 32-hex DocIds), namespace manifest (rename-preserving, globally collision-safe resolution), guarded import driven by recorded export state (F59 — stale/ambiguous saves stage, never fold), Merkle convergence witness, deterministic materialisation with obsolete-path cleanup and symlink/dot-path hardening.
  • Engine swap (T3): diamond-types → Loro as the one editing engine; CrdtBackend trait removed (SPEC-047 §9).
  • M2 network tasks (UNREVIEWED, opt-in only): T7 CBCL control-plane recogniser, T8 SPAKE2 pairing, T9 openmls group (Owner-only commits by leaf index), T10 roster, T11 did:crdt identity, T12 iroh transport + symmetric vault sync (concurrent frame exchange), T13 durable rotation outbox. The daemon runs P2P only when a vault is explicitly provisioned (.zetl/p2p/endpoint.key); local-only vaults are untouched.
  • External review remediation: all 21 findings of the canonical-store review fixed (clean-checkout git-pinned sibling deps, Windows gating, data-loss/namespace/daemon-race/liveness defects) — commits 34f4366/78badcb.
  • BUG-025 fix: live-editing session docs hold the raw Markdown source (from_source), restoring the client coordinate contract the engine swap broke; red-gated + live-verified. Spec: REQ-507 / ADR-483 / TEST-507a-c; report in bugs/BUG-025-….

Evidence

  • CI: pipeline #574 green — first green run in the branch's history: clone (rev-pinned did-crdt adb5c7a + cbcl-rs 1e43e47 resolve on a clean checkout), test (3356 tests / 83 suites incl. helper-js, golden-HTML, NFR gates, fmt, clippy under Rust 1.97), and the x86_64-pc-windows-gnu cross-check.
  • Live verification: playtest via browser automation — web edit → save → daemon guarded fold → materialise round-trip preserves edits; wikilink-note typing + quiescence flush works; sessions survive materialisation (byte-identical rewrites skipped).

Crypto-review scope (Tier 1)

Start from specs/SPEC-047-crypto-review-guide.md. The load-bearing surfaces: src/p2p/pair.rs (SPAKE2 over cap::pair), src/p2p/group.rs (openmls composition, leaf-index commit authority, seal/open), src/p2p/identity.rs + roster.rs (did:crdt binding — note upstream did-crdt delta signing is not yet wired), src/p2p/revocation.rs (outbox-before-merge ordering), src/p2p/transport.rs + src/daemon/p2p.rs (roster gate before any stream work; interim file-provisioned admit set — see the SIMPLIFY ceilings). Threat model: SPEC-047 §12; open questions Q1/Q2/Q7/Q11 in §18.

Known-open (documented, non-blocking for review)

  • bugs/BUG-026-… — UTF-16 vs unicode-scalar splice offsets on astral chars (pre-existing, S3, deferred to the M2 WebSocket-attachment slice).
  • Full WebSocket→daemon-doc attachment (review finding 4's complete fix) is the M2 editing slice; the interim measure is guarded reimport-before-materialise.
  • The implemented WS editing protocol (positional splices) diverges from SPEC-020's original opId-based message shape — pre-existing drift, flagged for a SPEC-020 amendment.
  • REQ-499 group-key frame sealing and MLS-derived admit sets compose in once the daemon holds a durable MLS group (elephant REQ-306 pattern); // SIMPLIFY: ceilings trace to ADR-481/482.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Aa69Feuo9oqkimGfV6ENo1

## Orientation **Intent:** SPEC-047 — a persistent `zetld` daemon owning each vault's canonical CRDT state (Loro, one doc per note + a namespace manifest), with roster-gated P2P realtime sync over iroh QUIC, MLS group keys, and did:crdt member identity. Markdown on disk becomes a deterministic *export* of the canonical store; external edits fold back in via a guarded import that never silently discards either side. **⛔ DO NOT MERGE — Tier-1 gate open.** The auth-core surface (`src/p2p/`: SPAKE2 pairing, MLS group, roster, revocation, transport; plus `src/daemon/p2p.rs` wiring) is implemented and tested but **UNREVIEWED** (see the module banners). Merging is gated on the human crypto review per `plans/IMPL-047.spl`: ``` hence task assert '(given verified-crypto-review-hoc-signed)' plans/IMPL-047.spl --agent hugo ``` Also pending before merge: the DESIGN-047 cross-model review (non-Anthropic model) and spec approval (SPEC-047 is at 0.22.0-strawman, status Draft). **This PR is the review vehicle, not a merge request.** ## What's in the branch (60 commits) - **M1 substrate:** `zetl daemon {start,stop,status,materialise,reimport}` lifecycle (idempotent, crash-recovering, flock-serialised startup, Unix-only via `cfg(unix)`); Loro canonical store (`crdt::loro_store`, 32-hex DocIds), namespace manifest (rename-preserving, globally collision-safe resolution), guarded import driven by recorded export state (F59 — stale/ambiguous saves stage, never fold), Merkle convergence witness, deterministic materialisation with obsolete-path cleanup and symlink/dot-path hardening. - **Engine swap (T3):** diamond-types → Loro as the one editing engine; `CrdtBackend` trait removed (SPEC-047 §9). - **M2 network tasks (UNREVIEWED, opt-in only):** T7 CBCL control-plane recogniser, T8 SPAKE2 pairing, T9 openmls group (Owner-only commits by leaf index), T10 roster, T11 did:crdt identity, T12 iroh transport + symmetric vault sync (concurrent frame exchange), T13 durable rotation outbox. The daemon runs P2P **only** when a vault is explicitly provisioned (`.zetl/p2p/endpoint.key`); local-only vaults are untouched. - **External review remediation:** all 21 findings of the canonical-store review fixed (clean-checkout git-pinned sibling deps, Windows gating, data-loss/namespace/daemon-race/liveness defects) — commits `34f4366`/`78badcb`. - **BUG-025 fix:** live-editing session docs hold the raw Markdown source (`from_source`), restoring the client coordinate contract the engine swap broke; red-gated + live-verified. Spec: REQ-507 / ADR-483 / TEST-507a-c; report in `bugs/BUG-025-…`. ## Evidence - **CI:** pipeline **#574 green** — first green run in the branch's history: clone (rev-pinned `did-crdt` `adb5c7a` + `cbcl-rs` `1e43e47` resolve on a clean checkout), test (3356 tests / 83 suites incl. helper-js, golden-HTML, NFR gates, fmt, clippy under Rust 1.97), and the `x86_64-pc-windows-gnu` cross-check. - **Live verification:** playtest via browser automation — web edit → save → daemon guarded fold → materialise round-trip preserves edits; wikilink-note typing + quiescence flush works; sessions survive materialisation (byte-identical rewrites skipped). ## Crypto-review scope (Tier 1) Start from `specs/SPEC-047-crypto-review-guide.md`. The load-bearing surfaces: `src/p2p/pair.rs` (SPAKE2 over `cap::pair`), `src/p2p/group.rs` (openmls composition, leaf-index commit authority, seal/open), `src/p2p/identity.rs` + `roster.rs` (did:crdt binding — note upstream did-crdt delta *signing* is not yet wired), `src/p2p/revocation.rs` (outbox-before-merge ordering), `src/p2p/transport.rs` + `src/daemon/p2p.rs` (roster gate before any stream work; interim file-provisioned admit set — see the SIMPLIFY ceilings). Threat model: SPEC-047 §12; open questions Q1/Q2/Q7/Q11 in §18. ## Known-open (documented, non-blocking for review) - `bugs/BUG-026-…` — UTF-16 vs unicode-scalar splice offsets on astral chars (pre-existing, S3, deferred to the M2 WebSocket-attachment slice). - Full WebSocket→daemon-doc attachment (review finding 4's complete fix) is the M2 editing slice; the interim measure is guarded reimport-before-materialise. - The implemented WS editing protocol (positional splices) diverges from SPEC-020's original opId-based message shape — pre-existing drift, flagged for a SPEC-020 amendment. - REQ-499 group-key frame sealing and MLS-derived admit sets compose in once the daemon holds a durable MLS group (elephant REQ-306 pattern); `// SIMPLIFY:` ceilings trace to ADR-481/482. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Aa69Feuo9oqkimGfV6ENo1
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin spec/047-loro-p2p:spec/047-loro-p2p
git switch spec/047-loro-p2p

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff spec/047-loro-p2p
git switch spec/047-loro-p2p
git rebase main
git switch main
git merge --ff-only spec/047-loro-p2p
git switch spec/047-loro-p2p
git rebase main
git switch main
git merge --no-ff spec/047-loro-p2p
git switch main
git merge --squash spec/047-loro-p2p
git switch main
git merge --ff-only spec/047-loro-p2p
git switch main
git merge spec/047-loro-p2p
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
anuna-research/zetl!79
No description provided.