Skip to content

Software

EDOS installs software with grab. The repository is a handful of static files under https://edos.edgl.dev/pkg — no API, nothing running server-side — and everything in it is covered by one ed25519 signature.

1 packageserial 3published 24 August 2026indexsignature

  • edos-edit0.1.1editors266 KiB

    Graphical text editor with a file tree, tabs and syntax highlighting

    grab install edos-edit

    What it writes
    • /bin/edos-edit
    • /share/icons/edos-edit.svg

    p/edos-edit-0.1.1.tar.gz
    24870244bed1c6175590a4bfdc1055eb0f4468b4b9a5bc1de0cb0216751e2abd

grab is on the image, so a booted system needs nothing else.

Terminal window
grab update # fetch and verify the index
grab list # what the repository carries
grab install edos-edit # download, check the hash, unpack
grab remove edos-edit # take back exactly what was recorded
grab upgrade # everything installed, to the published version

There is a window for it too. edos-grab renders the same catalogue with its icons, and runs every download on a worker thread so the window keeps drawing through one.

The edos-grab window: a search field and an Update button above a list showing edos-edit with its icon, version and summary, and a detail pane on the right giving the version, category, size, the paths the package installs, and Install and Remove buttons.

RFC822-style stanzas, one blank line between them — the format the page above is rendered from.

Repo: edos
Serial: 2
Generated: 2026-08-13T17:21:59Z
Package: edos-edit
Version: 0.1.0
Summary: Graphical text editor with a file tree, tabs and syntax highlighting
Category: editors
Size: 268819
SHA256: e1649498e58c4ad78cff232674976d78fba66ab15082c548abf16829e771dca5
File: p/edos-edit-0.1.0.tar.gz
Icon: icons/edos-edit.svg
Installs: bin/edos-edit share/icons/edos-edit.svg

Not JSON: it needs no dependency in the guest, it is greppable from a shell that already has grep, and it reads like the rest of /etc. Serial is monotonic and is an anti-rollback guard — grab refuses an index whose serial is lower than the one it already holds, because a signed old index is otherwise a valid way to hide that a fixed version exists.

A detached ed25519 signature over the exact bytes of index, at /pkg/index.sig. The index carries SHA256 and Size for every package, so every package’s integrity chains from that one signature. The public key is a 32-byte constant compiled into grab.

TLS is not enough on its own, and the reason is specific: Cloudflare terminates TLS for this domain, so the certificate a guest validates is Cloudflare’s, not the project’s. Under TLS alone the CDN — and anyone who reaches the origin — decides what binaries the OS runs. Signing makes the transport untrusted, which is also what makes mirroring possible later.

TLS is still used, because a signature gives integrity and not confidentiality, and there is no reason to publish which machine installs what.

A package is a gzipped tar of paths relative to /, and grab enforces two rules rather than trusting the archive:

  • Only bin/, lib/, share/ and opt/. Absolute paths and .. components are refused. etc/ is excluded deliberately: settings belong to the machine, not to a package.
  • Nothing may overwrite a file another package owns, and the install is recorded, so remove takes back that list and nothing else.

A package that needs a setting to exist ships a default rather than writing one. Files under share/defaults/ mirror the /etc tree, and an install copies each to its /etc path where nothing is there, or where this package put the previous default there and nobody has since changed it. Where both the default and the machine’s copy have moved, the two are merged over the default they came from — a line merge first, then, because a setting here is one value under its comment, a rule that says a side which changed no value changed documentation and cannot mean anything else. What is left is a real disagreement: the machine’s file stands and the install says so, naming where the new default can be read. Nothing prompts, and every outcome is announced. Removal is the mirror: a seeded file goes only while it still matches the default it came from, and one edited since is kept and reported.

grab install --allow-unsigned ./name-version.tar.gz installs a local file with no signature check, printing what it is about to do first. It exists so a package can be tested before it is published, it is the only path that skips verification, and it never applies to a URL.

Most programs ship on the image. A program becomes a package by declaring it in the pkg.toml beside its Cargo.toml:

summary = "Graphical text editor with a file tree, tabs and syntax highlighting"
category = "editors"
icon = "assets/edos-edit.svg"
shipped = false # false = packaged, absent = shipped

The version is deliberately not in that file. It comes from the program’s Cargo.toml, because two places to write a version is one place for them to disagree, and cargo’s is the one that built the binary.

edos-edit is the first package and the reason the classification exists: it is the graphical editor, it is the largest program in the tree, and edos-vi stays on the image so a live session with no network still has an editor.