Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The version uses the UTC date when the build starts. `N` is one more than the largest matching version tag already published to GHCR, so the first published image on September 21, 2026 is `20260921.1`. Failed and cancelled builds do not reserve a number. A rerun only advances the counter if its previous attempt published the version tag. CI writes this version into the image before BuildStream starts. It appears in `os-release`, the OCI metadata and the boot image selector as, for example, `Personal OS 20260921.1`.

The build uses standard GitHub-hosted Ubuntu runners and upstream BuildStream caches, without preserving local artifacts between runs. Full builds have already completed successfully on those runners.
The build uses standard GitHub-hosted Ubuntu runners and upstream BuildStream caches, without preserving local artifacts between runs.

Publication uses Red Hat's `push-to-registry` Action. It reuses the image already imported into Podman for bootc validation, then publishes the version, commit and `latest` tags. The workflow's `IMAGE_NAME` is `tb516/os`; keep it aligned with `include/image.yml` if the repository moves. Renovate tracks the publishing Action's pinned revision.

Expand All @@ -22,15 +22,15 @@ Docker's Engine, CLI, Compose and Buildx update together through the official Do

```yaml
# renovate: datasource=docker depName=docker.io/library/docker
track: 29.9.1-dind
ref: sha256:d18cae6d97a9ebf10a017859d3cdf728de0f2efc465364ba0bab6e2c9a87ccdc
track: <version>-dind
ref: sha256:<linux/amd64 manifest digest>
```

Keep the full version and `-dind` suffix. Renovate updates the tag and digest together and preserves the architecture of the existing Linux amd64 manifest pin. BuildStream's Docker source expects a platform manifest rather than a multi-platform index.

The shared BuildStream plugin junctions have their own release tags and commit pins, managed directly by Renovate. They no longer follow GNOME's plugin recipes. The Docker source carries a small compatibility patch shared with other OCI imports, covering HTTP content types, Zstd layers and `sha256:` refs. Review that patch when updating the plugin release.

GNOME and Dakota track their existing Git branches. Container images and Actions are also tracked; nested component versions remain owned by their upstream junctions. Dependency updates need no checksum or recipe synchronization script.
The Dakota recipe pin follows Dakota's `testing` branch, but only to commits whose Dakota CI build succeeded, so their artifacts are already in the Bluefin cache. A Renovate custom datasource reads the newest `build.yml` push run on `testing` and offers its commit only if that run succeeded. Dakota skips the build for a push when a newer push is already queued, so older successful runs are not trusted. While the newest build is still running or has failed, Renovate reports a lookup warning and leaves the pin alone. GNOME and freedesktop-sdk move with Dakota. Container images and Actions are also tracked; nested component versions remain owned by their upstream junctions. Dependency updates need no checksum or recipe synchronization script.

The kernel image in `elements/core/dakota-boot.bst` independently follows Dakota's `testing` channel with an exact amd64 manifest digest. Kernel, modules, signed EFI binaries and signing certificate come from the same image; the Dakota recipe pin does not have to match its source revision.

Expand All @@ -42,4 +42,4 @@ Kernel updates show image build timestamps, Dakota source revisions, kernel sour

The report uses the workflow's existing `RENOVATE_TOKEN`. It includes the PR revision and skips publishing if that revision changed during generation. Existing comments are updated only when their content changes. A temporary fetch failure preserves an existing successful report for the same PR revision.

Review GNOME/Dakota compatibility and local integration assumptions before merging. The build starts after merging, so an update PR does not establish that the new OS builds or boots.
Review Dakota updates and local integration assumptions before merging. The build starts after merging, so an update PR does not establish that the new OS builds or boots.
40 changes: 17 additions & 23 deletions docs/building.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/chunkah.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ Actual transfer savings need measuring across two builds with a small update.
Runtime validation still needs a chunked image boot and upgrade in a VM, plus
CI disk usage and packaging time measurements.

