itsgoin/website/download.html
Scott Reimers c40e093d01 v0.5.1-beta: version bump, changelog, download page update
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:06:26 -04:00

406 lines
43 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Download — ItsGoin</title>
<meta name="description" content="Download the ItsGoin app for Android and Linux. Free, open source, Apache 2.0.">
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav>
<a href="index.html" class="logo">ItsGoin</a>
<button class="menu-toggle" onclick="this.parentElement.querySelector('.links').classList.toggle('open')" aria-label="Menu">&#9776;</button>
<div class="links">
<a href="index.html">About</a>
<a href="tech.html">How It Works</a>
<a href="design.html">Design</a>
<a href="download.html" class="active">Download</a>
<a href="contribute.html">Contribute</a>
<a href="https://discord.gg/pCjMbY9PmN">Discord</a>
</div>
</nav>
<div class="container">
<section>
<h1 style="font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; margin-bottom: 0.25rem;">Download ItsGoin</h1>
<p>Available for Android and Linux. Free and open source.</p>
<h2 style="margin-top: 2rem;">Stable Release</h2>
<p style="color: var(--text-muted); font-size: 0.85rem;">Version 0.4.4 &mdash; March 23, 2026</p>
<div class="downloads">
<a href="itsgoin-0.4.4.apk" class="download-btn btn-android">
Android APK
<span class="sub">v0.4.4 stable</span>
</a>
<a href="itsgoin_0.4.4_amd64.AppImage" class="download-btn btn-linux">
Linux AppImage
<span class="sub">v0.4.4 stable</span>
</a>
</div>
<h2 style="margin-top: 2rem;">Beta Release</h2>
<p style="color: var(--text-muted); font-size: 0.85rem;">Version 0.5.1-beta &mdash; April 16, 2026</p>
<p style="color: var(--text-muted); font-size: 0.85rem;">Multi-identity, export/import, post merge with decryption key. May contain bugs &mdash; stable release recommended for daily use.</p>
<div class="downloads">
<a href="itsgoin-0.5.1-beta.apk" class="download-btn btn-android" style="border-color: var(--accent);">
Android APK
<span class="sub">v0.5.1-beta</span>
</a>
<a href="itsgoin_0.5.1-beta_amd64.AppImage" class="download-btn btn-linux" style="border-color: var(--accent);">
Linux AppImage
<span class="sub">v0.5.1-beta</span>
</a>
<a href="itsgoin-cli-0.5.1-beta-linux-amd64" class="download-btn btn-linux" style="border-color: var(--accent);">
Linux CLI / Anchor
<span class="sub">v0.5.1-beta</span>
</a>
</div>
</section>
<section>
<h2>Installation</h2>
<div class="card">
<h3 style="color: var(--accent);">Android</h3>
<ol class="steps">
<li><strong>Download the APK</strong> &mdash; Tap the button above. Your browser may warn that this type of file can be harmful &mdash; tap <strong>Download anyway</strong>.</li>
<li><strong>Open the file</strong> &mdash; When the download finishes, tap the notification or find the APK in your Downloads folder and tap it.</li>
<li><strong>Allow installation</strong> &mdash; Android will ask you to allow installs from this source. Tap <strong>Settings</strong>, toggle <strong>"Allow from this source"</strong>, then go back and tap <strong>Install</strong>.</li>
<li><strong>Launch the app</strong> &mdash; Once installed, tap <strong>Open</strong> or find ItsGoin in your app drawer.</li>
</ol>
<div class="note">
<strong>Note:</strong> If you don't see the "Allow from this source" prompt, go to <strong>Settings &rarr; Apps &rarr; Special access &rarr; Install unknown apps</strong> and enable it for your browser.
</div>
</div>
<div class="card">
<h3 style="color: var(--green);">Linux (AppImage)</h3>
<ol class="steps">
<li><strong>Download the AppImage</strong> &mdash; Click the button above to download.</li>
<li><strong>Make it executable</strong> &mdash; Open a terminal and run:<br><code>chmod +x itsgoin_*.AppImage</code></li>
<li><strong>Run it</strong> &mdash; Double-click the file, or from the terminal:<br><code>./itsgoin_*.AppImage</code></li>
</ol>
<div class="note">
<strong>Note:</strong> If it doesn't launch, you may need to install FUSE:<br><code>sudo apt install libfuse2</code> (Debian/Ubuntu) or <code>sudo dnf install fuse</code> (Fedora).
</div>
</div>
<div class="card">
<h3 style="color: var(--green);">Linux CLI / Anchor</h3>
<ol class="steps">
<li><strong>Download the binary</strong> &mdash; Click the CLI button above to download.</li>
<li><strong>Make it executable</strong> &mdash; <code>chmod +x itsgoin-cli-*</code></li>
<li><strong>Run as node</strong> &mdash; <code>./itsgoin-cli-* /path/to/data --daemon</code></li>
<li><strong>Run as anchor</strong> &mdash; <code>./itsgoin-cli-* /path/to/data --bind 0.0.0.0:4433 --daemon --web 8080</code></li>
</ol>
<div class="note">
<strong>Note:</strong> The CLI binary is the same as the anchor server. Run with <code>--help</code> for all options.
</div>
</div>
</section>
<section>
<h2>Changelog</h2>
<div class="changelog">
<div class="changelog-date">v0.5.1-beta &mdash; April 16, 2026</div>
<ul>
<li><strong>AppImage video fix</strong> &mdash; Bundled full GStreamer media framework. Video and audio now play correctly in AppImage builds (previously caused WebKit freeze due to missing plugins).</li>
<li><strong>Import fix</strong> &mdash; Imported posts now create proper BlobHeaders, visibility intents, and pinned blobs. Imported posts are indistinguishable from locally created ones.</li>
<li><strong>First-run chooser</strong> &mdash; New installs show &ldquo;Start Fresh&rdquo; or &ldquo;Import an Identity&rdquo; dialog instead of a blank profile setup.</li>
<li><strong>File pickers</strong> &mdash; Native Browse buttons on export (folder picker) and import (ZIP file picker) dialogs.</li>
<li><strong>Identity switch fix</strong> &mdash; Old node properly shut down before starting new one. Prevents zombie background tasks after multiple identity switches.</li>
<li><strong>Export path fix</strong> &mdash; Relative output paths (e.g. &ldquo;Downloads&rdquo;) resolve to home directory instead of process working directory.</li>
<li><strong>Lightbox fix</strong> &mdash; Clicking form elements inside wizards no longer closes the overlay.</li>
<li><strong>Lock contention</strong> &mdash; Three remaining handlers (pull request, address request, session relay) converted to brief-lock pattern.</li>
</ul>
<div class="changelog-date">v0.5.0-beta &mdash; April 5, 2026</div>
<ul>
<li><strong>Multi-identity</strong> &mdash; 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.</li>
<li><strong>ZIP export</strong> &mdash; 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.</li>
<li><strong>Public post import</strong> &mdash; Import public posts from another identity's export ZIP into your current identity. Creates new PostIds under your author, preserving original timestamps.</li>
<li><strong>Merge with decryption key</strong> &mdash; 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.</li>
<li><strong>Import as new identity</strong> &mdash; Import a ZIP containing an identity key as a new identity. Creates the identity subdir; switch to it to access the data.</li>
<li><strong>Hole punch address filtering</strong> &mdash; Relay introductions now filter by address family (IPv4/IPv6) and exclude LAN-only addresses for remote peers.</li>
<li><strong>Sync pipeline fixes</strong> &mdash; Per-peer sync resets last_sync_ms before pulling (fixes stale sync). ManifestPush now fetches blobs after discovering new posts.</li>
</ul>
<div class="changelog-date">v0.4.4 &mdash; March 23, 2026</div>
<ul>
<li><strong>UI overhaul</strong> &mdash; 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.</li>
<li><strong>Tab icons</strong> &mdash; Icons visible on both desktop (inline with text) and mobile (stacked above text).</li>
<li><strong>Safe area insets</strong> &mdash; Header pads below phone notch/camera cutout. Bottom nav pads above home indicator.</li>
<li><strong>Profiles lightbox</strong> &mdash; Name, bio, visibility, and circle profiles now in a lightbox from My Posts instead of settings.</li>
<li><strong>Redundancy lightbox</strong> &mdash; Post replication stats in a lightbox from My Posts.</li>
<li><strong>Diagnostics reorganized</strong> &mdash; Sync All and Stored Anchors moved into Network Diagnostics popover. Opened by clicking the network indicator. Buttons centered in rows.</li>
<li><strong>Settings streamlined</strong> &mdash; Removed profile editor, diagnostics button, sync button, redundancy panel, and anchor management from settings.</li>
<li><strong>Lightbox close on tab switch</strong> &mdash; Any open lightbox/overlay closes when switching tabs.</li>
</ul>
<div class="changelog-date">v0.4.3 &mdash; March 22, 2026</div>
<ul>
<li><strong>Lock contention overhaul</strong> &mdash; 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.</li>
<li><strong>StoragePool</strong> &mdash; 8 concurrent SQLite connections in WAL mode replace the single Mutex. Reads run fully parallel; writes serialize only at the SQLite level.</li>
<li><strong>Initial exchange fix</strong> &mdash; Failed initial exchanges now abort the mesh upgrade instead of silently continuing with a broken connection.</li>
<li><strong>Connect timeout</strong> &mdash; connect_to_peer and connect_to_anchor now use a consistent 15s timeout. ResolveAddress adds 5s per-query timeout (was unbounded).</li>
<li><strong>Worm cascade unlock</strong> &mdash; WormLookup, ContentSearch, and WormQuery use connection snapshots for lock-free fan-out.</li>
<li><strong>Bottom nav bar</strong> &mdash; Mobile/tablet (&le;768px) gets a fixed bottom navigation bar with icon tabs. Desktop keeps the top tab bar.</li>
<li><strong>Text size update</strong> &mdash; Five options: XS (75%), S (100%), M (125% default), L (150%), XL (200%). Persisted to localStorage for instant restore on startup.</li>
<li><strong>Startup fix</strong> &mdash; Fixed blocking_lock panic that prevented app from launching (async runtime conflict). StoragePool reduced to 4 connections for Android compatibility.</li>
<li><strong>Keepalive fix</strong> &mdash; Mesh keepalive pings were never firing due to timer reset bug in select loop. Connections were being zombie-reaped instead of kept alive.</li>
<li><strong>Auto-reconnect</strong> &mdash; Unexpected disconnects now trigger immediate reconnect attempt (3s delay, then direct connect to last known address). Falls back to growth loop if direct fails.</li>
<li><strong>Tab icon fix</strong> &mdash; Badge updates were destroying tab icons on mobile. Now updates label and badge separately.</li>
<li><strong>Video playback</strong> &mdash; Feed re-render skipped while video/audio is playing to prevent echo and restart.</li>
</ul>
<div class="changelog-date">v0.4.2 &mdash; March 22, 2026</div>
<ul>
<li><strong>Welcome screen</strong> &mdash; Startup shows &ldquo;How&rsquo;s it goin?&rdquo; with staggered counters (connections, posts, messages, reacts, comments) while the backend bootstraps. Replaces the blank-screen wait.</li>
<li><strong>Status ticker</strong> &mdash; Header ticker shows new posts, messages, reactions, comments, and connection state changes as they arrive.</li>
<li><strong>Notification improvements</strong> &mdash; Tauri plugin &rarr; Web Notification API &rarr; notify-rust fallback chain. Linux native desktop notifications now work.</li>
<li><strong>Responsive text scaling</strong> &mdash; Small/Normal/Large text size (100%/150%/200%), persisted via settings. Default bumped to Normal (150%).</li>
<li><strong>Diagnostics popover</strong> &mdash; Network diagnostics moved from inline section to overlay popover. Connections loaded on-demand. Timer countdowns removed.</li>
<li><strong>Share details lightbox</strong> &mdash; QR code + connect string in a modal overlay from People tab.</li>
<li><strong>Connect string improvement</strong> &mdash; Prefers external address (UPnP/public IPv6/observed) over local bind address.</li>
<li><strong>Stale N1 fix</strong> &mdash; Disconnected social routes excluded from N1 share. Prevents dead nodes appearing online to peers.</li>
<li><strong>Replication handler fix</strong> &mdash; Actively fetches posts + blobs from requester after accepting replication. Previously relied on pull cycle which doesn&rsquo;t work for infrastructure nodes.</li>
<li><strong>Hole punch fix</strong> &mdash; Target-side registers publicly routable remote address for relay introduction. Fixes address injection for subsequent connections.</li>
<li><strong>Replication semaphore</strong> &mdash; Concurrent replication handlers capped at 3 to prevent overload.</li>
<li><strong>Peer labels</strong> &mdash; Display names now show truncated node ID for disambiguation.</li>
</ul>
<div class="changelog-date">v0.4.1 &mdash; March 21, 2026</div>
<ul>
<li><strong>Security: Reaction signatures</strong> &mdash; Reactions now carry ed25519 signatures. Forged reactions from other NodeIds are rejected. Backward-compatible with unsigned reactions from older nodes.</li>
<li><strong>Security: Comment signature verification</strong> &mdash; Comment signatures (already present) are now verified on receipt. Forged comments rejected.</li>
<li><strong>Security: Reaction removal auth</strong> &mdash; Only the reactor or post author can remove reactions. Previously any peer could strip reactions.</li>
<li><strong>Security: BlobHeader author verification</strong> &mdash; Header rebuild verifies author against stored post, not trusted from payload.</li>
<li><strong>Lock contention: ManifestPush discovery</strong> &mdash; cm lock released before PostFetch network I/O. Was holding lock during entire discovery (5s+ freeze).</li>
<li><strong>Lock contention: Pull request handler</strong> &mdash; Load posts under lock, filter without lock, brief re-lock for is_deleted. Was holding lock during full post list iteration.</li>
<li><strong>Lock contention: Pull sender</strong> &mdash; Split into two brief locks (store, then batch upstream+sync). Was holding one long lock for all operations.</li>
<li><strong>Lock contention: Engagement checker</strong> &mdash; Batch writes per chunk with single lock. Was acquiring lock per post (100+ times).</li>
<li><strong>Data cleanup</strong> &mdash; Post deletion now cleans up post_downstream, post_upstream, and seen_engagement tables.</li>
</ul>
<div class="changelog-date">v0.4.0 &mdash; March 21, 2026</div>
<ul>
<li><strong>Protocol v4: Header-driven sync</strong> &mdash; Major sync protocol revision. ManifestPush now triggers post discovery from CDN tree headers. Bandwidth reduced ~90% for established nodes.</li>
<li><strong>Slim PullSyncRequest</strong> &mdash; Per-author timestamps replace full post ID lists. Request size drops from O(posts) to O(follows). Backward-compatible with v3 peers.</li>
<li><strong>Tiered pull frequency</strong> &mdash; Pull cycle checks every 60s but only syncs stale authors (4-hour default). Full pull only on first tick. Most ticks do nothing.</li>
<li><strong>Tiered engagement checks</strong> &mdash; Engagement polling frequency scales with content age: 5min (&lt;72h), 1hr (3-14d), 4hr (14-30d), 24hr (&gt;30d). Single SQL query filters due posts.</li>
<li><strong>Header-driven post discovery</strong> &mdash; ManifestPush triggers PostFetch for missing followed-author posts (capped at 10 per manifest). CDN tree becomes the notification system.</li>
<li><strong>Multi-upstream (3 max)</strong> &mdash; Posts track up to 3 upstream sources with priority ordering. Engagement diffs sent to all upstreams. Fallback on upstream failure.</li>
<li><strong>Lock contention fixes</strong> &mdash; 6 hot paths optimized: get_blob_for_post (3&rarr;1 locks), prefetch (lock-free blob checks), serve_post (4&rarr;2 locks), badge cycle (N+2&rarr;1 IPC call).</li>
</ul>
<div class="changelog-date">v0.3.6 &mdash; March 20, 2026</div>
<ul>
<li><strong>Network indicator</strong> &mdash; Header shows connection status dot (black/red/yellow/green for 0/1/2-10/11+ connections) with capability labels (Public, Server).</li>
<li><strong>Tab badges</strong> &mdash; Feed shows new post count, My Posts shows new engagement count, People shows online count, Messages shows unread conversation count. Numbers only, no labels.</li>
<li><strong>Message read tracking</strong> &mdash; Conversations marked as read on open, close, and send. Prevents re-notification of already-seen messages.</li>
<li><strong>Active CDN replication</strong> &mdash; All devices proactively request replication of their recent posts (&lt;72h) to connected peers. Targets prioritized: desktops &gt; anchors &gt; phones. Graceful with small networks (1 peer = 1 replica). ReplicationRequest/Response (0xE1/0xE2) wire messages.</li>
<li><strong>Device roles</strong> &mdash; Nodes classified as Intermittent (phones), Available (desktops), or Persistent (anchors). Advertised in InitialExchange. Influences replication target selection and budget defaults.</li>
<li><strong>Bandwidth budgets</strong> &mdash; 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.</li>
<li><strong>Cache management</strong> &mdash; 1GB default cache limit (configurable 256MB&ndash;unlimited). Eviction cycle now active (was implemented but never started). Priority scoring with share-link boost (+100 for 3+ downstream). Cache pressure score (0&ndash;255) for future budget advertisement.</li>
<li><strong>Engagement distribution fix</strong> &mdash; 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.</li>
<li><strong>Tombstone system</strong> &mdash; Deleted reactions/comments are tombstoned (<code>deleted_at</code> timestamp) instead of hard-deleted. Tombstones propagate through pull sync, ensuring deletes reach peers that missed the real-time diff.</li>
<li><strong>Persistent notifications</strong> &mdash; Notification tracking backed by <code>seen_engagement</code> and <code>seen_messages</code> tables. Only notifies on genuinely unseen content. Survives app restarts.</li>
<li><strong>DOS hardening</strong> &mdash; 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.</li>
<li><strong>Pull preference</strong> &mdash; Blob fetches prefer non-anchor sources (phones &gt; desktops &gt; replicas &gt; anchors) to preserve anchor delivery budget for web requests.</li>
</ul>
<div class="changelog-date">v0.3.5 &mdash; March 20, 2026</div>
<ul>
<li><strong>Private blob encryption</strong> &mdash; 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.</li>
<li><strong>Blob prefetch on sync</strong> &mdash; When posts are pulled from peers, their attachments are eagerly fetched for offline availability. Previously blobs were only fetched on view.</li>
<li><strong>Crypto refactoring</strong> &mdash; Extracted reusable primitives: <code>encrypt_bytes_with_cek</code>, <code>decrypt_bytes_with_cek</code>, <code>unwrap_cek_for_recipient</code>, <code>unwrap_group_cek</code>. Foundation for encrypted blob storage and future chunk-level encryption.</li>
<li><strong>Intent-based post filtering</strong> &mdash; Feed, My Posts, and Messages now filter on the author's original visibility intent (<code>intentKind</code>) rather than encryption state.</li>
<li><strong>Encrypted receipt slots</strong> &mdash; Private messages get encrypted receipt and comment slots in BlobHeader. Delivery indicators, read receipts, and message reactions.</li>
<li><strong>Download filename sanitization</strong> &mdash; Prevents path traversal in downloaded file names.</li>
</ul>
<div class="changelog-date">v0.3.4 &mdash; March 18, 2026</div>
<ul>
<li><strong>Comment edit &amp; delete</strong> &mdash; Edit or delete your own comments. Trust-based: post authors can also delete comments on their posts. Propagates via BlobHeaderDiff to all holders.</li>
<li><strong>Native notifications</strong> &mdash; System notifications via Tauri plugin (works on all platforms). Notifications for messages, new posts, reactions, and comments. Configurable in Settings with button-group toggles.</li>
<li><strong>Forward-compatible protocol</strong> &mdash; Unknown BlobHeaderDiffOp variants are silently ignored instead of crashing deserialization. Prevents old nodes from breaking when new features are added.</li>
<li><strong>Following: Online/Offline</strong> &mdash; Self removed from following list. Offline follows hidden behind lightbox popup. Shows expanded if no one is online.</li>
<li><strong>DM filter fix</strong> &mdash; Sent direct messages no longer appear in My Posts tab.</li>
<li><strong>Comment threading fix</strong> &mdash; Comments now work correctly in My Posts tab (duplicate element ID scoping fix).</li>
<li><strong>Dropdown text fix</strong> &mdash; Select dropdowns across the app now have legible text in WebKitGTK native popups.</li>
</ul>
<div class="changelog-date">v0.3.3 &mdash; March 16, 2026</div>
<ul>
<li><strong>IPv6 HTTP address fix</strong> &mdash; Nodes with public IPv6 now correctly advertise their real address for direct browser access, instead of <code>0.0.0.0</code>. Fixes share link video/image serving for IPv6-reachable nodes.</li>
<li><strong>Video preload fix</strong> &mdash; Share link videos and in-app videos from peers now buffer properly for playback (<code>preload="auto"</code>). Previously only the first frame loaded.</li>
<li><strong>Connection rate limiting</strong> &mdash; 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.</li>
<li><strong>Schema versioning</strong> &mdash; Database tracks schema version via <code>PRAGMA user_version</code>. Future upgrades can run data migrations automatically. Databases too old to migrate are reset cleanly.</li>
<li><strong>N2/N3 freshness</strong> &mdash; TTL reduced from 7 days to 5 hours. Full N1/N2 state re-broadcast every 4 hours catches missed diffs.</li>
<li><strong>Bootstrap isolation recovery</strong> &mdash; 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.</li>
<li><strong>Following: Online/Offline</strong> &mdash; People tab splits followed peers into Online and Offline sections with &ldquo;Last online&rdquo; timestamps.</li>
<li><strong>DM filter</strong> &mdash; Direct messages no longer appear in My Posts tab.</li>
<li><strong>Bidirectional engagement propagation</strong> &mdash; 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.</li>
<li><strong>Auto downstream registration</strong> &mdash; 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.</li>
<li><strong>Upstream tracking</strong> &mdash; New <code>post_upstream</code> table records which peer each post was received from, enabling engagement to flow back toward the author hop-by-hop through the CDN tree.</li>
<li><strong>N2/N3 freshness</strong> &mdash; 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.</li>
<li><strong>Bootstrap isolation recovery</strong> &mdash; 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.</li>
<li><strong>Following: Online/Offline</strong> &mdash; People tab splits followed peers into Online and Offline sections with &ldquo;Last online&rdquo; timestamps. DMs no longer appear in My Posts.</li>
<li><strong>Video playback</strong> &mdash; Videos now play correctly in-app on both desktop and Android.</li>
<li><strong>On-demand blob fetch</strong> &mdash; Media attachments that haven't synced locally are fetched from peers when you view them.</li>
<li><strong>Image loading fix</strong> &mdash; Asset protocol properly configured for streaming images from disk. Fallback to IPC if asset protocol fails.</li>
<li><strong>Image lightbox</strong> &mdash; Click any image to view full-size. Escape or click to close.</li>
<li><strong>File attachments</strong> &mdash; Attach any file type to posts. Non-media files show as download buttons with a trust warning prompt.</li>
<li><strong>Audio player</strong> &mdash; Audio attachments display with native playback controls.</li>
<li><strong>Video download</strong> &mdash; Download button under video player saves to Downloads folder.</li>
<li><strong>Share link fix</strong> &mdash; Fixed redirect to <code>0.0.0.0</code> &mdash; unroutable addresses are now skipped, falling through to QUIC proxy correctly.</li>
<li><strong>TCP hole punch protocol</strong> &mdash; New wire messages (TcpPunchRequest/Result) enable direct HTTP serving from nodes to browsers, reducing proxy load on itsgoin.net.</li>
<li><strong>Tiered web serving</strong> &mdash; Share links try direct redirect to HTTP-capable post holders before falling back to QUIC proxy.</li>
</ul>
<div class="changelog-date">v0.3.1 &mdash; March 13, 2026</div>
<ul>
<li><strong>Engagement sync</strong> &mdash; Pull sync now fetches reactions, comments, and policies from peers. Previously these only propagated via real-time push.</li>
<li><strong>Profile push fix</strong> &mdash; Name and bio changes now sent to all connected peers immediately, not just audience members.</li>
<li><strong>Auto-sync on follow</strong> &mdash; Following someone immediately pulls their posts into your feed.</li>
<li><strong>Popover UI</strong> &mdash; Notifications, diagnostics, and message threads open as overlay windows instead of inline sections.</li>
<li><strong>Notification settings</strong> &mdash; Configure message, post, and nearby-user notifications from Settings.</li>
<li><strong>Smart DM polling</strong> &mdash; Message refresh rate scales with conversation recency (5s&ndash;daily).</li>
<li><strong>Reaction display</strong> &mdash; Posts show top 5 emoji reactions + total response count.</li>
</ul>
<div class="changelog-date">v0.3.0 &mdash; March 12, 2026</div>
<ul>
<li><strong>Full rename distsoc &rarr; ItsGoin</strong> &mdash; ALPN, crypto contexts, data paths, Android package ID all changed. Clean break &mdash; incompatible with prior versions.</li>
</ul>
<div class="changelog-date">v0.2.11 &mdash; March 12, 2026</div>
<ul>
<li><strong>Engagement system</strong> &mdash; 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.</li>
<li><strong>CDN tree for all posts</strong> &mdash; New <code>post_downstream</code> table gives every post (including text-only) a propagation tree. Engagement diffs flow through the file layer via BlobHeaderDiff (0xD0), never mesh.</li>
<li><strong>4 new wire messages</strong> &mdash; BlobHeaderDiff (0xD0), BlobHeaderRequest/Response (0xD1/0xD2), PostDownstreamRegister (0xD3). Policy enforcement in handlers (blocklist, audience-only, permission checks).</li>
<li><strong>Thread splitting</strong> &mdash; Headers exceeding 16KB automatically split oldest comments into linked thread posts, keeping engagement propagation lightweight.</li>
</ul>
<div class="changelog-date">v0.2.10 &mdash; March 12, 2026</div>
<ul>
<li><strong>Per-family NAT classification</strong> &mdash; IPv4 and IPv6 public reachability detected independently. Fixes false "public (v4+v6)" when only IPv6 is public, which was silently breaking IPv4 hole punches.</li>
<li><strong>STUN always runs</strong> &mdash; IPv6-only anchors now correctly probe their IPv4 NAT type instead of assuming "Public". Only <code>--bind</code> (explicit server) skips STUN.</li>
<li><strong>Anchor address fallback</strong> &mdash; Anchors without <code>--bind</code> or UPnP now advertise their public IPv6 address, so peers save them in known_anchors for preferential reconnection.</li>
<li><strong>Bootstrap deprioritization</strong> &mdash; Discovered anchors are tried before hardcoded bootstrap anchors at startup, reducing bootstrap server load as the network grows.</li>
</ul>
<div class="changelog-date">v0.2.9 &mdash; March 12, 2026</div>
<ul>
<li><strong>ConnectionManager actor redesign</strong> &mdash; Replaced global mutex with actor pattern (ConnHandle + ConnectionActor). Network operations no longer block each other &mdash; 14 I/O code paths that previously held the lock for up to 15 seconds now run concurrently.</li>
<li><strong>60+ call sites migrated</strong> &mdash; All network and node code uses the new lock-free ConnHandle API. Public mutex accessor removed.</li>
<li><strong>I/O extraction</strong> &mdash; Broadcast, push, pull, relay, anchor register, and address resolution all execute outside state locks.</li>
</ul>
<div class="changelog-date">v0.2.8 &mdash; March 11, 2026</div>
<ul>
<li><strong>NAT filter probe</strong> &mdash; 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.</li>
<li><strong>Role-based NAT traversal</strong> &mdash; 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.</li>
<li><strong>IPv4 vs IPv6 public</strong> &mdash; Public reachability now distinguished by protocol family (v4 only, v6 only, v4+v6). Prevents false assumptions when only one family is public.</li>
<li><strong>Scanning cleanup</strong> &mdash; Scan tasks properly cancelled via JoinSet between attempts. Previous design spawned 37K+ fire-and-forget tasks.</li>
</ul>
<div class="changelog-date">v0.2.7 &mdash; March 11, 2026</div>
<ul>
<li><strong>Focused port scanning</strong> &mdash; Scanning now targets only the anchor-observed IP address instead of all self-reported addresses, reducing wasted scan budget on unreachable VPN/cellular IPs.</li>
<li><strong>Scan on unknown NAT</strong> &mdash; Port scanning now triggers when peer NAT type is unknown (e.g. peer running older version), not just when explicitly EDM.</li>
</ul>
<div class="changelog-date">v0.2.6 &mdash; March 11, 2026</div>
<ul>
<li><strong>Anchor self-verification</strong> &mdash; Nodes with public addresses now verify their reachability via cold-connect probes from N2 strangers. Two consecutive failures revoke anchor status.</li>
<li><strong>Advanced NAT traversal</strong> &mdash; Hard+hard NAT pairs are no longer skipped. Port scanning (tiered: &plusmn;500, &plusmn;2000, full ephemeral range) attempts direct connection before falling back to relay.</li>
<li><strong>NAT profile sharing</strong> &mdash; Peers exchange mapping (EIM/EDM) and filtering (open/port-restricted) classification during connection, enabling smarter hole punch decisions.</li>
<li><strong>Behavioral NAT inference</strong> &mdash; Filtering type is refined from actual connection outcomes &mdash; no unreliable upfront probing needed.</li>
</ul>
<div class="changelog-date">v0.2.3 &mdash; March 11, 2026</div>
<ul>
<li><strong>NAT type detection</strong> &mdash; STUN probing on startup classifies your NAT as Public, Easy, or Hard. Shared with peers during connection.</li>
<li><strong>Skip futile hole punches</strong> &mdash; When both peers are behind hard/symmetric NATs, skip the 30-second hole punch attempt entirely.</li>
</ul>
<div class="changelog-date">March 10, 2026 (v2)</div>
<ul>
<li><strong>Anchor advertised address</strong> &mdash; Anchors advertise their stable bind address in initial exchange, so peers always store the correct reconnection address.</li>
<li><strong>Observed address notification</strong> &mdash; Peers tell each other "I see you at &lt;ip:port&gt;" during connection &mdash; lightweight STUN-like address feedback.</li>
</ul>
<div class="changelog-date">March 10, 2026</div>
<ul>
<li><strong>UPnP port mapping</strong> &mdash; Devices behind NAT routers automatically request a port forward via UPnP, becoming directly reachable without manual configuration.</li>
<li><strong>Auto-anchor promotion</strong> &mdash; Devices with a successful UPnP mapping self-declare as anchors, improving bootstrap diversity for all peers.</li>
<li><strong>Hole punch fix</strong> &mdash; Target-side hole punch connections were silently discarded; now properly registered as sessions so both sides of a NAT punch succeed.</li>
</ul>
<div class="changelog-date">February 24, 2026 (v2)</div>
<ul>
<li><strong>Request Referrals button</strong> &mdash; On-demand peer referral requesting in Network Diagnostics.</li>
<li><strong>Docker bridge IP filtering</strong> &mdash; Peer introductions no longer leak Docker bridge IPs.</li>
<li><strong>Keepalive fix</strong> &mdash; Sender-side last_activity update prevents false zombie detection.</li>
<li><strong>Message threads</strong> &mdash; DM conversations grouped by partner with expandable thread view.</li>
<li><strong>Mesh/reach diagnostics</strong> &mdash; Peer cards show reach level badges (Mesh/N1/N2/N3).</li>
</ul>
<div class="changelog-date">February 24, 2026</div>
<ul>
<li><strong>Audience request button</strong> &mdash; "Ask to join audience" on followed peers.</li>
<li><strong>DMs filtered from feed</strong> &mdash; Direct messages show only in Messages tab.</li>
<li><strong>Peer bios displayed</strong> &mdash; Bio text shown below peer names in People tab.</li>
<li><strong>People tab auto-refresh</strong> &mdash; Follows, peers, audience refresh every 10 seconds.</li>
<li><strong>Button feedback</strong> &mdash; Loading state and toast confirmation on diagnostics refresh.</li>
</ul>
<div class="changelog-date">February 23, 2026</div>
<ul>
<li><strong>Fix connection lock contention</strong> &mdash; QUIC connect no longer blocks all tasks.</li>
<li><strong>Image attachments display</strong> &mdash; Fixed CSP blocking blob: URLs.</li>
<li><strong>Non-blocking startup</strong> &mdash; Referral connections run in background.</li>
<li><strong>Connect timeout</strong> &mdash; 15-second cap on connection attempts.</li>
<li><strong>Android foreground service</strong> &mdash; Mesh stays alive in background.</li>
</ul>
<div class="changelog-date">February 20, 2026</div>
<ul>
<li><strong>IPv4-mapped address fix</strong> &mdash; Normalized dual-stack addresses for NAT traversal.</li>
<li><strong>Mesh keepalive</strong> &mdash; 30-second pings prevent zombie detection on idle connections.</li>
<li><strong>Audience management</strong> &mdash; Approve/Deny/Remove audience members.</li>
<li><strong>Network diagnostics overhaul</strong> &mdash; Summary grid, peer cards, connection breakdown.</li>
<li><strong>Manual rebalance</strong> &mdash; Trigger immediate mesh rebalancing from Settings.</li>
<li><strong>Reset all data</strong> &mdash; Clear local data while preserving identity key.</li>
</ul>
<div class="changelog-date">February 19, 2026</div>
<ul>
<li><strong>Reactive mesh growth loop</strong> &mdash; New peers connect within seconds.</li>
<li><strong>Anchor matchmaking only</strong> &mdash; Anchors introduce peers, never proxy bytes.</li>
<li><strong>Parallel hole punching</strong> &mdash; NAT traversal tries all addresses simultaneously.</li>
<li><strong>Relay-observed address injection</strong> &mdash; Fixes NAT-to-NAT hole punching.</li>
<li><strong>Growth loop introduction fallback</strong> &mdash; Bilateral hole punching when direct fails.</li>
</ul>
</div>
</section>
<section>
<h2>Help build ItsGoin</h2>
<p>This project is open source and could use your help. Whether you're a developer, tester, or just have ideas &mdash; jump in.</p>
<p style="margin-top: 0.75rem;">
<a href="https://discord.gg/pCjMbY9PmN" class="btn btn-primary" style="margin-right: 0.5rem;">Join the Discord</a>
<a href="https://git.itsgoin.net/Sologretto/itsgoin" class="btn btn-secondary">Source code</a>
</p>
</section>
</div>
<footer>
<p>ItsGoin &mdash; Apache 2.0 License &mdash; <a href="https://itsgoin.com">itsgoin.com</a> &middot; <a href="https://discord.gg/pCjMbY9PmN">Discord</a> &middot; <a href="https://git.itsgoin.net/Sologretto/itsgoin">Source Code</a></p>
</footer>
</body>
</html>