PR Review#
Consolidated review workflow for dakota pull requests.
Before you review#
- Read
docs/workflow.md— issue lifecycle, labels, branch flow - Read
docs/pr-checklist.md— per-category checklist
Review priorities (in order)#
- Branch hygiene — PR must branch from
upstream/main, not a fork's localmain. Verify withgit diff upstream/main...HEAD --stat— it should be minimal and contain only the PR's changes. - Checklist compliance — verify the relevant items from
pr-checklist.mdfor the type of change (junction bump, patch, OCI, element, etc.). - CI gate status —
validateande2eare required status checks. If CI hasn't run, note it. Ife2ewas skipped (non-image paths), that counts as passing. - Scope discipline — one logical change per PR. Junction bumps must not include patch modifications in the same commit.
- Correctness — element syntax, layer kind (
composenotstack), cargo sources generated not hand-written, systemd units enabled via BST install commands.
Common rejection reasons#
| Signal | What's wrong |
|---|---|
| Hundreds of files in diff | Branched from fork main instead of upstream/main |
kind: stack in a layer element | Should be kind: compose — stack produces zero filesystem output |
| Hand-written crate entries | Must use generate_cargo_sources.py |
Missing Closes #NNN | PR isn't linked to an issue |
patches/ change in a junction bump commit | Must be separate commits or separate PRs |
No just lint / just boot-test evidence | Verification gate not met |
How to give feedback#
- Guide, don't just reject. Point contributors toward the correct pattern in
docs/workflow.mdordocs/pr-checklist.md. - One comment per review event. Combine all findings into a single review comment. Never post follow-ups for new observations — edit the existing comment.
- Do not duplicate GitHub UI. Don't restate approval counts, merge queue status, or CI summaries that GitHub already shows.
- Minimal test reports. What ran, pass/fail, blockers. No diff summaries.
Ghost detection#
Agent-assisted PRs are identified by the checked template checkbox:
[x] I am using an agent and I take responsibility for this PR
Hold these to the same standard as human PRs. The operator is accountable.
Mergeraptor pre-approval#
Junction-only bumps from mergeraptor[bot] are pre-approved once validate and e2e pass (or e2e is skipped for non-image paths). No human review required for those.
Dep-update PR review#
Auto-generated dep-update PRs (auto/track-*, renovate/*) always target
main by default. Before reviewing, check:
- Is it redundant? — Compare the
ref:field in the element against
upstream/testing. If identical, close the PR;testingalready has it. - Cherry-pick, don't merge as-is — The branch is based on
mainand
carries 4–6 unrelated CI/docs commits not intesting. Cherry-pick only
the top dep-update commit onto a cleantestingbase. - Skip e2e if infrastructure is broken — If the same e2e failure appears
on every dep PR simultaneously ("SSH never became ready"), it's a stale
:testingissue, not a PR issue. Validate passing + correct diff is enough.
See merge-queue.md for the full retarget/cherry-pick/merge flow.
Lessons Learned#
Rubber duck CI changes against bluefin/bluefin-lts before merging (2026-06-07)#
When making changes to .github/workflows/ that touch the publish, promote,
or release pipeline, run a rubber duck comparison against the equivalent
workflows in projectbluefin/bluefin and projectbluefin/bluefin-lts before
opening a PR. This surfaces inconsistencies and cross-repo bugs that pure
code review misses.
What to compare:
cert-identity-regexpanchoring — must be^...$end-anchored (dakoa is correct; bluefin/lts are not)environment: productiongate placement — should be on image promotion, not on release notes creation- SBOM handling — artifact-first with Syft fallback is stronger than always regenerating
- TOCTOU patterns — digest-pinned promotions, single skopeo inspect calls
Invocation:
rubber duck the release pipeline for consistency with projectbluefin/bluefin and bluefin-lts, built on projectbluefin/actions
Then pipe the findings directly into fixes before the PR lands. This session
caught 4 issues from rubber duck + 1 interaction bug (TOCTOU guard) from
doublecheck — all fixed before merging.
Check new service/file additions are wired into BST install-commands (2026-06-10)#
Dropping a file into files/firstboot/ (or any source directory) does not make
it land in the OCI image. elements/bluefin/firstboot-services.bst only installs
files explicitly listed in install-commands. A PR that adds a new file but no
corresponding install -Dm644 ... "%{install-root}/..." line is silently incomplete
— the file exists in the source tree but never reaches the image.
Review checklist for PRs adding new files:
- Find the
.bstelement that owns the directory (greppath: files/<dir>inelements/) - Confirm the element's
install-commandsblock has an entry for the new file - If the file should be enabled at boot, also check for a
ln -sfsymlink step
PR 750 added files/firstboot/keyring-unlock.service with no install-commands
entry — the service would never land in the image.