# Download ItsGoin

Available for Android, Linux, and Windows. Free and open source.

Upgrading from v0.5.1 or newer? v0.6 is a hard network fork — older versions can no longer reach the network. Bring your account over in three steps:

1. On your current v0.5 install, go to Settings → Export, tick “Posts + media + identity key”, and save the .zip somewhere safe.
2. Download v0.6 below (APK, AppImage, or Windows installer).
3. On first launch, choose “Import an Identity” and point it at the .zip.

Your posts, media, follows, and identity key all come across. Encrypted posts stay decryptable under the same key.

Upgrading from v0.5.0 or older? The v0.5 export format matured in v0.5.1, so a direct export from 0.5.0 won't import cleanly into v0.6. Do a two-hop upgrade:

1. Install v0.5.3 Linux AppImage / Android APK / Windows installer and open it. It reads your existing data in place.
2. In v0.5.3, go to Settings → Export and save the bundle.
3. Install v0.6.0 below and import that bundle on first launch.

v0.5.3 is kept online only as an upgrade bridge — it no longer connects to the live network.

## v0.6.2 — April 22, 2026

Every remaining persona-signed direct push is off the wire. Deletes, visibility changes, profile updates, and group-key distribution now travel as encrypted / signed posts through the CDN. Groups are a first-class primitive. Plus two pre-release fixes — an admin-forgery check on group keys and a cap on concurrent port-scan hole punches that explains the 10 Mbps upload storm some users saw on VPNs.

Android APK v0.6.2 Linux AppImage v0.6.2 Linux CLI / Anchor v0.6.2

- Deletes + visibility changes travel as signed control posts through the CDN. The `DeleteRecord` / `VisibilityUpdate` direct pushes are gone.
- Profile display data (name, bio, avatar) travels as a persona-signed profile post. Peer-visible names are back — but bound to the posting identity, not the network endpoint.
- Rich comments — a comment can reference a separate post for long bodies or attachments; inline preview is signed alongside the reference.
- Groups as a primitive — many-way posting anchored at a public root post. Circles remain one-way (admin-only).
- Group keys distribute as encrypted posts — the `GroupKeyDistribute` wire message is gone.
- Audience removed. Simpler social graph; anyone-can-send model via follows.
- PostPush / PostNotification wire messages retired — all content propagates via CDN.
- Port-scan hole punches are now capped at 1 concurrent — fixes sustained multi-Mbps upload on obfuscated VPNs after anchor connect.
- Outgoing-connect dedup — auto-reconnect, rebalance, and relay-introduction no longer race to the same peer.
- Security fix: group-key distribution verifies the claimed admin matches the post author, preventing a pollution attack where a peer who knows your posting id could overwrite your stored group key.

v0.6.2 is a wire-breaking fork from v0.6.1 (the retired message types are not optional). Upgrade both ends.

## v0.6.1 — April 22, 2026

Network identity is now fully separated from posting identity on every install. Plus: Android auto-backup disabled by default, Reset actually resets, import preserves your personas, and display name is optional.

Android APK v0.6.1 Linux AppImage v0.6.1 Linux CLI / Anchor v0.6.1

- Multiple personas on one device — Public, Private, Work, whatever you want. No switching; all active at once. Filter the merged feed per persona; compose as any persona.
- Network-ID / Posting-ID split — content is signed by a posting key, not the network endpoint. Peers cannot link network connections to posting identities.
- CDN-only DM propagation — encrypted posts no longer have a sender→recipient traffic signal. They travel through the same CDN path as any other content.
- Merged pull with recipient-match — DMs from strangers reach you without requiring a mutual follow. No distinguishable “searching for DMs” traffic pattern.
- File-holder CDN — replaces the upstream/downstream tree with flat lateral holder sets (max 5 per file, LRU-capped). Delete-notice and manifest fan-out are now uniform.

See the Identity Architecture section of the design doc for details. Rotating DM identities (from the original plan) are deferred — they need more work on the connection model.

## Installation

### Android

1. Download the APK — Tap the button above. Your browser may warn that this type of file can be harmful — tap Download anyway.
2. Open the file — When the download finishes, tap the notification or find the APK in your Downloads folder and tap it.
3. Allow installation — Android will ask you to allow installs from this source. Tap Settings, toggle "Allow from this source", then go back and tap Install.
4. Launch the app — Once installed, tap Open or find ItsGoin in your app drawer.

Note: If you don't see the "Allow from this source" prompt, go to Settings → Apps → Special access → Install unknown apps and enable it for your browser.

