watchthelight labs
Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 2 column 377
---
name: legion-check
description: Analyse the latest Project Legion native USB boot attempt. Pulls the boot-screen transcription Bash saved to watchthelight from Claude web ("Legion N-xx screen"), reads the OpenCore logs from the USB stick, works out the furthest boot stage and cause, records evidence, tracker row, git commit and watchthelight notes, and proposes the next single change. Trigger: /legion-check [N-xx], "check N-xx", "check the boot", "check da images".
---

Legion boot check

Project root C:\Users\Hackintosh (rules in its CLAUDE.md). Native track attempts are N-xx on the Boot Attempts sheet. Run these in order, without asking, and report briefly at the end.

  1. Find the attempt. Call list_changes since the last Claude Code write and read_note EVERY new project:legion-hackintosh note from Claude web (any title: "Legion N-xx: ...", "Legion N-xx screen", corrections). Bash often reports one boot as several short notes; never search only for "screen". The attempt ID is the one given, otherwise the highest N-xx in those notes. When nothing new was on screen, Bash reports straight here instead of using Claude web: then take his words as the screen record, save them yourself as "Legion N-xx screen" (say "reported in Claude Code, no photo", with time and what he observed) and go on with the stick log. Never stall or ask for a photo in that case. If there is no note yet, check Taildrop as a fallback: tailscale file get -conflict rename <scratchpad>\taildrop, convert DNG with magick <f> -auto-orient -resize 1600x1600 <f>.jpg and Read it.
  2. Read the stick. Find the USB volume (FAT32, label OPENCORE, usually D:). Use Get-CimInstance Win32_LogicalDisk or just ls /d/: the Storage cmdlets (Get-Volume, Get-Disk) can return nothing in the elevated session even when the stick is there, so never conclude "not plugged in" from them. After a reboot Windows often does not enumerate the stick even though it is plugged in (Bash: "you will need to manually initialize it"): if Win32_LogicalDisk has no OPENCORE volume, run pnputil /scan-devices, then "rescan" | diskpart, wait a few seconds and look again before asking Bash anything. List opencore-*.txt by time; the newest after the previous attempt belongs to this one. Strip NULs (tr -d '\0'). Look at: OpenCore start and drivers, the picker choice, OCAK patch results ([OK] Patch success, failures), EB.LD.LKC (kernel collection load), EB|LOG:EXITBS:START, and anything after. Also check for panic logs OpenCore saved (panic-*.txt or files named by ApplePanic) on the stick root.
  3. Stage reached. Combine log + screen: picker / boot.efi / kernel collection loaded / OpenCore kernel patches / ExitBootServices handover / kernel verbose output / panic text / installer UI. Known meanings:
    • wake-failure Err(0xE) and OS.dmg.root_hash Err(0xE) lines are normal.
    • Picker entry "OPENCORE (external)" (not "(dmg)") re-launches OpenCore and halts: a wrong pick, not a failure.
    • Freeze at EXITBS:START with no kernel text: CPU info handover (ProvideCurrentCpuInfo), Booter memory-map quirks, or early kernel death before the console.
    • The kernel collection takes about 70 s to load from the USB: a frozen EB.LD.LKC line in the first minutes is not a hang.
  4. Record:
    • Evidence: copy each log with python scripts/diag/redact-oclog.py <D:\opencore-...txt> evidence\native\N-xx\<same name> (strips NULs and redacts the Mac identity). From N-36 the stick carries a real, unique SMBIOS identity (private/native-smbios.plist), so a raw copy would publish the serial, MLB and ROM. Before committing, grep -i -E 'serial[^ ]*=|MLB|SystemUUID|ROM' and check that every identity value reads REDACTED.
    • Tracker: python scripts/tracker.py attempt Native ... for a new ID (or edit "Boot Attempts" N-xx <column> <value> if the row exists). Columns: Time, Change since last attempt, Furthest stage reached, Last thing on screen, Result, Issues, Evidence, Next step. New problems get tracker.py issue.
    • Git: commit as watchthelight admin@watchthelight.org, lowercase, no AI attribution, push (public repo: no serials).
    • watchthelight: remember a note "Legion N-xx result" (scope project:legion-hackintosh, cwd C:\Users\Hackintosh) with stage, evidence and the next change; echo the receipt.
    • Research repo: python scripts/upstream/backfill_evidence.py --only N-xx files the new evidence (text logs, redacted) under logs/watchthelight/lenovo-legion-5-15iax10/ in ~/src/research; then python ~/src/research/tools/privacy_check.py --map research/upstream/redaction-map.json --fix (0 problems), commit logs: n-xx and push.
  5. Next attempt. Pick exactly one change for N-(xx+1), explain why in one line, and apply it right away without asking (Bash: "Why would you ask"): back up the current config (config.N-xx.plist.bak on the stick), edit D:\EFI\OC\config.plist, mirror it in native\tools\make_config.py, commit and push. Only changes that touch the laptop itself need Bash's explicit OK: NVRAM WriteFlash true, the internal disk or ESP, BIOS/firmware settings.
    • Diagnostic before guessing: when the same stage repeats, prefer a change that reveals more (panic capture, more logging) over another quirk guess.
    • Git push in an elevated session: the repo uses credential.helper = !gh auth git-credential (Git Credential Manager fails when elevated).
  6. Tell Bash the boot steps: F12, USB, entry 3. OPENCORE (external) (dmg), wait at least 5 minutes, photo, then save it with the legion-boot-screen skill in Claude web. Since N-05 debug=0x100 is off: if the laptop reboots by itself, a kernel panic happened; Bash then presses F12 -> USB, waits for the OpenCore picker (ApplePanic saves the panic to the stick as a file) and powers off. Read that panic file first next time.
  7. Upstream scout (quick). For the targets this attempt touched (XeGfx/iGPU work: xe; NvGfx/NullMoth: nvgfx; Wi-Fi: mt7925-wifi/mt7925-wifi-native; Bluetooth: mt7925-bt; config/kext changes: legion-efi; otherwise skip), run the upstream-scout skill with --quick when python scripts/upstream/scan.py status shows the target's last run over 12 h ago. Put its actionable items (a related project that already solved what this attempt hit, a new upstream release that changes the next step) at the top of the report and let them inform step 5.