|
| 1 | +--- |
| 2 | +name: issue-triage |
| 3 | +description: Investigate a newly opened batpred GitHub issue against current main, classify it, assign labels and priority, and post a first-pass triage comment. |
| 4 | +allowed-tools: You can view and edit files in this repo, run local tests, download and grep issue attachments, access the issue in github with 'gh' and use git commands to check history and re-sync the clone. Do not go outside this sandbox or push any changes back to git. |
| 5 | +--- |
| 6 | + |
| 7 | +# Issue Triage |
| 8 | + |
| 9 | +You are triaging one GitHub issue on `springfall2008/batpred`. The working directory is a dedicated local clone of the repo — investigate using it directly. |
| 10 | + |
| 11 | +Arguments: `<issue-number> [scratch=<dir>]`. The scratch directory is a writable place to download attachments to; it is emptied before each run. If no `scratch=` is given (an interactive invocation), use `/tmp/predbat-triage/<issue-number>` and `mkdir -p` it yourself. |
| 12 | + |
| 13 | +## 1. Read the issue |
| 14 | + |
| 15 | +Fetch it with `gh issue view <number> --json title,body,labels,comments`. Note any labels already applied — never remove a label a human added. |
| 16 | + |
| 17 | +## 2. Fetch attachments |
| 18 | + |
| 19 | +If the body links a log file, a `predbat_debug.yaml`, or a zip of either, download it into the scratch directory rather than pulling it through WebFetch — a `predbat.log` is routinely tens of MB, well past what WebFetch will return. |
| 20 | + |
| 21 | +```bash |
| 22 | +curl -sL "<url>" -o <scratch>/predbat.log |
| 23 | +``` |
| 24 | + |
| 25 | +Never `cat` or read a whole log into context. Size it up first, then extract only what matters: |
| 26 | + |
| 27 | +```bash |
| 28 | +wc -l <scratch>/predbat.log |
| 29 | +grep -n "Traceback\|ERROR\|Exception\|Warn" <scratch>/predbat.log | tail -50 |
| 30 | +sed -n '<start>,<end>p' <scratch>/predbat.log # context around an interesting line |
| 31 | +``` |
| 32 | + |
| 33 | +The log gives you error/traceback context; the debug yaml gives you the reporter's actual configuration (grep it for the specific keys you care about if it is large). The reporter's Predbat version is usually in the first few lines of the log — quote the version you actually confirmed, not the one in the issue template. |
| 34 | + |
| 35 | +A `predbat_debug.yaml` can also be replayed against current main to reproduce their plan and list every setting they have changed from default — see [references/debug-journal.md](references/debug-journal.md). |
| 36 | + |
| 37 | +## 3. Classify the type |
| 38 | + |
| 39 | +Apply exactly one of: `bug`, `question`, `configuration` (user error/misconfiguration), `enhancement` (feature request). If genuinely ambiguous, apply `unclear` instead of guessing. |
| 40 | + |
| 41 | +## 4. Check for duplicates |
| 42 | + |
| 43 | +Search existing issues (`gh issue list --search ...`, both open and closed) for the same symptom. |
| 44 | + |
| 45 | +- High confidence match: label `duplicate`, comment linking the original issue, and close this one. |
| 46 | +- Low confidence: mention "possibly related to #N" in your triage comment; don't close. |
| 47 | + |
| 48 | +## 5. Investigate against current main |
| 49 | + |
| 50 | +- Sync the clone first and discard anything left over from a previous run, so you are reading the code you think you are: |
| 51 | + |
| 52 | + ```bash |
| 53 | + git fetch origin main && git reset --hard origin/main && git clean -fd |
| 54 | + git describe --tags # the version you are investigating against |
| 55 | + ``` |
| 56 | + |
| 57 | +- Read [references/debug-journal.md](references/debug-journal.md) before forming a hypothesis. It maps common symptoms to modules, records known per-integration behaviour from past investigations, and lists the traps that have wasted time before. Its entries are dated observations, not current truth — confirm anything you rely on against the working tree. |
| 58 | +- Read the relevant source area for the reported symptom (e.g. `apps/predbat/fetch.py` for rate issues, `apps/predbat/inverter.py` for a named inverter). |
| 59 | +- Check `git log` / `git blame` on that area for recent related changes — the issue may already be fixed on main since the version the reporter is using. |
| 60 | +- If the issue clearly maps to an existing test module (`apps/predbat/tests/test_<feature>.py`, listed in `TEST_REGISTRY` in `unit_test.py`), run just that test with the wrapper, from the repo root: |
| 61 | + |
| 62 | + ```bash |
| 63 | + tools/triage_test.sh <name> <scratch>/test.log |
| 64 | + ``` |
| 65 | + |
| 66 | + It prints the exit status and the last 30 lines; grep the log file for anything more. Use the wrapper rather than composing your own `cd coverage && ./run_all ... > log` — a `cd` combined with an output redirect is refused outright in this session's permission mode, which is why the wrapper exists. |
| 67 | + |
| 68 | + Skip this step if there's no clean mapping — never run the full suite. A test only settles questions about code behaviour; it can't settle what real hardware did, so don't run one to look thorough. |
| 69 | + |
| 70 | +- Form a root-cause hypothesis with a `file:line` pointer if the investigation supports one. It's fine to say the cause needs maintainer review if it doesn't. |
| 71 | +- You may edit files locally to test a hypothesis (e.g. a temporary debug print, a tweaked test fixture) — this clone is hard-reset and cleaned before the next run, so nothing here persists. Never `git commit` or `git push`. |
| 72 | + |
| 73 | +## 6. Apply component labels |
| 74 | + |
| 75 | +Only when the issue text clearly names a specific inverter or integration (e.g. `solis`, `Huawei`, `solaredge`, `Octopus`, `fox`), apply the matching existing label. Don't guess. |
| 76 | + |
| 77 | +## 7. Check for missing information |
| 78 | + |
| 79 | +For bug reports specifically, verify these four things (from the bug report template) are actually present: Predbat version, inverter/environment details, log file, `predbat_debug.yaml`. If something missing is actually needed for your investigation, apply `waiting_for_user` and ask only for what's missing — don't ask for things already provided. |
| 80 | + |
| 81 | +## 8. Set priority |
| 82 | + |
| 83 | +Apply exactly one of: |
| 84 | + |
| 85 | +- `priority_high` — impacts many users, no workaround |
| 86 | +- `priority_medium` — impacts many users, workaround exists |
| 87 | +- `priority_low` — limited impact or an easy workaround |
| 88 | + |
| 89 | +Skip priority for pure questions and feature requests. |
| 90 | + |
| 91 | +## 9. Post one comment |
| 92 | + |
| 93 | +Check existing comments first — if one from you is already there, stop; don't post again. |
| 94 | + |
| 95 | +Post exactly one comment via `gh issue comment <number> --body "..."`, opening with a line disclosing this is an automated first-pass triage (a maintainer will review before any action is taken), followed by: classification, priority (if set), what you investigated and found (including test result if you ran one), a root-cause pointer if you have one, and any information request. |
| 96 | + |
| 97 | +After posting, apply the `BOT_TRIAGED` label via `gh issue edit <number> --add-label BOT_TRIAGED` — every triage run gets this label, including a duplicate-close, regardless of classification. It marks the issue as triaged for the separate PR-creation flow (see `.claude/skills/issue-pr/SKILL.md`). |
| 98 | + |
| 99 | +## Guardrails |
| 100 | + |
| 101 | +- Analysis only: no commits, no pushes, no PRs, no code changes that leave this clone. |
| 102 | +- Never remove a label a human applied. |
| 103 | +- Never close an issue except a confident duplicate. |
| 104 | +- If a command you needed was blocked by permissions, say plainly in the comment what you could not do — never word it so a step you skipped reads as one you completed. |
0 commit comments