### Linux (AppImage)

1. Download the AppImage — Click the button above to download.
2. Make it executable — Open a terminal and run:
   `chmod +x itsgoin_*.AppImage`
3. Run it — Double-click the file, or from the terminal:
   `./itsgoin_*.AppImage`

Note: If it doesn't launch, you may need to install FUSE:
`sudo apt install libfuse2` (Debian/Ubuntu) or `sudo dnf install fuse` (Fedora).

### Linux CLI / Anchor

1. Download the binary — Click the CLI button above to download.
2. Make it executable — `chmod +x itsgoin-cli-*`
3. Run as node — `./itsgoin-cli-* /path/to/data --daemon`
4. Run as anchor — `./itsgoin-cli-* /path/to/data --bind 0.0.0.0:4433 --daemon --web 8080`

Note: The CLI binary is the same as the anchor server. Run with `--help` for all options.

### Windows

1. Download the installer — Click the Windows button above.
2. Run the installer — Windows may show a SmartScreen warning since the app isn't signed with a Microsoft certificate. Click More info then Run anyway.
3. Launch — Find ItsGoin in your Start menu or desktop shortcut.

## Changelog

v0.6.2 — April 22, 2026

- Deletes and visibility changes travel as signed control posts. New `VisibilityIntent::Control` post type carries a signed `DeletePost` / `UpdateVisibility` operation. Receivers verify the ed25519 signature against the target post's author, then apply. `DeleteRecord` and `VisibilityUpdate` wire pushes are removed.
- Persona display data (name / bio / avatar) travels as a signed profile post. New `VisibilityIntent::Profile`; authored by the posting identity, propagates via the CDN. The `ProfileUpdate` wire message keeps only routing fields (anchors, recent_peers, preferred_peers).
- Rich comments. `InlineComment` gains an optional `ref_post_id`; when set, `content` is a short preview and the full body (long text, attachments) lives in the referenced post. Signature binds the reference so a peer can't strip or swap it.
- Groups vs circles. Groups are a new many-way primitive — anchored at a public root post, any member can post to the group once they have the seed. Circles stay one-way (admin-only). The distinction is a `canonical_root_post_id` field on the group-key record; groups reuse the same encryption machinery.
- Group-key distribution as an encrypted post. The `GroupKeyDistribute` (0xA0) wire push is retired. Admins publish an encrypted post carrying the seed; members decrypt with their posting secret. Removes the last persona-signed direct push.
- Audience primitive removed. No more audience tables, no more `AudienceRequest`/`AudienceResponse` wire messages, no more `SocialRelation::Audience`/`Mutual`. Comment permission `AudienceOnly` renamed to `FollowersOnly`.
- PostPush + PostNotification retired. All content propagates only via CDN (pull + header-diff neighbor propagation). `BlobDeleteNotice` also retired — orphan blobs on remote holders evict via LRU.
- Security: group-key admin-forgery rejection. Distribution posts whose inner `admin` field doesn't match the post's author are rejected before storage. Prevents an attacker who knows a victim's posting id and the target group_id from overwriting the victim's legitimate group-key record.
- Bandwidth: port-scan hole punch capped at one concurrent scanner. Each scanner fires ~100 QUIC ClientHellos/sec for up to 5 minutes. Without a cap, parallel referrals could drive sustained multi-Mbps upload — especially on obfuscated VPNs where every probe stalls at a proxy timeout. Extra callers fall back to the standard 2s-round hole punch.
- Outgoing-connect dedup. `PendingConnectGuard` prevents auto-reconnect, rebalance-slots, and relay-introduction from racing to connect to the same peer. Same-peer only — different peers connect independently; inbound connections are unaffected.
- Merged-pull bugfix. The pull query now includes every posting identity we hold (not just the network id), so DMs addressed to any of our personas are found via the recipient-match path.

v0.6.2 is a wire-breaking fork from v0.6.1. Retired message types (0x42 PostNotification, 0x43 PostPush, 0x44 AudienceRequest, 0x45 AudienceResponse, 0x95 BlobDeleteNotice, 0xA0 GroupKeyDistribute) are not optional — upgrade both ends.

v0.6.1 — April 22, 2026

