Q3 Development Overview
By DeHub Team — 2026-08-22
A quarter of shipping
Since the start of July we merged more than 900 changes across three repositories: dehubweb (642 commits), dehub-stream-backend (52) and dehub-mobile (221). The web repository went public on July 17 under an MIT licence (3d84d06714), so every line ships in the open. This round-up covers every distinct piece of work — not just the highlights — and carries its most relevant commit so you can read along.
Stages became the product
Stages began the quarter as a live audio room. It ends it as a broadcast stack:
- Hosts schedule stages and announce them (ff1343f1dc, mobile ca97c9366c), on a foundation that added reminders, guest listening, short invite links and per-stage share cards (b60fef88ec).
- Everyone who set a reminder is alerted the moment a stage goes live (fc8b163ccf) — and again when it is starting soon (6dc9f62b07).
- The announcement card shows who is waiting (6aaae602af) and reminder faces sit right on the deep-link page (04b36e5984).
- Stage pages run full width with an ad slot and latest posts beneath (916a60f6a8, c92423d069), land you on a tab that has something in it (f410e2f5c2), and say which timezone a scheduled time is in (a24d758d85).
- Covers got one treatment everywhere, 16:9 and never cropped (92a267b044), shown whole rather than as a crop (0ae5c506ca) and sized for share cards on live rooms too (d900b9c8c7).
- Stage cards carry the host avatar and handle back to their profile, behind a glass reminder button (03020ff72f).
- Going live no longer needs OBS: hosts broadcast straight from the browser camera (1e140f5295) and share their screen mid-room (53268ed328), sized for whatever device it lands on.
- The audience talks back in stage chat (#359), reads live subtitles (#364) translated into the languages the room is reading (#369), and can hear the whole stage dubbed live in the host's own voice — paid in DHB by the minute (#372), running on a tab so it survives leaving the room (#375), billed to the wallet rather than a credit balance (#378), and kept out of the entry bundle so joining stays light (#389).
- Hosts put a radio station on air (#379) or play their own music clips between conversations (#382).
- Early arrivals are seated in the live crowd before the room opens (6ae8b746e0), and the ended-room state was rebuilt around a Hosting tab (#346).
- Every stage records. The upload shows as a corner toast with the preloader (#331); recordings play from the same corner player everywhere (#360) including straight off the card they appear on (#368); they seek properly on Android (#422) and match web playback on mobile (mobile #162), encoded as real AAC instead of a fake MP4 (mobile #165). A parked page can no longer lose the recording (#329), only the host can delete one (#325), and the upload is labelled after its true format (#420), with a speed control on playback (#428). Mobile recordings are remuxed so they seek too (#471), and any recording reposts straight from the share sheet (#429).
- Stage links keep working after the stage ends (#363): they unfurl for crawlers, mute state persists, wallet comparisons are case-insensitive, and the short invite form shares from inside a running room too (5b2768e5e6), and the share sheet grew a repost action (#429).
- Moderation moved into the admin panel (backend #109), proxied through the service that actually holds the key (backend #114, #404), with the audit trail restored behind every action (backend #110). Super admins can set a stage's listen count directly (#416, backend #115).
- Stage writes are authenticated behind a publisher token gate (#324), hardened before it ever reached deploy (#330), and the room survived the old token service's retirement by recounting without the RPC (#328, mirrored on mobile in mobile #147).
AI moved into every corner
The assistant
- @assistant exists: an assistant tool API and chat bot landed on the backend (backend #72), answering mentions in posts and comments (backend #73) only after re-checking the post on a fresh read (backend #74), pointed at the real @assistant account (backend #75).
- On the web it got real tools instead of keyword guessing (b691e62062), receives your actual token rather than a self-declared address (60bd056028), kept a local fallback until the API side was live (596c887506), and recognises the real @assistant account everywhere (8d066e1207, mobile ea7bb89d08).
- It answers visibly in comment threads (80eb82febd, mobile 23faa4726f), joined mobile live chat with live data (14ffa299bb, auth token attached (8193b130a5)), keeps working when an image is attached (ec8b41b72a), surfaces real image-generation errors (#333), knows about Last Chad Standing (71d6c3f44f), and stopped answering week-old mentions through the legacy fallback (#370). The backend exposes a model endpoint and says so when it has none (backend #111).
- Support tickets filed through the assistant are mailed to dev@dehub.io (backend #106, f22485e94d), carry real facts about your session (backend #108), have somewhere to go once filed (backend #107), and cannot flood the inbox during an outage (backend #108).
- An MCP server edge function was restored (76a589e1f9), its tool payloads fully typed (539417372a) so handlers call the endpoints the API actually has (141e36cf80), with LiveStream injected into the toolset on the backend (backend #86). The ai_agents table underneath got a migration that is safe to replay (a08b2c5e15), an ownership column its policies can actually match (d33e0dbbbd), and a service-role policy scoped to service_role (393a4e0f87).
Creator Studio v2
- A native generation studio arrived with a Canva-style editor and a shared render queue across surfaces (cdbd24dabb), with the studio composer as the only prompt bar on /creator (49e4bd1d51) and sticky behaviour that actually sticks (1ef900835a).
- Audio mode landed on ElevenLabs voices (9b23618195), and 3D model generation shipped with an expanded model catalogue (92782d2b4b) behind a viewer hardened against WebGL failure and display drift (77e1a9c405, recovering restored GL contexts (461034db7e)).
- A free asset library opened inside the editor (bdefb38d0e), scoped per wallet with renders claimable across tabs (0b8cf4c96f).
- Pricing was rebanded around video-first model tiers with the Creator tier listed (6e41941d31), the creator marquee rebuilt from the real model catalogs (b50d67bbd7), and generation routed through kie.ai at a 20% markup (5f84971a7e).
Credits and translation
- AI credits became real and are denominated in DHB (0eb7496bf0): a starter grant plus daily accrual claimed on sign-in makes free credit reachable (49333e63bd), pay-as-you-go runs alongside it with the replay window closed (87777465f8), credit has a place to be bought (bcf428963c), and the edge-function auth check behind it all was made real while finishing the credit migration (0ef77c093e).
- The feed auto-translates into your language without gating on a wallet, with spend capped (85154309fd). Under the hood: translations persist server-side and Gemini is called directly (333cf42591), fal acts as a paid fallback between Gemini and the gateway (a833f4af70), retired models are walked down a list instead of failing (6e74ca7022), every locale is named in the prompt with failure caching stopped (d90a456598), nobody pays to translate text into its own language (44dd1f59f6), emoji render on desktop while images translate into the chosen language (198fb5c83b), and translation never blocks page load (f2cbd3d1fc). Mobile matches web for public content (mobile 719d8f2aa9).
Posters went free
- Brand graphics are drawn by a deterministic SM Template 2.0 renderer built on brand-kit assets and resvg rather than charging for diffusion renders (1323a3a2ee). It gained a column-based layout so headlines fit and wrap off the hero (6acc7152fd), LLM spec fields coerced defensively (7c04276493), retries that stop hiding when they give up (#326), HUD badges pinned to one inset on all four sides (#418), heroes standing inside the frame again (#384, #383), and headline leaks fixed (a28deb77fd).
- CPU-safe pixel budgets were tuned per size: 960px canvases with lighter blurs for square/portrait (723115f846), gradient ellipses replacing gaussian shadows with landscape-only grain (11211a8f94), portrait standardised at 864x1080 (0ad1e45b63).
- Poster Studio now defaults to on-brand templates instead of diffusion scenes (6df26d792a), DeHub banners became free everywhere (#327, mobile #146 stopped charging on phones too), and the dehub-poster skill moved onto SM Template 2.0 (#367).
- Every blog banner was re-rendered in the v2 style (#366), along with every per-route OG card (#365), and the in-app banner renderer itself came up to design language v2 (#343).
Ten themes, each a full skin
The platform now ships ten appearance themes — Light, Minimal, Cosmic, Hazy Nights, Swarms, Lava Lamp, Winter, War, Osaka and Jungle. Three of those landed this quarter:
- War wraps the interface in a tactical HUD (5bd68b529a), bound to every surface that was missing it (6fda089b63).
- Osaka is rain-on-glass neon (89e2762c9b): a backplate that retries before falling back (ed6fbcf0e9, daa21f5cc9), sparse splash pops and drying wipe streaks (0fd4062371), holographic rail CTAs replaced with liquid glass (b5da25ba85, b29f6746a2), coverage finished through hover-at-rest states (56d49303f1), plus dedicated fixes for media letterboxing (7762efbcac), post panels (b15777f4eb), focus rings (35074942c1), page backgrounds (e1ac44a278) and rain/bento geometry (ad0d82f8a2).
- Jungle rebuilds the chrome as carved wood under a walkable WebGL canopy trail (de391bdffe), rebuilt flat-shaded low-poly with local wind (1515a21a9b), real depth recovered from a material that hid it (fc02ccb029), a camera that started inside the terrain (87c5fe92f3) and a denser thicket shot from blade height (5b83b3c37a), with fixed elements no longer reparented and planks no longer stacking (0e882bee63).
The rest of them got deeper this quarter:
- Theme-specific 3D icon sets shipped (c2e4386be9), themed page-title icons were completed (2b23087d10), and empty and not-found states carry themed icons (4bc6333b0b).
- The reaction picker got proper glass styling (0fecf6b7a1), switch knobs read correctly on every theme (f38c941c40), signing out restores your default system theme (ee17ae074f), light/minimal no longer flash black sidebar boxes at boot (e71a8ddda9), canvas themes stopped painting a black column over the post layer (81e0a12808), and animated backgrounds cap at 60fps with reduced-motion honoured for lavalamp and ambient animation generally (383474547d, 5ba9ae3fdb).
The arcade opened
A dedicated Arcade section landed at dehub.io/arcade (e45393f6f0), promoted up the nav alongside Prompt (231631147e), with a monochrome System Arcade icon (be2996a22b) and its own share cards for the section and every game (bb335f2aae).
- King's Gambit grew an online lobby with live boards (bd9a85e00b), match tables refereed end to end (4707f0c16c), challengers shown as people not addresses (71d0de2dc8), an upstream-fork re-vendor (62b3f050c6), and a leaderboard shared with Street Slayer (#362). The Wager button went away (#338).
- Claude of Duty arrived as a vendored build served from /war-game (a16f976dbb) with its own launcher (8d74c1954e), HUD-glyph artwork replacing glossy 3D renders (beee270bf8), quality picked from the GPU rather than core count (44535cb344), a reliable self-retiring boot readout (190773b862, d4e4313590), CORS so it loads sandboxed (539ec85fa1), a comments composer rebuilt as a HUD console (c6cbc49df1), and a functional-audit repair pass (1071aba896).
- Street Slayer joined (e561157151) after its payload was shrunk and given a boot screen of its own (68cff98f7f).
- Trenchstar launched as our market-terminal arcade game (#339): the desk monitors are real controls (#374), any chart reads at any timeframe (#358), one bad market reading can't black out the room (#354), it boots on the DeHub loader with a green readout (#342), Fat Chad rides along as a 2 MiB GLB (#371, back on the roster from the bucket (#352)), and the whole thing boots in VR through WebXR on a camera rig without the composer (#347).
- Jungle Trail serves with CORS so it loads in its sandboxed frame (629515e674), and the war and jungle games both play on touchscreens now (6f0f65dff8). Phones got the arcade too, as a native screen carrying Claude of Duty and Jungle Trail (mobile 348672dc78, mobile 802e275a8f).
- Shared arcade plumbing: boot progress bars for war and jungle (055937d3d2), close buttons inside every game's own settings menu (b3658ca690), wallet-extension crashes no longer relayed as boot faults (875201e033), GPU-struggle no longer blacks out rooms (#351), the host's exit link removed from players (7c69f939ab), copied links counted as shares everywhere including games (#349, mobile #151), card art evened out with control hints, taglines, theme cross-references and credit rows dropped (80266b4810, 208c3be6b4, 337df5f51c, 88bfb3bd78), and the docs Games list rewritten around the five games that actually exist (#388).
Wallets and sign-in rebuilt
- Web3Auth went away entirely. Web and mobile now run a self-custody smart wallet (d74f99b73c) built on a crypto core ported byte-compatible to mobile (mobile #200), released only after device owner verification (mobile #201), with the mobile seed format pinned by test (364721189f).
- Phone login shipped, delivering OTPs through CloudTalk (#97) via custom OTP edge functions that bypass the native SMS hook (21f4037106), routed through on web too (84fc7d1c6f, mobile da90c78fc6), sent as a single GSM-7 fragment so delivery is reliable (8d9e7664b9), signing phone accounts in via synthetic email (355f83096c) with the plus-prefix handled correctly (648854f1fe), one-shot sign-in passwords hardened (9443ef0591), smart-account sessions allowed passwordless (6e85ee0aa9), and mobile gained the full flow (97c70f7621) with entry and lockout escapes fixed (c78e1e41f3).
- Sign in with Apple shipped on web (#96) and mobile (96f56da8a4), with social login migrated off Web3Auth onto Supabase identity plus local wallet on mobile (eaf106354c), stale WalletConnect pairings stopped from hijacking it (f2adace4ff), and stale wagmi reconnects no longer force gas prompts (2c91c8b82e). Magic links now complete same-device (3fe63cc0c8), and the hosted MFA page stays out of social login on mobile (33cbdb392d).
- The wallet unlocks with biometrics instead of a password (77e6bd0c2d): once per login rather than every page load (4247a0cd7c), asked about once per login (1ba583e5ef), audited and corrected twice (9f8795d450), enrolled per device rather than per account (3e99acde54), reachable instead of a dead end (4d9bed5698), with a log-out escape hatch in the drawer (d7db45ae38), phones without screen locks never locked out (mobile 54693bd6ba), and gasless setup failures surfaced instead of silently posting without gas (mobile a03a899487). The password meter now predicts the verdict before you submit (8a463c259c).
- Legacy account migration got impossible to miss: returning users are auto-detected at wallet setup (4bb2098a3e), multiple old accounts preview before migrating (462b387e54, b9713b7c2e), old accounts confirmed by avatar and username rather than raw addresses (9c1157502c) with address confirmation required (e13e5ebbb2), the email option properly labelled (7e7e17104d) and SMS joining it (#419). Mobile mirrors this with a recovery flow (7a383716b7), a warning modal with detection (57cc2e7ac9), an escape hatch for unrecoverable dead ends (e5f222615d) and mismatched web-account handling removed (92c0a76fe3).
- Active sessions and device management landed in settings (80c1e2f726), returning users skip the wallet password sheet entirely (#391), and a Supabase session exchanges for a DeHub token without any wallet signature (backend #66).
- Email became a way in as well as a way back: edge functions mail the code and resolve the identity behind it (#445), Settings grew an attach flow so an existing account can add an address, and linked accounts resume exchange-first (#447) with the login sheet held up for the whole resume and the wallet password demoted to a last resort (#444). The SMS migration path now sends the number along with the login (#468).
- One browser, several identities: multi-profile switching landed in Settings → Profile (#446), adding a profile stopped being destructive and the list explicit-only (#453), a switch that fails to restore rolls back (#448), a refresh response can no longer cross identities and a hung switch unsticks itself (#467), and how many profiles you can hold is priced by staking badge (#469).
- A refused wallet signup says why instead of telling people to retry (#476), all three wallet-auth paths say the same thing (#486), and the web client sends a stable device id so sessions are attributable (#473).
- Session stability was ground down all quarter: spurious teardown and false recovery reports stopped (89294d7bf3), stale-identity clearing centralised (b0c4f5f667), spurious logouts and sign-out-to-post fixed with force passed from every rejection path (d27b80d09d, 3198444d40), a signature prompt that never appeared no longer wedges login until refresh (ecf076e39a), failed signatures stopped blaming the user (fe4bd611ab), a lost connection-source tag no longer locks people out of posting (9e668def25), a stale connection tag no longer swallows the wallet signature (#415), a cancelled signature ends the attempt and taps reach the wallet you tapped (#423), the login sheet opens on the click not after its contents load (#417) and stops flashing sign-in options before the wallet unlock (#381). Sign-up copy leads with what the wallet step protects (182ccf1d70) and signing in no longer asks for the wallet on the way in (96cc9d074e).
Posting got lighter
- Minting became optional, with a Mint post toggle on both platforms (016380ebac, mobile 04eada0530), enabled server-side by the publish-without-minting PR (backend #95). Off-chain posts show everywhere with placeholder NFT info explaining why there is nothing to mint yet (c8ae4feb1d, mobile 22a0606d52), carry their own /newpost slugs across web, backend and mobile (a8d42756eb, backend #100, mobile 9e12a8dcae), backfill on boot for everything already published (backend #102), publish across every read path (backend #98) including deliberate off-chain posts through status=minted (backend #97), and count in dashboard stats with reactions surfaced on admin endpoints (backend #103, backend #101).
- Reactions became nine deep by holding the thumbs-up (dd4499bec4, mobile d787ddc661), served by dedicated request and per-post reaction endpoints (backend #69): per-reaction totals in the tray (5dc78b32c9), your pick marked with a glow in the colour you chose (0ff800f6f5, 0510efc703), tapping casts exactly the reaction the thumb shows (4000d5d0fb, mobile 0863ec0dd8), and the roll-call lives in the tray author-only (8a8cfa1775, backend #71) with comment likers author-only and self-likes refused (backend #96).
- Comments gained tipping on every comment and reply (#104, mobile 2ab363b6bb), a who-liked drawer behind your own comments' like buttons (a242b03f89, mobile 0bd3da514c), nesting without limit including threads past the first 20 roots (be31e9fee3, e07a509ed2), and per-post comment controls (e467fbab96, backend #68).
- Posting went from an unmetered free-for-all to a daily allowance in four steps: a per-day cap by staking badge tier (#421, backend #116), then one post per author on the home feed with posting unlimited again (#457), then each author's first N posts of the day carried by tier (#461), and finally the allowance itself — ten text posts and a gigabyte free every day, scaling with your badge, with DHB charged pro-rata only on what runs over (#484). It is documented on the dApp page (#490), including what the dollar peg and a lent badge mean for it (#492).
- Mature content got a home that is not the home feed: creators mark a post mature while composing it, and viewers choose whether they see them (#477, backend #130, mobile #180). Marked posts stay off public discovery while remaining visible to followers and on the creator's own profile.
- The negative half of reactions was finished: a dislike button on comments wired to server-confirmed counts (#452), dislike counts plumbed through text, image and short cards (#459), negative reactions skipped in the who-reacted drawer (#458), tray counts that always add up to the post's like count (#466), and a reconcile that no longer crashes on a fraction or allocates on every call (#482). A reaction now moves the count by the reactor's badge weight rather than by one (#493).
- An author replying to themselves becomes an X-style numbered thread at /posts/:id/b (#464), comments carry BadgedName so a badge never crowds the name (#460), and the comments header got a close button (#449).
- Muting an author works from any post, with an X in the card header and the block wiring behind it (#451), moved to the far right of the header icons (#454).
- Drafts sync to the account rather than the device, crash-proof against force-quit so nothing is lost (mobile 69d9b17516, 013b9fee52).
- File attachments moved out of posts and into DMs where they belong (f8480e096f, backend #89 with its feed-file post type (7fb2cd3e4f), mobile 25beb2602e), links in direct messages became clickable (42f3342f6a, tappable on mobile (f0e0ef6347)), DM replies draft straight from the composer (55ea0f34f2, mobile 73f540f7e4), and the reply tray raises on focus rather than on a button (8d10478348, mounted properly on mobile (c22925acec)).
- Direct messages got a reply rail: a resting strip under the composer on mobile (#426) shown on any narrow viewport including the empty state (#430), smart replies drafted in both directions with the strip surviving a failure (#434), replies kept inside the chat viewport (#443), the dead band under the composer killed and the orb seated in a bordered notch (#465), then the whole rail rebuilt as one component across phone, tablet and desktop (#478) with the two suggestions stacked and the orb centred on the rail (#441, #483, #488, #491).
- Scheduled posts skip the mint instead of minting early (mobile c0df104dee), scheduling gained real fee math, payable PPV and a canonical audio type (df6d8a4a25), and publishing is idempotent so a retried upload can never double-post anywhere (9eae08148d, backend #105, mobile #137).
- Asset posts card up contract addresses and tickers, with an asset picker in the composer itself (#118, mobile 5c0dae352e).
- View counting became one honest number: signed-out visitors are counted (13d42376dd, backend #78), forwarded deduped to the DeHub API (4206563c81) with the spoofable header replaced by cf-connecting-ip (c655ea14a7), and a single definition of a view count now backs web, API and mobile (backend #87, mobile c131374714).
- The feed tells you when the timeline has moved on (a10c9928aa, mobile 8b77cc18f4); follow suggestions returned alongside a New members carousel (#402); New members became an endless, chronological, complete roster (#405); and new members are identified across platforms, reopening the feedback survey (#395, mobile #159, survey round three for testimonials (#403)).
- Edit Post came back, with three-dot menus on every card plus the info page (11fa06ff10), image edits are baked into the upload so they stop vanishing (81ce3a20c2), route names can no longer be claimed as usernames (bcec2258a9, mobile 0b0cbb9d2e).
- Sharing was unified: everything shareable uses the same share sheet (82ecb47872), every DeHub link renders as a card on every surface including mobile (cbc1920d45, mobile 90e1cfde15), stores, shop items and events unfurl for crawlers (87507ef1aa), and shorts clear their own chrome on both platforms (7ad232db07). The mobile composer matches web: one attach button for photos and videos (da4e9e71ac), body as the 500-character description with title as a toggle (bde34b72ad), mint folded into the option list (5ecd4738b3), and posting without a confirmation step (f917f7d537).
- Notifications became manageable on both platforms: a real browser-notification switch in Settings (1448b3024f), a soft-ask toast that asks once you are signed in (2b93a9f743) mounted inside the auth provider (eff3ed5a3d), Quiet Hours that actually silences everything (a1f296574e), Account Alerts (0875d48db5) and Direct Messages (mobile 8dfa5ba60b) toggles, preferences read and written in the exact shape the API uses (dd0a161af4) with a type filter server-side (backend #80), and per-row clear and mark-read buttons on mobile (mobile 782a5ea461).
The economy works end to end
- DHB sells at the fixed $0.001 peg instead of a market quote (backend #77), the buy page shows the staking-badge discount and sells on BNB again (#424, backend #117), and payments arrive from any chain via NEAR Intents (backend #82).
- Solana PPV became payable on web (037fc999fa) with gas and rent sponsored from the backend wallet and abuse capped (backend #104); mobile prefers an authenticated Alchemy RPC with better broadcast diagnostics (mobile ded39270c1), and its Solana wallet is recoverable and visible with seed derivation split out for testing (mobile 631000afb3, d7bc8220f6).
- Robinhood Chain joined the network list everywhere (d245a73a81, backend #92 with the v3 stream stack, mobile 4d9758c264).
- Staking badges matter day to day now: they unlock the moment tokens land rather than waiting for a webhook (#398, stale balances repaired without waiting (backend #112)), they render beside every display name (78087844b5), your tier caps how much you can post to the main feed per day (#421, backend #116) and discounts what you pay (backend #117).
- The badge ladder stopped being a token count and became a dollar cost: thirteen tiers priced in dollars at the live DHB price, with the requirement capped so a drawdown never raises the bar, and an earned tier locked to the cheapest requirement it was ever reached at so holders keep what they earned (#481, backend #136, mobile #185).
- Badges became lendable. Every rung climbed grants one delegation slot, and a slot hands another account the grantor's own tier (backend #135, #137) — crews form out of delegation rather than out of a membership table, and alts stop being badge-less. The panel and the patron line shipped on web (#487), and a delegated badge names its patron on hover (#489). Entitlements still read the stake you hold yourself, so a lent tier is status and not a discount.
- Open paid endpoints got spend stops (#450).
- Creators see how DeHub earnings compare against other platforms in the Command Centre (#103, mobile e1d19acd21), pending store earnings from card sales show in the mobile wallet (mobile 0a6e4fc1d0), marketplace checkout is quoted and verified server-side before charging (c4d96b86e7), the affiliate page lists who your affiliates actually are with a hardened counter (2ed525e17c), and the leaderboard ranks referrers (a00f0d5509).
- The World Cup giveaway ran end to end: winners picked in a popup with DHB credited straight into the wallet (f711cd95ef).
- PPV shortfalls became a top-up step that resumes when funds land instead of a dead end (#380, #385, mobile #154, #155).
- Live engagement got real: working tips, likes, activity log and an honest end-stream state (c7ff6a1f3c), shoppable products on live streams paid through Stripe on web and mobile (b2d916f8b7, mobile 9d7c4a2135).
- Random pairing arrived as a gateway with matchmaking and WebRTC signalling (backend #94), a client with a connection test page (c671f46122), ICE servers delivered from match events (f35fe89d47), queues cleaned up on leave (2deda4f7cb).
- A DePin landing page shipped (ef5c0e1b04), the backend grew guarded admin endpoints for role changes and deletes with list filters fixed (backend #91), a guarded endpoint resolving a token's own address (backend #81), godmode origin allowed (backend #90), admin invites mailed through a send-admin-invite function riding the shared email queue (d942854ae7, backend #93), and analytics gained new-user growth on users_count plus subscriber stats on my-analytics (backend #67).
Communities, TV and the Builder
- Communities got a real admin system with grantable rights that actually do something (#102, #350), a re-runnable migration (543fd18439) with drift detection so an unapplied migration stops being silent (e5e91a4e3b), restored upload limits (a049d2651b), and the client INSERT policy kept until mobile ports off it (411caf9aac).
- Community chat notifies @mentions and gained @here (6f86e89c67) plus a jump-to-latest button (7f236adb02); every TV channel carries live chat while it plays (#100); and feature requests and bug reports take multiple attachments (38b715fa6d).
- Moderation grew a control surface: admins hold chat moderation powers and the admin panel gained a Chat page (#462), alongside a moderation page listing every report with its outcome and reviewer (#455).
- The Builder turned prompts into working mini-apps as its own full-page surface (b28901e78e, b2c6d9519d): previews host from Storage so they actually render (caeaebfb94, correct content-types from typed uploads (b36ef80662)), render inside a sandboxed frame with public share routes (d449666dc1), rate-limited per IP on the expensive build path (eddbafcc63). It moved to dehub.io/builder with the name reserved (#355, mobile #153), logged-out visitors get its title not the homepage's (#356), and mobile mirrors the reservation (mobile a85fb00818).
Mobile caught up and shipped
Mobile cut v1.15.0 (mobile #166) at quarter end:
- The parity push brought Bounties, Stores, Feature Requests and Affiliate to native screens (mobile ad8e756798), then native Ads, TV and Prompt screens (mobile 8e9047fbde), Top 100 assets (mobile f4fcc68547), Command Centre (mobile d913abc9b6), an Audio tab serving web's Music feed (mobile #163), a feature requests page rebuilt to match the web board (mobile #164), communities at parity with web (mobile 93288a02aa), TV live chat (mobile 712f937b64) and a native community management suite (mobile 27dd11b916).
- Settings rebuilt around web's tab system (mobile ba9b6a1669); Data Saver actually works (mobile 789386abcc); the whole UI moved onto the monochrome web experience (mobile c6c9d7c751) with palette unification across story rings, image feeds and empty states (mobile afcf1c6e80, 6c90574305, contrast lifted (0dceafc107), dark foregrounds on accent buttons (0c53313d04), visible pull-to-refresh spinners (a302dc9cc0)).
- Signing in on phones settled on one set of controls, led by the DeHub mark (mobile 769a19e75e, mobile ee307ff618), with the wallet picker no longer buried under the sheet (mobile 670040a327) and web's sign-in gate matched with the Exo typeface actually applied (mobile 301e0e25e3).
- Localization was completed for new flows (mobile f5277a064f, navigation labels (4c2cf95809, 6dd79d3200)), covered by navigation translation tests (b2d6135974), and translation uses your chosen language with the commenter's avatar shown (2b1a7d0ed2). Controls every session touches became screen-reader usable (21e6734d0a).
- Stages work properly on phones: scheduling and announcing (ca97c9366c), reminders with start alerts (mobile #145), shared-screen viewing (mobile #148), the soundboard (620a4658d8), caller identification on every write and speaker token (mobile #144), host role retained on rejoin with mute persisted and invite links opening (e2c3e10bc3), raised-hands banner pinned and speaker avatars fixed (mobile #152), and flaky token refresh no longer signs people out of Stages (mobile #161).
- Store readiness: Android releases stopped signing with the public debug key (mobile #158) and point at the real DeHub key (mobile #160); assetlinks.json publishes with the Play App Signing fingerprint (#401, association files served as real files including Apple's (#393, #399, bodies validated (#396)); the links we hand out are claimed and unverifiable hosts dropped (mobile #157); EAS grew a test-apk profile yielding installable artifacts (mobile #149); the APK download page dates its builds (4821652aa8, d359811a27); push moved onto the dehub-ca4d8 Firebase project (6cb41b6c70) and EAS onto the dehubapp account (e8e79b8bb8).
- Dead weight came out: 73 unreferenced bundled assets (52639d9d24), four Rive animations nothing loads (95d374ae47), icons resized to within 4x of render size (e8aadba4e0), default banners encoded as JPEG (7e429b0616), and the dead video-player subtree deleted (836f77010e).
- Audio moved off expo-av across useSyncedAudio/SoundPickerSheet (836c52989b), StageTranscriptSheet/VoiceNotePlayer (0e3cd884a5) and SoundtrackBadge/StagesBrowseModal (1c04305cfe).
- Notifications ask behind a branded pre-prompt (mobile #150), Android badges stay in sync (b9db8777e3), tapping an announcement push opens its link (mobile #136), and every notification type defaults on (d130dbebd5).
Design system and navigation
- The branded DeHubLoader rolled out across app surfaces (9e40ca6dde), merged (cfe42e2af5)), color-scheme is declared at boot with the mark shown for every page wait (1f8331d1d6), and open tabs are told when a new build has shipped via a toast in the app's own chrome — bottom-right on desktop, translated and mirrored for RTL (595ba5b281, b5248da59e, 0a3c67ce70, a908b77db9).
- PWA install offers work again with the icon sizes browsers need (#332), brand assets serve as real static files instead of pointers (07d2a6faad), and /creator leads with the DEHUB ORIGINALS wordmark banner (773e2b1b12).
- Menu search landed in the left panel (b42df422e8) finding pages by what people call them (a34d9edab8), mirrored as a bottom menu search with the rail reordered (#377) and hidden once the mirror shows (#386); the drawer gained it too on mobile (8a19834642). Nav order changed: Home first with Settings above Leaderboard everywhere (bd78e89440, mobile f9cae50dea), Leaderboard and Stages swapped (4b1cd3dfbd), Shorts next to Home (746a8499b1).
- Every tooltip shares one hover label style (#408), side panel tabs label themselves on hover (#407), the feature board's header pill hides on scroll including desktop (#409), the features audit repaired the request board and shipped two requested features (cf21dd2d9d) with shipped popups no longer re-showing every login (6ab9d892e0), Work was renamed Bounties (9267087e05), and bounty posters can edit their own listings (#105).
- The signed-out welcome panel was rebuilt as a branded SM Template 2.0 story panel (ebc834e59c, matched against reference boards (649c50336e)): sized to its own column with the hero shown on phones (#394), hero kept inside the panel (#400), decorative frame cleared from the globe (#406), HUD chrome rounded without motion blur (3da71a9460) — so "/" can hold the brand term (b5280ab3a5).
- Messages surfaces draw as frames rather than slabs (c9fb5523ec) running edge to edge (e639e39bd1); TEST and NEW badges came off nav, UI and buttons (bd27dee0c3); the platform mark was squared off, announcements link somewhere and carry the mark (1494fd96ee, 20074c2e00) centred in mobile headers (cc16574b59, mobile 936681ad3d).
- Skill cards unified across both popups with Use moved to a full-width bottom bar (cd6759a59b, 482a469d97), a full-width segmented filter control with live counts (607514739a), and Build something moved into the assistant quick-action row (9027097cce).
- Stats gained 3d/7d/all-time ranges beside 24h/30d (cf3aa6b8f5), publish live visitor numbers with their provenance (e938d7f17f) and proper English strings (baf6b2df46, b3d73b29d2); /top-100 got its own icon (8b6251df92); the desktop rail's bento and post/login buttons share a width ending the menu on Log out (cf2086925e, 30e7ba8546).
- The Features header collapses to a search bar on scroll-down, rebuilt as natural scroll-away through CSS grid rows to kill jitter (225430613e, b9767207dd, 0fab9c0282, 7eb8200726).
- Feed chrome: video posts wrap in one feed-styled bento on cards and dedicated pages (c05c3ccf02, 4f4677c458), tapping a video reveals controls instead of opening the post (b4d0407eff) and opening a post from a feed video carries the player along (03c87750ac), the composer swallows the page as it scrolls under while staying parked with rails above it (20eb68149f, 4cfd5c7c65), and the images grid swaps instantly, scrolls through the right element with an ad slot, exits via the nav pill, and shows collages in a drawer with repaired carousels and +N markers on mobile (b5971ad168, ce9e82c2df, a7df93db60, 3517b6167c, 034bd0ac21, f320b98d31). Mobile's nav pill holds every destination with rebuilt stage cards (38cc7966ac), its shorts viewer matches the web player frame for frame with one set of controls (f7a80b72b5, 5bce43fb32, 2be39981d6), the prompt-to-feed tuning flow was ported (8cf793b5ce), and the assistant came in line with web (1e3dea40f9).
SEO, docs and the blog
- A staging deploy lives at staging.dehub.io (#98). Marketing routes stopped 404ing for crawlers with bot/human URL parity and a meta truth pass (#101); route previews render statically at the edge with working share images (fcf5c56560), every SEO route carries its own share card (9301a1a233) and cards describing the wrong page were fixed (2727a4bc99).
- The dehub.net domain move completed at the worker: domain-move 301s served from the worker (fae6baf994), www 301s with immutable asset caching restored (6d4f651a03), legacy edge artifacts retired (404fb654fa), legacy /web/app/* and /learn paths mapped onto real pages (07889b650d), /radio and /mcp 301ing the way the app already does (4493146590), orphaned milestone URLs redirected (6c7167cb23), legal URLs 301ed to their real /docs home (8eb6ca03c5), subdomains stopped soft-404ing (#373) and the dead dehub.net URL space maps onto real pages (#376).
- The app shell no longer outranks /docs as a homepage duplicate (1e6f25ac60), non-rendering fetchers get real content with http upgraded to https (2aa15fc3bd), per-route titles, empty-state fallbacks, sidebar scroll and a11y labels landed together (a55cd69868), and an August SEO audit with keyword targets was written up (7cb5a69c23).
- The docs were restyled in monochrome liquid glass with the dApp guide consolidated (82211f6b03), coverage extended over shipped features with anchor sub-nav (a79327dfa8), real app screenshots throughout (a44faa1e67, stale screenshots replaced (4fd42f0ce8)), Bounty Hunting corrected against the live app (068de333bf), folded-in sections reading as sections (9a80ffcddd), on-this-page scroll-spy (3bdc2bfec6), a Currency Overview page as the Token landing (aa03f3de26) with Token renamed Currency in nav and the Discord icon fixed (80848d42ce), and the architecture section refreshed for current infra (8481d088e0).
- Blog search unified into the docs header search (a982c017c1); every milestone post got its own full article (d5529f6126), the thinnest ones expanded (060e1fb57c) and in-body section art added to 17 posts (5fa1f571e2); banner crops bottom-anchor so the logo pill band cuts cleanly (836cfba769); ## headings render instead of being discarded (b86d8f95bf). A Featured In press page shipped with its own post (91b7a41fe5) and a creator-vs-Higgsfield pricing guide landed with blog images (4fe0c5a122).
Under the hood
- Eight app-wide speed rounds landed (820052d674, 4e53ae0fb1, f254de7f00, 72cec7c525, 22f6b9c734, d117d46e92, memory and listener repairs (9a09e1284a), boot parallelism with cache caps (168d40d8a6)): native HLS preferred on iOS/Safari to stop TV overheating (ce7124afdf), radio suspends its AudioContext when idle (25e5aac5c3), music feed mount latency cut (47d14c7623), deploy polls cut to three minutes (91c34dc0b4), next short preloaded so swipe playback starts instantly (a53a2a5b45), posts open instantly at their top without the feed accumulating listeners (1bd435bcaa), filter switches show a preloader on both platforms (8aa6b051eb, mobile 612e8e4694).
- The boot path got a JS budget reported on every build (491315e295) ratcheted so it cannot drift back up (#412); the stories row and Stages sheet came off the boot path (#411, #410); RainbowKit scoped to the login flow instead of the whole app tree (c170938b01) with prefetch stopped (#413) and the modal chunk matched by filename (#414); three.js, oversized art and the emoji font left the load path (8baa88572a); CDN images serve through Cloudflare transformations sized to the box they render into (6911d543ce, c78c2a9448) including video posters and live thumbnails (23ca9b37fe). Mobile ran its own passes: lazy screens with cached profile/community feeds (22e740f454), real pager tab switching (8ba4426431), windowed rows no longer each attaching a player (0cbc1cf928), media churn stopped mid-scroll (a884a9ad57, 82288c9530), image decode and test time cut (0bbedb3efb), images fetched at render size (2f878ec127, CDN-sized galleries (1d4a4a8ca8)), first sign-in sped up with the profile step restored (72a7c928e5), a dropped radio no longer tears down the app (fddc03cf47).
- Security: paid edge functions carry per-IP rate limits and an SSRF guard (206d9827c4), the auth confirmation open redirect closed (7b498ebcaf), grouped Dependabot security updates configured (a7b861b2e2); mobile bumped socket.io-parser for CVE-2026-69185, undici, brace-expansion and fast-uri plus postcss (168cdc16e6, cc3ccd8315, 996efd375d, 68544fee28, 9cae3295f8).
- Plumbing: a Cloudflare Worker reached parity with the previous SSR function behind wrangler (acbc6f9b79, a1ff2f7e4a, 02b34f7bee, 65975e256c, name matched (f1722f9432)); typecheck CI added on pull requests (894ea57a2e) with generated Supabase types restored so main typechecks (1e78739c5c); lockfile churn tamed — stale bun.lock failing every builds dropped (0ec6b5f671), hash-wasm synced (5f52398b2b), pnpm hoisted so the host resolves phantom deps (c3ddcd9afc), installs unfrozen until locks regenerate (21cf98118b); the white-screen hotfix hardcoded publishable fallbacks (9fef5ad076); stale deploys stopped crashing navigation (43b45e24fe); painted surfaces were hunted down — sheet chrome hidden for every sheet type (07a95bc287), stale likes after silent session refresh fixed (883245d0fc), slab nets repainting the post overlay cleared (54b9c9270f, backings inheriting main's background (204c4cf878), middle columns cleared (e02afce298)), and panel backgrounds never paint on panel backgrounds again (067d367834) with scroll edge fades masked rather than painted everywhere (dcf056285f, 73418382b4, mobile 97d19e41bf, swallow radius re-read on theme change (4c6a53d721)).
- Backend ops: tests run on pull requests with deploys firing only on merge (backend #76), the droplet installs with pnpm like CI (backend #85), deploys authenticate pulls with the run's own token (backend #84) targeting the origin address not the proxied hostname (backend #83), unreachable RPC endpoints stopped filling the disk (backend #113), and mobile gained a green CI baseline of jest-junit and typecheck (mobile c03cf2e406) with test coverage rebuilt across validators, uploads, mentions and drafts stubs (443f9c2f60, baa2d54cd1, 8af4b03556, 195ff6c10c, 5d3d71f597).
What's next
The quarter is not over, and neither is the list. Q4 continues exactly where this leaves off: more stages, more arcade, deeper economy — shipped in the open, as always.
Open DeHub