Skip to content

wisp 0.0.4

Choose a tag to compare

@vcealicu vcealicu released this 04 Oct 17:18
· 58 commits to main since this release

LocalGhost wisp 0.0.4

The fourth cut of wisp. 3 October 2026.

Still a wisp: the name is the release line, the number is the cut. Everything in
0.0.1's notes still holds (what LocalGhost is, what is in it, how it works, how a box
and a phone are installed); 0.0.2's and 0.0.3's say what those cuts
changed. This page is what changed since 0.0.3, most of it answering two outside reviews of 0.0.3
and the questions they left.

What changed since 0.0.3

Built with Go 1.27.1

The server is built with Go 1.27.1 (the earlier cuts were built with 1.25.4, which has had
thirty-five standard-library advisories fixed since). The toolchain comes from the mirror as
before: setup installs it (tools/install_go.sh), and redeploy.sh runs the same before every
build, so a running box follows the version go.mod names and a later Go rides in with the code.
The build never fetches a toolchain by itself (GOTOOLCHAIN=local, and every version check asks
from outside the module, where an older go command cannot quietly download a newer one to answer);
tools/go_for.sh picks the Go every build uses, go.mod's version wherever it is on the box, so a
shell whose PATH still points at an older Go builds with the right one; the cut refuses a Go other
than go.mod's, since the bytes differ between versions; and RELEASE.txt and NOTICE.txt say
which Go built the set, so anyone rebuilding the bundle to check its hashes knows which to use.

The phone's geocoder is gone, and less goes to the web

The country the lock-screen phrases follow (the one the phone is in, so the card speaks the local
language) was read from the phone's own geocoder, which on most phones is a network call to Google
carrying the fix. The box answers it now from its own Natural Earth polygons (GET /v1/geo/at);
a phone with no box keeps the country it had and falls back to the mobile network, the SIM and
the time zone, as before. A "what is X" that the box's own copy of Wikipedia answers no longer
goes to the web at all, the way the weather does not; the README names the two public endpoints
the phone may still ask while searching, Frankfurter for a currency question the box did not
answer and Wikipedia's summary API for a "who is" the box's copy does not have.

Wikipedia comes with the rest

update.sh takes the English Wikipedia (one file of about 50 GB, as Kiwix packages it) with the
other sets whenever the volume has 60 GB free, rather than only when named; GHOST_WIKI=0 leaves
it out. The free-space check reads the volume itself now (through ghost.secd's door it used to
read the OS disk, and refused on a box with room to spare). The download lands on the volume
directly, as a hidden part file beside its final name, and resumes.

CRYPTO50: a price that is not this coin's

A constituent priced at more than twenty times its month base (a venue's ticker naming another
asset, a base recorded in another unit) moved the whole index by its weight times that; it is now
held at its last good price and named in the day's record, Box Status says so and calls a day
change past a quarter a fault, and ghost-cli ghost.tallyd rates index=1 lays the index out term
by term (each coin's weight, base, price, where the price came from and its share) for the value
now and the last day's, so a wrong number shows itself.

The map follows the phone while it is open

With the map on screen the phone asks for its position every few seconds (the fused provider,
else GPS, else the network), so the dot is where the phone is and its circle is that fix's own
accuracy, not a quarter of an hour's. The fixes also feed the trail, whose rules (25 m or an
hour) keep a still phone from writing a point a second. Nothing runs once the map is closed.

Smaller things

The README and CONTRIBUTING say what CI runs when: the server on every push and pull request,
the app's JVM tests on pull requests and on demand. The known gaps below say again that a fresh
box trusts nginx's client-certificate header until ghost-ctl edge-passthrough moves the phone's
TLS into secd (the line had dropped out of 0.0.2's and 0.0.3's notes; the gap is as it was).

What the release holds

One GitHub release, v0.0.4:

  • server/: the server set, built reproducibly from the tag with Go 1.27.1: the bundle
    (localghost-server-0.0.4-linux-amd64.tar.gz), RELEASE.txt, these notes as NOTES.md,
    NOTICE.txt, TERMS-MIT.txt.
  • app/: localghost-app-0.0.4.apk, built on the release machine from the tag and signed with
    the app's keystore (the same key as before, so it installs over any earlier wisp), its GPG
    signature by the site key, and APP.txt (its hash, commit, version and signing certificate).
  • source/: localghost-0.0.4-source.tar.gz, the whole tree at the tag.
  • SHA256SUMS over all of it, signed by the site key (SHA256SUMS.asc; the key is at
    https://www.localghost.ai/.well-known/pgp-key.asc, fingerprint DCE9 A3D1 4EB4 6197 1DD5 F393
    706E 4194 F08A 09A0). The signatures themselves are not in the sums.

The server set is the same bytes any machine gets from tools/cut_release.sh 0.0.4 at the tag
with Go 1.27.1 (RELEASE.txt says so). The APK is not yet byte-reproducible (a gradle build
differs from run to run), so the one in the release is the one to verify: its signature, its
certificate in APP.txt, and VERIFY BUILD in the app, which shows the commit it was built from.

Installing 0.0.4

A box on an earlier wisp takes 0.0.4 from the phone: SETTINGS › SERVER shows "wisp 0.0.4 is out"
once the mirror carries it; DEPLOY downloads the set, the box checks the manifest's signature and
every hash, restarts onto the new build and opens a trial, and rolls back by itself if the first
unlock fails or a critical daemon keeps falling over. A box that builds from source
(tools/redeploy.sh) installs Go 1.27.1 from the mirror before it builds. sudo ./tools/update.sh
afterwards brings Wikipedia if the volume has the room.

The phone installs localghost-app-0.0.4.apk over the earlier app (same signing key, the
enrolment kept). A fresh box or phone is installed as 0.0.1's notes say.

Known gaps at 0.0.4

  • A fresh box trusts the device-certificate header nginx passes over 127.0.0.1 until the operator
    runs ghost-ctl edge-passthrough --domain <box name>, after which secd checks the phone's
    certificate itself; a box reached by IP alone cannot take the passthrough yet (nginx routes it
    by name), which is next.
  • The box CA key stays on the OS disk, by choice: a phone can be enrolled and refused while the
    vault is locked.
  • Device certificates last ten years; shorter ones renewed by the phone are next.
  • Releases are signed by the site key alone; an offline release key is planned.
  • The APK is not byte-reproducible; the server set is.
  • The weather is a chat answer; a card on HOME and the lock screen is next.
  • The ZIM reader has read files written to its specification and, at the time of this cut, not
    yet a published Wikipedia file; the first box to finish the download proves it.
  • Mail, the Mist (peer-to-peer backup) and the decoy volume are not built.