diff --git a/website/design.html b/website/design.html index e2cb41b..671de73 100644 --- a/website/design.html +++ b/website/design.html @@ -44,7 +44,8 @@
This is the canonical technical reference for ItsGoin. It describes the vision, the architecture, and the current state of every subsystem — with full implementation detail. This document is versioned; each update records what changed.
v0.3.6 (2026-03-20): Active CDN replication — all devices proactively replicate recent posts to peers (desktops > anchors > phones priority). ReplicationRequest/Response (0xE1/0xE2). Device roles (Intermittent/Available/Persistent) advertised in InitialExchange. Bandwidth budgets: replication (pull to cache) + delivery (serve requests), hourly auto-reset, phones 100MB/1GB, desktops 200MB/2GB, anchors 200MB/1GB. Cache management: 1GB default, configurable, eviction cycle activated with share-link priority boost. Engagement distribution fix — BlobHeader JSON rebuilt after diff ops. Tombstone system — deleted reactions/comments tombstoned, propagate via pull sync. Persistent notifications via seen_engagement/seen_messages tables. DOS hardening: fan-out cap (10), prefetch cap (20), downstream registration cap (50), delivery budget enforcement. Pull preference reordered: non-anchors first. Network indicator — header dot (black/red/yellow/green) + capability labels. Tab badges — contextual counts (new posts, engagement, online, unread). Message read tracking on open/close/send. Stats bar removed.
+v0.4.0 (planned): Protocol v4 — header-driven sync. ManifestPush as primary post notification. Slim PullSyncRequest (per-author timestamps, not full post ID list). Tiered engagement checks (5min/1hr/4hr/24hr by content age). Multi-upstream (3 max) with fallback chain. Auto-prefetch followed authors <90d. Self Last Encounter per-author tracking. Encrypted-but-not-for-us CDN caching. Serial engagement polling. ~90% bandwidth reduction for established nodes.
+v0.3.6 (2026-03-20): Active CDN replication — all devices proactively replicate recent posts to peers (desktops > anchors > phones priority). ReplicationRequest/Response (0xE1/0xE2). Device roles (Intermittent/Available/Persistent) advertised in InitialExchange. Bandwidth budgets: replication (pull to cache) + delivery (serve requests), hourly auto-reset, phones 100MB/1GB, desktops 200MB/2GB, anchors 200MB/1GB. Cache management: 1GB default, configurable, eviction cycle activated with share-link priority boost. Engagement distribution fix — BlobHeader JSON rebuilt after diff ops. Tombstone system — deleted reactions/comments tombstoned, propagate via pull sync. Persistent notifications via seen_engagement/seen_messages tables. DOS hardening: fan-out cap (10), prefetch cap (20), downstream registration cap (50), delivery budget enforcement. Pull preference reordered: non-anchors first. Network indicator — header dot (black/red/yellow/green) + capability labels. Tab badges — contextual counts (new posts, engagement, online, unread). Message read tracking on open/close/send. Stats bar removed.
v0.3.5 (2026-03-20): Private blob encryption — attachments on encrypted posts (Friends/Circle/Direct) now encrypted with same CEK as post text; public blobs unchanged; CID on ciphertext. Blob prefetch on sync — attachments eagerly fetched after post pull for offline availability. Crypto refactoring — extracted reusable primitives (encrypt/decrypt_bytes_with_cek, unwrap_cek_for_recipient, unwrap_group_cek). Intent-based post filtering — feed/myposts/messages filter on intentKind instead of encryption state. Blob decryption API (get_blob_for_post). Download filename sanitization. Encrypted receipt & comment slots — private posts carry noise-prefilled encrypted slots in BlobHeader for delivery/read/react receipts and private comments; CDN-propagated as opaque bytes; slot key derived from post CEK; 3 new BlobHeaderDiffOps (WriteReceiptSlot, WriteCommentSlot, AddCommentSlots). Message UI — DM delivery indicators (checkmark/double/blue/emoji), auto-seen on view, react button on messages.
v0.3.4 (2026-03-18): Comment edit & delete with trust-based propagation. Native notifications via Tauri plugin (messages, posts, reactions, comments). Forward-compatible BlobHeaderDiffOp::Unknown variant. Following Online/Offline lightbox. Comment threading scoping fix. Dropdown text legibility fix. Mobile hamburger nav for website.
v0.3.3 (2026-03-16): Connection rate limiting — incoming auth failures rate-limited per source IP (3 attempts, exponential backoff to ~256s). Schema versioning — PRAGMA user_version tracks DB version with migration framework. N2/N3 freshness — TTL 7d→5h, full N1/N2 re-broadcast every 4h, startup sweep clears stale entries. Bootstrap isolation recovery — 24h check verifies bootstrap is in N1/N2/N3, reconnects + sticky N1 advertisement if absent. IPv6 HTTP address fix — nodes advertise actual public IPv6 (not 0.0.0.0) for share link redirects. Upstream tracking — post_upstream table records post source for engagement diff routing toward author. Video preload fix — share links and in-app videos use preload=auto. Following Online/Offline split. DM filter from My Posts. Any-type file attachments with download prompt + trust warning. Image lightbox. Audio player.
@@ -1146,6 +1147,98 @@ FAILURE: C → B → A: AnchorProbeResult { reachable: false }DM conversations display delivery indicators: single checkmark (sent), double checkmark (delivered/on device), blue double checkmark (seen), emoji (reacted). Opening a conversation auto-marks incoming messages as seen. Messages have a react button for emoji responses. +Major sync protocol revision that replaces the current pull-everything-from-everyone model with header-driven discovery, per-author tracking, and tiered engagement polling. Reduces bandwidth by ~90% for established nodes.
+ +The AuthorManifest already carries a post neighborhood (20 previous + 20 following PostIds). When this neighborhood is pushed via ManifestPush (0x94) or travels with blob responses, receiving nodes can diff their local post list against the neighborhood to discover new posts without a full pull sync. The CDN tree becomes the notification system.
Implements the v0.2.0 design intent: track last_sync_ms per followed author. Pull sync triggers only when now - last_sync_ms > check_interval. Updated on:
Current: { follows: Vec<NodeId>, have_post_ids: Vec<PostId> } — sends ALL post IDs every request.
v4: { follows: Vec<NodeId>, since_ms: HashMap<NodeId, u64> } — per-author timestamps. Response contains only posts newer than the requester's timestamp for each author. Drops request size from O(posts) to O(follows).
Instead of pulling from ALL mesh peers every 5 minutes, pull is driven by Self Last Encounter staleness:
+last_sync_ms is stale AND no header updates were received in the intervalpost_upstream / post_downstream for that author), falling back to mesh peers only if CDN sources are unavailableEngagement header polling (BlobHeaderRequest 0xD1) frequency scales with content age and activity:
| Content age / last engagement | Check interval |
|---|---|
| < 72 hours | 5 minutes |
| 3–14 days | 1 hour |
| 14–30 days | 4 hours |
| > 30 days | 24 hours |
DB tracks last_engagement_ms and last_check_ms per post. A single SQL query filters posts due for check:
SELECT post_id FROM posts
+WHERE last_check_ms < now_ms - CASE
+ WHEN last_engagement_ms > now_72h THEN 300000
+ WHEN last_engagement_ms > now_14d THEN 3600000
+ WHEN last_engagement_ms > now_30d THEN 14400000
+ ELSE 86400000
+END
+ Checks are serial (one peer at a time). A single “no new engagement” response is treated as authoritative — if that peer missed an update, it would have been replicated to them by now.
+On connect/wake: if since_last_check > check_rate for any post, an automatic check runs immediately.
Extend post_upstream from 1 entry to up to 3 per post:
BlobDeleteNotice (0x95) already handles “I no longer hold this.” Extend to upstream: “I’m no longer your upstream for this post.”When a post by a followed author appears in any header (PullSyncResponse, ManifestPush, BlobHeaderDiff neighborhood), prefetch the post and its blobs if:
+Encrypted posts without key: Store the encrypted post in DB marked as “not-for-us.” The node contributes to CDN availability for those who CAN decrypt it. Normal cache decay handles cleanup — these posts are given low eviction priority (stranger relationship score of 0.1) and will be evicted when space is needed.
+ +This makes the CDN tree the primary content distribution channel, with pull sync serving only as a safety net for missed headers.
+ +v4 is backward-compatible via ALPN negotiation. Nodes running v3 continue to work with the existing pull model. v4 nodes detect peer capability during InitialExchange and use the optimized paths when both sides support them. The v3 pull cycle remains as a fallback for mixed-version networks.
+ +| Table | Column | Purpose |
|---|---|---|
posts | last_engagement_ms | Timestamp of most recent reaction/comment |
posts | last_check_ms | Timestamp of last engagement check |
follows | last_sync_ms | Self Last Encounter per followed author |
post_upstream | (expand to 3 rows) | Multi-upstream with priority |