• v1.0.0-beta.18 9af0b3f55a

    Morphit v1.0.0-beta.18
    All checks were successful
    morphit-ci / TypeScript typecheck (sweep all workspaces) (push) Successful in 38s
    morphit-ci / apps/web svelte-check (svelte-kit sync + svelte-aware tsc) (push) Successful in 31s
    morphit-ci / ansible-lint (playbook quality gate) (push) Successful in 14s
    morphit-ci / Smoke suite (run-smokes.sh, triple-pulse) (push) Successful in 16m52s
    morphit-release / Build + publish release tarball (push) Successful in 17m28s
    Stable

    agorise released this 2026-06-15 04:53:58 +00:00 | 19 commits to main since this release

    Signed by agorise
    GPG key ID: 53524E1F1017EB9C

    A small operator-quality release, plus one user-facing fix. For users: the
    printable backup card on the onboarding screen now renders instead of producing
    a blank page. For operators: it removes a recurring upgrade nag and makes the
    upgrade's "is the new build actually live?" check reliable — both changes are in
    morphit-ops upgrade itself, with nothing extra to do beyond deploying it. This
    release also expands the default Blurt RPC pool to six independent nodes and
    makes the client back off properly from rate-limited endpoints, so chain reads
    and broadcasts are steadier.

    Fixed

    • The printable backup card no longer prints as a blank page. On the
      onboarding "your keys are ready" screen, the Print backup card button could
      open the print/PDF dialog showing a single empty page. The card was isolated
      for printing using a position: fixed element inside a deliberately
      collapsed page subtree — a combination some print-to-PDF engines drop
      entirely. The card is now lifted to the top of the page and printed in normal
      flow, so it renders reliably as a single clean page. (The seed words still
      never leave your device — this is pure local rendering, no network, no PDF
      library.)
    • morphit-ops upgrade now tidies up old backups for you. Each upgrade
      keeps a rotating set of /opt/morphit.bak-<timestamp> backups and prunes
      the oldest. Previously, if you happened to have a leftover login shell, or a
      pager left open from a systemctl status …, parked inside one of those old
      backup directories, the upgrade refused to delete it and printed a [WARN]
      asking you to go find and stop those processes — on every single upgrade.
      The upgrade now prunes those backups anyway, because a parked shell or pager
      is harmless (the system keeps it running fine even though its working
      directory is gone). It still refuses to delete a backup only when something
      is genuinely running its code from it — for example, a relay or indexer you
      started by hand from the old tree — since deleting that out from under a live
      service would be unsafe.
    • The post-upgrade "is the new frontend live?" check is now reliable. That
      check, and the manual command it printed when it couldn't confirm
      automatically, used to grep a token out of the service worker — but that
      token is assembled at runtime and doesn't survive minification, so the check
      almost always came back "could not auto-verify" and the suggested
      curl … | grep -o 'morphit-[0-9]*' command returned nothing useful. It now
      reads the morphit_version field from /verify.json instead, which is a
      single, stable value. If you ever need to confirm the served version by hand,
      the upgrade now tells you to run curl -s <your-site>/verify.json and check
      that its "morphit_version" matches the build.
    • Two more Blurt RPC endpoints in the default pool, and rate-limited nodes
      now back off properly.
      The default Blurt RPC set grew from four to six
      independent public nodes (added rpc.drakernoise.com and
      blurtrpc.dagobert.uk), giving more headroom when an endpoint is slow or
      down. Separately, when a node replies 429 Too Many Requests, the client now
      parks it on a dedicated, longer cool-off (starting at 30 s and escalating)
      rather than re-trying it every couple of seconds — which was what kept
      re-triggering the rate limit. While a node is parked, requests are served
      from the other endpoints, so this is invisible in the UI; it just removes the
      needless 429 round-trips. Operators running a hand-written reverse proxy or
      CSP:
      if your deployment pins a connect-src allow-list, add the two new
      origins (https://rpc.drakernoise.com https://blurtrpc.dagobert.uk) to it
      and to your indexer/relay RPC env vars, or the browser/server will refuse to
      reach them. A fresh install picks all six up automatically.
    • A clearer error when the database URL was never expanded. If a
      MORPHIT_*_DATABASE_URL was set to a value containing a shell command
      substitution — e.g. a host written as $(docker inspect … ) — environment
      files are read literally (the shell never runs), so the substitution was
      passed through verbatim and morphit-ops failed with a baffling
      getaddrinfo ENOTFOUND $(docker inspect … ). The CLI now detects the
      unexpanded $(…)/backticks up front and tells you exactly what happened and
      how to fix it (resolve the host to a concrete IP, or publish the DB on
      localhost), instead of a cryptic DNS error.

    Under the hood

    • The backup-prune safeguard previously keyed on whether any process had its
      current working directory under the backup tree. That is a weak signal —
      it caught harmless campers (shells, less/pager processes) and blocked the
      prune forever. The new pidsRunningFrom check instead looks at whether a
      process's executable (/proc/<pid>/exe) or an absolute path in its command
      line lives under the tree, which is the real "unsafe to delete" condition;
      a process that merely parked its cwd there no longer blocks pruning. A new
      regression smoke (upgrade-backup-prune) pins this so the prune cannot
      silently revert to the cwd-blocks-forever behaviour.
    • The frontend freshness verification (readBuiltVersion /
      resolveServedVersion) now parses build/verify.json's morphit_version on both
      the built side and the served side, replacing the brittle service-worker
      token grep. The upgrade-frontend-deploy smoke was updated to cover the new
      parseVerifyJsonVersion parser.
    • The RPC pool gained a dedicated rate-limit cooldown ladder
      (DEFAULT_RATE_LIMIT_COOLDOWN_LADDER_MS, 30 s → 5 min) and an
      isRateLimitError predicate; a 429 now selects that longer ladder while
      any other transport failure stays on the generic one. The single source of
      truth for the default endpoint set (@morphit/operator-config
      DEFAULT_BLURT_RPC_ENDPOINTS) carries the two new nodes, and the
      non-importing copies (frontend config.ts, the two env examples, the
      four-surface CSP connect-src) are kept in sync by rpc-endpoint-canon and
      csp-header-consistency. New rpc-pool-smoke scenarios cover the rate-limit
      ladder and the predicate.
    • morphit-ops' database-URL reader (readDatabaseUrl) now rejects an
      unexpanded shell command substitution ($(…) / backticks) with an actionable
      message before pg is ever handed the literal host; pinned by a new
      instance-env-loader-smoke scenario.
    Downloads