Documentsbluefin
copilot-instructions
copilot-instructions
Type
External
Status
Published
Created
Jun 13, 2026
Updated
Jun 22, 2026
Updated by
Dosu Bot

Read AGENTS.md and docs/skills/README.md before any work.
In-repo skills (version-controlled, always current — load these first):

  • ujust recipes and gum patterns: .github/skills/ujust-recipes.md
  • Local/hardware OTA testing: docs/skills/local-ota.md
  • Agent role policies (Hive): files/hive/agent-policies/
  • Full skill index: docs/skills/README.md

/chronicle improve — target skills, not this file#

When running /chronicle improve or any session retrospective:

  • Do not edit this file with session learnings.
  • Write all findings to the appropriate file in docs/skills/.
  • Use the routing table in docs/skills/README.md to find the right file.
  • If no relevant skill file exists, create one and add it to the routing table.
  • Format: add a ### <pattern name> (YYYY-MM-DD) entry under ## Lessons Learned.

Exception: Add a new entry to ## ⚠️ Hard rules below when a pattern has caused repeated failures across multiple sessions and warrants enforcement as a rule (not just knowledge). That is the only reason to edit this file.

This file contains hard architectural rules. docs/skills/ contains accumulated operational knowledge. Keep them separate.

Build commands#

just bst build oci/bluefin.bst # full image build (inside bst2 container)
just build # alias for the above
just export # export OCI image from BST into podman
just lint # bootc container lint (requires exported image)
just bst show oci/bluefin.bst # inspect element dependency graph

Builds run inside the pinned bst2 container. BST_FLAGS env var injects flags:

just bst build oci/bluefin.bst

⚠️ Hard rules (learned from real mistakes)#

1. Work directly in projectbluefin/dakota — always push to upstream#

git checkout upstream/main -b feature/my-change
git push upstream feature/my-change

Never push via the castrojo fork for any PR or retrigger intended for projectbluefin/dakota. The fork diverges and PRs/CI runs against the fork have no effect on upstream.

Dep-update PRs (auto/track-*) are same-repo branches in projectbluefin/dakota. Retrigger by pushing directly to upstream:

git push upstream local-branch:auto/track-foo

Verify your diff is clean before pushing:

git diff upstream/main...HEAD --stat

2. cargo2 source blocks are generated — never hand-written#

python3 files/scripts/generate_cargo_sources.py path/to/Cargo.lock

The first ~65 lines of a Rust BST element are hand-authored (build commands, install paths). Everything after that is generated crate manifest. Do not write crate entries by hand.

3. Layer elements must be kind: compose, not kind: stack#

Elements staged as /layer in OCI script elements must be kind: compose. kind: stack is a dependency aggregator that produces zero filesystem output — the image builds successfully but the layer is silently empty.

# ✅ correct — produces filesystem content
kind: compose

# ❌ wrong — silently empty layer
kind: stack

4. No /issues/NNN paths in issue bodies#

GitHub autolinks org/repo#NNN and /issues/NNN paths regardless of code fence context, firing cross-repo notifications. Write upstream references as plain text:

# ✅ correct
bootc-dev/bootc issue 7

# ❌ wrong — spams the other repo
https://github.com/bootc-dev/bootc/issues/7

5. Never post unsolicited GitHub comments#

Do not post a GitHub comment, review, or PR body edit unless explicitly asked to. Proactively posting comments has caused repeated inbox spam and user frustration across multiple sessions.

  • One comment per PR when you do post — combine all findings.
  • Never post to report status that is already visible in the GitHub UI (CI pass/fail, merge queue position).
  • When in doubt: do the task silently and report back in the chat, not on GitHub.

6. All pushes target upstream (projectbluefin/dakota), never origin (the fork)#

The castrojo/dakota fork exists only as a working copy. Never push a PR branch to origin. Always push to upstream:

git push upstream my-branch

PRs are opened against projectbluefin/dakota. The fork is irrelevant to the PR workflow.

7. Check projectbluefin/testsuite before building any e2e/testing infrastructure#

