This file contains durable project rules for coding agents. It should stay stable and focused on conventions, invariants, commands, and project-specific gotchas.
bluecat is a rebranded Fedora Atomic/Kinoite-style bootc/rpm-ostree image.
The image intentionally uses ID="bluecat" in /usr/lib/os-release while
retaining Fedora compatibility through ID_LIKE=fedora.
The project builds:
- An OCI image published to GHCR.
- An offline Anaconda installer ISO that embeds the locally built OCI image
payload as
/images/bluecat.oci. - Branding assets and installer/ISO rebranding so user-facing Fedora branding is removed where this project controls it.
Use mise tasks as the public project interface:
mise build:imagebuilds the local OCI image.mise build:chunked-imagebuildsoutput/bluecat.oci, the chunked OCI layout used for ISO and publish. It removes the unchunked:localimage by default after successful chunking; setKEEP_UNCHUNKED_IMAGE=1only when the intermediate image is needed.mise buildkeepsoutput/bluecat.ociafter the ISO build so a followingpublish:imagecan push it. The layout is replaced by the nextbuild:chunked-imagerun; it is not deleted automatically after publish.mise publish:image releasepushes release tags formainbuilds.mise publish:image pr <number>pushes the PR test image tag only. Publishing recompresses the OCI layout to zstd for the registry; alias tags are copied registry-to-registry with preserved digests.mise build:isobuilds the offline installer ISO.mise publish:isouploadsbluecat.iso,bluecat.iso.sha256, andbluecat.iso.md5to S3-compatible storage.mise verify-keysvalidates Secure Boot MOK signing material.mise lintruns the full static verification suite.mise taskslists available tasks.
Run project tools through mise. Prefer the matching task when one exists; for
ad-hoc tools use mise x -- <command>. Do not call tools like spellcheck,
shellcheck, deno, yq, or similar directly because some are only available via
the mise environment.
Before marking shell/workflow changes done, run the relevant checks:
bash -nfor Bash tasks.shellcheck --external-sources --severity=warningfor Bash tasks only.- Do not run ShellCheck on
mise-tasks/verify-keys; it is a Deno script. - Validate workflow YAML with the existing workflow lint task or
yq. - Prefer
mise lintfor the final project-level verification when feasible.
- Keep
ID="bluecat"in/usr/lib/os-release. Do not change it toID=fedorato make tools happy. - The ISO is an offline Anaconda installer ISO. It embeds the local bootc image
as an OCI layout and installs it with Anaconda's
bootcKickstart command. Do not switch back to Titanoboa unless the project explicitly changes direction. build:imageandpublish:imagerun rootless for performance. Do not switch them to rootful without re-evaluating overlay performance.build:isostarts as the normal user but uses rootful podman internally for themkksisostep because loop devices are required.- Do not enable
libvirtservices by default. They are installed only. toolboxis removed anddistroboxis installed.- Nushell is installed from the upstream GitHub release tarball pinned by
dependencies.yaml. Do not use the Gemfury RPMs; their package scriptlets have broken image builds. - Keep changes surgical. Do not refactor adjacent code or documentation unless it is directly required by the task.
.github/workflows/build.yaml is the artifact workflow. It builds the OCI image,
the chunked OCI image, and the ISO locally first, then publishes artifacts only
after those builds succeeded.
The artifact workflow runs:
- On every push to
main. - Once per day from
main. - For PRs only when the
test imagelabel is applied.
For release builds it pushes:
- the Fedora major tag, for example
44 - a timestamp tag in the existing format
44.<YYYYMMDDTHHMM>
Timestamp-tag retention is controlled with RELEASE_TAG_RETENTION and is set to
3 in CI. PR image push behavior must remain independent from this cleanup.
For release builds, build:iso runs before publish:image release, so a broken
ISO build prevents publishing the release image tags. The workflow then runs
publish:image release and finally publish:iso. PR test image builds also run
the local ISO build as a gate, but do not publish the ISO. publish:iso uploads
bluecat.iso, bluecat.iso.sha256, and bluecat.iso.md5 to the configured
S3-compatible storage under s3://bluecat/latest/. The public ISO URL is
https://download.bluecat.echocat.org/latest/bluecat.iso. GitHub Releases are
not used for ISO publishing.
The workflow uses concurrency cancellation so a newer queued run on the same branch cancels an older running one.
mise build:isoembeds the existingoutput/bluecat.ocilayout under/images/bluecat.ociin the ISO. It hardlinks the layout into the temporary mkksiso tree to avoid a second full copy.iso/bluecat.ks.inuses Anaconda'sbootcKickstart command withoci:/run/install/repo/images/bluecat.oci:bluecat:local-chunkedas source and the configured release image ref as update target.- Files that should land in the ISO root live under
iso/rootfs/. Files that should land inside Anaconda's temporaryproduct.imglive underiso/product.img/and are packaged duringmise build:iso. mkksiso -Vsets the ISO volume ID and rewrites GRUB stage2/LABEL references to match. Do not run broad replacements like-R "Fedora" "bluecat"; only replace human-readable GRUB menu strings with targeted-Rrules.- ISO publication uses generic S3 variable names (
ISO_S3_BUCKET,ISO_S3_PREFIX,ISO_S3_ENDPOINT_URL) even though the current backend is Cloudflare R2.
Containerfile- image build stages and build arguments.dependencies.yaml- central definition of pinned versions of dependencies.image/setup/stage1- stage 1 setup runner.image/setup/stage1.d/- module build and signing steps.image/setup/stage2- stage 2 setup runner.image/setup/stage2.d/- package installation, OS rebranding, and most image customization.iso/bluecat.ks.in- offline bootc Kickstart template.iso/rootfs/- files added to the ISO root.iso/product.img/- Anaconda product image branding files.mise-tasks/build/image- rootless local image build.mise-tasks/build/chunked-image- chunked OCI layout build used for ISO and publish.mise-tasks/build/iso- offline Anaconda installer ISO build.mise-tasks/publish/image- release and PR tag/push logic plus release timestamp tag retention.mise-tasks/publish/iso- S3-compatible rolling ISO upload.mise-tasks/verify-keys- Deno-based MOK key/cert validation..github/workflows/build.yaml- OCI image CI workflow plus release ISO build and S3-compatible rolling ISO upload.image/rootfs/- files copied into the final image.image/rootfs/usr/lib/bootc/kargs.d/00-nvidia.toml- NVIDIA-related bootc kernel arguments.
- Development may happen under WSL2 even when the user's primary environment is Windows. Be careful when discussing paths; prefer relative repo paths.