Dakota Build System#
What Is Dakota?#
Dakota is Bluefin's CoreOS-model bootc image, built entirely from source using BuildStream 2. Zero RPMs. Zero dnf. No Containerfile package overlays — BST elements only .
The stack assembles in three layers:
- freedesktop-sdk — provides glibc, systemd, kernel
- gnome-build-meta — provides GNOME Shell, Mutter, GTK
- Dakota elements (
elements/bluefin/) — Bluefin-specific packages on top
At runtime, Dakota uses the composefs-oci backend via bootc — not OSTree, not rpm-ostree . It is published as ghcr.io/projectbluefin/dakota:{testing,stable,next,btw} .
Watch out for legacy paths: the repo still uses
bluefinin filenames likeelements/bluefin/*andoci/bluefin.bst. These are Dakota build paths, not a signal that the dnf/RPM workflow applies here .
Architecture Comparison#
The fundamental difference: production Bluefin images are Containerfile-based overlays (FROM base_image + dnf install). Dakota builds the entire stack from source .
| Dimension | Dakota | Bluefin | Bluefin LTS |
|---|---|---|---|
| Base | freedesktop-sdk + gnome-build-meta (source) | Fedora Silverblue (pre-built RPMs) | CentOS Stream 10 (pre-built RPMs) |
| Build system | BuildStream 2 (hermetic sandbox) | Containerfile + dnf install | Containerfile + dnf install |
| Desktop | GNOME nightly/latest | GNOME (Fedora's version) | GNOME 48 (pinned) |
| Kernel | freedesktop-sdk kernel | Fedora kernel + akmods | CentOS kernel + akmods |
| Update model | bootc (native) | rpm-ostree (migrating) | bootc (native) |
| Package count | ~20 Bluefin-specific elements | ~80 base + ~60 DX RPMs | ~80 base + DX/GDX RPMs |
| Architectures | x86_64, aarch64, riscv64 | x86_64 primarily | x86_64, aarch64 |
Dakota is explicitly a curated subset of production Bluefin — it includes things production doesn't (sudo-rs, uutils-coreutils, GNOME nightly) and intentionally omits things impractical for from-source builds (Nvidia drivers, ZFS, enterprise AD/Kerberos) .
gnome-build-meta Integration & Junction Architecture#
Dakota's entire GNOME stack is sourced through two tightly coupled BuildStream junctions:
elements/gnome-build-meta.bst— pins a specific gnome-build-meta git SHA; overridesmeta-gnome-core-apps.bst(strips default GNOME apps),bootc.bst(tracks newer bootc), and kernel module signingelements/freedesktop-sdk.bst— pins freedesktop-sdk; cross-overrides ~20 SDK components (glib, cairo, gtk3, systemd, pango, etc.) to use versions from gnome-build-meta
Because freedesktop-sdk.bst references gnome-build-meta elements directly, these two junctions must always be updated together in a single atomic commit — bumping one without the other breaks the build .
Local patch queues live in patches/gnome-build-meta/ and patches/freedesktop-sdk/. Every patch requires an Upstream-Status: header (Submitted, Accepted, Pending, or Not-applicable) and a clear exit condition. Patches apply in alphabetical filename order. See docs/skills/patch-junctions.md for the full lifecycle .
This direct integration with gnome-build-meta is what gives Dakota access to GNOME upstream before it reaches any distribution.
Rust Components & Build Optimization#
Dakota's distinguishing packages are its memory-safe Rust components — the "crown jewels" of the from-source approach :
| Component | Crate count | Purpose |
|---|---|---|
| bootc | ~200 crates | Image-based update model |
| uutils-coreutils | ~250 crates | Memory-safe coreutils replacement |
| sudo-rs | — | Memory-safe sudo replacement |
These are built via make + cargo2 element kind, with cargo2 sources handling crate vendoring. See docs/skills/packaging-rust.md for the Rust packaging pattern.
Other heavy build contributors :
- GRUB — built in 3 variants (
i386-pc,i386-efi,x86_64-efi). Upstream GNOME OS uses systemd-boot; Dakota adds GRUB for bootc compatibility. - Junction patches — local patches modify junction identity hashes, which may reduce upstream CAS cache hit rates. Upstreaming patches improves build performance.
Pre-built binary pattern — Tailscale, Zig, Homebrew, and Go CLI tools use kind: manual + source: remote (single-file download). New packages that don't require from-source compilation should follow this pattern.
Image Streams & Release Model#
| Tag | Branch | GNOME | Cadence | Junction updates |
|---|---|---|---|---|
:testing | testing | GNOME 50 (stable) | Daily (13:00 UTC), boot-check gated | Manual review |
:stable | main | GNOME 50 (stable) | Auto-promoted from :testing | Manual review |
:next | next | GNOME 51 (master) | Daily (03:00 UTC) | Auto-merge |
:btw | next | GNOME 51 (master) | Daily (03:00 UTC), nvidia variant | Auto-merge |
:next / :btw track gnome-build-meta master (GNOME 51 development). Junction bumps are fully automated via track-next-junctions.yml at 20:00 UTC — no human review required. This stream never promotes to :stable .
:testing / :stable use track-bst-sources.yml (runs 06:00 UTC) which requires human review before merging junction bumps, since they can break downstream elements .
Runtime: composefs, not OSTree#
The BST export includes /sysroot/ artifacts (build tooling leftover) — these are stripped via --prune /sysroot/ at rechunking time. The booted system uses the composefs-oci backend. Never suggest rpm-ostree, bootupd, or ostree admin for a running Dakota system .
Validation gate: bootc upgrade on test hardware + reboot + GDM active. CI green is not sufficient — hardware confirmation is required .
Key Files & References#
| File / Path | Purpose |
|---|---|
elements/gnome-build-meta.bst | GNOME stack junction — pins gnome-build-meta SHA, overrides apps/bootc |
elements/freedesktop-sdk.bst | SDK junction — pins freedesktop-sdk, cross-overrides ~20 components |
elements/bluefin/ | All Dakota-specific BST elements |
oci/bluefin.bst | OCI image assembly element (kind: script) |
patches/gnome-build-meta/ | Local patch queue for gnome-build-meta |
patches/freedesktop-sdk/ | Local patch queue for freedesktop-sdk |
docs/skills/overview.md | Product context & architecture summary |
docs/skills/patch-junctions.md | Patch lifecycle, headers, rebase instructions |
.github/workflows/track-bst-sources.yml | Atomic junction tracking for main |
.github/workflows/track-next-junctions.yml | Atomic junction tracking for next |
Common just commands#
| Command | What it does |
|---|---|
just build | Full image build |
just bst build bluefin/<name>.bst | Build one element |
just validate | Validate full element graph (no build) |
just bst shell --build bluefin/<name>.bst | Enter build sandbox |
just bst source track bluefin/<name>.bst | Track a git/tarball ref |
BST weak-key caching gotcha#
Adding a package to deps.bst (kind: stack) does not trigger a rebuild of downstream OCI layers (kind: compose) in non-strict mode. Workaround: force-invalidate the compose element's cache, or build in strict mode: just bst --no-cache-buildtrees build oci/bluefin.bst .
Further reading: BuildStream 2 docs · AGENTS.md · Dakota repo · docs/SKILL.md