projectbluefin/testsuite provides a reusable workflow for all GNOME desktop e2e testing. Before implementing any e2e, VM boot, SSH, or QEMU pipeline:

  1. Check projectbluefin/testsuite/.github/workflows/ for an existing reusable workflow.
  2. If it exists, call it — do not build a parallel solution.
# ✅ correct — delegate to testsuite
uses: projectbluefin/testsuite/.github/workflows/e2e.yml@<sha>
with:
  image: ghcr.io/projectbluefin/dakota:testing
  suites: smoke

Building a custom QEMU/SSH/BIB pipeline when a reusable action exists wastes sessions and always loses.

8. Mandatory skill contribution before task_complete#

Every PR must include an update to the relevant docs/skills/ file (per AGENTS.md). Before marking a task complete, verify:

  • Did any code change introduce a new pattern worth documenting? → add to the relevant skill file.
  • Is a new skill file needed? → create it and add it to docs/skills/README.md routing table.

task_complete without the skill contribution is incomplete.

9. Mandatory CI pre-flight — run this before every CI action, no exceptions#

Before merging any PR, pushing to any branch, or dispatching any workflow, run the
pre-flight check and verify the output shows zero active runs. This is not optional.
There is no exception. There is no rationalization that makes skipping this correct.

# MANDATORY PRE-FLIGHT — run before every CI action
gh run list --repo projectbluefin/dakota --limit 30 \
  --json databaseId,status,name,headBranch \
  | python3 -c "
import json, sys
runs = json.load(sys.stdin)
active = [r for r in runs if r['status'] in ('in_progress', 'queued', 'pending', 'waiting')]
if active:
    print(f'BLOCKED: {len(active)} active run(s). Cancel all before proceeding:')
    for r in active:
        print(f' gh run cancel {r[\"databaseId\"]} --repo projectbluefin/dakota # {r[\"name\"]} [{r[\"headBranch\"]}]')
else:
    print('OK: field is clear, safe to proceed')
"

If the output is not OK: field is clearstop. Cancel every listed run, then
re-run the pre-flight until it is clean. Only then proceed.

What counts as an active run that must be cancelled:

  • Any Build Bluefin dakota run — regardless of branch, age, or how long it has run
  • Any Warm BuildStream Cache run — cache-warm is not exempt, ever
  • Any Publish Bluefin dakota run in progress

The rationalizations that have caused real failures — all are wrong:

  • "The cache-warm run is additive, it helps the new build" → No. It starves both. Cancel it.
  • "This build is almost done, just a few more minutes" → Cancel it. You don't know that.
  • "The stale build is for a different branch, it won't interfere" → It uses the same runners and CAS. Cancel it.
  • "I already cancelled one build, that's enough" → Cancel ALL of them. Run the pre-flight again.

Concurrent BST builds share the same ubuntu-24.04 runner pool and the same remote CAS
write bandwidth at cache.projectbluefin.io:11002. Two concurrent builds do not halve
wall time — they more than double it and risk 6-hour timeouts with
Cached elements after warm: 0.

One build. Field clear first. No exceptions.

CI overview#

  • Schedule: nightly at 13:00 UTC (after gnome-build-meta nightly ~08:00 UTC finish)
  • Publish triggers: merge_group, schedule, workflow_dispatch (not pull_request)
  • Remote cache: cache.projectbluefin.io:11002 (mTLS — CASD_CLIENT_CERT + CASD_CLIENT_KEY)
  • Image: ghcr.io/projectbluefin/dakota:{testing,latest,stable} and :<sha>

Key architecture#

  • Built on gnome-build-meta + freedesktop-sdk via BST junctions
  • elements/bluefin/deps.bst (kind: stack) — add new packages here
  • elements/oci/layers/ — compose chain filters artifacts into the final layer
  • elements/oci/bluefin.bst — final OCI assembly script
  • patches/gnome-build-meta/ — drop .patch files here (alphabetical order, no edits to gnome-build-meta.bst)
copilot-instructions | Dosu