- Network ID and posting ID are now separate by default. Fresh installs generate two independent ed25519 keys. Upgraders rotate their network key on first launch; the old key stays as the default posting persona. Peers see the same author; only the QUIC endpoint changes.
- Android auto-backup disabled. Previously the app inherited Android's default `allowBackup=true`, which silently uploaded `identity.key` (your root secret — full access to all private content) to Google Drive for any user with cloud backup enabled. That's published-to-a-third-party without asking. Now off by default, plus `data_extraction_rules` for Android 12+ cloud and device-transfer paths. Users who want off-device backup use Settings → Export (explicit ZIP under their control).
- Reset All Data actually resets on Android. The sentinel file was being written to a subdir the startup check never looked at. Also wipes `identity.key`, WAL/SHM, and all identity subdirs — truly fresh on next launch.
- Display name is optional on first-run. Blank field is accepted — proceed as an anonymous user. Attaching a human-readable name to a network ID would correlate the QUIC endpoint to a person; v0.6.2 will reintroduce peer-visible names via persona-signed profile posts.
- Import preserves personas. New default import option restores source posting keys as personas on the current device; posts keep their original authors and signatures. Encrypted content imported becomes decryptable because we now hold the keys. The old "merge with key" option stays available for consolidating posts under the current default persona.
- Android import Browse button works. Wired to Storage Access Framework's `OPEN_DOCUMENT`; picked file is staged in the app's private cache for the existing importer.
- Decrypt tries all held personas. Multi-persona users (or anyone who imported prior identities as personas) can now decrypt DMs addressed to any of their keys.
- Profile broadcasts strip persona display data. Network-keyed profile carries only routing metadata (anchors, recent_peers, preferred_peers). `display_name` / `bio` / `avatar` are no longer sent on the wire. Peers render author names as hex until v0.6.2 adds persona-signed profile posts.

v0.6.0 — April 21, 2026

- Network fork from v0.5. The network protocol has changed enough that v0.5 and v0.6 cannot interoperate. Upgrade if you want to stay reachable.
- CDN-only encrypted-post propagation. Direct `PostPush` for encrypted posts is removed; encrypted DMs look identical on the wire to any other encrypted post.
- Flat per-file holder sets replace upstream/downstream trees. Each file tracks up to 5 most-recent peers it was exchanged with. Engagement diffs, manifest pushes, and delete notices all route through this holder set uniformly.
- Merged pull with recipient-match. Pull queries contain a uniform list of NodeIds (follows + your own); server matches on post author OR wrapped-key recipient. Non-follower DMs now reach you via a normal pull cycle — no sender→recipient traffic signal.
- Posting-key / network-key split. Content is signed with a dedicated posting key; the network endpoint uses a separate network key. Peers can no longer correlate posting identity to network traffic.
- Multi-persona support. Hold multiple posting keys on one device; each peer sees distinct authors. Settings → Personas to create/manage; compose box picks which persona posts each item; feed has filter pills per persona.
- pkarr default lookup suppressed. `clear_address_lookup()` + mDNS only; no implicit DNS publishing.
- Schema: four legacy tables dropped (`post_upstream`, `post_downstream`, `blob_upstream`, `blob_downstream`); replaced with `file_holders`. One-way migration seeds the new table from the old ones on first launch. Also adds `post_recipients` index for merged pull, and `posting_identities` table for multi-persona.

v0.5.3-beta — April 19, 2026

- Feed pagination — Cursor-based pagination (20 posts/page) with pre-fetch and infinite scroll. Batched engagement queries (3 SQL queries instead of 4 per post). Media loads only for visible posts via IntersectionObserver.
- Fast startup — Bootstrap (anchor connect, NAT probe, referrals) runs in background. UI shows immediately with local content.
- Duplicate identity detection — Anchor detects when same identity is connected from two devices. Shows warning with “Continue Anyway” override for false positives (network changes).
- Privacy: pkarr leak fixed — Removed default dns.iroh.link publishing. Only mDNS (local network) discovery enabled.
- Android SAF — Exports open native “Save As” dialog via Storage Access Framework. Downloads use app data directory.

v0.5.1-beta — April 16, 2026

- AppImage video fix — Bundled full GStreamer media framework. Video and audio now play correctly in AppImage builds.
- Import fix — Imported posts now create proper BlobHeaders, visibility intents, and pinned blobs.
- First-run chooser — New installs show “Start Fresh” or “Import an Identity” dialog.
- File pickers — Native Browse buttons on export and import dialogs.
- Identity switch fix — Old node properly shut down before starting new one.
- Lock contention — Three remaining handlers converted to brief-lock pattern.

v0.5.0-beta — April 5, 2026

