# Tasks: Collaboration Agent briefs in `scripts/mm/`. `[ ]` open. - [x] 1. OT core: `TextOp`, apply/compose/transform/invert, cursor transform, client state machine, server `Room`. Pure crate `crates/collab`. Brief `scripts/mm/collab-ot.md`. Done when: convergence property tests (random op pairs and random client interleavings) pass; crate clippy clean. (done 2026-10-20 by GLM 5.3 Flash via Pi; orchestrator fixed 5 clippy lints and removed a stray probe test; 22 tests) - [x] 2. Accounts, many vaults, membership, roles, invites on the sync server (`users`, `members`, `invites`, account-level device tokens, `GET/POST/PATCH/DELETE /v1/vaults`, per-vault role checks on every endpoint, ledger LRU cache, audit, lockout). Brief `scripts/mm/accounts-sharing.md`. Done when: HTTP tests for each role and for invite use/expiry/lockout pass. (done 2026-10-20 by GLM 5.3 Flash via Pi until its provider quota ended; orchestrator fixed 7 clippy lints, a missing assertion in `lifecycle.rs`, the read half of the role matrix and two outdated expectations; 40 server tests) - [x] 3. Live endpoints: `join`, `ops`, `events` (SSE), room registry, idle flush into the ledger, presence. Needs 1 and 2. (done 2026-10-20 by MiniMax M3.1 Flash through the Claude Code harness: `live/` module, 14 HTTP tests incl. two-client convergence over SSE; verified by the orchestrator. Rooms are in memory, flush after 2 s idle through the ledger, conflicts become `(conflict live ...)` copies.) - [x] 4. (live session client DONE 2026-10-20 by MiniMax M3.1 Flash: `crates/engine/src/live/`, 8 stub-server tests and a two-client e2e against the real server, verified; `share.*` and `server.*` commands DONE 2026-10-20 by MiniMax M3.1 Flash: `crates/engine/src/share/`, 9 stub tests plus 2 real-server e2e tests, verified; `live.*` commands DONE 2026-10-20 by MiniMax M3.1 Flash via the harness: `live.join/edit/poll/peers/selection/info/leave` and `server.file_meta`, 13 tests incl. two sessions converging through the real server) Engine: per-vault `binding.json`, keychain entry per account, `vault.server_list`/`connect`/`create_remote` commands; live session client (SSE reader thread, OT client, apply remote ops to the open buffer), `share.*` commands (invite, accept, members, mount), mount-aware sync state. - [ ] 5. UI: Vaults screen and vault switcher (design 14), Share dialog, members list, presence avatars and remote cursors in Source and Visual views, shared folder badge in the Explorer, "removed from shared folder" banner (designs in PaperCraft page "Collaboration"). - [ ] 6. Deploy with the sync server (needs owner approval); load test with 10 simulated peers. - [ ] 7. Later: comments, per-folder sharing, public read-only links. ## From the research (`research/collaboration-landscape.md`, 866 lines, browsed), ranked Finding: server-ordered OT stays the right call for plain `.md` (no maintained Rust OT crate, every Rust CRDT makes the file a projection; HedgeDoc 1.x ships server-ordered OT on Markdown). NotesCraft's owner/editor/viewer roles plus presence already exceed Obsidian's shared vaults (one role, no cursors) and Relay (key based, no read-only tier). - [x] 8. (engine `server.file_meta` and the status-bar "Last edit - name, time ago" line DONE 2026-10-20: GLM 5.3 Flash; Visual-view carets still open) "Last edit" attribution line per note ("Last edit - Ana, 2 min ago") from the accepted op's author and `files-meta`; presence in the Visual view (carets there are Source-only today). - [~] 9. (server side DONE: `/s/{token}`, expiry, revoke, rate limits; engine commands and UI open) Expiring, revocable read-only share links from the same renderer as publish, validated server-side (404 after expiry or revocation, never listed in sitemap or search). - [ ] 10. Role ceiling audit: no grant can exceed the vault role; every refused write is audited without secrets (mostly done: verify per-note grants stay out of v1). - [~] 11. (server side DONE; engine commands and UI open) Publish as a filtered projection (folder filters, `publish: false` frontmatter, no binary attachments by default, unpublish 404 within a minute). - [ ] 12. Per-note attribution view ("who changed what") from the OT op log, served by the server and kept across restarts. - [x] 13. (done with publish-server: token buckets 60 per minute per route and slug, 600 global, 429 with Retry-After) Rate limiting and abuse protection on anonymous routes (share links, publish): per-vault budget, 429 with `Retry-After`. - [ ] 14. Suggestions and comments stored inside the Markdown as CriticMarkup, accept or reject rewrites the note. - [ ] 15. Mentions and a small activity feed (who joined, who edited, invites) from the audit log.