• v1.21.6 1ea70b1390

    Morphit v1.21.6
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 43s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m10s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 54s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 5m7s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 45s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h20m57s
    morphit-release / Build + publish release tarball (push) Successful in 38m16s
    Stable

    Ghost released this 2026-10-12 16:57:02 +00:00 | 17 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.6

    A Tor/I2P-only server whose new release is not reachable yet now says so plainly and offers a way
    forward, instead of stopping with a red ✗. Chats can be scrolled back to the first message and exported
    whole, every FAQ answer was checked against the code and rewritten, a branded site names itself in many
    more places, and the stats page's RPC card shows each node's measured state the moment it opens.

    Upgrading: sudo morphit-ops upgrade on every server. No database change. Like every change to the
    upgrade, the new behaviour starts with the upgrade AFTER the one that installs it. Every instance must
    run v1.21.1 or later before 2026-11-01 00:00 UTC.

    Zero-clearnet upgrades that have to wait

    On 2026-10-10, morphitlat's upgrade to v1.21.5 stopped twice ("could not reach this node's own indexer
    … no answer within 60s"); the third try, a minute later, went through. Nothing was wrong: its indexer reads
    the chain over Tor and I2P, and one read can take longer than a minute.

    • It keeps asking. The signed release record is now asked for again, for up to 8 minutes, when no
      answer comes in time — not only when the answer lacks the record.
    • It says what it is doing. One line on how a zero-clearnet upgrade works, then a spinner that names
      the step (reading the signed record over Tor/I2P; searching the federation, which instance it is asking,
      how many it has asked, how many had no copy) and counts the time. The long per-URL lines are gone.
    • When the release cannot be reached yet: what it searched and for how long, what each instance
      answered (by its directory name: "does not have v1.21.6 yet", "did not answer in time", "could not be
      reached"), and that nothing was changed. At a terminal it asks: 1 try again now, 2 keep trying by itself
      for up to an hour, 5 minutes after each try (it still asks before installing), 3 stop for now and try
      again once more trusted instances have upgraded. Unattended it explains and stops, nothing changed
      (exit 5).
    • A record signed by another key, or any other fault, is still a plain fail-closed error — also when the
      node it asks lists a second record or did not answer in time on an earlier try.
    • An instance that does not answer no longer holds up the others: the next one is asked as soon as any
      one has answered (before, one silent instance could hold up every one after it for up to 20 minutes).
    • If the server was upgraded by another session while it waited, it says so and stops, nothing changed.
    • The waits run on a steady clock, so a Tor-only box that corrects its clock mid-wait neither stretches
      nor cuts them; "kept trying for" shows the time it really took. Instance names in other scripts
      (Chinese, Hindi, Persian) are shown whole and fit the spinner line; anything that could steer the
      terminal is removed from them.

    The site

    • Chats: scroll back to the first message, and export all of it. Scrolling up in a conversation now
      loads older messages, page by page, all the way to the first one. Before, only the newest 50 messages
      between the two of you could be reread, and a discussion whose messages were all older than those 50
      showed as empty; it now shows them. Export chat now puts every message the two of you ever exchanged
      in the PDF, from every discussion, each run of messages headed by the order it is about ("Not about an
      order" for the rest). It reads the whole history first and keeps trying for up to about two minutes if
      the site is busy; if part of it still can't be read, nothing is saved and it says so. Nothing is saved
      either if the session locks while the file is being made. Messages sent in the same block now show in
      the order the chain recorded them (they could appear the other way round). Old payment and address
      messages loaded by scrolling back never change the status of a trade.

    • Run a node → "Your relay account pays". Shorter lines, in every language: "Startup: 102 BLURT for
      each new account your site creates (the chain's fee plus 2 BLURT to start)."; "10 BLURT + 10 Blurt
      Power (BP) upon your user's first completed (paid) trade."; "BP rewards lent: 1 BP welcome stake and
      loyalty-program rewards up to 1260 BP per user. You can retract it." The top-up line is unchanged.

    • A branded site names itself in many more places. About 120 more strings now show the site's own
      name instead of "Morphit" (about 150 more mentions in English, mirrored in all ten languages): the FAQ (21 questions
      and the answers that speak about the site the visitor is using), the glossary, sign-up and the backup
      card, the backup-keys page, the wallet and posting errors, the post form, the security page, settings,
      page descriptions, the update notice, and the Blurt posts a user publishes ("I joined Vigilante
      Trading", "Check out my offer on Vigilante Trading!"). Mentions of the software, the project, the
      federation and other instances, releases and versions, the treasury and @morphit still say Morphit.
      The degraded-mode page names the site too.

    • Places that showed the address morphit.io on every site no longer do: the cheat sheet's "lost your
      device" step, the Safari push-notification help, the phishing warning ("sites that look like this
      one"), the QR-login warning and "the web app you see at morphit.io". The footer's Compare link said it
      compares Morphit "to other options"; it compares this site's orderbook with another instance's, and
      now says so.

    • Homepage: the first-trades card. No "Your first trades" pill; the line under the heading reads "Pick
      a cool username, that's it. Once it's registered on the chain, you can start trading anything,
      instantly." Six numbered tiles, all in the brand tint and all floating gently: Get in, Post a buy (its
      "(it's free)" only where this site pays the free first buy), Private chat, Welcome coins, Passive income
      ("…auto-pay you daily at N.NN% apr", the same staking rate and formula as the wallet, read through this
      site's indexer; no rate is named until it arrives, or when the figure is not one a real chain gives) and
      Loyalty rewards. A site without an operator tag
      pays no rewards, so it shows four tiles (no welcome coins, no loyalty rewards). More room above and
      below, so the glow no longer crowds the cards above or the coins below. The card, and its rate read,
      load only when it scrolls near (a placeholder of the same height holds its place; without JavaScript
      the placeholder takes no room).

    • Primary buttons light up on hover. Every button with the solid brand face (the "Create your free
      account" style, including the hand-built ones in the wallet, chat and modals) shows a 1px edge in the
      brand accent on hover; disabled buttons do not.

    • "BLURT" in capitals means the coin, and only the coin. The chain is "Blurt": "Blurt is Morphit's
      coordination chain", "Morphit runs on Blurt, and listing fees are paid in its coin, BLURT", the
      glossary entry ("Blurt (BLURT)": a blockchain and its coin), the BLURT payment-method and asset
      descriptions ("the coin of Blurt, the chain … runs on"), and "Blurt Power" everywhere (it was written
      "BLURT Power" in ten places per language). Every BLURT left is an amount, a balance, a price or a fee.

    • Footer. The "Runs on Morphit" line under the footer logo is gone (it showed only on branded sites).
      About this instance, linked in the footer, still shows which Morphit version a site runs.

    • Six languages still said "on Morphit" in three older texts (the USDT and Dash privacy guides, the
      Dogecoin asset note) where English names no site; they name the site now.

    • FAQ search finds the introduction for "what is this", "what is this site", "what's this app" and
      "what is this platform about" again, and on a branded site also for the site's name ("what is
      Vigilante Trading"). In v1.21.5 it answered "what is this" with an unrelated entry (the iPhone one on
      an unbranded site). On a branded site, a name made of everyday words no longer buries answers about
      those words ("escrow" on a site called "Escrow Shop" finds the escrow answer), a name inside other
      words is left alone ("Bit" in "Bitcoin"), and a search that names Morphit still finds its answer.
      "where is the app" finds how to install it.

    • Stats → RPC endpoints shows real measurements the moment the page opens, and keeps them fresh.
      Before, the card first showed the relay pool's passive view (every hidden node "offline", clearnet
      latencies from whenever they were last used), then about 20 seconds later the result of a fresh probe;
      the refresh button repainted the passive view (mostly red) while it spun. Now the indexer measures
      every published node itself, each one every 20 seconds (with one retry on a miss), and answers the
      card instantly from those measurements. The card asks again every 10 seconds while it is visible and
      when you come back to the tab, shows how long ago each node was measured ("measured 6s ago"), and never
      replaces a newer answer with an older one. The refresh button asks the indexer for a fresh round
      (at most once every 5 seconds; nodes are never probed twice at once) and keeps the current rows on
      screen while it waits. A node not measured yet (just after the indexer starts) says "probing…", not
      "offline"; a failed node shows its real reason (a node that stalls mid-answer now reads "timed out"); the
      "reestablishing" label is gone. The card no longer waits for the page's other statistics to load first
      (or vanishes when they fail), and those statistics keep their place while they load, so the card does
      not jump. It counts "measured … ago" on the indexer's clock, and keeps working if either clock is off or
      is corrected; without JavaScript the stats page shows no empty figures or "probing…". morphit-ops health now shows each node's latency (it showed "—" for every node), and a node the indexer has not
      measured yet reads "being measured" instead of counting as unreachable.

    • For API users: /v1/chat/:a/:b takes order=<permlink> to read one discussion (order= with no
      value: the one about no order). Paging through /v1/chat/:a/:b, /v1/accounts/:account/feedback and
      /v1/accounts/:account/feedback-given could skip rows recorded in the same block (they were sorted by
      their id as text, "100" before "99", while the cursor compares numbers); every row now comes once. A
      page far back in a chat history reads only that page. Each row of /v1/rpc-endpoints now carries
      checked_at, and cooldown_ms is always 0. /v1/stats counted a trade reviewed by both people twice; it counts it once now.
      /v1/activity/volume added an order's volume once per review; it adds it once per order now. docs/API.md
      documents /v1/rpc-endpoints and the reputation receipt, and no longer lists a /v1/accounts/:account
      route the indexer never served.

    • Every FAQ answer was checked against the code and rewritten to be short and plain. All 146
      answers, in all ten languages, about 40% shorter overall (44% in English). A second, independent check
      of every answer against the code followed, and its corrections are in too. Every number and claim was verified in the
      code (fees, limits, timings, rewards, rate limits, menu labels); claims the code does not support were
      removed or corrected, internals and history were cut, and cross-references now match the current
      question titles. Answers now link to the pages they mention (My Orders, Run a node, the privacy
      guides, the explorer…), and the three that showed "/privacy/{asset}" literally now link to the privacy
      guides. "What's the most private way to sign in?" has a new title. Notable corrections: the no-JavaScript
      answers (the FAQ answers, privacy guides, orderbook, profiles and reviews need JavaScript; pages like
      security, glossary and run-a-node, the FAQ's questions and the RSS feeds do not), the welcome bonus (two
      welcome rewards, how the free first buy fits in), hidden accounts (saved with your encrypted settings
      while signed in, so they follow you; the hide button is on computers and tablets), the "New trader"
      label (fewer than 4 completed trades), QR sign-in (the computer can't read chat messages), the chain's
      smallest Blurt Power loan (about 33 BP), the chat export and rereading old messages (now everything
      ever said, see above), the Monero TxID (also asked for when you tell a partner you paid in XMR), and when a
      BTC/XMR price falls back to other sources.

    • The same check found a few screens saying things the code does not do; they now match it: the
      no-JavaScript notice (it said orders, profiles and reviews work without JavaScript), Settings →
      Utility (signing out does wipe your keys from the device; Lock session keeps them), the hidden-accounts
      note and hide button (the list follows you while signed in), the "New trader" screen-reader label, the
      stranger-fee slow-down notice (blocks do not lower your standing), the QR-paired computer (chat
      messages open only on the phone), the DAI network warning, the free first order's next steps (a review
      can't cite the free order) and the review form ("free" → only Blurt's tiny network fee).

    Smaller

    • The snapshot mirror names only the addresses this server really has (clearnet, .onion, .b32.i2p).
    • The staking rate shown on the wallet, the explorer and the homepage is left out when the chain data
      behind it gives a rate no real chain state gives (20% or more); a lying RPC node could otherwise put any
      rate there.
    • FAQ links that point to another site always open in a new tab and never pass the page along.
    • The indexer reads at most as many RPC directory nodes as a valid signed directory can hold.
    • A chat that reconnects to its live stream no longer misses messages sent in the same block as the last
      one it had (the catch-up read sorted ids as text). The indexer also sorted block numbers as text in a
      few places (operator registrations, BTC fee addresses, the upgrade reconcile); that would have gone
      wrong from block 100,000,000. Fixed now.

    About the v1.21.5 upgrade (no action)

    • An upgrade to v1.21.5 run by v1.21.4 printed "⚠ Your instance origin could not be applied (… this build
      is branded …)" and the same run then applied the origin anyway. v1.21.4's branding reset wrote back a
      setting v1.21.5 no longer uses, so the fresh build looked branded for a moment. One-time: the self-heal
      (run by v1.21.5) fixed it, and v1.21.5's own upgrades do not do it. A box upgraded straight from an
      older release (timeapp) shows it once too, then the same fix.
    Downloads
  • v1.21.5 21e56d47e2

    Morphit v1.21.5
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 41s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m11s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 51s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 4m31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 46s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h29m38s
    morphit-release / Build + publish release tarball (push) Successful in 45m48s
    Stable

    Ghost released this 2026-10-11 01:02:38 +00:00 | 18 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.5

    A Tor/I2P-only server can now copy the federation snapshot from its peers over Tor/I2P, and a brand-new
    one can fast-sync privately instead of replaying the whole chain. The site names only the coins its
    operator accepts, the homepage invites visitors to make their first trades, the stats page's RPC card
    shows each node's real state again, and the BETA marker is gone from the logo.

    Upgrading: sudo morphit-ops upgrade on every server. No database change. morphit.io first: its
    next anchored snapshot then names its .onion and .b32.i2p. Every instance must run v1.21.1 or later
    before 2026-11-01 00:00 UTC
    , when the stricter consensus rules start.

    The federation snapshot over Tor/I2P

    • The mirror asks the federation. v1.21.4's fallback looked for peers only in operator registrations
      in @morphit's history. That history holds none (all 169 entries read on morphit.io, 2026-10-10), so on
      morphitlat it asked nobody ("no federation peer's .onion or .b32.i2p address was found"). It now asks,
      in order: the publisher's own addresses from the signed snapshot record, this server's federation
      directory (the same list its upgrades use; the publisher's instance first), then any registration in
      that history. A peer that does not hold the snapshot answers at once.
    • The snapshot record names the publisher's hidden addresses. ops/pin-indexer-snapshot.sh adds
      hidden_mirrors (this server's .onion and .b32.i2p, as its indexer advertises them at /v1/instance)
      to the indexer_snapshot_v1 record, under the same signature. A new server fast-syncs before it has an
      indexer, so this is where it learns a private source. Servers that do not know the field ignore it
      (checked against the v1.21.3 validator); a malformed one is dropped, and the publisher refuses to
      sign one.

    The site

    • Homepage. The "Run your own Morphit site" card is replaced by a card that invites a visitor to sign
      in and make a first few trades: three steps, and on a site whose relay pays them, the three rewards (a
      free account, a free first buy, 10 BLURT + 10 Blurt Power after the first completed trade on a paid
      listing). Its border light, glows and heading sheen move slowly, use only the theme's colours (so a
      branded site re-tints it), and stop for visitors who ask for reduced motion. Someone who already has an
      account on the device is sent to post or browse instead of to sign up.
    • Orderbook. The "What you get on Morphit" card is gone.
    • Run a node. The "You automatically earn" and "Your relay account pays" boxes have the new wording
      (the Startup cost per new account, Blurt Power (BP), retractable rewards, the rule of thumb).
    • Download. The Install, Source code & releases, Setup walkthrough and Join the federation cards are
      gone. The intro says you can "install" an instance with an "app" icon or run your own node and be listed
      in the Federation directory, with links. The Codeberg mirror says, in red, "Crypto projects banned".
      "Morphit is 100% free and open source."
    • Stats → RPC endpoints. The card asks the indexer to ping every node, and the indexer answers only
      once the slowest has answered or timed out — up to about 42 seconds when an I2P node is slow or down
      (two tries of up to 20 seconds). The browser waited 8 seconds, gave up, and kept the pool's passive
      snapshot: "Probing…" for the hidden nodes, which the pool seldom calls, and stale figures for clearnet
      nodes it had not used lately. The browser now waits for the probe. (The reverse proxy's 60-second limit
      for /v1/ is longer than the indexer's worst case; a new smoke holds the three numbers together.)
    • Footer. The "Source" link under Resources is gone.
    • licenses.txt. Now also lists Vite (its small lazy-loading helper is in every page's code; Vite's own
      MIT licence only, not those of the build tools it bundles) and the Comfortaa font with its SIL OFL text,
      and shows every source as a plain https link.
    • Security page. "Look at the Network tab in your browser." The zero-clearnet, chat and release cards
      were checked against the code and rewritten:
      • Zero clearnet: the software refuses clearnet and a firewall lets only Tor and I2P out; package updates
        and the clock go over Tor too; the node moves to Tor bridges by itself. Fee checks and prices travel
        over Tor (not I2P). The claim is the node's own, made when its own checks pass.
      • Chat: the encryption (X25519 and ChaCha20-Poly1305) and sender proof as before, plus key pinning and
        the 60-digit safety number; and plainly what is public — messages live on the Blurt chain, so who,
        when, which order and each message's length are visible.
      • Releases: the git tag is GPG-signed on main; the record also anchors the offline bundle's hash; the
        browser reads it from a public Blurt node and names any file that differs.
      • The directory's "Zero use of clearnet internet" badge now says, on hover, that it is the instance's
        own claim.
    • Privacy & terms. "your chat conversations stay 100% private"; "a VPN, Tor, I2P, ENS or Lokinet";
      the zero-clearnet paragraph corrected the same way (and "a marketplace node with no clearnet address to
      block").
    • About this instance. The "BTC fee key" row is gone: it showed a short key id a visitor could not
      check against anything. (Which BTC address an order's fee goes to is still checked in the browser
      against the key @morphit pinned on chain.) The file count is the number of files verify.json lists —
      per site and per version — and the text now says exactly that.
    • The coins this site accepts. An operator who switches coins off (MORPHIT_INDEXER_DISABLED_ASSETS)
      now sees that everywhere the site names coins:
      • the homepage carousel (a network appears only while an accepted coin settles on it; barter only when
        accepted; the two rows stay within one icon of each other);
      • the cheat sheet's asset list and the privacy guides' index;
      • the FAQ: the entries about a switched-off coin are left out (and from "Related"), and the answers that
        list the coins traded here ("What is Morphit?", "Where can I buy Blurt?", the welcome bonus, the
        stablecoin warnings, privacy coins) list this site's coins and count them.
    • Plan. "Phase 7 — Cryptocurrency support", planned.
    • Logo. The BETA marker is gone for good. morphit-ops branding apply --beta now says so and stops;
      a MORPHIT_INSTANCE_BETA_BADGE line left in morphit.config.env is ignored.

    Correction to the v1.21.4 notes

    • They said the mirror asks "the publisher's own .onion and .b32.i2p (from its on-chain registration)".
      @morphit has no such registration, so it asked nobody.

    Documentation

    • docs/SECURITY.md said the release job fails without the signing key. It publishes without .asc files
      then, and installed nodes accept the tarball only by its SHA-256 in @morphit's signed record.
    • docs/VERIFY-YOUR-DOWNLOAD.md named three git hosts; the source is mirrored to many.

    Tests (maintainer)

    • ops-cli tests can no longer reach the internet (test/setup/noInternet.ts), judged by the address a name
      resolves to (CI's database is the container postgres).
    • The snapshot mirror's lookup of its own directory names itself (user-agent), like every indexer fetch.
    Downloads
  • v1.21.4 940ea8aa39

    Morphit v1.21.4
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 56s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m41s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 47s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 4m37s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 45s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h20m40s
    morphit-release / Build + publish release tarball (push) Successful in 38m5s
    Stable

    Ghost released this 2026-10-10 05:21:02 +00:00 | 19 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.4

    A server on a network that filters Tor now moves its Tor onto bridges by itself, so its .onion stays
    reachable. The twice-a-day release check, new in v1.21.3, works now: it could not run anywhere. An
    upgrade no longer refuses a release because one node's history did not list its on-chain record yet.
    A Tor/I2P-only server can now hold its own copy of the federation snapshot.

    Upgrading: sudo morphit-ops upgrade on every server, Tor/I2P-only ones included. No database change.
    This upgrade is run by the upgrade program of the release the server runs now. The repairs below run
    from this release during the upgrade; the changes to how an upgrade reads the release record and to its
    last lines take effect from the next upgrade. Every instance must run v1.21.1 or later before 2026-11-01 00:00 UTC, when the
    stricter consensus rules start.

    Tor on a network that filters it

    On 2026-10-09, morphitir's Tor loaded nothing:

    • Its network sends every torproject.org name to a sinkhole (10.10.34.36).
    • Connections to Tor relays open, but the circuits built over them stall.
    • Plain Tor loaded 0 of 6 pages, and so did a fresh Tor client.
    • The .onion could not publish its address record, so nobody could reach it over Tor.

    Over the Tor Project's built-in bridges, Snowflake and obfs4, Tor connected at once. With those bridges
    in /etc/tor/torrc, morphitir's .onion answered, from morphitir itself and from morphit.io.

    • The Tor bridges repair. It runs in the upgrade's background checks, and on a new timer
      (morphit-tor-bridges.timer: half an hour after the timer starts, at boot or when the upgrade turns
      it on, then every 6 hours). To run it now: sudo morphit-ops upgrade --tor-bridges.
      • It first checks that Tor works: this server's own .onion, then a page through Tor. A Tor that works
        without bridges keeps its configuration.
      • When Tor loads nothing, it installs the transport programs from the distribution
        (snowflake-client, obfs4proxy).
      • A Tor/I2P-only server uses obfs4 only: Snowflake needs DNS, which that server's egress rule refuses.
        Its downloads go through Tor, so it installs obfs4proxy while Tor still works. If its Tor loads
        nothing before that, the result says how to bring the package in by hand.
      • It writes the bridges into /etc/tor/torrc between # >>> morphit: Tor bridges markers, only
        after tor --verify-config accepts the file. The first original is kept as
        /etc/tor/torrc.bak-before-bridges. The onion service's keys are not touched.
      • Tor restarts and must connect within 5 minutes; then the .onion or a page must load through it.
      • A server already on bridges that loads nothing gets the release's bridges again, then plain Tor;
        when plain Tor works, the bridges come out again.
      • A server on bridges that works is checked, at most once a day, with a separate, throwaway Tor client
        without bridges, run as Tor's own user. It connects to public Tor relays, which a filtering network
        can see. When it loads through plain Tor, the bridges come out, proven the same way. If this
        server's Tor then does not work without them, they go back, proven, and plain Tor waits a week.
      • When nothing works, the previous torrc goes back and Tor restarts on it. If it cannot be written
        back, the result says so.
      • /etc/tor/torrc is read again before each write, by this repair and by the onion proof-of-work
        repair. An edit made meanwhile, by an operator or another repair, is never overwritten or put back
        over.
      • Each Snowflake bridge also names one domain front as front=, the only form Ubuntu's
        snowflake-client reads.
      • The whole repair takes at most 45 minutes, and runs one at a time.
      • The timer only runs with an upgrade program that knows --tor-bridges. On a server moved back to an
        older release it does nothing.
    • The bridges ship with the release. A network that filters Tor blocks torproject.org too, so the
      list Tor Browser uses is in ops/tor/builtin-bridges.json. docs/OPERATIONS.md §51.0 says how to
      refresh it.
    • The IPFS seed check tries a .onion three times. When it still fails, it says why (curl's own
      message) and names the repair, instead of one try and "HTTP 000".

    The release check

    • It works now. In v1.21.3 it failed on every server with "morphit-indexer.service is not running"
      while the indexer ran:
      • It runs as a throwaway user in a sandbox that cannot read /etc/morphit/indexer.env. So it could
        not tell a clearnet server from a Tor/I2P-only one, and took the strict path.
      • That path proves the answer on the indexer's address comes from the indexer service. To do so it
        asked systemctl for the indexer's process ID, and systemctl cannot reach systemd from that
        sandbox ("Transport endpoint is not connected").
      • It now reads the indexer's processes from its cgroup, which only systemd writes. The listener must
        still belong to the indexer's user. Proven on morphitir's real unit.
    • A reason too long for its alert ends with "…", instead of breaking off mid-word; one that already
      ends with a full stop no longer gets a second one.

    Upgrades and the release record

    • One node's answer no longer decides that a release has no record. On 2026-10-08 morphit.io's
      upgrade read @morphit's history through one node that did not list the new record yet, and refused;
      the same command a minute later worked.
      • The upgrade now asks this server's indexer, then each configured Blurt node directly (not on a
        Tor/I2P-only server).
      • When a node answered without the record, or listed it without having its block yet, it asks again
        for up to 3 minutes, under the spinner, before refusing.
      • The record's signature decides, so any node may be asked. On a clearnet server, a release signed
        by a pinned key needs no record and never waits.
      • The wait ends on time: no node is asked once the 3 minutes are up.
    • The last lines say "Every service restarted on it (checked)." whenever each restarted service,
      the MCP server and the Matrix alert bot included, was seen to stay up on the new version. Before, any
      unrelated warning, such as one from the IPFS seed check, dropped that sentence. It is left out when
      one did not come back, or when no service was restarted.

    The federation snapshot

    • A Tor/I2P-only server can mirror the snapshot. The mirror only asked IPFS's own network. A
      Tor/I2P-only server sees two or three IPFS peers, and they need not hold the snapshot, so morphitlat
      never became a mirror.
      • When IPFS cannot fetch it, the mirror now asks the publisher's own .onion and .b32.i2p (from its
        on-chain registration) for the snapshot as a CAR (/ipfs/<cid>?format=car), and imports it under
        the same CID.
      • Only the snapshot's own CID is pinned from it, whatever the peer's CAR names as its root. A peer's
        answer is read only up to 64 MB, and a redirect is never followed.
      • Fetching stops 18 minutes into the mirror's run, leaving the later steps their time within its 30
        minutes. A server with only a few IPFS peers gives the swarm 3 minutes and leaves the rest to the
        federation peers.
      • The check against the signed SHA-256 still decides whether it is kept.
      • morphit.io answers ?format=car both from its IPFS node and through its site (kubo 0.42.0).

    Releases (maintainer)

    • Block 4 waits until the nodes list the record. After the broadcast it waits up to 5 minutes
      until the nodes list the transaction in @morphit's history, which is where upgrades look for it.
      Start Block 5 when it prints "Block 5 can start". This is what protects servers still running an
      older upgrade program, which believes the first node that answers. A node that listed it once counts
      as listing it, even if it stops answering.
      • It asks the public nodes. A Tor/I2P-only server on an older upgrade program reads through its own
        hidden nodes, which can list the record later: if its upgrade says there is no record, run it again
        a few minutes later.

    Correction to the v1.21.3 notes

    • They said "This upgrade is run by v1.21.2's upgrade program". Servers on v1.21.1, such as morphitir
      and morphitlat, ran v1.21.1's.
    Downloads
  • v1.21.3 697bc93e6e

    Morphit v1.21.3
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 36s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m4s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 43s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 4m20s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 43s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h18m17s
    morphit-release / Build + publish release tarball (push) Successful in 36m32s
    Stable

    Ghost released this 2026-10-09 01:50:56 +00:00 | 22 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.3

    Every server now tells its operator when a newer release is out. The relay no longer restarts itself
    over an abandoned node request. Blurt Power rewards that a node refuses now stop and say why. The site
    now says plainly what operators earn and pay and what users get, and the first-trade bonus is no longer
    lost to a reply.

    Upgrading: sudo morphit-ops upgrade on every server, Tor/I2P-only ones included. No database change.
    This upgrade is run by v1.21.2's upgrade program; the release check, the backup question's removal and
    the after-restart wait below run from this release during the upgrade. Every instance must run
    v1.21.1 or later before 2026-11-01 00:00 UTC
    , when the stricter consensus rules start. This release
    adds one rule from that same time, about what uses up a user's first-trade bonus (below); instances that
    have not upgraded by then still pay the bonus, by the old rule.

    Knowing a release is out

    • The main menu reads @morphit's on-chain release record. Before, it asked only git.agorise.net and
      gave it 2.5 seconds. When that host was slow, the menu showed "(couldn't check for updates — network)"
      even though the record of the new release was already on chain, and an operator who opens the menu
      now and then would read that as "nothing to do".
      • The menu now reads the record from this server's own indexer, on the server with no network. It
        uses the answer only after checking that the process listening on that address is the indexer
        service.
      • The record names exactly what an upgrade installs, so it decides.
      • The code host is asked only when the record does not answer, never on a Tor/I2P-only server, and
        once instead of twice. "Tor/I2P-only" is now decided the way the upgrade decides it; when that
        cannot be told, the node is treated as Tor/I2P-only.
      • "Update available" appears only for a release newer than the installed one.
      • It says "couldn't check" only when nothing answered.
    • The release check runs on every server, twice a day. morphit-release-monitor shipped from v1.9
      but nothing installed it. It sends an alert through the Matrix bot when Matrix alerts are set up.
      • Every install and every upgrade now puts it in place and turns its timer on.
      • The upgrade also runs it once, reads what it logged, and says so if that run did not succeed,
        with the command to look at it.
      • It runs every 12 hours (it was written for 6), as a throwaway user systemd makes for each run.
      • It reads the record from this server's indexer. It asks the code host only when the indexer
        answers but holds no record.
      • When it cannot check, its alert now gives the reason.
    • morphit-ops upgrade --check-only reads the on-chain record first on every server, and stops at
      the first release source that answers.
    • A real upgrade says when the record names a newer release than the code host offers, for example
      when git.agorise.net is blocked or has not published it yet, so the operator knows to run it again
      later.
    • Requests to the code host get the time they are given. Node's own limit ended every connection
      attempt after 10 seconds, whatever wait was set, so a slow code host failed a 30-second check after
      20 seconds. The upgrade's release lookup and its download now use the wait they were given.

    The relay and the indexer

    • The relay no longer restarts itself over a node request nobody waits for. On 2026-10-08 it
      restarted twelve times with "unhandled_rejection", logged as "AbortError" or "TypeError: fetch failed".
      The cause was a request to a second node that ended after the relay had already moved on, with nothing
      catching its failure. Two things did that:

      • the node pool could still send its backup request after the first node had answered;
      • a request cancelled before it started was left unwatched.

      Both are fixed, in the indexer as well. Should such a request ever end unwatched again, the relay
      logs it as a warning with its stack and keeps running. Any other unexpected error still stops it.

    • A node answer the indexer cannot read no longer stalls its block reading. Before, it was left
      unhandled, and the request waiting on it never finished.

    • A database error while the relay settled a payment no longer gets it sent twice. It erased the
      record of the signed transaction, so the next cycle signed and sent a new one. The record is now kept
      and the payment is settled from the chain history; the failure is still counted, so a row that keeps
      failing stops and reaches the operator.

    • Blurt Power rewards (delegations) below the chain's minimum are held, not re-sent. Blurt accepts a
      new delegation only of at least a third of its account fee (about 33.4 BP at today's 100 BLURT fee),
      and a change to one only of at least a thirtieth (about 3.4 BP). The 1 BP welcome stake and the 10 BP
      first loyalty reward are below that, so the chain refused them every time: on morphit.io two rewards
      to one account were signed again about once a minute for five days, without the relay looking at the
      chain, and the retry count never rose, so they never stopped or reached the operator.

      • The relay now reads the chain's limits and the current delegation before sending. A reward below
        the minimum is held ("held: … below the chain's minimum delegation …" in drain-queue), checked
        again every 6 hours, and lent once the account's rewards add up to it, usually at the 500 BLURT
        milestone (61 BP). A target the chain already holds is marked done without a transaction.
      • A delegation is now looked up in the relay's account history, like a transfer.
      • Only the newest reward for an account is sent. Each one carries the account's whole amount, so
        an older one is retired as replaced.
      • A reward is never sent while an older one for that account may still land.
      • Rewards waiting on each other no longer hold up the rest of the payout queue.
      • What the nodes answered is kept, in the queue and in the log, so a refusal the chain repeats ends
        the retries and shows its reason.
      • An older reward that has reached the retry limit no longer blocks newer ones for that account, and
        an older one is retired only for a newer one that can still be sent.
    • morphit-ops drain-queue shows a delegation's amount in BP (it showed "0.00 BLURT"). It marks a
      row that is waiting on the chain as waiting, and shows what the nodes answered in full.

    Upgrades and the command line

    • The upgrade no longer asks about encrypting database backups.

    • The checks after the restart wait for the services to answer. systemd reports a service as
      started before it listens, so the relay check could run against a relay that was not yet answering,
      and warn.

      • The checks now wait up to 5 minutes in all for the services to answer on their health addresses,
        and say which one did not.
      • The indexer is asked where its unit says it listens.
      • The relay check's own wait is 30 seconds of time, not a count of tries.
    • The braille spinner shows during the waits at the terminal, for example:

      • the database commands (status, signups, drain-queue, moderation and the like);
      • doctor's configuration checks;
      • fast-sync's stop and start;
      • the guided install's pre-flight and the silent stretches of the playbook;
      • the unpack and each restart of an upgrade;
      • the release check's run and retry;
      • the service restarts that edit, alt-address and mcp offer.

      Its label is cut to fit the terminal; a longer one used to fill the screen with copies. Ctrl-C while
      it turns gives the cursor back. The database commands no longer print the label into piped or
      logged output, and under --json the output is still only JSON.

    • fast-sync reads the indexer's state from systemctl's answer alone. A warning on its error output
      made the state unreadable, which fast-sync took as "stopped".

    Rewards

    • A reply to someone else's listing no longer uses up a user's first-trade bonus (10 BLURT + 10
      BLURT Power), from blocks dated 2026-11-01 00:00 UTC. The bonus is paid for the first completed trade
      on a listing the user paid for. Before, the user's first reviewed trade of any kind used up the
      one-time flag, so a new user whose first trade answered someone else's listing was never paid. Older
      blocks keep the old rule, so a resync pays exactly what was paid before, and an account whose flag
      was already used up that way stays as it is.
    • What the site says about rewards now matches what is paid. These statements were false and are
      corrected in all ten languages:
      • "Leave feedback after your free first buy to unlock the 10 + 10 bonus": the free buy has no listing
        fee, so it cannot unlock it.
      • "Save the free buy for later, it never expires": it is offered for the first order only.
      • "500 signups a week need about $1 of Blurt": about 51,000 BLURT.
      • "Morphit" delegates and can withdraw rewards "for abuse": the relay of the site lends them.
      • The 1 BP welcome stake "arrives instantly": it is set aside and lent once the rewards reach the
        chain's minimum delegation.
      • The four FAQ answers on the free first buy, the welcome rewards, loyalty rewards and operator
        earnings are retranslated in full from the English, since some translations had drifted.

    The website

    • The run-a-node page is rewritten. It is shorter and plainer. The download button names the
      current version, and the install step shows the one command to run. The operator-tag form is gone:
      the guided install offers to register the tag.
    • The run-a-node page shows what an operator earns and pays. It lists the income (90% of BLURT
      listing fees, featured-slot bids and first-message fees on the site) and what the relay pays (about
      102 BLURT per new account, the first-trade bonus, Blurt Power lent as rewards, top-ups), with a rule
      of thumb for how many paid listings cover one new account.
    • The home page invites visitors to run a site, with a link to the run-a-node page and to the
      running sites.
    • Visitors see what an account gets. A "What you get" panel on the orderbook lists every reward,
      when it arrives and how, with the signup button. After signing up, the success screen shows the same
      list and stays up for 20 seconds, with a button to go on at once. A site without an operator tag pays
      no rewards, so it does not show the panel.
    • "Run a node!" is in the footer's Federation menu, between Instances and Compare.

    The repository

    • A tidier top level.
      • SECURITY.md and THIRD-PARTY-LICENSES.md are now in docs/.
      • The configuration example is ops/env/morphit.config.env.example.
      • The audit allowlist and the smoke typecheck configuration are in scripts/.
      • The Prettier settings are the "prettier" key of package.json.
    • scripts/run-smokes-chunk.sh now fails when a smoke fails. It printed "N runners failed" and
      still exited 0, so a battery run in chunks read every failing chunk as passed. It now exits non-zero,
      as scripts/run-smokes.sh does.

    Releases (maintainer)

    • Block 3 is one code block. If the dry-run printed the payload, Block 3 is done. Only a release
      without an IPFS CID needs more, and the payload builder then prints the command for morphit.io and
      how to retry.
    • The ceremony writes its files to /tmp (/tmp/morphit-build-manifest.json,
      /tmp/morphit-release.json), not into the repository, and Block 3 clears them first.
    • Block 4 confirms the broadcast by reading the new blocks. A node that accepts the transaction
      without its block number no longer leaves it "NOT confirmed". The other nodes are asked for the blocks
      produced since the broadcast, and the transaction is confirmed when one of them holds exactly this id.
    Downloads
  • v1.21.2 c958540303

    Morphit v1.21.2
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 39s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m10s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 51s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 4m25s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 46s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h17m23s
    morphit-release / Build + publish release tarball (push) Successful in 37m3s
    Stable

    Ghost released this 2026-10-08 06:04:39 +00:00 | 23 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.2

    Upgrades that get through a censored network, a warrant canary that keeps renewing on Tor-only servers,
    and a release ceremony in the right order.

    Upgrading: sudo morphit-ops upgrade on every server, Tor/I2P-only ones included. No database change.
    This upgrade is run by v1.21.1's upgrade program; the canary repair below runs from this release during
    the upgrade. Every instance must run v1.21.1 or later before 2026-11-01 00:00 UTC, when the stricter
    consensus rules start; this release changes none of them.

    Upgrades

    • From the next upgrade, a server that cannot reach the public Blurt nodes still finds the release record. The upgrade asked
      its own indexer for the on-chain record for 4 seconds, then the public nodes. On a server whose indexer
      reaches the chain over Tor (where the public nodes are blocked), both could fail, and the upgrade
      refused the release. When the public nodes fail too, it now asks its own indexer again and gives it
      time to answer; the error names both paths when neither answers. This takes effect from the upgrade
      after this one (this one is still run by v1.21.1's program): if a server refuses this release with
      "all RPC endpoints unavailable", run the upgrade again once its network is better.

    Warrant canary

    • The weekly renewal runs the installed release's canary code. The canary setup recorded the folder
      it was run from (an unpacked copy in ~/Downloads/morphit on a wizard install), which no upgrade
      updates, so the weekly renewal kept running old code. The setup now records the installed
      /opt/morphit, and the upgrade repairs an existing weekly renewal that runs as root: it points it at
      the installed release, and rewrites one written by an older setup with the same key, operator, address
      and account, the public key exported once from root's keyring, then starts a renewal in the
      background. A renewal script in another account's home, an older one that uploads the canary to
      another server, or one missing a value is not changed; the upgrade names the command to run. On a
      server where the weekly renewal used the old copy, this upgrade's own renewal still runs before the
      repair: if its last lines list the warrant canary, run the command they give on that server
      (sudo systemctl start morphit-canary.service).
    • On a Tor-only server the canary carries the Bitcoin block height again. Every Bitcoin explorer
      failed over Tor, so the canary's Bitcoin block height read "(unavailable at signing time …)". Their https:// addresses are now
      reached through Tor with the certificate checked as usual. A failed source now shows the reason, not
      only "fetch failed".

    Releases (maintainer)

    • The ceremony broadcasts the on-chain record before morphit.io upgrades. Since v1.21.0 an upgrade
      installs an unsigned release only by its SHA-256 in that record, so the old order (upgrade in Block 3,
      broadcast in Block 5) made morphit.io refuse the release ("The release is not signed, and no signed
      on-chain release record names its hash"). The blocks now run: Block 3 builds and dry-runs the payload (the
      manifest from the published tarball, checked against the verify.json inside it), Block 4 broadcasts,
      Block 5 upgrades morphit.io, Block 6 checks that morphit.io serves the anchored build and repairs the
      canary. If a release has no IPFS CID, Block 3 has morphit.io host the release (installing nothing) with
      the release's own seed scripts, taken from the published tarball after checking its SHA-256, and print
      the CID. Because the record now reaches every node before it upgrades, a change to what the record may
      contain ships in one release and is used only by a later one.
    • The key prompt of the broadcast scripts stays on screen. Its last line (in the snapshot scripts,
      the whole "Paste the … POSTING WIF" line) was erased the moment it appeared, so they seemed never to
      ask for the key.
    • A broadcast a node accepts without a block number is looked up on the other nodes by its
      transaction id, and reported as confirmed once another node lists it in its block, instead of "NOT
      confirmed by a second node". An answer counts only for exactly this id, in a block the transaction
      can be in; the nodes are asked together each round, until the transaction has expired. A
      "duplicate transaction" answer is looked up the same way.
    Downloads
  • v1.21.1 8e615041ff

    Morphit v1.21.1
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 40s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m5s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 44s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 4m12s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 45s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h14m13s
    morphit-release / Build + publish release tarball (push) Successful in 35m26s
    Stable

    Ghost released this 2026-10-07 18:28:57 +00:00 | 24 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.1

    A calmer upgrade, a working language filter, branded Blurt post pictures, and fixes to the consensus
    rules before they switch on.

    Upgrading: sudo morphit-ops upgrade on every server, Tor/I2P-only ones included. Every
    instance must run v1.21.1 before 2026-11-01 00:00 UTC
    , when the stricter consensus rules start
    (v1.21.0 is not enough: this release corrects some of them). One small database migration (a column
    description) runs by itself at start-up. This upgrade is still run by v1.21.0's upgrade program: read
    any warning lines it shows, even if its last lines say there is nothing else to do.

    Consensus rules (from 2026-11-01)

    • A featured-slot bid's place no longer depends on when a server's own fee re-check happened to run:
      every instance reaches the same answer.
    • The look-alike name check gives the same answer on every Node.js version.
    • The site no longer sends text every instance would drop (some invisible characters): an order with
      one would have lost its listing fee. "Mark complete / review" sends the completion before the review,
      so the review is not dropped. Profile links are sent in the form instances store.

    Upgrade output

    • The upgrade prints what changed and what is left for you, not every routine check ("✓ N other checks
      found nothing to change"). From the upgrade after this one it ends with one summary: "Left for you:"
      (with the commands), or "Nothing else to do." — including how the background web-proxy checks ended.
    • Every long step shows the spinner; a failed step keeps its full output in /var/log/morphit/.
    • On a Tor/I2P-only server the frontend's web-server base image is fetched through Tor in the
      background and the frontend rebuilt on it; nothing to do by hand.

    Orderbook

    • The language filter works. A language filter shows only orders written in the chosen languages;
      with no language chosen, every order shows, including those posted before v1.15.0 (they carry no
      language). The filter you leave on the orderbook is kept for your next visit on that device.

    Open to every country

    • No instance blocks visitors by country. People behind national firewalls (China, Iran, North
      Korea, …) must be able to reach the instance of their choice; that is what federation is for. The
      upgrade empties a BunkerWeb country list (BLACKLIST_COUNTRY, WHITELIST_COUNTRY, also per-site
      ones) in BunkerWeb's settings file, removes one saved in BunkerWeb's web UI from BunkerWeb's database
      (keeping a copy of the database first), and checks BunkerWeb runs without one; a list set any other
      way is named in the upgrade's output and in sudo morphit-ops status, with where to clear it.
      v1.21.0's note that country blocks "still work" is withdrawn.
    • The instances page badge reads "🏅 Zero use of clearnet internet" again.

    Branding

    • Blurt posts show the instance's own picture, never Morphit's on a branded instance — also when
      the brand cannot be read at that moment (then no picture). Blurt loads such a picture only from an
      https:// address, so a post made over Tor or I2P carries none. Unbranded instances keep Morphit's
      pictures. A logo given without a name no longer puts "Morphit" next to it in the preview picture,
      and an own og-image.png that is not 1200 × 630 is named in a warning. See docs/BRANDING.md.

    Security

    • Root's files no longer live where the service account could redirect them: the web-proxy and
      mirror state moved to /var/lib/morphit-ops/, /var/log/morphit becomes root's (the upgrade fixes
      existing servers), and nothing root writes follows a link there.
    • The MCP server limits each visitor, not everyone behind the web proxy together, and counts every
      call in a batch. Its SDK is updated to 1.32.1.

    Releases

    • A release whose IPFS address could not be computed is no longer broadcast without one: the
      ceremony's Block 4 stops and says how to pass the address the release server printed.
    • The release notes now live in docs/release-notes/ and the claims list is
      docs/MORPHIT-BRAG-LIST.md.
    Downloads
  • v1.21.0 0248892e7f

    Morphit v1.21.0
    All checks were successful
    morphit-ci / Supply-chain audit gate (every advisory triaged, none fixable in range) (push) Successful in 41s
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 1m25s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 57s
    morphit-ci / Integration tests (real Postgres 16) (push) Successful in 9m14s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 57s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 1h12m35s
    morphit-release / Build + publish release tarball (push) Successful in 35m56s
    Stable

    Ghost released this 2026-10-05 20:43:23 +00:00 | 28 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    Morphit v1.21.0

    A full security and privacy review of the whole codebase, done the way a hostile expert would: 19
    independent reviewers, a red team against a running instance, a fresh threat model, and four rounds of
    fixes, each checked by reviewers who had not seen the fix. Every fix comes with a test that was run
    against the old code and seen failing.

    Upgrading: clearnet servers run sudo morphit-ops upgrade as usual (see "Every node" below for the
    new --questions and --heals). Zero-clearnet servers must use the signed offline bundle — follow
    "Zero-clearnet nodes" below step by step. There is one database migration (new indexes, and stored
    push-subscription browser details removed); it runs by itself at start-up.

    New consensus rules switch on at 2026-11-01 00:00 UTC (by block timestamp, so every indexer agrees).
    Please upgrade every instance before then. The rules are listed under "Marketplace" below.

    Indexer: things one user or one node could break

    • One cheap on-chain operation could stop every indexer for good. Two duplicate fee-bearing operations
      in one transaction, or a deeply nested JSON operation of about 6 KB, made every indexer retry the same
      block forever. Both now fail only that operation; indexing goes on.
    • A single RPC node could feed the indexer unsigned "official" operations (a release record or a new
      RPC node list) and so add its own nodes to the pool or change the treasury. Official operations are now
      accepted only with a valid signature from the pinned key.
    • Trusted reads (posting keys, snapshots) need operators to agree, and a stale answer never wins. A
      value is confirmed only when at least two operator names agree and form a majority; an answer that is
      provably older is overruled, and a lone disagreement delays confirmation instead of deciding it.
      Operators are counted by node name.
    • One node answering errors no longer freezes indexing; the pool moves on to the next node.
    • Peer price federation works. A field-name mismatch meant no peer price was ever counted.
    • Memory and load limits: RPC replies are capped by what was asked for, account-history reads have
      per-client and total limits (413 reply_too_large, 503 history_busy), the indexer has a 1536 MiB
      memory cap, and the database gets per-request timeouts, missing indexes and no JIT stalls.

    Privacy

    • BunkerWeb contacts no one. As shipped it sent blocked visitors' IP addresses, full URLs and request
      headers to its maker's service, looked every visitor up in public DNS blocklists, and downloaded lists and
      databases from third parties. All of that is off, on new and upgraded servers alike.
    • Fee checks and prices go over Tor first. BTC fees are checked with onion block explorers, XMR fees
      with onion xmrblocks explorers, and BTC/XMR prices come from the agreeing median of five Haveno and Bisq
      price nodes over Tor. Clearnet sources are only a fallback, and never used on zero-clearnet nodes —
      which now offer BTC and XMR fees again.
    • The relay no longer writes visitor network prefixes or account names to its log, stores no browser
      details with push subscriptions, and only sends Web Push to the real push services.
    • The browser's release check: two small requests to one node, once a day, shared by all tabs. The
      browser now checks the release signature itself, so one node cannot forge it, and a release older than
      the running site never supplies fee addresses.
    • Nothing about who you are survives Sign Out or a "just this session" sign-in in another tab, the
      profile cache or chat state; account-named server answers are no longer cached by the browser.
    • The public health pages show only status; host memory, disk and counters need the local header.
    • Every instance uses its own address in page links and previews; zero-clearnet instances carry no
      clearnet address at all.

    Chat

    • Messages now prove who sent them. New messages use an authenticated format, so the operator's server
      cannot insert a message "from" the other trader. Older messages still open but are marked unverified and
      never offer "Pay now" or change a trade.
    • "Verify peer" is a 60-digit safety number (it was 64 bits, which a determined attacker could match).
      Compare once more after upgrading.
    • A changed chat key always asks you first, Lock keeps your comparisons, and a replaced key can only
      open old messages.

    Keys and sign-in

    • The page's Content-Security-Policy no longer allows inline or eval'd scripts.
    • Removing or hardening a YubiKey can no longer be undone by a later password change; the YubiKey
      path also asks for your 2FA code when 2FA is on.
    • Decrypted keys are no longer written to disk during a page reload.

    Marketplace

    • A stranger can no longer mark your order "paid"; payments are checked against the amount you asked
      and the actual counterparty, and a payment with no amount asked shows as "received", not "paid".
    • Prices shown in the app are live, from the indexer; when none is known the pay field stays blank.
    • Rules that switch on at 2026-11-01 00:00 UTC: deeper-than-64-level payloads and U+FFFE/U+FFFF text
      are rejected; a review must cite an order the two of you discussed or completed; attestor loyalty counts
      only the treasury's share; feature bids under the step are queued, and only live, paid orders rank;
      display and operator names are checked for look-alikes of reserved names; profile fields are validated;
      chat read receipts are bounded; an order replacement offering only disabled payment methods is refused.

    Servers

    • Services no longer run as root where they don't need to, and the service account can no longer gain
      root through files it owns.
    • TLS certificates renew on BunkerWeb servers (they could not before), and hardening no longer cuts off
      Docker's forwarding.
    • Zero-clearnet servers enforce it: only Tor and i2pd may reach the internet; DNS goes nowhere but the
      box itself; the Matrix alert bot is refused unless it goes over Tor to an onion homeserver.
    • Upgrades verify the release against the on-chain record or the pinned signing key on every path, and
      zero-clearnet upgrades install nothing from the internet.
    • Branded instances get their own link-preview image, drawn from their logo and name.

    Repository

    • Internal working notes, personal details and process records are no longer in the public repository.
      The threat model (docs/audit/2026-10-*) and docs were rewritten to match the code; claims that were not
      true were corrected or removed.
    • Vulnerability reports: Matrix direct message to @agorise:matrix.org only (see SECURITY.md).

    Every node: questions and repairs after the upgrade

    The repair part of the upgrade never waits for an answer now. A question asked part-way through could hold up
    the upgrade or cut it off. On the upgrade to this release, the old upgrader's own two questions (described below) still
    wait unless you pass --yes.

    Where the repairs used to ask, they now take the safe choice and tell you:

    • the journal is left as it is;
    • on a tor-only node, a Matrix bot on a clearnet homeserver is stopped;
    • plain-text backups are left as they are.

    sudo morphit-ops upgrade --questions, run from a terminal, asks those questions. Each upgrade lists the
    questions it left on its last lines.

    When a line says "the next sudo morphit-ops upgrade tries again", that is now true even when you are already on
    the newest release.
    A plain sudo morphit-ops upgrade on an up-to-date box prints "✓ Already on the latest
    release." and then re-checks this release's repairs; nothing is downloaded or installed. --check-only and --json
    still only look.

    sudo morphit-ops upgrade --heals does the same directly, without checking for a release first. Use it when a
    line asks you to, or when an upgrade says its repair step ran out of time.

    Tor-only node, Matrix bot kept on a clearnet homeserver (KEEP-CLEARNET): the rule that lets only Tor and i2pd
    reach the internet is then not loaded on that node, and the upgrade says the node is not zero-clearnet while the bot
    is kept. The rule would cut the bot off, including the DNS lookups it needs. To get the rule:

    1. Move the bot to a homeserver on the node or a .onion one: sudo morphit-ops matrix setup.
    2. Run sudo rm /etc/morphit/matrix-bot.tor-only-decision.
    3. Run sudo morphit-ops upgrade --heals.

    Zero-clearnet nodes: upgrade from the signed offline bundle

    On a zero-clearnet node, do not run the plain upgrade for this release. That includes menu option 2 and a bare
    sudo morphit-ops upgrade. The upgrader already on your box (v1.20.3 or older) would then install the packages with npm ci
    from the npm registry over the clearnet.

    Use the offline bundle instead. The release job builds it, and it is signed with the release key your box already
    trusts, so nothing on the box touches the clearnet and npm is not used.

    On your own computer (any computer with internet), download the two files from the release page. The bundle is
    about 250 MB: 246.5 MB measured when it carries its Node.js and Kubo runtimes. Without the runtimes it is
    135.0 MB; Kubo v0.42.0 is 54.6 MB and Node.js v22.22.2 about 57 MB.

    curl -fLO https://git.agorise.net/agorise/morphit/releases/download/v1.21.0/morphit-v1.21.0-offline.tar.gz
    curl -fLO https://git.agorise.net/agorise/morphit/releases/download/v1.21.0/morphit-v1.21.0-offline.tar.gz.asc
    

    Copy both to the node, logging in the way you normally do. Use scp -O, not plain scp:

    scp -O morphit-v1.21.0-offline.tar.gz morphit-v1.21.0-offline.tar.gz.asc <you>@<your-node>:/tmp/
    

    On the node, in a terminal:

    1. Check that the node can verify the signature. Each command must print something, and neither may say
      "No such file" or "command not found":

      gpg --version | head -1
      ls /opt/morphit/.forgejo/release-signers/agorise.asc
      
    2. Run the upgrade from the bundle. --yes answers the two questions the old upgrader asks; they would
      otherwise wait for you with no time limit:

      sudo morphit-ops upgrade --from-file=/tmp/morphit-v1.21.0-offline.tar.gz --yes
      

      You should see these three lines, in this order:

      • ✓ Integrity verified (gpg-signature).
      • Offline bundle detected (prebuilt node_modules) — skipping npm ci; no registry needed.
      • Using the prebuilt web frontend shipped in the release (no rebuild).

      Let it run until ✓ Success — your Morphit server is now running v1.21.0 (about two to three minutes).

      The rest of the output comes from the old upgrader already on your box, which cannot be changed. Read it like this:

      • Without --yes, it asks "Apply upgrade from v1.20.x to v1.21.0? … This will: … run npm ci, rebuild + redeploy
        the web frontend …".
        That text is old. With the bundle, nothing is installed from npm and nothing is rebuilt
        (see the two lines above). Answer y.
      • Without --yes, a box that has never had a warrant canary may also ask "Set one up now, right here on this
        box? …".
        Answer n. The upgrade then goes on, and you can set a canary up any time later with
        sudo bash /opt/morphit/scripts/canary/setup.sh.
      • If your Matrix bot is set up, it prints "Matrix alert username configured — enabling + restarting
        morphit-matrix-bot…".
        On a tor-only node whose bot uses a clearnet homeserver, ignore it. The bot refuses to
        start, and the background checks (step 4) switch it off again. To keep the bot on its clearnet homeserver
        anyway, use step 3.
      • It ends with "Congratulations! … nothing else to do". That is not true for this release: carry on with
        step 3.
    3. Answer the questions the upgrade did not stop for: the old relay log lines, the Matrix bot, and plain-text
      backups. Any it does not need to ask, it skips:

      sudo morphit-ops upgrade --questions
      
    4. Read what ran after the services restarted:

      sudo cat /var/log/morphit/after-upgrade-heal.log
      

      The last line must be Done.. If it is not, the checks are still running: they wait up to 15 minutes for the
      services to restart and then up to 10 minutes for the background web repairs. Wait a minute and read it again.

    5. Once Done. is there, run the repairs once more. This picks up whatever had to wait until Docker pulls through
      Tor, which the checks in step 4 set up. One example is the frontend's newer nginx base, if a line said the
      frontend "stays on its current nginx base for now". Nothing is downloaded over the clearnet:

      sudo morphit-ops upgrade --heals
      
    6. Remove the two files:

      rm /tmp/morphit-v1.21.0-offline.tar.gz /tmp/morphit-v1.21.0-offline.tar.gz.asc
      

    If something goes wrong:

    • Cannot verify the integrity of release v1.21.0: nothing was changed. The two files must sit side by side
      under exactly these names. Download the .asc again and repeat step 2. If the same error also says "No on-chain
      hash available … Start it with: sudo systemctl start morphit-indexer", ignore that hint. the old indexer never
      stores the bundle's hash, so starting it does not help. Only the .asc does.
    • Could not import release-signer key agorise.asc: gpg could not start its helper. Run step 2 as
      sudo env TMPDIR=/tmp morphit-ops upgrade --from-file=/tmp/morphit-v1.21.0-offline.tar.gz --yes.
    • A line starting The upgrade stopped its heal step at the time limit: wait until the upgrade has finished,
      then run sudo morphit-ops upgrade --heals.

    What this upgrade changes on installed servers, by itself

    • BunkerWeb no longer contacts anyone. These were already off: BunkerNet, DNS blocklists, the reverse-DNS
      black/white/grey lists, the anonymous report and third-party captchas. Now:

      • its daily GeoIP download (db-ip.com), release check (api.github.com) and "preview" Pro-plugin download
        (assets.bunkerity.com) are replaced: the upgrade mounts Morphit's own job lists into BunkerWeb's scheduler, and
        country rules use the GeoIP file inside the BunkerWeb image;
      • reverse scan and plugin downloads stay off;
      • BunkerWeb's in-memory list of the last 100 blocked requests is off (USE_METRICS=no). That list held each
        visitor's address, full URL and browser with no time limit.
    • BunkerWeb's blacklist is off, and part of it cannot be replaced. BunkerWeb checks every blacklist entry only
      after a reverse-DNS lookup of each visitor's address, which tells outside DNS servers who visits your site. With
      the blacklist off:

      • Addresses and networks you listed (BLACKLIST_IP) keep working. The upgrade moves them into an nginx deny
        rule (CUSTOM_CONF_SERVER_HTTP_morphit_ip_blocks) and says so.
      • Network (ASN) blocks, reverse-DNS name blocks, user-agent and URL lists no longer apply. The upgrade names
        each one it finds. Ansible-installed servers had BLACKLIST_ASN=AS14061 AS24940 AS16276 (DigitalOcean, Hetzner,
        OVH); visitors from those networks, VPN users among them, are no longer turned away.
      • The Tor-exit list and the downloaded bad-bot list are no longer used.
      • Country blocks (BLACKLIST_COUNTRY) still work, from the GeoIP file on the server.
    • Kubo (IPFS) takes no settings from the internet. AutoConf, HTTP routers (cid.contact, delegated-ipfs.dev) and
      DoH resolvers are off. A clearnet node seeds over the public DHT, joined through the standard bootstrap peers.

    • Ubuntu's own fetches a server does not need are off on every node:

      • the login banner's news (motd.ubuntu.com) and apt's Ubuntu Pro news;
      • the release-upgrade check at login (changelogs.ubuntu.com; Prompt=never in
        /etc/update-manager/release-upgrades). To move to a new Ubuntu release later, set it back to Prompt=lts and
        run sudo do-release-upgrade;
      • fwupd's firmware-list refresh and pollinate;
      • rkhunter's data-file update. Ubuntu's rkhunter cannot download one anyway; its data comes with the apt package.

      snapd and Ubuntu Pro's status check stay on: installed snaps and a Pro subscription need them.

    • Zero-clearnet nodes can reach their own local network again. The rule that lets only Tor and i2pd reach the
      internet now also allows the local network (10/8, 172.16/12, 192.168/16, IPv6 fc00::/7), so a NAS, a printer or
      your laptop work as before. DNS goes nowhere but the box itself: it is refused to the local network, to
      link-local addresses (home routers often announce their fe80:: address as the resolver) and to the internet, over
      IPv4 and IPv6, from every program — Tor, i2pd and the containers included (none of them needs it).

    • No Docker Hub download on a zero-clearnet node. The frontend moves to this release's pinned nginx base image
      only when that image is already on the box, can be loaded from a vendor/docker/ file you put there, or can be
      fetched with Docker going through Tor. Otherwise it keeps its current base and says so; once Docker pulls through
      Tor, sudo morphit-ops upgrade --heals on the server switches it. (The release's offline bundle carries no Docker
      images.)

    • Running the indexer and relay as their own users (not root) is now checked where each one really listens, and
      each gets up to two minutes to start. A service that runs as its user but has not answered yet keeps running as
      its user, and the upgrade says so. Only a service that is down, keeps restarting or runs as someone else is put
      back on root.

    • The indexer has a memory cap (1536 MiB, systemd MemoryMax), like the relay (512 MiB) and the MCP server
      (256 MiB). A burst of large requests can no longer take the whole box. The cap is about twice the most the indexer
      was measured to use honestly. sudo morphit-ops upgrade checks that the running indexer carries it; if the
      indexer happens to use more than 80% of the cap at that moment, nothing is changed and the upgrade says so.
      The indexer now reads its own cap, so the optional flow catch-up sizes its buffer to fit.

    • Served web files stay with the canary user. The service-user heal no longer hands apps/web/static back to
      root (it already left apps/web/build alone).

    Releasing (maintainer)

    The offline bundle. The release job now builds it itself, without Docker, and attaches it with its .sha256.
    Without the bundle the release is not published. The job signs the tarball and the bundle only when the
    MORPHIT_RELEASE_SIGNING_KEY secret is set; otherwise it attaches no .asc, and a node running this release
    installs later ones by the SHA-256 in @morphit's signed on-chain record. For this release only, the maintainer signs
    the bundle and attaches its .asc, because the upgrader on v1.20.x zero-clearnet nodes accepts the bundle only with
    a signature.

    The bundle carries no OS packages or Docker images. A fully offline fresh install still needs the full appliance
    bundle: bash scripts/build-offline-bundle.sh on an Ubuntu 24.04 box with Docker. That build is optional and not
    part of the release steps.

    Moved tags. The release job checks that the tag still points at what you signed. If a release for the tag already
    exists, the job attaches to it only when it was built from the same signed tag object. A tag moved back to an older
    signed object after publishing is therefore refused before anything is attached, and nothing is published for it.

    Block 4 also checks that the release job built the very tag you pushed in Block 2. If it stops with "the tag was
    moved after it was pushed", do not broadcast. Delete that release on git.agorise.net, codeberg.org and gitea.com,
    because its tarball, bundle and signatures are already published there.

    Neither check adds a command.

    Downloads
  • v1.20.3 d7e5957593

    agorise released this 2026-10-02 04:48:05 +00:00 | 32 commits to main since this release

    Morphit v1.20.3

    Visitors' browsers contact a Blurt node far less often, and pages download less. There are no
    database changes.

    Privacy

    • The release check reaches a Blurt node at most once a day. To make sure an operator is not
      keeping visitors on an old build, each browser asks a public Blurt node for Morphit's signed
      release record — the one request that leaves the site, and that node sees the visitor's IP. It
      ran on every visit. A good answer is now remembered in the browser for 24 hours (and asked again
      right after the site updates), so further visits that day contact no one.
    • That request is much smaller: it reads @morphit's last 100 history entries instead of 10,000
      (a few KB instead of about 115 KB), and looks further back only if it must.
    • The FAQ says exactly what goes out ("Does anything see or leak my IP address…"), in every
      language: at most once a day, two small requests.

    Faster pages

    • The served build's version file is downloaded once per page load, not twice. The release
      check and the update check both need it, and it is about 80 KB.

    Release fixes

    • Zero-clearnet instances can always upgrade. v1.20.2 was first broadcast without its IPFS name,
      and a Tor/I2P-only instance refused it. The release builder now always includes the name, warns
      when a release has no IPFS address, and refuses an IPFS record left over from an earlier release.
      A zero-clearnet upgrade also accepts a release located by its IPFS address alone.
    • The release build retries the IPFS tool download (and has a second source), so a slow
      download no longer leaves a release without an IPFS address.
    • The ceremony's Block 4 clears values an earlier ceremony left in the terminal.

    Upgrading

    Run sudo morphit-ops upgrade on each server. Nothing needs doing by hand.

    Downloads
  • v1.20.2 bb06920ce5

    agorise released this 2026-10-02 00:51:51 +00:00 | 33 commits to main since this release

    Morphit v1.20.2

    Pages load faster and are easier to read, Bitcoin fees go to a separate address for each order,
    Monero fee checks no longer depend on two websites, and the compare page works again. There are
    no database changes.

    Faster pages

    • Each page downloads about half the text it used to. The FAQ, the privacy guides, "run a
      node" and the cheat sheet now load only with their own page. Before, every page downloaded all
      of them (and, in any language but English, the English copy too): about 100 KB less per page,
      and 200 KB less for a visitor reading another language.
    • The logo shows first. The browser now fetches the header logo before the app's code, keeps
      its space reserved while it loads (nothing jumps), and downloads it once instead of twice. Its
      occasional shine is drawn by the graphics card instead of repainting the logo.
    • Fonts: one font file was downloaded twice under two names; it is now downloaded once, all
      three fonts start loading at once, and the browser keeps them for a month.
    • The update check waits. The check for a newer version (an 80 KB file) no longer competes with
      the page while it loads, and no longer runs on every switch back to the tab.
    • On a simulated slow phone, the home page's PageSpeed score went from 61 to 77–80; accessibility
      and SEO from 96 and 92 to 100.

    Easier to read and to find

    • Grey text is readable. The muted grey used for hundreds of labels was too faint on the dark
      background (3.4:1); it now meets the 4.5:1 readability standard everywhere. Operator colour
      themes get the same lift.
    • A missing file is a real "not found". Asking for a file that does not exist (for example
      /.well-known/ai-catalog.json or /favicon.ico) used to return the app's page, so search
      engines and AI tools were told those files exist. They now get a proper 404.
    • Screen readers: the "Start" button says what it does (sign in or create an account), the
      logo links no longer announce an English "home" in every language, and the footer's headings are
      in the right order.
    • Pages are isolated from other sites' windows (Cross-Origin-Opener-Policy).
    • The privacy guide list showed a raw text key for goods trades (which have no guide). Fixed.

    New — fees

    • Each Bitcoin fee gets its own address. This release pins the treasury's Bitcoin account key.
      From this release on, every order paid in BTC gets a fresh address of that account, and a
      payment to it can only ever count for that one order. Nobody can claim someone else's payment.
    • More sources check Monero fees, and payers don't get stuck.
      • Three public Monero nodes join the three explorers. A node gets only the transaction id (never
        the payer's transaction key), and the indexer checks the payment itself, so a node cannot fake
        one.
      • Two sources still have to agree. If only ONE can be reached for two hours and nothing
        contradicts it, its answer is accepted once the payment is 10 blocks deep. Sources that
        disagree never settle it; the log names what each one said.
      • The upgrade removes the three explorers that stopped answering (still listed on nodes set up
        before v1.20.0) and adds the newer sources, once. A default you remove later stays removed.

    Fixed

    • The compare page. It could not reach other instances at all: each page's security policy
      lets the browser talk only to its own instance, so the request was refused before it left
      ("Failed to fetch"). The instance now fetches the other instance's orderbook itself, only for
      instances registered on chain, over their onion address when they have one. Messages are clear
      and in every language.
    • Pages switching language by themselves. On a slow connection, a browser set to another
      language could turn an English page into that language a few seconds after it loaded. The
      page's own language now always wins.
    • The treasury setup scripts. The Bitcoin key script lost the key when run as documented, and
      the Monero self-test stopped before printing anything when run from the repo folder. Both work
      now. The Bitcoin script also refuses an account that has ever received coins.
    • A dependency. devalue (used by SvelteKit) is updated to 5.9.4 for three advisories.

    New — checks

    • Block check (report only). For every block, the indexer recomputes the chain's own
      fingerprints (the transactions' merkle root, the block id and its link to the block before) and
      counts whether they match what the RPC node served. Nothing is refused yet. sudo morphit-ops health shows it as "Block check".

    Upgrading

    Run sudo morphit-ops upgrade on each server. Nothing needs doing by hand.

    • The Monero source list is updated by the upgrade where needed.
    • The web container is rebuilt from this release's config (missing files, font caching, the
      opener policy) — on clearnet and on Tor/I2P-only servers alike.
    • Check sudo morphit-ops health → "Block check" a day after upgrading.
    Downloads
  • v1.20.1 9223ccd131

    agorise released this 2026-10-01 03:16:50 +00:00 | 34 commits to main since this release

    Morphit v1.20.1

    A fix release for problems found while upgrading the live instances to v1.20.0. There are no
    database changes and no changes to on-chain operations.

    Fixed — upgrades and operations

    • BunkerWeb could stop taking any new settings.
      • Morphit's firewall exception for its API was stored twice on some servers. With two copies,
        BunkerWeb rejects every new config it builds and quietly keeps serving the last one that
        worked. On one instance that had been true for three weeks, so settings changed since then,
        including the one that stops visitors choosing their own IP address, never took effect.
      • The upgrade now keeps exactly one copy and removes the others, after a backup of BunkerWeb's
        database. It then checks on the live site that the API still gets through and the rest of
        the site is still protected, and puts the copies back if not.
      • The upgrade now reads BunkerWeb's own verdict on every change. If BunkerWeb refuses a config,
        you see nginx's reason instead of a vague "not applied yet".
    • Slow BunkerWeb servers finish their settings change.
      • Where BunkerWeb's downloads time out, it needs minutes to rebuild its config after a change,
        which is longer than the upgrade could wait. The change was always put back.
      • On a BunkerWeb server the privacy and header settings are now applied in the background, for
        as long as BunkerWeb needs. The upgrade shows the progress while it can, and
        sudo morphit-ops status shows the result under "Web proxy (BunkerWeb)".
    • A relay that stopped could stay stopped. The relay could end without an error, so systemd
      did not restart it, and the upgrade then skipped it because it was not running. One instance's
      relay was down for three days this way, and sign-ups there failed.
      • The relay and the indexer now restart after any exit.
      • A relay that ends without being asked to logs why and exits with an error.
      • The upgrade starts an enabled relay that is not running, and checks that it stays up.
    • The sign-up limits work. The relay could not reach its state folder, so the daily sign-up
      ceiling was never saved and a SIGNUPS_DISABLED file was never seen. The folder is now
      /var/lib/morphit-relay. The upgrade moves anything already in the old one, so paused sign-ups
      stay paused, and /var/lib/morphit/relay now points to the new folder.
    • The release ceremony's payload step installs its packages first (npm ci), so it cannot
      run against outdated ones on the maintainer's computer.

    Upgrading

    Run sudo morphit-ops upgrade on each server. Nothing needs doing by hand.

    • On a BunkerWeb server, the upgrade ends with the result of the background settings change,
      or says it is still running. Check it later with sudo morphit-ops status.
    • Signed-up counts: the first day after the upgrade starts a fresh daily count, because the
      old count was never saved.
    Downloads