- Multi-identity — Create, switch, and delete multiple identities on one device. Per-identity data directories with hot-swap switching (~3s). Legacy flat layout auto-migrates on first launch.
- ZIP export — Export your data as a ZIP with scope selection: identity only (key backup), posts only (safe to share), posts + identity (full migration), or everything (complete backup including follows and settings). Auto-chunks at 4GB.
- Public post import — Import public posts from another identity's export ZIP into your current identity. Creates new PostIds under your author, preserving original timestamps.
- Merge with decryption key — Import encrypted posts from another identity by providing the original identity key. Decrypts posts and blobs, re-creates them under your current identity. BlobHeader tracks prior_author for provenance.
- Import as new identity — Import a ZIP containing an identity key as a new identity. Creates the identity subdir; switch to it to access the data.
- Hole punch address filtering — Relay introductions now filter by address family (IPv4/IPv6) and exclude LAN-only addresses for remote peers.
- Sync pipeline fixes — Per-peer sync resets last_sync_ms before pulling (fixes stale sync). ManifestPush now fetches blobs after discovering new posts.

v0.4.4 — March 23, 2026

- UI overhaul — Sticky header with tabs as one floating block on desktop. Fixed header + bottom nav on mobile. Full-width dark header with 15px fade gradient into content.
- Tab icons — Icons visible on both desktop (inline with text) and mobile (stacked above text).
- Safe area insets — Header pads below phone notch/camera cutout. Bottom nav pads above home indicator.
- Profiles lightbox — Name, bio, visibility, and circle profiles now in a lightbox from My Posts instead of settings.
- Redundancy lightbox — Post replication stats in a lightbox from My Posts.
- Diagnostics reorganized — Sync All and Stored Anchors moved into Network Diagnostics popover. Opened by clicking the network indicator. Buttons centered in rows.
- Settings streamlined — Removed profile editor, diagnostics button, sync button, redundancy panel, and anchor management from settings.
- Lightbox close on tab switch — Any open lightbox/overlay closes when switching tabs.

v0.4.3 — March 22, 2026

- Lock contention overhaul — All conn_mgr lock holds during network I/O eliminated across 14 handlers. Brief locks for data gathering only; all network operations run lock-free.
- StoragePool — 8 concurrent SQLite connections in WAL mode replace the single Mutex. Reads run fully parallel; writes serialize only at the SQLite level.
- Initial exchange fix — Failed initial exchanges now abort the mesh upgrade instead of silently continuing with a broken connection.
- Connect timeout — connect_to_peer and connect_to_anchor now use a consistent 15s timeout. ResolveAddress adds 5s per-query timeout (was unbounded).
- Worm cascade unlock — WormLookup, ContentSearch, and WormQuery use connection snapshots for lock-free fan-out.
- Bottom nav bar — Mobile/tablet (≤768px) gets a fixed bottom navigation bar with icon tabs. Desktop keeps the top tab bar.
- Text size update — Five options: XS (75%), S (100%), M (125% default), L (150%), XL (200%). Persisted to localStorage for instant restore on startup.
- Startup fix — Fixed blocking_lock panic that prevented app from launching (async runtime conflict). StoragePool reduced to 4 connections for Android compatibility.
- Keepalive fix — Mesh keepalive pings were never firing due to timer reset bug in select loop. Connections were being zombie-reaped instead of kept alive.
- Auto-reconnect — Unexpected disconnects now trigger immediate reconnect attempt (3s delay, then direct connect to last known address). Falls back to growth loop if direct fails.
- Tab icon fix — Badge updates were destroying tab icons on mobile. Now updates label and badge separately.
- Video playback — Feed re-render skipped while video/audio is playing to prevent echo and restart.

v0.4.2 — March 22, 2026

- Welcome screen — Startup shows “How’s it goin?” with staggered counters (connections, posts, messages, reacts, comments) while the backend bootstraps. Replaces the blank-screen wait.
- Status ticker — Header ticker shows new posts, messages, reactions, comments, and connection state changes as they arrive.
- Notification improvements — Tauri plugin → Web Notification API → notify-rust fallback chain. Linux native desktop notifications now work.
- Responsive text scaling — Small/Normal/Large text size (100%/150%/200%), persisted via settings. Default bumped to Normal (150%).
- Diagnostics popover — Network diagnostics moved from inline section to overlay popover. Connections loaded on-demand. Timer countdowns removed.
- Share details lightbox — QR code + connect string in a modal overlay from People tab.
- Connect string improvement — Prefers external address (UPnP/public IPv6/observed) over local bind address.
- Stale N1 fix — Disconnected social routes excluded from N1 share. Prevents dead nodes appearing online to peers.
- Replication handler fix — Actively fetches posts + blobs from requester after accepting replication. Previously relied on pull cycle which doesn’t work for infrastructure nodes.
- Hole punch fix — Target-side registers publicly routable remote address for relay introduction. Fixes address injection for subsequent connections.
- Replication semaphore — Concurrent replication handlers capped at 3 to prevent overload.
- Peer labels — Display names now show truncated node ID for disambiguation.

