Family, Team and Community plans can now invite collaborators from the dashboard — they create their own passkey and read you a short code, so their keys never touch us. A managed hub now only accepts the people on your list, seats are billed as advertised, and the free tier finally has a working sign-up button.
Need more room? Buy 100 GB, 500 GB or 1 TB on top of the plan you already have — same hub, same seats, same AI budget, same price for all of it. Extra space applies immediately; removing it waits until your data fits, so a quota never shrinks out from under stored data.
The Charter now declares the oldest machine xNet supports — a 2017-class laptop with 8 GB of RAM — and a CI check fails any change that makes a first load cost more there. We make no claim to be greener than anything else, and we will never sell efficiency as a paid tier.
Plans that publish an uptime target now keep a warm instance, so they are not woken from cold on first use. We also corrected wording across the site and dashboard that said we cannot read your data — on a managed hub we can, and now say so plainly, along with what our operators may see and the signed log that records it.
Follow xNet on Bluesky and you'll see new blog essays as they publish, plus the changelog entries worth interrupting you for — not every commit. Links in the posts are properly clickable.
The site footer now links the project's Bluesky and X accounts, so you can follow along for new essays and release notes. The icons are inline artwork — no platform embed scripts, so the pages still load nothing third-party.
The seeded demo dashboard referenced a widget type that no longer existed, so its habit heatmap rendered as an empty tile. It now resolves to the real widget, and a test checks every seeded widget against the registry.
Dragging a card to another column now animates it into its new spot, and reordering tabs slides the neighbours aside rather than snapping. The animation code loads only when you first drag something, so start-up is unaffected.
Settings now has an AI section where you pick whether the assistant scaffolds your thinking or drafts finished prose. Scaffold stays the default. First-run tips also start appearing again — every one of them had been silently rendering nothing.
xNet's public economics doc adds a fifth test — every promise we make not to charge you for something must name the revenue that pays for it — and the build now fails on scarcity countdowns and act-now prompts anywhere in the product.
When the full-text index is unavailable, the in-app assistant falls back to scanning a limited window of your workspace. It now says so alongside its answer instead of replying as if it had searched everything, and cites the path it followed to each item it used.
Imported TikTok favourites and collections get their own feeds, every surface now shows real titles and thumbnails instead of platform ids, a saved lens can be projected onto the canvas as cards with the connections between them, and YouTube transcripts can be fetched per import run so an AI agent can search what was actually said in videos you saved.
The habit heatmap and Today panel used to show a 🔥 streak — a chain a single missed day destroyed. They now show the share of scheduled days you completed over the window on screen. Same information, but a miss lowers a number instead of wiping one out, which is what our charter's commitment against loss-aversion mechanics actually asked for.
Contacts can hold the shared activities a word like "friend" leaves out, and xNet reads the label from them instead of storing it — including which activities people in that kind of relationship commonly share that you don't.
Apps can now find your hub by name instead of a fixed URL, so moving it between regions or hosts no longer leaves your devices pointing at the wrong place. A hub waking from sleep says so and reconnects, instead of looking offline, and an exported backup carries the address so it alone is enough to get you syncing again.
Your imported YouTube, Instagram and TikTok saves can now be published to your own AT Protocol repo — a link, a date and your own tags, never the platform's titles or thumbnails. A new comparison shows what you and one other person both saved, across networks. Messages, comments, searches and who you follow are never offered: they describe other people. Publishing is permanent, so it asks every time and shows you the exact records first.
If a card fails, xNet Cloud now walks a clear path instead of doing nothing: two weeks of normal service while the charge retries, then read-only (everything stays readable and exportable), then a paused hub with your encrypted data kept in cold storage. You get an email at every step, with real dates, and paying at any point restores everything immediately. Data on your own devices is never affected.
Why dating apps are metered on purpose — match scarcity as inventory, the market for lemons run on people — and what the matchmakers people actually loved got right. The essay ships with a receipt: a new CI rule and Charter clause mean xNet can never sell an introduction.
Any agent connected to xNet — OpenClaw, Hermes, Buzz, Claude Code — now gets its own key and a narrow grant, and everything it does exports as a receipt you can verify offline. A new xnet audit verify command checks the signatures, spots a removed action, and proves you approved anything risky.
Claude Code and Codex now use xNet's real retrieval instead of scanning the first 500 nodes, the new `xnet recall` answers questions that span several notes and shows how it got there, and xNet remembers what you have told it between sessions.
Capture your screen and camera, get a transcript, and let xNet propose cuts for dead air — all on your machine. Edits are non-destructive: every cut is listed, reversible, and the original is never overwritten.
When a connected coding agent asks to make a high-risk change — creating a page, editing one — an approval card now appears in the app with the change to review, and Approve and Deny buttons. Previously those requests waited invisibly and expired after five minutes, so the change never happened and nothing said why. Approving now also hands the result straight back to the agent, so it can carry on in the same turn.
The desktop dev app now takes its profile and ports from the git worktree it was started in, so parallel checkouts no longer fight over one set of ports and one data directory. Collisions that used to exit silently now fail with a message naming what holds the lock.
A failed hub setup now cleans up after itself instead of leaving a paid-for server running with nothing attached to it, and scheduled maintenance jobs no longer get skipped when the service restarts.
Sharing with no hub connected now offers a Connect a hub button that opens the connection panel with an inline hub-URL form, instead of a dead-end message. Links from a private hub ask for confirmation before copying, so a LAN-only link is not pasted somewhere it cannot work.
Turn on 'Allow edits' in the AI panel and the assistant can create and edit pages. Risky changes pause for your explicit approval in the chat, every action is audited, and the local agent bridge now shows tool activity and per-turn cost.
The desktop shell is the same workbench the web app uses: sidebar with search and filters, command palette, tabs, and panels — with the canvas home, meetings, data workspace, and social import inside it. The two apps now stay in sync by construction.
Open Assistant from the system menu or command palette to chat with your workspace on desktop. It finds your Claude Code or Codex subscription automatically and pairs with one click — your model, your machine, and it can search and read your actual pages and data.
The app icon and favicon use a refined geometric mandala, and the mark now appears as a subtle debossed engraving beside the wordmark in the site and docs headers.
Opening the menu in the desktop app crashed it to a black screen with no way back. It works again, and a shell error now shows a recoverable panel instead of taking the whole window down.
A copy-editing pass across all twenty essays cuts an overused em-dash habit and the mirrored sentence pairs that came with it. No facts, quotes, links or arguments changed.
The desktop app's AI chat now hands your coding agent xNet's own tools, so it can search your workspace and create pages and tasks in it — not just talk about them.
The xnet_query tool used to ignore a schemaId filter and return nodes of every type, so an agent asked about your pages could answer with canvases. It now filters correctly, and a query with no type at all fails loudly instead of quietly returning everything.
Hold Option and hover to see whether a piece of the interface comes from a theme token, a panel, a plugin, or xNet's own source — and one sentence on what changing it would affect. Option-click to adjust a token or move a panel, with one Undo.
On models that call tools reliably, the in-app assistant searches and reads your workspace directly instead of only answering from context it was handed — and shows you each lookup as it happens. It still cannot make changes.
The desktop app can download and run in-browser AI models and build its on-device search index — its content policy previously blocked the model weights, WebAssembly, and the local agent bridge.
New `xnet connect claude-code|codex` wires a coding agent to your workspace in one step; the agent CLI verbs now work with the app closed via a standalone SQLite store.
The local AI bridge can now stream tool calls, cost, and session info as structured frames over a new endpoint, keeps chat sessions across restarts, and sources model info from models.dev.
The agent bridge's default origin allowlist (and the CLI/docs examples) pointed at app.xnet.fyi, which no longer exists — the deployed app at xnet.fyi/app could never pair. The default is now https://xnet.fyi; XNET_BRIDGE_ALLOWED_ORIGINS still extends the list.
The local bridge streams tokens as they arrive, remembers your conversation across turns, and every AI thread is saved as a searchable chat in your workspace. New: one-command login-item install (xnet bridge install), a helpful offline card with the exact command to start the bridge, read-only workspace tools by default with explicit write consent, faster workspace search behind AI answers, and an OpenRouter account-connect flow for machines without the bridge.
xNet can now project a published page onto the shared site.standard lexicon as a rich card while the body stays on your hub, sign in and recover with your Bluesky identity, and make a self-hosted hub discoverable across the network — the private half of the atmosphere.
All, Docs, Chats, People and Views used to re-filter the sidebar and leave the main screen exactly as it was. Now every section in the left nav takes you somewhere — and People, Views and AI have their surfaces back.
The top-left New menu now creates tasks, channels, meetings and spaces alongside pages, databases and canvases. The plus button in the corner of the sidebar has been removed — it always made a page even when you were looking at chats.
Database file cells now hold several attachments, show thumbnails inline, and open a full-screen viewer with paging and download when clicked. Attachment bytes sync between your devices through the hub instead of staying stranded on the device that uploaded them.
Lists, chat transcripts, the sidebar tree and long menus now fade their content into the background at any edge that still has more to scroll, and the fade disappears once you reach the end. Works in light and dark mode on every surface.
Dropdown selects with many options (like the database field-type picker) were capped at a fixed height with no way to scroll by mouse, hiding options past the twelfth. The list now scrolls and shows scroll arrows, so every option is reachable.
Changing a column's data type from the table view's ⋯ menu works again. The type dropdown was painting behind the field popover, so its options were unclickable — clicks landed on the menu underneath instead. Every portalled select, menu, popover, and tooltip now sits above the overlays it opens from.
Arriving from the landing page's Try-the-app link now opens a lived-in demo workspace — sample documents, a tasks database, chat channels, and CRM records — instead of an empty screen. The demo only seeds brand-new profiles; existing workspaces are never touched.
One hub binary now runs as named roles (personal, demo, community, index, registry, gateway) selected with --role. The index role rebuilds a deterministic public atproto index from source; gateway hubs mirror other hubs' public Spaces over the existing sync protocol; every hub gets a persistent system identity on /health; and a compose template runs a hub beside the official AT Protocol PDS behind one domain.
The append-only change log is metered against the same per-user storage quota as backups and file uploads. Previously this gate ran only on demo hubs, so a hub's change log could grow past its plan quota without being rejected.
Placing your cursor inside a commented passage no longer pops up a second, differently-styled comment card. The comment island is now the only comment surface in the editor.
Comment threads now open as a proper floating island: the reply box stays out of the way until you need it, so you can actually read the conversation, and the card follows the text it is attached to when you scroll. Clicking a highlighted passage opens its thread — previously only the sidebar could.
Essays get revised after publication — corrections, tone passes, spelling sweeps — and a page showing only its publication date quietly implies it never changed. Each post's byline now carries a History link to the full commit history of that post's source file on GitHub, so anyone can check what was altered and when. It makes no claim that a given essay has changed; it just puts the record one click away.
Linking a Bluesky or other ATProto account now actually records the identity binding in your repo. The sign-in flow previously requested identity-only permission, so the binding write was never authorised and silently did nothing.
Blog post #20 on why layered perennial food systems lost — not to a better design but to a better ledger. Grain genuinely won on calories and labour; the forest won on variance, soil carbon, micronutrients and input independence, and no ledger has a column for any of them. Includes two corrections to our own earlier essay.
Plugin authors, self-hosters and hub operators can now file a Rule Change Proposal against an enumerated operational rule — the humane-patterns gate, allowed plugin licences, marketplace terms, the Charter's refused rents, the Moat Register, or plan quotas — and get a public written answer with reasoning within 30 days. Decisions, including refusals, are recorded in a public append-only log.
Community Spaces now have a discussion feed with topics, replies and a welcome queue that surfaces newcomers nobody has answered yet — plus schemas for courses, lessons and events.
Invite links for a space are now restricted to the person who created it, or someone they have made an admin. Previously the hub had no record of who owned a space, so anyone who learned a space's id could mint an invite link to it — and because a space invite grants access to everything filed beneath it, that covered the whole subtree. The hub now derives ownership from the signed change that created the space, so existing spaces are covered without any migration.
The Charter now carries a Sleep test alongside improvement, BATNA and vanish — asking not just whether a revenue lane is fair to you, but whether it would survive a competitor open-sourcing our whole feature set. A new ECONOMICS.md sets out how xNet earns, what it deliberately refuses to charge for, and what that position costs us; LICENSING.md settles why the core is MIT. The marketplace terms now commit to ranking neutrality: our own plugins get no placement preference.
The workbench now opens as a single calm surface: no tab strip, with what you are working on kept as Pinned and Recent rows in the sidebar. The nine separate left-hand navigations collapse into one list of your workspace, filtered by lens — Docs, Chats, People, Views — so channels and contacts live alongside your documents. Chats sort by recency and bump on unread; documents hold their order. Cmd-[ and Cmd-] walk history, Ctrl-Tab flips between your last two views, and tabs remain one command away.
Importing or deleting a large data set now sends changes in batched frames instead of one at a time, and verifies them with native crypto — a 10,000-change import reaches the hub in under a second instead of several minutes.
Syncing a workspace with a big backlog could silently lose changes: the hub sent them 1000 at a time but told the client it was fully caught up, so everything past the first batch was skipped and never re-requested. Clients now walk every batch to the end.
First-run now asks how xNet should feel — focused, cozy, or quiet — instead of hiding warmth in settings. The demo workspace gains Night Bloom Records, a small record-archiving collective, alongside Acme Inc. And a new CI rule bans ratio/leaderboard scorekeeping for good.
Pages compose like Lego: slash in a live view of any database (table, board, map, calendar and plugin views), transclude other pages, and drop nodes onto frames to link or add rows. Hovering a row lights the same item up in every frame on the page, every surface carries the same node passport, and the assistant can compose whole pages of live frames with a reviewable plan.
Settings → Data now exports a signed .xnetpack bundle: the full change log with history, signatures, and document contents from the real local database (the old export missed the master copy). Restore it on any xNet — a fresh device, the CLI (xnet data export/import/snapshot/export-folder), or back into the same app — with every record verified before anything is written. Lossy CSV/JSON exports now say what they drop, and hubs gained export/restore/purge endpoints so leaving takes everything with you.
Sign in with any ATProto handle to claim a free global name, with a verified-handle badge and Bluesky-identity account recovery — all optional and self-hostable.
Every hub now quarantines its own deployment's crash reports — nothing leaves your infrastructure by default. Operators import reports into a Diagnostics Space (Settings → Privacy & Diagnostics) and triage them in the workbench; managed-hub owners see pending counts and top issues on their cloud dashboard, read live from their own hub. Sharing anything with xNet stays a separate, explicit choice: preview-and-send a single report, opt in to anonymous crash counts, or grant time-boxed, revocable support access.
Every database now offers Notion-style views beyond the table: a kanban board grouped by any select field (drag cards between stacks), a cover-image gallery, a month calendar with drag-to-reschedule, a roadmap timeline with month/quarter/year zoom and swimlanes, a compact list, and a map that pins rows by latitude/longitude with clustering. Each view remembers its own configuration, colors, and layout — and says so honestly when a large database is windowed.
External agents (OpenClaw, Hermes, Claude Code) can now be enrolled with their own scoped identity: every tool call is recorded as a signed audit node, risky actions require a typed approval code in chat or an in-app confirmation, reversible actions can be undone, and the new DevTools Agent Audit panel shows the full per-agent trail.
The database grid now loads more rows as you scroll (up to 2,000), shows the true total ('500 of 12,000 rows') instead of the window size, and stays smooth on wide tables by rendering only the visible columns. Filtered views on large tables say when they only cover the loaded rows.
Turn a spec document into a live, sandboxed, composing plugin without leaving the workspace: an agent writes the plugin's source as a synced node, it hot-loads into an isolated iframe, and its console/errors feed back to the agent so it self-debugs.
Every page, task, database, and canvas gains a Time Machine — scrub through its history with named versions, author colours, and one-click restore — and Patchwork-style drafts: fork content into a private working copy, review a three-way diff against a moving main, and merge back in one step. Assistant edits now land in a draft awaiting your review instead of touching live content.
The new editor no longer floats as a white card: the document background matches the page, checkboxes and list markers line up with their text, and the blue focus border around the document is gone.
Blog post #15 frames xNet as LEGO for data on the web: one coupling — node shape, namespace, merge rule, permission algebra — and why the grip that lets go matters as much as the snap.
The schema picker now shows schemas that actually have data in the workspace (plus the current selection), instead of every schema registered by imports — in small embeds like the live demos, side-effect registrations buried the two real schemas under twenty unused ones.
Every demo at xnet.fyi/play (and the paired frames on /demos) ships the real DevTools inspector — click the floating wrench or press Ctrl/Cmd+Shift+D to watch the data, change log, and sync frames live while you play.
Pages, tasks and canvases now use a BlockNote-based editor: cleaner formatting toolbar, slash menu, drag handles, tables, and an emoji picker — with mentions, hashtags, wikilinks, callouts, embeds, mermaid diagrams and math carried over. Existing documents are converted best-effort on first open (prerelease: complex blocks may degrade to text).
A new opt-in "Report a problem" flow lets you send scrubbed crash and diagnostic reports to a first-party endpoint — you see and can edit the exact contents before anything is sent. xNet does not use a third-party error service.
Opening a document could fail with a storage error ("no such column: tiebreak_key") when the local database had been created by an older build. The missing column is now repaired before the first read, so existing workspaces open documents without needing a data reset.
xnet.fyi/demos shows two copies of the same app syncing in real time; the demos live at /play with shareable room URLs, and a copy-paste examples/minimal-app starter gets a synced app running in two commands. React apps get a new usePresence hook for live cursors and ephemeral peer state.
Schema authorization gains create and update actions that refine the coarse write action. Chat messages and comments now declare contributor semantics: anyone in the space may post, but only the author (or a space admin) may edit afterwards.
Sync integrity checks now verify author signatures cryptographically instead of merely checking they are present, hash auto-repair no longer runs on untrusted data, the hub validates dynamic query column identifiers against SQL injection, and it warns loudly when auth or signed-replication safety is relaxed.
The sidebar, status bar, dock, and context panel no longer cast a drop shadow — islands sit flat on the surface with just a hairline edge. Modals and menus keep their shadow so they still read as floating.
The last-write-wins tiebreak no longer lets a hand-picked identity win every simultaneous edit; conflicts now break by a per-conflict hash of what was written. Sync bumps to protocol v4.
Tab content — pages, databases, settings, chat — now blends into the backdrop behind the floating islands, and every overlay (modals, menus, dev tools, sheets) shares the same island fill as the sidebar and status bar, in both light and dark mode.
Upload a profile picture in Settings → Profile — it shows in the top-left profile button, menus, chats, and presence, with your generated avatar as the fallback. Profiles now reach people you share with: names and pictures render on shared channels, pages, and the Share dialog instead of DID fragments. Only you can write your profile; collaborators can read it.
Block drag-and-drop, the slash menu, and all suggestion popups were rebuilt on Tiptap's official MIT components (drag handle, Floating UI positioning, toolbar primitives with arrow-key navigation), fixing inconsistent handle and popup behavior. The editor also gains :emoji shortcodes and KaTeX math (^2$ inline, 97747…97747 blocks).
Opening a shared channel link now shows the real channel — its name, full message history, and members' names/avatars — and new messages arrive live. Previously a shared channel opened empty.
Setting a username in your profile now surfaces you in the @mention autocomplete in comments, task inputs, and page editors — not just chat. You can also @mention yourself in chat, and pickers show the @username next to each person's name.
Opening a database view containing a formula or rollup column (such as the seeded Tasks Tracker) crashed the editor. Computed cell values are now rendered as text, and link detection safely ignores non-text values.
Paste a link in chat and it up-reses: internal deep links become live-titled chips, share links become titled document cards (owner-controlled via a new 'Show title in link previews' toggle), and external URLs get preview cards resolved once by the sender — readers never ping the link. The page editor's pasted-URL cards now hydrate with real titles too.
You can now generate a share link for a chat channel (from the channel header or its menu) and for a saved workspace layout — the same way you share a page or database. A channel share with 'comment' access lets people post messages without editing the channel.
Checking off or deleting page checklist items no longer spams the DevTools Changes tab with false conflicts, and a mid-delete snapshot can no longer rename a task to 'Untitled task'. Replayed sync changes now apply idempotently, and true cross-author conflicts are distinguished from routine last-write-wins housekeeping.
The mobile-e2e placeholder workflow is retired, Fallow's weekly run now gates only the dead-code ratchet (the full audit runs on demand), five orphaned end-to-end suites joined the nightly soak lane with their rot fixed, and hub image releases no longer fail on SBOM upload permissions.
Blog post #13: graduates boo AI executives, then go home and run open-weight models on their own laptops. Two video essays woven into the series' exit-over-voice thread — open weights, owned assets, analogue media, and the software layer of the exit.
Clicking a share link no longer fails with 'Missing link, handle, or payload' when it falls back to the web app — the app was accidentally discarding the link's parameters during startup. Share links also no longer leave their secret in the address bar.
The shared demo hub enforces its 10 MB per-user cap, wipes demo data daily, and sheds writes before its disk fills instead of crashing. Workspace (bench) share links now work end-to-end, and a hub that is down reports 'isn't responding' instead of a cryptic 'Failed to fetch'.
The plugin browser now tells the truth and does the work: plugins only say Built-in when they're actually installed, every first-party integration (GitHub, Slack, Notion, Linear, Discord, Stripe, and more) gets a real Install button, and a new Configure form collects tokens and settings — stored on your device only.
The floating Assistant island no longer opens over the editor at launch. It starts collapsed to its reopener pill so the workspace is clear at rest — one click reopens the full island.
Opening a page from the sidebar, command palette, or Settings now opens a temporary (italic) preview tab that the next open replaces — double-click the item, or start editing, to promote it to a permanent tab. Previously this VS Code-style behaviour only applied to Explorer rows.
Browsing plugins in Settings now lets you click a plugin to open a details view — with its description, stats, requested permissions, and what it adds — and install it right from there.
On phones, the center navigator sheet's first tab is now contextual — like the desktop bottom-left island. It shows Explorer on the workspace, Settings on the settings screen, Tasks on tasks, and so on, instead of always saying Explorer.
The cloud dashboard shows a real "data safe as of" time from Litestream's measured R2 sync, cold-tiering never destroys a hub until its backup is confirmed fresh, and nightly restore drills verify recoveries. Self-hosters can enable the same Litestream durability against any S3-compatible store.
You can now point the AI panel at a local Claude Code, Codex, or Ollama model through a hardened loopback bridge — protected by a pairing code, an origin allowlist, and Host-header checks so no other website can reach it.
The mobile editor now matches the desktop Floating Islands look: a floating control cluster at the bottom of the screen replaces the old top bar and bottom nav, and every panel opens as a rounded island sheet hovering over your document.
The developer tools panel now opens as a floating overlay island — rounded corners, a soft drop shadow and the warm island colour — hovering on top of your content instead of sliding up as a flush bottom sheet. Its tabs are now pills that match the rest of the workbench's hover panels.
Opening Settings now creates a proper tab in the editor's tab bar (with a gear icon), alongside your documents — you can switch to it, close it, and it survives back/forward like any other tab. Switching between settings sections stays on the one tab.
When Settings is open, its section list (Profile, Appearance, Labs, …) moves into the lower-left contextual island, matching the rest of the workbench, and the selected section fills the main area. The active section now rides in the URL (/settings?section=…), so it's deep-linkable.
The What's New panel and modals now render as solid "floating islands" — matching the workspace chrome with a slightly darker surface and deeper shadow so they read as hovering on top, and are fully legible instead of translucent.
The dev-tools button beside the status bar now toggles the panel directly instead of opening a menu. The floating Assistant dock now uses the same 8px spacing as the other islands — it no longer floats with extra margin on the left, right, and bottom.
The workspace selector at the top of the sidebar now switches which workspace (Space) you're scoped to and filing into — it no longer changes your shell layout. The old workspace-filter chips and the duplicate New button have been removed from the Explorer, which now stays focused on your files.
The New button in the sidebar's top island is now the one place to create a page, database, canvas, dashboard, map or lab, a folder, or add a shared link — and it files new items into the workspace you're scoped to, matching the Explorer's New menu. The Explorer and the contextual '+' now use the same action, and the profile menu gained Sign out.
The docked developer-tools island (beside the status bar) now appears whenever the developer tools are actually available — matching where the old floating button used to show — instead of only in local dev servers, so it no longer disappears in preview builds while its space stays reserved in the status row.
In dev builds, the developer tools now dock as their own small island beside the status bar (with an upward menu into the query console, schema inspector, and sync log) instead of a floating button. The workbench header island can also collapse to a compact rail via a caret at its base, giving the Explorer below more room; the change is animated and respects reduced-motion.
The desktop workbench is now one warm canvas with all chrome floating as rounded, softly-shadowed islands — a calmer, Notion/Claude-desktop feel. Two stacked sidebar islands (navigation + a contextual surface), a base-surface editor with a breadcrumb header and pill tabs, a right context island, a status-bar island, and a bottom-center Assistant dock. A new surfaces model lets you pin the few surfaces you want visible and reach the rest from a roll-out.
Right-click (or the hover ⋯ kebab) now opens an actions menu on Explorer items, channels, chat messages, editor tabs, and card/list/timeline/board/task rows — rename, move, archive, delete and more, in place.
Opening a document with a single click now shows it as a preview tab (italic) that the next click replaces — double-click, or start editing, to keep it. Matches VS Code, and now works from every list including the home page.
The web app is now a single shell: a sectioned, collapsible sidebar surfaces every tool (and previously-hidden routes like Meetings, Finance and Analytics), with a ⌘. focus mode to hide the chrome. The quiet/calm/workbench modes are gone.
Blog post #12, the series' first personal essay: on autism, dissociation, and the network dreamed in the timeout — with a new 'personal' tag on the blog index.
Fixed a workflow-file bug that failed every push, unblocked desktop releases (audiotee now targets macOS 14.2), moved the quality audit to a weekly schedule, and added guards (actionlint, storybook-shim conformance, DCO auto-sign-off) so red checks track real defects.
The malleable shell now has a real front door: a Labs section in Settings toggles it (and the other experiments) without any console tricks. Once on, panels show a grab handle, every dock lights up as a drop target while you drag (closed docks appear as edge strips), and a new Customize layout mode lays the whole shell out as draggable chips you can move, reorder, pin or hide — then save as a named workspace.
The Workspaces button now appears on the workbench rail and in the quiet shell's corner glyphs, not just the calm mode switch — and Settings → Appearance picks between the three layout presets (Quiet, Calm, Bench) with a shortcut to the workspace switcher.
The shell is one layout tree with three presets (Quiet, Calm, Bench) behind an experiment flag: move any panel between docks from its header menu, drag, or the command palette; save the arrangement as a named workspace node that syncs and can be shared like any document; and let the companion rearrange or scaffold new dockable views through undoable, consent-gated tools.
New Meetings surface: record a meeting without a bot — your mic plus (on desktop) system audio — with live Me/Them transcription that runs on-device by default (NVIDIA Parakeet v2 or Whisper, swappable in Settings), then merge your rough bullets with the transcript into AI-enhanced notes. Includes a meetings list + detail view, engine picker with model downloads, and privacy-first defaults: audio is never stored unless you opt in.
Turn any database into a form: build questions from fields with show-if rules, share a public link that needs no account, and collect responses as rows — validated and signed by your own device, never the server.
Blog post #11 traces the fifty-year lineage of apps-as-views-over-your-data — from Codd's data independence through Solid's pods and local-first to xNet's substrate — and why AI-cheap views make user-owned data the ground that's left.
The web and desktop canvases now share one core: media and PDF cards, dashboard widgets, query frames, and pinned records render identically on both (no more degraded cards after sync), and the web gains the desktop's power features — peek and inline editing of pages and databases, the selection action bar, linked-copies lookup, and multi-domain undo. Scene undo on the desktop canvas is fixed, and inside a focused canvas Cmd+Z can now undo an inline source edit when that was your latest change.
The storage engine, sync server, and app shells were reorganized into smaller, independently tested modules — same behavior, one shared conflict-resolution rule everywhere, and page comments now share one implementation across web and desktop.
Fixed the Share dialog failing with 'Failed to fetch': the hub now answers browser CORS preflights on its HTTP APIs, so listing, creating, and managing share links works from apps hosted on a different origin than the hub.
Console capture now lives on the devtools provider, so log lines recorded before you open the Logs tab (or while another panel is active) are no longer lost. A new opt-in Preserve toggle keeps the log across reloads for the current tab session, with tokens and emails scrubbed from the stored copy.
Opt in to quiet chrome (⌘K → View: Quiet chrome): the surface owns the screen, and the navigator, context panel, and a devtools-style dock are summoned from the corners and edges. Pin pages, databases, and views onto your new Desk — a bounded home canvas that follows your identity.
Two durability fixes: edits made offline before an app restart no longer get stuck behind the sync circuit breaker, and two devices editing the same field at the same logical time now always agree on the winner instead of depending on delivery order.
New reliability suite: deterministic sync simulation with seeded network chaos, SIGKILL crash-consistency testing, backup restore drills, 100k-node scale rails, and hub load smoke — run shallow on every PR and deep every night.
With xnet:query:debug enabled, plan diagnostics issued hundreds of serial SQLite worker round-trips per boot (EXPLAIN + per-index PRAGMAs per query), delaying real query results by 18-20s. Index metadata is now fetched in one batched statement, shared across concurrent callers, and plan diagnostics are collected once per unique query shape per session.
Every essay on the blog carries a byline — the human author linked to their GitHub profile, and Claude credited as the AI co-author — with first-party avatar images, per-author RSS credits, and structured data for search engines.
Blog post #10: how game modding built genres, why the walled-garden era locked that creativity out, and how capability-scoped views over data you own bring it back safely.
Fixed the release pipeline stall: the desktop app's version sync now maintains its own changelog (the missing file crashed every release run since July 4), and a failing npm Release workflow now raises a loud alarm issue instead of failing silently.
Reading your workspace got a structural speed-up: the database now returns each item as a single row instead of one row per field, list queries travel in one round-trip, and the query planner finally keeps statistics. On top of that, the app remembers your last-loaded lists and paints them immediately on the next visit while fresh data loads behind them.
The one-time database conversion that speeds up cold opens is atomic, so reloading mid-run used to cancel it with zero progress — and the slowness it fixes is exactly what makes people reload. xNet now remembers interrupted attempts: it shows a subtle "keep this tab open" hint while the optimisation is running again, and after repeated interruptions it starts the work right at first paint so the conversion finally lands.
Opening xNet in a second tab no longer loses local persistence: tabs elect a leader and share its database, and if the leading tab closes another takes over seamlessly. Queries also got faster — repeated statements skip re-parsing, multi-part reads travel in one message, and lists refresh more selectively after large syncs.
Freed pages from change-log compaction were returned to the filesystem one page at a time due to a WASM binding quirk, so the storage file plateaued instead of shrinking. Reclaim now drains the whole freelist per pass, and a pass that finds a stranded backlog returns it even when there is nothing left to prune.
Databases created before incremental auto-vacuum existed were never converted, so reclaimed space never returned to disk. The one-time conversion now keys off the database's actual auto-vacuum mode instead of a latched flag, so existing profiles get converted and the storage file starts shrinking.
The download page pulls the actual Electron desktop release (macOS, Windows, Linux) instead of the most recent npm package release, so every platform button points at a working installer. Desktop builds now also publish automatically alongside each core release.
Local databases now return freed space to the filesystem when old change-log history is compacted, so the file that determines cold-open speed shrinks over time instead of staying large. This steadily speeds up opening large, long-lived workspaces.
xNet Cloud now recognizes Stripe payment-failure and recovery webhooks and tracks a per-account non-payment lifecycle, so a failed card opens a grace period (and recovers cleanly) rather than silently doing nothing until the subscription cancels.
Change-log compaction, database VACUUM, and presence cleanup now wait until the workspace has painted before touching the single SQLite worker, so opening a large workspace is no longer slowed by maintenance work. A reset or protocol-skewed hub no longer triggers a full change-log re-offer on connect.
New runtime primitives (createMultiHubSyncManager + replication-scope helpers) that route each Space to only the hubs its policy selects, wiring up selective multi-hub replication over the existing multiplexed transports.
A new dunning lifecycle decision powers grace, suspend, and retention so a failed payment degrades an account gracefully — and never deletes your local data — instead of an abrupt cutoff.
A new Run on Mobile page (linked in the footer) shows a QR code that launches the xNet demo inside Expo Go — no App Store, no sideloading — plus copy-paste steps to run it yourself.
The humane-pattern build check now scans the site too, and the telemetry commitment is worded honestly — 'scrubbed and bucketed', not 'k-anonymized' — to match what the code actually does.
A new blog essay reframes alignment as continuous course correction across a nested stack of systems — physics, planet, society, technology, AI — and shows the instruments xNet hands back: undo, exit, consent, and a machine you can read.
A lagging sync cursor made the first outbound resync process the whole change-log slice synchronously — a multi-second main-thread freeze on cold open. It now sorts by code units (not locale) and yields to the event loop between batches.
A slow local-database open (which could intermittently exceed the startup timeout and show an initialization error) now retries automatically with a fresh worker instead of failing the whole boot.
A main-thread stall detector records how long the app freezes during a slow cold start and at which phase, so the cause can be pinpointed from one localStorage value.
The persisted boot timeline now re-captures itself after a stall settles, so a slow cold start is recorded in localStorage even when it happens after the app reports connected.
Boot-phase timings are now persisted to localStorage (xnet:boot:last) so a slow cold start can be diagnosed from a single value even when the console log is truncated.
A timed-out database open now releases its storage handles immediately instead of holding them while still initializing, so a retry no longer compounds the delay. Adds cold-start boot diagnostics that pinpoint where startup time goes.
Fixed a content-security-policy gap that blocked the WebLLM in-browser model from downloading its weights, so the on-device assistant now loads and replies.
The AI chat box no longer sits disabled with no explanation when you pick an in-browser model. WebLLM now runs a small model fully on-device after a one-tap download (with progress), Gemini Nano offers a download button when its model isn't ready yet, and every tier that can't run shows why instead of a silent dead box.
A developer-facing deep-dive on xNet's React hooks: how useQuery and useMutate let you specify your whole API in the client — including authorisation — and trust it, with a dive beneath the surface to the SQLite-in-a-worker, the priority scheduler, and the signed change log that make it safe.
On phones the calm layout shares the same three modes as desktop — Companion, Workspace, and Network drop to a bottom tab bar, with the list and contextual canvas as sheets.
New 'Calm' layout (now the default) reorganises the app into three modes — Companion, Workspace, and Network — with a conversation surface and a contextual canvas. Switch back to the multi-pane Workbench anytime in Settings → Appearance or via 'View: Switch layout'.
Returning to xNet now paints your recent pages, databases and canvases from a local snapshot in well under a second, instead of waiting on the first cold database read.
Click the status icon on any task — in the task list, on board cards, or inline — to open a dropdown and pick any workflow status (Triage, Backlog, To Do, In Progress, In Review, Done, Cancelled). It no longer just toggles the task complete.
You can now split your recovery across trusted people (any 2 of 3 can help you back in) and recover on a new device by collecting their share codes — no recovery phrase to memorize, and the cloud is never involved.
A deep-dive essay that follows one note all the way through xNet's internals — local-first storage, the signed change log, the keys you mint, and the no-referee merge — framed as the Luddite argument for a machine you're allowed to open.
If your xNet passkey syncs via iCloud Keychain or Google Password Manager, you can now recover your workspace on a new device with one tap — no recovery phrase needed.
Settings now shows your recovery phrase (behind a passkey prompt) for recoverable identities, so you can save it any time — and back it up to the system keychain in the desktop app.
Our fifth blog essay is live — a response to Benn Jordan's 'The Richest Country Is Pretty Mid Now' on how the economy shifted from growth to extraction, and the part local-first software can give back: the right to leave. Read it at /blog/the-right-to-say-no.
xNet Cloud now verifies the passkey that claims a hub with a real signature over a single-use server nonce, and the dashboard can recover your paid account and hub from your billing login if you lose the passkey (your encrypted data still needs a saved recovery phrase).
Fixed the plan default models (Claude Haiku/Sonnet/Opus) to OpenRouter's real catalog IDs, so managed AI works out of the box instead of failing with model-not-found.
Managed AI now lets you pick any plan-allowed model and set a personal spend cap by week, month, or rolling window — we stop calls when you hit it. Replies stream in token-by-token, prices shown are what you pay, and billing stays provably above cost.
Our third blog essay is live — what a star's equilibrium teaches us about information, attention, and building technology that burns long instead of burning out. Read it at /blog/the-gentlest-furnace.
The second post on the xNet blog is live: an essay on mycelial networks, the nervous systems of bodies, companies, and forests, and how an internet — like a damaged forest — is healed by biodiversity, reciprocity, and care. Read it at /blog/data-should-work-like-soil, or subscribe via RSS at /blog/rss.xml.
The top navigation is shorter and better organized: home-page sections (App, Teams, Vision) come first, then key pages (Why, Build, Blog). Cloud, Plugins, React, Commitments, and the changelog moved to the footer.
A new blog at /blog opens with an essay — A Great Pirate Age for the Internet — on data ownership, self-governance, and why you are the cargo. Subscribe via RSS at /blog/rss.xml.
The landing page got a thorough refresh — an AI-native section, an integrations gallery, the full app surface (CRM, finance, maps, labs), our six commitments, and an honest by-the-numbers strip whose counts are verified against the repo at build time.
Mobile is now wired to host the same xNet web app inside a native webview (Capacitor) rather than re-implementing documents, databases, canvas and dashboards — with OPFS storage capability detection so it picks the right backend per device.
New Languages & SDKs docs (Swift's XNetKit, Rust's xnet-core, and a maturity matrix), a /build-with marketing hub, a footer link, and cross-links across the site — so the native Swift/Rust implementations and the Vue/Svelte/Solid adapters are finally discoverable, each with an honest maturity badge.
The headless runtime is now the official 'use xNet from any framework' surface: a documented Vue/Svelte/Solid/vanilla binding over createXNetClient + liveQuery, plus runAdapterConformance — a shared, framework-agnostic suite that proves a binding's live-query, mutate, auth, and lifecycle behaviour in one call.
Settings → Data now has a 'Leave with everything' export that bundles your whole workspace, your portable did:key identity, and a re-import README into one file — nothing held back. Clearing your data is routed through an honest Delete Day with no guilt or nagging.
The Compare page's Protocols layer now includes xNet alongside AT Protocol and Matrix, and the sync-engines section's framing was corrected so it no longer contradicts the own-store tools (Turso, Ditto) it lists.
A new Settings → 'What we know about you' panel enumerates everything xNet has derived about you — buffered diagnostics, and (as they arrive) embeddings and AI memory — and lets you purge any of it. Because xNet keeps no behavioral surplus, the usual answer is simply: nothing.
An opt-in 'time well spent' reminder (off by default, in Settings → Appearance) that, after a long continuous session, slides up a calm note inviting you to step away — never a streak, never a guilt trip. xNet competes for your wellbeing, not your time.
New Right to Leave flow bundles your whole workspace and portable identity into one archive (with an honest Delete Day, no confirmshaming), and a 'what we know about you' mirror enumerates every derived artifact — telemetry, embeddings, AI memory — so you can purge any of it.
A narrative landing page (/why) that reframes everyday web surveillance as a physical-world thought experiment — then shows, with cited sources, how xNet's local-first model keeps your data yours.
The in-app AI assistant defaults to a 'scaffold' mode — it proposes and cites while you stay the author — and marks anything it writes as AI-generated, a guard against AI deskilling. Backed by a new Humane Internet Charter and a CI gate that keeps dark patterns and third-party tracking SDKs out of the codebase.
Reopening a populated workspace paints sooner: the first database read after a reload is now memory-mapped and the local file is defragmented in the background, cutting the cold-start stall.
The bottom status bar's connection indicator is now a click-through cluster: a calm chip when synced, plus on-demand chips for unsynced changes, integrity warnings, and storage pressure — with a detail popover and a Reconcile action. Mobile gets a matching sync glyph.
New opt-in Appearance options: a warm 'Cozy' theme (paper surfaces, terracotta accent, soft shadows, editorial serif headings) and a 'Comfortable' density that opens up type and spacing. Find them in Settings → Appearance; the default monochrome look is unchanged.
To-do checkboxes now show their real checked state and line up with their text, the block drag handle sits in the margin instead of overlapping bullets and checkboxes, and headings use a consistent vertical rhythm.
Server-side URL fetching (link unfurling, federation, crawling) now uses a single strict SSRF guard that blocks private network ranges earlier blocked inconsistently, and several duplicated helper functions were consolidated.
Map layers can now bind to a database by lat/lon and render live in the viewport, switch to a satellite basemap, or overlay aerial imagery — backed by new query, raster, and pmtiles layer sources and pure geohash spatial helpers.
Your workspace now starts syncing with the server immediately on load instead of waiting for local startup work to finish, so changes appear sooner. We also added detailed boot diagnostics and a one-time cleanup that reclaims disk space from old presence data.
Interactive reads now take priority over background writes, so opening pages and searching stay snappy even while a large sync or import is running. Repeated identical reads are also collapsed into one.
Returning users no longer wait through a long blank-screen pause before their workspace appears — local data now paints right away instead of queuing behind presence/document warming. Also fixes a background error that stopped your tracked-node list from saving.
Database views can now reuse their cached results across reloads even when per-row permissions are in effect — authorized once when the view is built, and automatically rebuilt the moment access changes, so a revoked viewer never sees stale rows.
The dev-tools Performance panel now shows a latency heat map (trace latency distribution over time), a frame-time/jank heat map, and an aggregated flame graph of where time goes across recent operations; the Traces panel adds a Waterfall/Flame view toggle for per-trace call nesting and self-time.
The dev-tools seed now bakes contextually-rich content into every node type — populated dashboards (charts, metrics, time ranges), pages exercising the full editor block + inline vocabulary, databases with all six views and advanced fields, canvas scenes with framed/grouped cards, and rich Task/Project/CRM/Experiment documents.
A single-page walkthrough of xNet React — the hooks, then a choice between a managed Hub or your own @xnetjs/server backend — plus a DevTools showcase and docs for running your own server.
Adversarial review of @xnetjs/server closed authorization, identity, and conflict-resolution gaps (cross-tenant write/delete, create clobber, signed-change spoofing, custodial clock drift) before the kit is exercised in production.
New @xnetjs/server lets developers run xNet's data layer on their own server with their own auth — a structured-query executor, backend-authoritative mutations, and a server/custodial/signed trust spectrum — while React hooks stay unchanged.
The dev-tools seed now fills out databases (columns, rows, views), a full CRM and ledger, nested folders and team workspaces, multiple rich linked documents, and canvas scenes — so it exercises every relationship in the app.
The dev tools can now seed a full demo workspace — projects, tasks, pages, canvases, dashboards, channels, comments and metrics, plus the relationships between them — from one button. Re-running converges instead of duplicating, and every new content type is covered automatically.
Each entry on the What's New page now shows the precise time of day it shipped (in UTC) next to its date, and the RSS and JSON feeds carry the exact merge timestamp — so feed readers and the in-app What's New order and date entries correctly, down to the minute.
The What's New / changelog list is now ordered strictly by when each change actually merged — down to the time of day — so several updates that shipped on the same day appear in the true order they landed, newest first, instead of being shuffled by entry name.
The Data panel in the dev tools (Ctrl/Cmd+Shift+D) now makes editing legible: read-only cells show a lock with a hover reason, editable cells don't, and the panel explains when a schema can't be edited — instead of silently refusing.
The schema dropdown in the dev tools' Data panel (Ctrl/Cmd+Shift+D) now shows how many entities each schema holds — e.g. Task (12), Person (0) — so it's obvious at a glance where the data lives. The counts respect your read permissions and update live as nodes are created or deleted.
The Data panel in the dev tools (Ctrl/Cmd+Shift+D) now reflects your real authorization per cell — cells you can't edit are locked instead of failing when you try, and a row's detail pane shows exactly how your read and write permissions are derived.
The Data panel in the dev tools (Ctrl/Cmd+Shift+D) now has the same rich table toolbar as the database UI — click a column to sort, build filter conditions with real operators, change row density, and show or hide columns.
When the app and your hub are on incompatible versions, every change can be rejected with an opaque 'invalid hash' error. Before, the app retried forever — flooding the hub and silently never syncing. Now the hub explains exactly what mismatched (it names both hashes and protocol versions), and the app stops pushing after a few rejections, logs one clear, actionable message, and automatically resumes the next time it reconnects to a compatible hub.
The hub's rejection now names the client hash, the hub's recomputed hash, and both protocol versions — a version skew is obvious instead of looking like data corruption
The app trips a circuit breaker after repeated structural rejections, so it no longer floods the hub with changes that can never be accepted
Outbound sync resumes automatically on the next reconnect, once the hub and app are back in sync
The in-app dev tools (Ctrl/Cmd+Shift+D) are reorganized around four high-signal panels — Data, Changes, Logs, and Performance — with everything else tucked into a grouped "More" menu and a ⌘⇧P command palette, so the bottom strip is no longer a wall of tabs.
Data panel: query and browse every node in the real database grid, with schema-aware columns, live updates, and a query-plan inspector
Edit data inline where it makes sense — toggle editing on a selected schema to change values directly in the grid (system and computed columns stay locked)
Logs panel: flip the sync/SQLite/query/boot/trace debug channels and read captured output in-app
Performance panel: cold-start boot timeline, live frame budget and memory, storage stats, and recent traces in one place
Jump to any panel by name with the ⌘⇧P command palette
Upgrading your managed hub is seamless — your data just gets more room, applied instantly. Downgrading is now guarded: if your data is larger than the smaller plan allows, we tell you up front and offer two clear paths — free up space and try again, or wipe and start fresh — instead of silently shrinking your quota. File uploads now count against the same plan quota as backups.
Your Cloud dashboard's Desktop tab now offers an "Open in desktop app" button that hands your hub to the installed app over an xnet://connect link. The app asks you to confirm before pointing itself at the hub — it never repoints silently, and only xNet-hosted wss hubs are accepted.
The xNet Cloud dashboard now walks you through connecting your web, desktop, or mobile app — with a copyable hub URL, a getting-started checklist, and links to help.
Ahead of xNet Cloud going live, the Terms and Privacy Policy now reflect accounts, billing, managed hosting, managed AI, and the marketplace — clearly separating the local-first path (we see ~nothing) from Cloud (exactly what we process). New Sub-processors and Acceptable Use pages, plus draft Data Processing Addendum and Marketplace Terms.
The xNet Cloud dashboard now has a persistent "Open web app" button in the header, so you can jump to your workspace from anywhere in the control plane — including before a hub is connected.
The home page now renders each list as soon as it loads instead of blocking on the slowest query, and your recently-opened documents are restored more reliably after a reload.
xNet now speaks to the services developers and hobbyists actually use — GitHub, RSS, Stripe, Sentry, Discord, and a generic webhook in both directions.
The last-writer-wins tiebreak that settles concurrent edits to the same field compared author IDs with `localeCompare`, which is locale- and ICU-version-dependent — so two devices could, in rare same-timestamp ties involving mixed-case IDs, disagree on which edit wins. It now compares by code-unit order everywhere, matching the protocol spec and the conformance vectors, so all peers converge identically. Found by the Rust core's adversarial review.
Phase 2 of the native-SDK work: `xnet-core`, a Rust implementation of the protocol's byte-exact kernel (did:key, the canonical-JSON change hash, Ed25519 sign/verify, per-property LWW, version negotiation, authorization eval). It passes the shared golden-vector corpus — and, with deterministic RFC-8032 Ed25519, re-signs changes byte-for-byte (which the Swift/CryptoKit kernel can't). It's the foundation for backing the Swift, Kotlin, and .NET SDKs from a single core via UniFFI.
`rust/xnet-core` reproduces the conformance corpus (identity, change incl. byte-exact re-sign, LWW, replication, authz) — a fourth conforming implementation alongside TypeScript, Python, and Swift
Ed25519 implemented on audited `curve25519-dalek` + `sha2` (RFC 8032); base58btc and canonical JSON inline — minimal, dependency-light crypto
An FFI-ready surface (`String`/`Vec<u8>`/`bool`) is built and tested; generating Swift/Kotlin (UniFFI) + a C ABI for .NET is the documented next step
Turn on Semantic search in the AI chat and the assistant finds context by meaning, not just matching words — fused with keyword search and your data's connections. It runs entirely on your device and is off by default.
XNetKit gained an on-device store: pass a `SQLiteChangeLog` to a `NodeStore` and every signed change is written to SQLite, then replayed on next launch to rebuild state. A native app's xNet database now survives restarts, with last-writer-wins preserved across the replay. Uses the system SQLite library — no extra dependency.
XNetKit's hub connection gained real-time streaming: a Swift client subscribes to a room and receives relayed changes the moment a peer publishes them — not just on-demand catch-up. Proven end-to-end against the reference TypeScript hub: one Swift client publishes a change and a second Swift client sees the live update arrive instantly. Full bidirectional, real-time native-Swift ↔ hub sync.
`HubConnection.subscribe(room:)` + `startStreaming()` run a read loop that delivers relayed `node-change`s to `onRemoteChange` live (each verified before apply)
`xnet-sync-demo` now proves both phases against the real hub: catch-up via `node-sync-request`, then a real-time streamed update between two Swift clients
Complements the existing publish + catch-up path — a native app can now stay continuously in sync, not just reconcile on demand
A new xnet_graph_expand tool lets a connected agent (via MCP, or the CLI) walk the typed links out from any node to its neighbors — fetching just the connections it needs for a question instead of loading the whole workspace.
When you chat with the assistant about your workspace, it now pulls in related items by walking the links between them — not just keyword matches — so multi-step questions get the connected context they need.
XNetKit gained a live hub connection: a native Swift client can publish a signed change to a running xNet hub over WebSocket and catch up changes from it. It's proven end-to-end against the real TypeScript hub — a Swift-signed change is verified (hash + Ed25519 signature) and stored by the hub, then caught up and materialized by a second Swift client. This is the first true cross-language round-trip, unblocked by the integer-lamport protocol fix.
`HubConnection` speaks the L2 replication protocol over `URLSessionWebSocketTask`: version handshake, room subscribe, `node-change` publish, and `node-sync-request` catch-up
`WireCodec` maps a Swift `Change` to/from the hub's `SerializedNodeChange` wire shape; a `NodeStore.onLocalChange` hook publishes local writes
`xnet-sync-demo` demonstrates the round-trip live against the reference hub; 16 Swift tests pass including a wire-codec JSON round-trip
While building the native Swift SDK we found that the runtime hashed a change's `lamport` field as an object `{time, author}`, but the protocol spec, the conformance golden vectors, and the reference kernels all treat it as a plain integer — so real changes didn't match the vectors and a spec-conformant client would be rejected by the hub. The runtime is now aligned to the spec: `lamport` is an integer, the author tiebreak comes from `authorDID`, and the conformance corpus finally represents reality. A breaking change (no migration; not live yet).
`Change.lamport` is now a `number` (the logical clock); the materialized per-property timestamp carries `author` separately for the LWW tiebreak
Cross-language interop unblocked: a change created by the TypeScript runtime now hashes identically to one from the Python/Swift kernels and XNetKit
Swept across sync, data, hub, history, runtime, react, data-bridge, devtools, cli, and the Electron IPC layer — 88/88 typecheck tasks and all suites green
A new brain layer connects your governed graph, full-text search, and the vector engine into one retriever — so the assistant pulls the right, connected slice of your data instead of being overwhelmed by all of it.
A real, runnable native Swift SDK lands. Define schemas in Swift, write and query the database in Swift, and bind results into a SwiftUI re-rendering loop — no JavaScript, no React. It's built on the conformance-pinned protocol kernel, so identity, signed change hashes, and LWW convergence match the TypeScript reference. This is the native-authoring slice of the Swift exploration (0210); live hub sync and persistence are the next steps.
Swift schema DSL (Schema { text(…); select(…) }) emits the same SchemaIRI as TS defineSchema; a native NodeStore signs every write into a Change and folds it via per-property LWW
Reactive @Observable LiveQueryModel drives a SwiftUI re-render loop the way useQuery does in React — plus a framework-agnostic LiveQuery and an AsyncSequence view
swift run xnet-demo walks it end-to-end; 11 tests pass including the shared golden vectors (identity, change hash, LWW) — verified on Swift 6.3 / macOS
The first step toward a native Swift SDK: an independent Swift implementation of xNet's interop kernel now reproduces the same did:key, canonical bytes, and BLAKE3 change hashes as the TypeScript reference, and verifies TypeScript-signed changes. The conformance corpus also grew new L2 (replication) and L3 (authorization) golden vectors, so the wire protocol stays honest across languages.
New Swift reference kernel (conformance/reference/swift) passes 18/18 L0+L1 checks against the shared golden vectors — proof the protocol, not the TypeScript source, is what implementations follow
Conformance corpus extended to L2 (version handshake, catch-up filtering, the byte-exact signed Yjs envelope) and L3 (authorization expression evaluation), drift-guarded in CI
Surfaced and documented a real Apple-platform constraint: CryptoKit's Ed25519 is randomized, so it verifies signatures but can't reproduce them byte-for-byte
The app now captures boot failures instead of showing a blank screen, the site and app gained cookieless analytics that need no cookie banner, the cloud server logs and reports errors, and one Privacy & Diagnostics control governs everything you share — off by default.
New managed AI tier: the chat panel routes through xNet Cloud's metered gateway with a live used/included/cap budget gauge — no key in the browser.
Switch between models from a picker grouped by family, with per-token price and context badges; cheaper plans get a curated set, bigger plans the full OpenRouter catalog.
Optional model fallbacks keep a chat working through a provider outage.
The public /open dashboard now publishes live usage at scale — workspaces hosted, documents synced, data under management, people on the platform, and AI tokens metered — alongside the financials, all privacy-safe aggregates.
xNet now greets you with light, one-at-a-time tips the first time you open a view — what ⌘K does, where your CRM lives, how Tasks work — each dismissible and never in the way. Replay them anytime from Settings → Tips & tours.
The app no longer re-sends its whole change history to the hub on every load; sync now resumes from where it left off and throttles bursts, so the connection stays steady instead of tripping the hub's rate limit.
The Extra Charts plugin (donut + horizontal bar) now ships in the desktop app too, and the plugins marketplace clearly flags first-party connectors that need explicit setup rather than implying they auto-install.
New chart types, map basemaps, and canvas shapes can be added by a plugin with no change to core code, via shared runtime registries. A bundled Extra Charts plugin adds donut and horizontal-bar charts as a worked example.
Fixed a regression where a reload race could drop the local database into memory-only mode, so the app appeared empty until it re-synced from the hub; it now retries and stays on persistent storage.
The app now warms the local cache and hub connection during boot and shows a clear 'restoring' state instead of a blank screen, so returning users see their workspace sooner.
Each changelog entry now shows every contributor to its pull request — not just a single author — as linked GitHub avatars, on the website and in the in-app What's New.
Browse every plugin xNet ships out of the box and everything the community builds — on the website and inside the app — and publish your own with a one-line PR.
xNet Cloud now publishes its live operational status, ships a containerized control plane you can deploy to Cloud Run, and can run against real Stripe/WorkOS APIs straight from your laptop.
New /status page — control plane, hub fleet, managed AI, and backups, with aggregate-only uptime (no tenant is ever identifiable)
The control plane is now containerized (apps/cloud/Dockerfile) with a build + smoke-test script and a keyless (Workload Identity Federation) deploy workflow
Run against staging credentials locally with `pnpm --filter xnet-cloud dev:staging` plus a git-ignored .env.staging.local for localhost OAuth/webhook overrides
A weekly job refreshes the run-in-public /open metrics from live Stripe and opens a PR for review
A new governed connector and game-interop schema pack let an Unreal Engine 6 title's durable player data — identity, inventory, achievements, matches, and economy — sync into space-scoped xNet nodes you own.
xNet Cloud gains a managed AI gateway with transparent, metered billing — usage is shown against an included budget with a hard cap so there are no surprise bills — plus self-serve plan changes. And a new public dashboard shows our real customer growth, revenue, and full cost breakdown as we build toward break-even.
Changelog screenshots are now a scrollable gallery: click any shot to enlarge it, hover a before/after to flip to the before image, and press and hold to reveal the diff.
Chat and channels are rebuilt to feel like Slack, Discord, or Zulip — grouped messages with avatars, emoji reactions, threaded replies, presence, and a smarter scroll.
Database grids gain a summary footer with per-column aggregations and an adjustable row height, so you can read totals and tune density right in the view.
A small, consistent animation vocabulary now runs across the app, so things move in a calm, on-style way. Toasts and banners glide in and out, and switching workspace scope cross-fades instead of snapping.
Moving from Slack just got easier. A new Slack connector imports your channels and message history into native xNet messages, and a Slack-compatibility layer translates Slack formatting so existing integrations are easier to carry across.
Page documents now read like Notion or Obsidian. Body text, bullets, numbered lists, to-dos, and blockquotes all share one clean left edge, the text column is centered, and the page title has a clear hierarchy.
The Tasks surface gets a Linear-style overhaul — faster in-surface navigation, multi-select bulk actions, a detail slide-over, and powerful filtering and grouping.
Connectors sync an external service into governed nodes and expose agent tools — your AI works with policy-checked data while the access token stays in the hub.
When you drive a local agent from xNet, it now gets governed tools to read and write your workspace — with writes gated by policy and your token staying local.
A new local bridge lets xNet drive your own Claude Code or Codex CLI — bring your own agent, no extra API key, and your token never leaves your machine.
xNet now keeps a changelog you can actually read. Every release is summarized here, on the website, and inside the app — so you always know what changed when a new version lands.
A public changelog page with a JSON and RSS feed you can subscribe to
An in-app "What’s New" panel that flags updates since your last visit
Release notes on the desktop app are now written in plain language, not raw commit logs
UI screenshots captured by CI can be embedded directly in changelog entries
The in-app assistant now reads your own workspace — your notes, tasks, contacts, and more — so its answers are grounded in your data, with citations. It also remembers the conversation instead of treating every message as the first.
xNet Cloud now measures uptime against real service-level objectives, ties upgrades to error budgets, and runs backup restore drills — the operational backbone behind the managed fleet.
Building and sharing plugins is now first-class. A scaffolder gets you from zero to a working plugin in seconds, and an enforceable capability model keeps installs safe.
Plugins, labs, the AI surface, and the editor are converging into a single extensibility fabric, so a capability built in one place can be reused everywhere.
Don’t want to run your own hub? xNet Cloud hosts one for you. A new onboarding flow takes you from signup to a provisioned hub, then lets you claim it from the app.
Plugins now run on an enforceable platform layer — capability gates, provenance and trust checks, dependency resolution, and a searchable marketplace index — so installing a plugin is governed end to end.
CRM, accounting, tasks, experiments and spaces are now fully editable and consistent. Open any record to see every field, with bespoke views where they help.
xNet grew a native CRM — a universal party model, pipelines, deals and activities that reuse the same social and schema primitives as the rest of the app.
Every pull request that touches the interface now gets before/after screenshots and GIFs captured by CI — the same visuals that can feed this changelog.
Run personal experiments and track habits in xNet, with streaks, correlations and a verdict engine that stays honest about what the data can and can’t show.