References: [Chunkah usage](https://github.com/coreos/chunkah/blob/v0.6.0/README.md)
and [fallback component detection](https://github.com/coreos/chunkah/blob/v0.6.0/src/components/bigfiles.rs).
References: [Chunkah usage](https://github.com/coreos/chunkah/blob/main/README.md)
and [fallback component detection](https://github.com/coreos/chunkah/blob/main/src/components/bigfiles.rs).
10 changes: 4 additions & 6 deletions docs/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ The initial base is GNOME 51 and freedesktop-sdk 26.08, using baseline x86_64. D

x86-64-v3 was tried during bring-up, then disabled because upstream GNOME and Dakota CI use the baseline target. Reusing upstream artifacts takes priority over CPU-specific compilation, especially for future hosted CI builds.

Dakota tracks `testing` with a fixed commit. The initial `next` pin was replaced after confirming that the borrowed components were identical on `testing`; the rolling branch was unnecessary for the pinned GNOME 51 base.
Dakota is pinned to commits on its `testing` branch whose CI build succeeded. Its rolling `next` branch follows GNOME's development branch and is not used.

## Composition decisions

- Keep one shared GNOME/freedesktop-sdk graph. Pin compatible upstream revisions and review them together when updating.
- Take GNOME and freedesktop-sdk through Dakota's junctions and pin only Dakota, so the graph matches the artifacts Dakota's CI caches. This also accepts Dakota's GNOME-level choices, such as its boot splash and bootc.
- Own the final composition locally. Reuse individual Dakota elements through a junction without importing `bluefin/deps.bst` or `bluefin/common.bst`.
- Use public artifact and source caches read-only. Preserve upstream recipes where possible, but let image requirements determine composition.
- Build one complete OS image. The initial split into two editions was removed to keep builds and validation focused on the system that will be used.
Expand All @@ -24,8 +24,6 @@ Dakota tracks `testing` with a fixed commit. The initial `next` pin was replaced

GNOME supplies the desktop session and host integration. Flatpak is the normal GUI application format, with Bazaar as the store and an explicit default application list. Files and Disks are native applications. Sushi is selected as a default Flatpak for file previews. PDF thumbnails are omitted so the image does not need native Papers or a separate extraction recipe.

Helium and Microsoft Visual Studio Code were initially included as native applications for host integration. They have since been removed from the image.

Use Flatpak's built-in `.preinstall` declarations and a boot service, following Dakota's approach. The default set includes the app store, system monitor, file previews, GNOME extension management, GNOME tweaks, Flatpak permission management and journal viewing. Flatpak owns installation state and respects manual removals; changes to the default selection do not require maintaining a custom installer or completion marker.

Keep parental controls and Help as supplied by upstream. An initial attempt to exclude them required modifying three GNOME recipes; maintaining those changes was not worth the smaller application selection. GNOME user documentation remains excluded through the local session list. Keep sharing services, remote desktop, accessibility and color management.
Expand All @@ -34,7 +32,7 @@ Ghostty is image-managed and supplies the preferred terminal integration. Distro

Tailscale and QEMU/libvirt belong in the image because they need host services. Selected Dakota elements also provide resolver integration, the composefs disk-visibility rule and the PC-speaker audio rule.

The initial implementation keeps bootc install defaults local to select Btrfs. It retains GNOME's bootc version and zram defaults. Exact pins and recipe ownership are documented in the [build guide](building.md).
The initial implementation keeps bootc install defaults local to select Btrfs. It uses Dakota's bootc and GNOME's zram defaults. Exact pins and recipe ownership are documented in the [build guide](building.md).

## Deployment decisions

Expand All @@ -50,4 +48,4 @@ Dependency-update PRs and CI publication to GHCR are in place.
2. Verify a fresh installation through the adapted installer, its update origin, and a subsequent update-and-rollback cycle.
3. Complete hardware and external-integration acceptance, including accelerated graphics, audible output, Tailscale enrollment and running libvirt guests.

The full image builds, installs and boots through systemd-boot into a GNOME Wayland session. Initial setup, native apps, default Flatpaks, PDF previews, container networking and persistence across reboot have passed VM checks. Keep exact results and limits in the validation notes rather than treating this roadmap as evidence of completion.
The full image builds, installs and boots through systemd-boot into a GNOME Wayland session. Initial setup, native apps, default Flatpaks, container networking and persistence across reboot have passed VM checks. Keep exact results and limits in the validation notes rather than treating this roadmap as evidence of completion.
6 changes: 3 additions & 3 deletions docs/secure-boot.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Personal OS uses Dakota's signed boot chain. The full image build and disposable

`core/dakota-boot.bst` imports the signed kernel, matching modules, signed systemd-boot/fwupd EFI loaders, Fedora's Microsoft-signed shim/MokManager and Dakota's public certificate from one pinned production OCI image. It preserves signatures and builds our own initramfs. The import requires the signed payload and relevant kernel capabilities; it does not fall back to unsigned files.

Dakota's merged source recipes provide the enrollment helper, its boot-time EFI maintenance service, explicit `lockdown=integrity`, and `kernel.kexec_load_disabled=1`. A local patch installs the helper as `/usr/libexec/personal-os-secure-boot`, updates the service to call it, and labels new firmware entries `Personal OS`. GNOME supplies `mokutil`. Local boot arguments request `intel_iommu=on` and `iommu.passthrough=0`; AMD IOMMU is enabled by the kernel by default. The imported kernel must include BPF LSM and lockdown in its default LSM list.
Dakota's merged source recipes provide the enrollment helper, its boot-time EFI maintenance service, explicit `lockdown=integrity`, and `kernel.kexec_load_disabled=1`. A local patch installs the helper as `/usr/libexec/personal-os-secure-boot`, updates the service to call it, and labels new firmware entries `Personal OS`. freedesktop-sdk-extra supplies `mokutil`. Local boot arguments request `intel_iommu=on` and `iommu.passthrough=0`; AMD IOMMU is enabled by the kernel by default. The imported kernel must include BPF LSM and lockdown in its default LSM list.

Signing stays upstream. Keep Dakota's `secure_boot_signing` build option false here: enabling it would request upstream signing elements and private-key inputs, which this project does not need.

The image tracks `testing` for Renovate updates and pins its production image at revision `95ff6c060392d2c3b05c82d057b1e9e5adf59eb8`. Builds use the exact pinned digest. The import rejects unsigned payloads; review the payload before accepting an image update.
Renovate follows Dakota's production `testing` image, and builds use the exact pinned digest. The import rejects unsigned payloads; review the payload before accepting an image update.

## Enrollment after build and boot validation

Expand Down Expand Up @@ -43,7 +43,7 @@ Lockdown prevents hibernation and loading modules signed by untrusted keys. Disa

Dakota's `check` command is an upstream diagnostic, not Epic's acceptance test. Read its reported failures/waits; its exit code alone does not establish readiness.

The tested VM boots through Microsoft-trusted shim, Dakota-signed systemd-boot and the signed kernel. Dakota's checker reports eight passes and two waits for key recognition. Firmware rejects a direct bootloader launch that bypasses shim, and the kernel rejects a module with its signature removed. The maintenance service restores stale/missing EFI files. See [validation results](validation.md) for the image digest and evidence.
The tested VM boots through Microsoft-trusted shim, Dakota-signed systemd-boot and the signed kernel. Dakota's checker reports eight passes and two waits for key recognition. Firmware rejects a direct bootloader launch that bypasses shim, and the kernel rejects a module with its signature removed. The maintenance service restores stale/missing EFI files. See [validation notes](validation.md) for what has been tested.

Remaining validation before upgrading the host:

Expand Down
Loading