v0.4.1 — March 21, 2026

- Security: Reaction signatures — Reactions now carry ed25519 signatures. Forged reactions from other NodeIds are rejected. Backward-compatible with unsigned reactions from older nodes.
- Security: Comment signature verification — Comment signatures (already present) are now verified on receipt. Forged comments rejected.
- Security: Reaction removal auth — Only the reactor or post author can remove reactions. Previously any peer could strip reactions.
- Security: BlobHeader author verification — Header rebuild verifies author against stored post, not trusted from payload.
- Lock contention: ManifestPush discovery — cm lock released before PostFetch network I/O. Was holding lock during entire discovery (5s+ freeze).
- Lock contention: Pull request handler — Load posts under lock, filter without lock, brief re-lock for is_deleted. Was holding lock during full post list iteration.
- Lock contention: Pull sender — Split into two brief locks (store, then batch upstream+sync). Was holding one long lock for all operations.
- Lock contention: Engagement checker — Batch writes per chunk with single lock. Was acquiring lock per post (100+ times).
- Data cleanup — Post deletion now cleans up post_downstream, post_upstream, and seen_engagement tables.

v0.4.0 — March 21, 2026

- Protocol v4: Header-driven sync — Major sync protocol revision. ManifestPush now triggers post discovery from CDN tree headers. Bandwidth reduced ~90% for established nodes.
- Slim PullSyncRequest — Per-author timestamps replace full post ID lists. Request size drops from O(posts) to O(follows). Backward-compatible with v3 peers.
- Tiered pull frequency — Pull cycle checks every 60s but only syncs stale authors (4-hour default). Full pull only on first tick. Most ticks do nothing.
- Tiered engagement checks — Engagement polling frequency scales with content age: 5min (<72h), 1hr (3-14d), 4hr (14-30d), 24hr (>30d). Single SQL query filters due posts.
- Header-driven post discovery — ManifestPush triggers PostFetch for missing followed-author posts (capped at 10 per manifest). CDN tree becomes the notification system.
- Multi-upstream (3 max) — Posts track up to 3 upstream sources with priority ordering. Engagement diffs sent to all upstreams. Fallback on upstream failure.
- Lock contention fixes — 6 hot paths optimized: get_blob_for_post (3→1 locks), prefetch (lock-free blob checks), serve_post (4→2 locks), badge cycle (N+2→1 IPC call).

v0.3.6 — March 20, 2026

- Network indicator — Header shows connection status dot (black/red/yellow/green for 0/1/2-10/11+ connections) with capability labels (Public, Server).
- Tab badges — Feed shows new post count, My Posts shows new engagement count, People shows online count, Messages shows unread conversation count. Numbers only, no labels.
- Message read tracking — Conversations marked as read on open, close, and send. Prevents re-notification of already-seen messages.
- Active CDN replication — All devices proactively request replication of their recent posts (<72h) to connected peers. Targets prioritized: desktops > anchors > phones. Graceful with small networks (1 peer = 1 replica). ReplicationRequest/Response (0xE1/0xE2) wire messages.
- Device roles — Nodes classified as Intermittent (phones), Available (desktops), or Persistent (anchors). Advertised in InitialExchange. Influences replication target selection and budget defaults.
- Bandwidth budgets — Hourly replication budget (content pulled to cache) and delivery budget (content served). Phones: 100MB/1GB, Desktops: 200MB/2GB, Anchors: 200MB/1GB. Auto-reset hourly. Blob serving declines when delivery budget exhausted.
- Cache management — 1GB default cache limit (configurable 256MB–unlimited). Eviction cycle now active (was implemented but never started). Priority scoring with share-link boost (+100 for 3+ downstream). Cache pressure score (0–255) for future budget advertisement.
- Engagement distribution fix — BlobHeader JSON now rebuilt after processing BlobHeaderDiff ops. Previously reactions/comments stored in tables but header JSON stayed stale, breaking pull-based sync for downstream peers.
- Tombstone system — Deleted reactions/comments are tombstoned (`deleted_at` timestamp) instead of hard-deleted. Tombstones propagate through pull sync, ensuring deletes reach peers that missed the real-time diff.
- Persistent notifications — Notification tracking backed by `seen_engagement` and `seen_messages` tables. Only notifies on genuinely unseen content. Survives app restarts.
- DOS hardening — BlobHeaderDiff fan-out capped at 10 concurrent sends. Blob prefetch capped at 20 per cycle. PostDownstreamRegister capped at 50 per sync. Delivery budget enforcement on blob serving.
- Pull preference — Blob fetches prefer non-anchor sources (phones > desktops > replicas > anchors) to preserve anchor delivery budget for web requests.

