Declarative embedded build system / 2026 to present
Gaia Image Builder
Embedded releases usually entangle dependency selection, cross-compilation, board boot details, root-filesystem mutation, packaging, and evidence in one script.
Explore public repositoryAn appliance image depends on source selection, several language toolchains, target-specific boot mechanics, root-filesystem staging, partition assembly, and release metadata.
In shell, those phases share implicit state, discover mistakes late, overuse host resources, and make it difficult to explain whether an output is current.
I separated configuration loading from a canonical ResolvedBuildSpec, validation, typed planning, provider execution, and reports.
Stable operation IDs, explicit dependencies and optionality, bounded scheduling, conservative fingerprints, process-group cleanup, and scoped rollback turn the build into an inspectable system rather than a sequence of commands.
A typed build definition becomes a traceable OS image.
Gaia resolves layered board, source, toolchain, and release choices into a validated operation graph before expensive work starts. It bounds nested build concurrency and records the exact input or output change behind every rebuild.
Typed TOML · sources · target · policy
Normalize configuration into one ResolvedBuildSpec
Typed operations · dependencies · failure policy
Parallel artifact work · exclusive image stages
Buildroot · Rust · Go · Java · Node · Python
Image · artifacts · provenance · report
- Scoped-thread scheduler
- Timeout + cancellation
- Process-group cleanup
- Plan + selection
- Provenance + manifest
- Rebuild reasons
The decisions beneath the summary.
One declarative developer workflow
A build can extend reusable layers, import target or profile fragments, expose typed choices, and accept environment or command-line overrides. Dynamic choices can come from source-control refs, releases, JSON, or commands with cached and offline fallbacks. Both the CLI and terminal interface use the same resolve, validate, plan, run, and clean workflow, so an engineer can inspect the merged specification and operation graph before committing to a long build.
- One interpretation: planners and providers consume the same ResolvedBuildSpec instead of assigning different meanings to raw TOML
- Earlier feedback: validation returns the set of configuration problems before expensive source or toolchain work begins
- Reviewable selection: reports record the target, profile, dynamic-input source, and masked secret values that shaped the release
Typed plan and scheduler
Each operation has a stable ID, dependencies, required, conditional, or best-effort semantics, parallelism metadata, a fingerprint, and a reuse decision. The planner rejects invalid dependency policy. For example, a required release output cannot depend on work that is allowed to fail. Independent source and artifact operations can run concurrently, while installation, staging, image mutation, checkpoints, and reporting remain exclusive.
- Workload fit: the scheduler uses scoped threads because it orchestrates subprocesses and filesystems rather than waiting on network sockets
- Host protection: Gaia limits top-level jobs separately from compiler or provider workers so nested parallel tools cannot multiply into unbounded concurrency
- Extension boundary: source acquisition, language builds, and image assembly use separate provider families instead of one unrestricted command hook
Reuse and process lifecycle
Incremental decisions combine the resolved specification, per-operation fingerprints, tool signatures, provider and runtime state, output signatures, and actual output existence. When something changes, reports say why. A shared process runner drains bounded stdout and stderr, enforces timeout and cancellation, terminates Unix process groups, and gives failure policy enough structure to preserve evidence or roll back only outputs created by the current run.
- Cancellation stops new scheduling, terminates owned process groups, and remains distinct from a provider failure
- Atomic publication restores the previous output when replacement fails rather than leaving a half-published artifact
- Release evidence records selected inputs, artifact provenance, file manifests, and the reason each operation ran or was reused
HeliOS as a real composition
The HeliOS configuration exposes CM4, CM5, and generic aarch64 entrypoints with base-OS and full-product profiles. Imports compose the base system, board and firmware policy, applications and services, and release layout. Gaia prepares Buildroot and kernel inputs, stages backend and frontend artifacts, applies device-tree transforms, creates boot and root filesystems, lays out the disk, and emits a compressed image.
- Cross-language boundary: Rust, Go, Java, Node, and Python providers give product layers a common artifact contract instead of separate release scripts
- Concrete output: the HeliOS path creates the boot filesystem, rescue initramfs, read-only system roots, partitioned disk image, and compressed release artifact
- Responsibility limit: HeliOS layers describe the two-slot update layout; Gaia assembles it but does not perform updates on a running device
What this work does not claim.
Gaia is an active v2 typed rewrite, not a zero-configuration universal OS builder.
Every board-specific Buildroot contract and remote checkpoint restore or upload path is not complete.
Reuse is designed to reduce unnecessary work and explain decisions; the repository does not contain a trustworthy universal build-time speedup claim.
Architecture, evidence, and limits.
Explore public repository ↗Architecture
- 01 Canonical specification boundary
layered imports, inputs, presets, environment values, and CLI overrides resolve once; validators and executors do not reinterpret raw TOML
- 02 Typed operation graph
every operation carries a stable ID, dependencies, failure policy, parallelism metadata, fingerprint, and reuse decision
- 03 Provider families by responsibility
source materialization, language artifacts, and image strategies can evolve without collapsing into one command backend
- 04 Bounded synchronous scheduling
subprocess and filesystem work uses scoped threads; independent work can overlap while image mutation and reporting remain exclusive
- 05 Conservative incremental builds
spec fingerprints, tool signatures, provider state, output signatures, and real file checks decide reuse and emit the exact rebuild reason
Validation
- 01
Planner and policy tests exercise invalid dependencies, optional work, cancellation, rollback, and reuse decisions rather than treating compilation as proof
- 02
Buildroot and polyglot aarch64 smoke flows cover source resolution, cross-compilation, staging, filesystem creation, raw-image assembly, and privileged cleanup
- 03
HeliOS configurations compose base OS, CM4 and CM5 board mechanics, application content, and release policy into boot, initramfs, SquashFS, disk, and compressed release artifacts
Why it matters in practice.
- 01Moves configuration and dependency failures ahead of long cross-compiles and privileged image assembly by exposing a validated plan first
- 02Reuses artifacts only when the build spec, tools, provider state, signatures, and physical outputs agree, then explains the exact rebuild reason
- 03Composes CM4, CM5, and generic aarch64 HeliOS images from common layers, allowing board mechanics and product policy to change independently
- 04Bounds nested build concurrency and owns process-group cleanup, so one provider cannot silently exhaust the host or leave child processes behind
- Configuration language and developer workflow
- Typed planner, scheduler, and lifecycle policy
- Source, artifact, and image provider boundaries
- Fingerprinting, reuse, provenance, and reports
- HeliOS target and image-assembly integration
- Rust
- TOML
- Buildroot
- Linux images
- CLI + TUI
- Release automation