arrow_back Announcements

Project history / September 2023

The first cpak sketches

cpak started on September 10, 2023. Before the runtime had a stable manifest or a Store, two issue threads already described the ideas that would define it: packages that remember where they came from, and packages that can use other packages without absorbing them.

These diagrams were drawn while the first implementation was still moving quickly. They are part of the project's history, not a current runtime specification. cpak v2 kept the intent, but the machinery underneath it is stricter than the first drawings suggest.

Packages keep their origin

The first update design separated installs that follow a branch or release from installs pinned to one commit. That rule still exists. The origin is now the stable identity of a package, while the selected Git reference tells cpak how it should move when an update is requested.

Original cpak origin sources diagram showing commit, branch and release sources
The source model drawn for issue #2 in September 2023.
Original cpak installation and update decision diagram

Today the manifest is validated first, the OCI image is resolved to an immutable digest and the new package is staged before it becomes active. A failed update leaves the previous installation available. A manifest change is applied even when the image itself did not change, including new permission defaults and desktop metadata. The simple source decision in the sketch became a transaction that can be inspected, rolled back and reproduced with a lock file.

A package can call another package

The second design used VS Code and Git as its example. Instead of putting every SDK and tool in the editor image, VS Code could request a Git package at runtime. The first sketch proposed a host service because an isolated application could not enter or start another package by itself.

Original nested cpak diagram showing VS Code asking the host to run Git
The first nested package flow from issue #3. The private bridge survived, but the permission model changed.

In cpak v2 the parent declares the dependency in its manifest and receives a narrow request path for that package. It does not see the host package database or the general cpak control socket. The dependency runs with its own manifest and user overrides, so the parent cannot inherit extra host access simply by asking another package to run. Its layers and writable state also remain separate from the parent.

This is now used by Bottles and UMU. Bottles owns its interface and game library, while the UMU package owns the environment used to launch a game. The same model lets an editor gain an SDK as an optional addon without rebuilding the editor image around every possible toolchain.

What the sketches did not show

The current runtime stores OCI layers by digest, shares equal layers across packages and can use DaBaDee to remove duplicate files that arrived through different layer layouts. Package content, writable application data and transaction state are kept apart. The sandbox is assembled directly with Linux namespaces, OverlayFS, seccomp and Landlock where the host supports them, without a Docker or Podman daemon behind every application.

The drawings captured the two decisions that mattered most: an application should remain tied to its real source, and composition should not require copying the same runtime into every package. The last three years have been spent turning those decisions into a runtime that can carry desktop applications for real.