v0.3.5 — March 20, 2026

- Private blob encryption — Attachments on encrypted posts (Friends, Circle, Direct) are now encrypted with the same CEK as the post text. Public blobs remain plaintext. CID computed on ciphertext preserves content addressing.
- Blob prefetch on sync — When posts are pulled from peers, their attachments are eagerly fetched for offline availability. Previously blobs were only fetched on view.
- Crypto refactoring — Extracted reusable primitives: `encrypt_bytes_with_cek`, `decrypt_bytes_with_cek`, `unwrap_cek_for_recipient`, `unwrap_group_cek`. Foundation for encrypted blob storage and future chunk-level encryption.
- Intent-based post filtering — Feed, My Posts, and Messages now filter on the author's original visibility intent (`intentKind`) rather than encryption state.
- Encrypted receipt slots — Private messages get encrypted receipt and comment slots in BlobHeader. Delivery indicators, read receipts, and message reactions.
- Download filename sanitization — Prevents path traversal in downloaded file names.

v0.3.4 — March 18, 2026

- Comment edit & delete — Edit or delete your own comments. Trust-based: post authors can also delete comments on their posts. Propagates via BlobHeaderDiff to all holders.
- Native notifications — System notifications via Tauri plugin (works on all platforms). Notifications for messages, new posts, reactions, and comments. Configurable in Settings with button-group toggles.
- Forward-compatible protocol — Unknown BlobHeaderDiffOp variants are silently ignored instead of crashing deserialization. Prevents old nodes from breaking when new features are added.
- Following: Online/Offline — Self removed from following list. Offline follows hidden behind lightbox popup. Shows expanded if no one is online.
- DM filter fix — Sent direct messages no longer appear in My Posts tab.
- Comment threading fix — Comments now work correctly in My Posts tab (duplicate element ID scoping fix).
- Dropdown text fix — Select dropdowns across the app now have legible text in WebKitGTK native popups.

v0.3.3 — March 16, 2026

- IPv6 HTTP address fix — Nodes with public IPv6 now correctly advertise their real address for direct browser access, instead of `0.0.0.0`. Fixes share link video/image serving for IPv6-reachable nodes.
- Video preload fix — Share link videos and in-app videos from peers now buffer properly for playback (`preload="auto"`). Previously only the first frame loaded.
- Connection rate limiting — Incoming connections that fail authentication are rate-limited per source IP (3 attempts, then exponential backoff up to ~4 minutes). Prevents CPU exhaustion from rogue or stale nodes spamming auth failures.
- Schema versioning — Database tracks schema version via `PRAGMA user_version`. Future upgrades can run data migrations automatically. Databases too old to migrate are reset cleanly.
- N2/N3 freshness — TTL reduced from 7 days to 5 hours. Full N1/N2 state re-broadcast every 4 hours catches missed diffs.
- Bootstrap isolation recovery — 24 hours after startup, nodes verify the bootstrap anchor is within N1/N2/N3 reach. If absent, they reconnect and request referrals. Bootstrap is added to sticky N1 for 24 hours so mesh peers discover it via diffs.
- Following: Online/Offline — People tab splits followed peers into Online and Offline sections with “Last online” timestamps.
- DM filter — Direct messages no longer appear in My Posts tab.
- Bidirectional engagement propagation — Reactions and comments now flow both upstream (toward author) and downstream through the CDN tree. Previously only downstream propagation existed, so the post author often never received reactions.
- Auto downstream registration — Nodes that receive a post via pull sync or push notification automatically register as downstream peers. This ensures engagement diffs reach all holders without manual registration.
- Upstream tracking — New `post_upstream` table records which peer each post was received from, enabling engagement to flow back toward the author hop-by-hop through the CDN tree.
- N2/N3 freshness — TTL reduced from 7 days to 5 hours. Full N1/N2 state re-broadcast every 4 hours catches missed diffs. Disconnect cleanup already removes departed peer's contributions immediately.
- Bootstrap isolation recovery — 24 hours after startup, nodes check if the bootstrap anchor is within their N1/N2/N3 reach. If absent, they reconnect and request referrals. The bootstrap is added to sticky N1 for 24 hours so mesh peers discover it via diffs, bridging isolated network segments back together.
- Following: Online/Offline — People tab splits followed peers into Online and Offline sections with “Last online” timestamps. DMs no longer appear in My Posts.
- Video playback — Videos now play correctly in-app on both desktop and Android.
- On-demand blob fetch — Media attachments that haven't synced locally are fetched from peers when you view them.
- Image loading fix — Asset protocol properly configured for streaming images from disk. Fallback to IPC if asset protocol fails.
- Image lightbox — Click any image to view full-size. Escape or click to close.
- File attachments — Attach any file type to posts. Non-media files show as download buttons with a trust warning prompt.
- Audio player — Audio attachments display with native playback controls.
- Video download — Download button under video player saves to Downloads folder.
- Share link fix — Fixed redirect to `0.0.0.0` — unroutable addresses are now skipped, falling through to QUIC proxy correctly.
- TCP hole punch protocol — New wire messages (TcpPunchRequest/Result) enable direct HTTP serving from nodes to browsers, reducing proxy load on itsgoin.net.
- Tiered web serving — Share links try direct redirect to HTTP-capable post holders before falling back to QUIC proxy.

