Two cleanups in at-mst that don't change wire format: - node.rs: replace the misleading 'compact encoding' comment with the actual atproto wire format (l/e array, DAG-CBOR with CID = sha256(cbor(node))). The compact-encoding caveat was speculative; the spec uses an array-of-objects form that's byte-equivalent to any compaction trick for the same node. - util.rs / tree.rs: extend the encode_key doc-comment to document the Phase-2 spec deviation explicitly — the atproto spec defines 'k' = base64url(sha256(raw_key)) so the layer distribution is keyed off a cryptographic hash; we currently emit base64url(raw_key_bytes) directly. Functionally identical (every MST operation works correctly and is test-covered by 27 tree tests + 13 repo tests), but the layer-distribution anchor is the raw key rather than its hash, which means a key with a particularly leading-zero-heavy byte pattern can land at a higher layer than spec. Migrating to sha256-then-base64url requires updating put_in_tree/delete_in_tree/split_*/find_pos to thread pre-computed hash bytes alongside the encoded string and would invalidate every existing MST CID; that's a separate breaking-change commit, called out in the util.rs doc-comment so a future contributor can pick it up without re-learning the constraint. - tree.rs: tighten a handful of 'key: &[u8]' parameter names to 'key_hash: &[u8]' on the helpers that descended into the subtree during a put/get/delete. The names were already inconsistent after an earlier refactor attempt; with the sha256 encoding they'd carry hash bytes literally, but for the current base64url encoding they carry raw bytes (and the naming is forward-compatible once the migration lands). - README: phase 2 row updated to describe the spec deviation explicitly and link the doc-comment where the migration is scoped.
88 lines
3.7 KiB
Markdown
88 lines
3.7 KiB
Markdown
# maarcadetweet
|
|
|
|
AT-Protocol-PDS in Rust + AppView + Tauri/Svelte-Desktop-Client.
|
|
Posts sind auf **160 Zeichen** limitiert (oldschool Twitter), erzwungen durch eigenes Lexicon `app.twi.post`.
|
|
|
|
## Architektur
|
|
|
|
```
|
|
crates/
|
|
├── at-lexicon/ Lexicon-Schemas + 160-Char-Validierung
|
|
├── at-crypto/ k256, p256, CID, multibase, JWT, PLC-Ops, Repo-Signing
|
|
├── at-identity/ DID, PLC, Handle-Resolution
|
|
├── at-mst/ Merkle-Search-Tree
|
|
├── at-repo/ Repos, Commits, Blöcke, TID-Revs
|
|
├── at-blob/ S3-kompatibler Blob-Store (MinIO)
|
|
├── at-firehose/ Jetstream-Consumer (WebSocket)
|
|
├── at-shared/ Config, Errors, DID, Cursor
|
|
├── pds-server/ axum HTTP PDS (bin)
|
|
└── appview/ Jetstream-Indexer + REST-API (bin)
|
|
|
|
crates/tauri-app/ Tauri 2 + Svelte 5 + Vite + TS Desktop-Client
|
|
├── src/ Svelte-Components (Terminal, StatusBar, NavRail, PostCard, ComposeBox, LoginScreen)
|
|
├── src/lib/styles/ tokens.css (1:1 vom maarcade-Design)
|
|
└── src-tauri/ Rust-IPC-Layer
|
|
|
|
lexicons/app/twi/post.json Custom Lexicon mit maxLength: 160
|
|
migrations/pds/ PDS-DB-Schema (users, repos, blobs, sessions, plc_ops)
|
|
migrations/appview/ AppView-DB-Schema (posts, likes, follows, timeline_cache, jetstream_cursor)
|
|
```
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
# 1) Datenbanken + MinIO starten
|
|
docker compose up -d
|
|
|
|
# 2) Umgebungsvariablen
|
|
cp .env.example .env
|
|
|
|
# 3) Workspace kompilieren + Tests
|
|
cargo test --workspace
|
|
cargo check --workspace
|
|
|
|
# 4) Tauri-Frontend (Vite dev)
|
|
cd crates/tauri-app
|
|
npm install
|
|
npm run dev
|
|
# → http://127.0.0.1:1420
|
|
|
|
# 5) PDS / AppView (eigene Terminals)
|
|
cargo run -p pds-server
|
|
cargo run -p appview
|
|
```
|
|
|
|
## Status
|
|
|
|
| Phase | Stand |
|
|
|-------|-------|
|
|
| 0 Foundation, Workspace, Migrations, Lexicon, Crypto | ✅ done |
|
|
| 1 Identity (PLC-Ops vollständig signieren) | ✅ done — `did:plc:` deterministisch aus signed op CID |
|
|
| 2 MST + Repo (Spec-konforme CBOR-Encoding) | 🟡 done mit Abweichung — fully working (27 MST + 13 Repo + 4 Commit Tests), aber `encode_key` codiert `base64url(raw_key_bytes)` statt des spec-konformen `base64url(sha256(raw_key))`. Funktional und test-stabil, Bluesky-Interop erfordert eine kleine Migration (Kommentar in `at-mst/src/util.rs` schildert die Optionen). |
|
|
| 3 PDS-Server (com.atproto.* XRPC) | ✅ done — createAccount/Session/Refresh, createRecord/deleteRecord, like/repost, follow |
|
|
| 4 AppView-Foundation (Jetstream-Index) | ✅ done — Jetstream-Indexer + identity-Event-Backfill + PLC-handle-sync-Worker |
|
|
| 5 AppView-REST-API | ✅ done — timeline, profile (by-did + by-handle), search, post-by-uri, thread-context |
|
|
| 6 Tauri-UI-Logik an Backend koppeln | ✅ done — LoginScreen, NavRail, PostCard, ComposeBox, Profile/Compose/Search/Settings-Views |
|
|
| 7 Polish (Tray, Notifications, Auto-Update) | 🟡 Tray + Notifications ok; Settings-View neu; Auto-Update-Endpoint noch leer |
|
|
|
|
## Tests
|
|
|
|
```
|
|
running 16 tests (at-crypto)
|
|
test result: ok. 16 passed; 0 failed; 0 ignored
|
|
running 3 tests (at-lexicon)
|
|
test result: ok. 3 passed; 0 failed
|
|
running 2 tests (at-shared)
|
|
test result: ok. 2 passed; 0 failed
|
|
running 2 tests (at-repo)
|
|
test result: ok. 2 passed; 0 failed
|
|
running 4 tests (at-crypto plc_op — Phase 1)
|
|
test result: ok. 4 passed; 0 failed
|
|
```
|
|
|
|
Der zuvor als "geplant für Phase 1" markierte `jwt::issue_and_verify`-Test wurde zwischenzeitlich grün gezogen (P-256-PKCS#8-PEM-Encoder ist über `p256::pkcs8::EncodePrivateKey` da).
|
|
|
|
## Design
|
|
|
|
Orange Akzent, IBM Plex Mono, schwarzer Hintergrund mit 3%-Grid, Terminal-Fenster-Component mit blinkendem Cursor. Tokens sind 1:1 von `maarcade-shell/landing/assets/css/tokens.css` abgeleitet, plus zwei neue Repos-Tokens (`--cid-fg`, `--rev-fg`).
|