--- name: bug-report description: > Decode and triage pipensx bug reports from QR-code screenshots or photos. Use when the user shares a bug-report image (Settings → Report a bug), paths under bug-reports/, decode_report.py, QR log reconstruction, or asks to analyze a Switch-side crash/update/download/install failure from a reporter photo. --- # Bug reports (QR log capture) Reporters open **Settings → Help → Report a bug** (or the equivalent locale string). The console renders the recent `pipensx.log` tail as a grid of QR codes on one screen and sends the developer a **photo or Capture screenshot** — nothing is uploaded automatically. Your job: **decode → reconstruct the log → triage**. Never read a decoded log whole; grep it by tag the way `AGENTS.md` says for `pipensx.log`. ## 1. Read the screenshot first (no decoder needed) Before running any script, open the image with the Read tool. Extract: | On-screen field | What it tells you | |---|---| | Summary line (`pipensx X · firmware Y · …`) | App version, HOS version, free space, installed count, catalog size, active downloads, **error count** | | `Report ABCD · codes: N` | Session id `ABCD`, expected QR count | | `(recent log only)` / `(verbose lines dropped)` | Tail was **truncated** or **filtered** before encoding — gaps are expected | | Hint about Capture vs photo | **Detailed mode** (Y toggles): denser codes, needs a screenshot not a TV photo | | User's filename / message | Human description of the symptom (e.g. `cant update.jpg`) | Cross-check: decoded session id and chunk count must match the caption. A mismatch means mixed reports or a partial photo. ## 2. Decode Image decoding needs Pillow plus **either** `pyzbar` **or** the `zbar` package's Python bindings (Arch: `pacman -S zbar python-pillow` — no pip needed): ```sh # Arch sudo pacman -S --needed zbar python-pillow # Debian/Ubuntu (pyzbar) sudo apt install libzbar0 python3 -m pip install pyzbar pillow ``` Run from the repo (or pass the full script path): ```sh cd ~/pipensx scripts/decode_report.py ~/bug-reports/cant\ update.jpg -o /tmp/report-ABCD.log ``` Stderr prints metadata, e.g.: ```text decode_report: report B7CD (3 codes, default mode, 42112 bytes, verbose lines dropped) OK ``` **Exit codes and fixes** | Error | Cause | Fix | |---|---|---| | `no QR codes in …` | Blur, glare, rotation, codes cropped | Ask for a Capture screenshot; entire grid visible | | `missing chunk(s) [k] of N` | Photo cut off one code | Recapture whole screen; all N codes from caption | | `CRC mismatch` | Corrupt decode (common on TV photos) | Detailed mode + Capture, or retake with less glare | | `bad magic` | Random QR in frame (e.g. web companion QR) | Crop to bug-report screen only | | `image decoding needs pyzbar` / `needs Pillow` | Missing deps | `pacman -S zbar python-pillow` (Arch) or `pip install pyzbar pillow` | Raw chunk mode (no image deps, used by tests): ```sh scripts/decode_report.py --raw chunk_0.bin chunk_1.bin … ``` Wire format: `src/app/bug_report.hpp`, must stay in lockstep with `scripts/decode_report.py`. ## 3. Triage the reconstructed log Work **newest → oldest**. Start with structured errors, then widen. ```sh LOG=/tmp/report-ABCD.log # Hard failures — always read these lines in full rg '\[diagnostic\].*level=error' "$LOG" # System snapshot written at report capture (version, HOS, storage, counts) rg '\[diagnostic\].*stage=system' "$LOG" # Symptom-specific (pick what matches the user's report) rg '\[update\]' "$LOG" # app self-update rg '\[install\]' "$LOG" # NSP/NCA install pipeline rg '\[deploy\]' "$LOG" # post-download extract/copy rg '\[debrid\]' "$LOG" # cloud download path rg '\[magnet\]' "$LOG" # metadata resolution rg '\[torrent\]' "$LOG" # peer/download engine rg '\[dht\]' "$LOG" # peer discovery rg '\[storage\]' "$LOG" # disk / FAT32 / path issues rg '\[meta\]' "$LOG" # torrent parse errors rg '\[net\]' "$LOG" # DNS, bind, socket rg '\[catalog\]' "$LOG" # catalog refresh/import rg '\[installed\]' "$LOG" # title list / NCM ``` **`[diagnostic]` lines** are the primary signal: `level=error` with `stage=` / `tag=` / body point at the failing subsystem. **`[telemetry]`** and borealis `[DEBUG]` lines are often **dropped** when the tail is filtered — do not treat their absence as proof nothing happened. **`[torrent]` / `[dht]`** are noisy; grep for `error`, `failed`, `mismatch`, `timeout`, `rejected` before reading health spam. Map `stage=` from diagnostics to code: | stage | Start in | |---|---| | `update` | `src/ui/settings/settings_panels.hpp` (check/install/restart) | | `install` | `src/install/install_backend_switch.cpp` | | `deploy` | `src/app/switch_deploy.cpp` | | `magnet` | `src/app/magnet_resolver.cpp` | | `debrid` | `src/app/debrid_transfer.cpp` | | `storage` | `src/platform/storage.c`, settings storage panel | | `catalog` / `metadata` | `src/ui/catalog/`, `GameMetadataService` | | `installed` | `src/app/installed_title_service.cpp` | | `settings` | `src/ui/settings/` | ## 4. Report back Use this template: ```markdown ## Bug report ABCD — **Reporter context:** pipensx X.Y.Z · HOS A.B.C · · **Capture quality:** ### Findings - - … ### Likely cause ### Next steps - [ ] ``` If the log is empty or only has the system snapshot, say so — the bug may be UI-only or happened before logging was enabled. ## 5. Constraints - `bug-reports/` may live **outside the repo** (e.g. `~/bug-reports/`). Use absolute paths; the folder is cursorignored in-repo. - Do **not** open multi-MB catalog JSON while triaging. - Changing the wire format or QR UI requires `make -f Makefile.pc test` (`test_bug_report`, `test_bug_report_decode.py`).