v0.3.1 — March 13, 2026

- Engagement sync — Pull sync now fetches reactions, comments, and policies from peers. Previously these only propagated via real-time push.
- Profile push fix — Name and bio changes now sent to all connected peers immediately, not just audience members.
- Auto-sync on follow — Following someone immediately pulls their posts into your feed.
- Popover UI — Notifications, diagnostics, and message threads open as overlay windows instead of inline sections.
- Notification settings — Configure message, post, and nearby-user notifications from Settings.
- Smart DM polling — Message refresh rate scales with conversation recency (5s–daily).
- Reaction display — Posts show top 5 emoji reactions + total response count.

v0.3.0 — March 12, 2026

- Full rename distsoc → ItsGoin — ALPN, crypto contexts, data paths, Android package ID all changed. Clean break — incompatible with prior versions.

v0.2.11 — March 12, 2026

- Engagement system — Reactions (public + private encrypted), inline comments with ed25519 signatures, and author-controlled comment/react policies. Full UI with emoji picker, reaction pills, and expandable comment threads.
- CDN tree for all posts — New `post_downstream` table gives every post (including text-only) a propagation tree. Engagement diffs flow through the file layer via BlobHeaderDiff (0xD0), never mesh.
- 4 new wire messages — BlobHeaderDiff (0xD0), BlobHeaderRequest/Response (0xD1/0xD2), PostDownstreamRegister (0xD3). Policy enforcement in handlers (blocklist, audience-only, permission checks).
- Thread splitting — Headers exceeding 16KB automatically split oldest comments into linked thread posts, keeping engagement propagation lightweight.

v0.2.10 — March 12, 2026

- Per-family NAT classification — IPv4 and IPv6 public reachability detected independently. Fixes false "public (v4+v6)" when only IPv6 is public, which was silently breaking IPv4 hole punches.
- STUN always runs — IPv6-only anchors now correctly probe their IPv4 NAT type instead of assuming "Public". Only `--bind` (explicit server) skips STUN.
- Anchor address fallback — Anchors without `--bind` or UPnP now advertise their public IPv6 address, so peers save them in known_anchors for preferential reconnection.
- Bootstrap deprioritization — Discovered anchors are tried before hardcoded bootstrap anchors at startup, reducing bootstrap server load as the network grows.

v0.2.9 — March 12, 2026

- ConnectionManager actor redesign — Replaced global mutex with actor pattern (ConnHandle + ConnectionActor). Network operations no longer block each other — 14 I/O code paths that previously held the lock for up to 15 seconds now run concurrently.
- 60+ call sites migrated — All network and node code uses the new lock-free ConnHandle API. Public mutex accessor removed.
- I/O extraction — Broadcast, push, pull, relay, anchor register, and address resolution all execute outside state locks.

v0.2.8 — March 11, 2026

