Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
pr_number: 5125
title: "fix(ci P0): cascade #4 audit blocking ALL ISO builds since #5119 \u2014 bootloader any-of"
author: "AceHack"
state: "MERGED"
Comment on lines +1 to +5
created_at: "2026-05-26T07:55:11Z"
merged_at: "2026-05-26T08:01:33Z"
closed_at: "2026-05-26T08:01:33Z"
head_ref: "otto-cli/p0-fix-iso-audit-bootloader-any-of-2026-05-26"
base_ref: "main"
archived_at: "2026-05-26T12:30:46Z"
archive_tool: "tools/pr-preservation/archive-pr.ts"
---

# PR #5125: fix(ci P0): cascade #4 audit blocking ALL ISO builds since #5119 — bootloader any-of

## PR description

## Summary — URGENT P0

The cascade #4 ISO content audit (shipped in #5119) is **blocking every ISO build since merge**. Empirical: 4 consecutive workflow failures on commits `35fd3aeef`, `848467588`, `5d9f8605a`, `ed6a7b8b9` — all on the audit step asserting `boot/grub/grub.cfg` as a required path.

**The assertion was wrong.** NixOS installer ISOs as of `nixos-24.11` use:
- **isolinux** for BIOS boot → `isolinux/isolinux.cfg`
- **refind** for UEFI boot → `EFI/BOOT/refind_x64.efi`

Not legacy GRUB at `boot/grub/grub.cfg`. The build log even shows `efi-image_eltorito > Copying grub.cfg` — it lands in `EFI/`, not `boot/grub/`. My cascade #4 draft was version-skewed (training-data default leaked through — ironically the exact gap **B-0805 capstone** names as the systemic agent-discipline failure mode).

## What this means for the maintainer

The last successful ISO build was **`17523e4fb`** (PR #5117, iter-5.2.1 era) — BEFORE iter-5.2.2 (login-banner) and iter-5.3 (password prompt) shipped. If the maintainer flashed a CI artifact today, they'd get a stale ISO missing both. **Hold off on re-flash until this merges + next ISO builds green.**

## Fix

- Drop `boot/grub/grub.cfg` from `REQUIRED_ISO_PATHS` — the remaining 3 (nix-store.squashfs + boot/bzImage + boot/initrd) are sufficient to assert "bootable NixOS installer ISO" (without those nothing boots).
- Add `REQUIRED_BOOTLOADER_ANY` — at-least-one-of family check across known NixOS bootloader layouts (isolinux + refind variants + legacy grub for forward-compat).
- Header comment documents the empirical anchor so future-Otto doesn't reintroduce the legacy-path assumption.

## Test plan

- [x] TS typecheck clean
- [ ] Auto-merge armed; CI build will confirm the audit no longer false-positives
- [ ] Post-merge: verify next CI ISO build succeeds + names commit SHA for the maintainer's re-flash

## Composes with

- B-0805 (capstone, P1) — dep-pin-search-first-authority discipline; this PR is exactly the kind of failure that backlog row was designed to prevent

🤖 Generated with [Claude Code](https://claude.com/claude-code)

## Reviews

### COMMENTED — @copilot-pull-request-reviewer (2026-05-26T07:57:56Z)

## Pull request overview

Fixes the cascade #4 CI ISO content audit so it no longer falsely fails on modern NixOS installer ISO bootloader layouts, restoring ISO build workflows that were blocked by an incorrect GRUB path assertion.

**Changes:**
- Removes `boot/grub/grub.cfg` from the “must exist” ISO paths and keeps only the squashfs + kernel + initrd as hard requirements.
- Adds a bootloader “any-of” check (`REQUIRED_BOOTLOADER_ANY`) to accept multiple known bootloader layouts (isolinux/refind/legacy GRUB).
- Documents the empirical NixOS ISO layout that motivated the change to prevent reintroducing the legacy-path assumption.

## Review threads

### Thread 1: tools/ci/audit-installer-iso-content.ts:289 (resolved)

**@copilot-pull-request-reviewer** (2026-05-26T07:57:56Z):

P0: `bootloaderHit` is assigned but never used. With `noUnusedLocals: true` in tsconfig, this will fail `tsc` for this file. Replace the `.find(...)` with a boolean `.some(...)`, or use `bootloaderHit` (e.g., include which path matched in the PASS/diagnostics) so the variable is actually referenced.

## General comments

### @chatgpt-codex-connector (2026-05-26T07:55:16Z)

You have reached your Codex usage limits for code reviews. You can see your limits in the [Codex usage dashboard](https://chatgpt.com/codex/cloud/settings/usage).
Loading