- NAT filter probe — Anchor probes your NAT filtering type (address-restricted vs port-restricted) by attempting to reach you from a different source port. Eliminates unnecessary port scanning for the majority of connections.
- Role-based NAT traversal — Each side now takes the correct role based on its NAT profile: EIM nodes punch every 2s (stable port), EDM nodes walk outward at 100/sec (opening firewall entries). Previous burst-scan design replaced with steady ~100 ports/sec outward walk.
- IPv4 vs IPv6 public — Public reachability now distinguished by protocol family (v4 only, v6 only, v4+v6). Prevents false assumptions when only one family is public.
- Scanning cleanup — Scan tasks properly cancelled via JoinSet between attempts. Previous design spawned 37K+ fire-and-forget tasks.

v0.2.7 — March 11, 2026

- Focused port scanning — Scanning now targets only the anchor-observed IP address instead of all self-reported addresses, reducing wasted scan budget on unreachable VPN/cellular IPs.
- Scan on unknown NAT — Port scanning now triggers when peer NAT type is unknown (e.g. peer running older version), not just when explicitly EDM.

v0.2.6 — March 11, 2026

- Anchor self-verification — Nodes with public addresses now verify their reachability via cold-connect probes from N2 strangers. Two consecutive failures revoke anchor status.
- Advanced NAT traversal — Hard+hard NAT pairs are no longer skipped. Port scanning (tiered: ±500, ±2000, full ephemeral range) attempts direct connection before falling back to relay.
- NAT profile sharing — Peers exchange mapping (EIM/EDM) and filtering (open/port-restricted) classification during connection, enabling smarter hole punch decisions.
- Behavioral NAT inference — Filtering type is refined from actual connection outcomes — no unreliable upfront probing needed.

v0.2.3 — March 11, 2026

- NAT type detection — STUN probing on startup classifies your NAT as Public, Easy, or Hard. Shared with peers during connection.
- Skip futile hole punches — When both peers are behind hard/symmetric NATs, skip the 30-second hole punch attempt entirely.

March 10, 2026 (v2)

- Anchor advertised address — Anchors advertise their stable bind address in initial exchange, so peers always store the correct reconnection address.
- Observed address notification — Peers tell each other "I see you at <ip:port>" during connection — lightweight STUN-like address feedback.

March 10, 2026

- UPnP port mapping — Devices behind NAT routers automatically request a port forward via UPnP, becoming directly reachable without manual configuration.
- Auto-anchor promotion — Devices with a successful UPnP mapping self-declare as anchors, improving bootstrap diversity for all peers.
- Hole punch fix — Target-side hole punch connections were silently discarded; now properly registered as sessions so both sides of a NAT punch succeed.

February 24, 2026 (v2)

- Request Referrals button — On-demand peer referral requesting in Network Diagnostics.
- Docker bridge IP filtering — Peer introductions no longer leak Docker bridge IPs.
- Keepalive fix — Sender-side last_activity update prevents false zombie detection.
- Message threads — DM conversations grouped by partner with expandable thread view.
- Mesh/reach diagnostics — Peer cards show reach level badges (Mesh/N1/N2/N3).

February 24, 2026

- Audience request button — "Ask to join audience" on followed peers.
- DMs filtered from feed — Direct messages show only in Messages tab.
- Peer bios displayed — Bio text shown below peer names in People tab.
- People tab auto-refresh — Follows, peers, audience refresh every 10 seconds.
- Button feedback — Loading state and toast confirmation on diagnostics refresh.

February 23, 2026

- Fix connection lock contention — QUIC connect no longer blocks all tasks.
- Image attachments display — Fixed CSP blocking blob: URLs.
- Non-blocking startup — Referral connections run in background.
- Connect timeout — 15-second cap on connection attempts.
- Android foreground service — Mesh stays alive in background.

February 20, 2026

- IPv4-mapped address fix — Normalized dual-stack addresses for NAT traversal.
- Mesh keepalive — 30-second pings prevent zombie detection on idle connections.
- Audience management — Approve/Deny/Remove audience members.
- Network diagnostics overhaul — Summary grid, peer cards, connection breakdown.
- Manual rebalance — Trigger immediate mesh rebalancing from Settings.
- Reset all data — Clear local data while preserving identity key.

February 19, 2026

- Reactive mesh growth loop — New peers connect within seconds.
- Anchor matchmaking only — Anchors introduce peers, never proxy bytes.
- Parallel hole punching — NAT traversal tries all addresses simultaneously.
- Relay-observed address injection — Fixes NAT-to-NAT hole punching.
- Growth loop introduction fallback — Bilateral hole punching when direct fails.

## Help build ItsGoin

This project is open source and could use your help. Whether you're a developer, tester, or just have ideas — jump in.

Join the Discord Source code