Gandalf only comments on tickets and never closes them. So a ticket can stay open long after its problem is fixed: the pbs host-unreachable ticket sat open for a month after the host came back. An alert can also stay active for days once everyone has stopped looking at it.
What
Open ticket sync (monitor): every 15 minutes the monitor reads Tinker's open ticket list (api/tickets_api.php, statuses Open, Pending and In Progress, read scope only) and saves it to monitor_state. A failed read keeps the previous list, and the dashboard ignores a list older than 2 hours instead of guessing.
Stale badge: an active alert older than monitor.stale_alert_days (default 3) gets a ⏳ badge with its age in days.
Ticket closed badge: shown when an alert is still active but its ticket was closed in Tinker.
Needs Follow-up panel: open tickets whose every alert cleared at least monitor.stale_ticket_hours (default 24) ago. Hidden when empty.
Status chip: "⏳ N TO FOLLOW UP" counts both, and links to the panel or to the alert table.
Both the server render and the 30 second JS refresh produce the badges, chip and panel.
New config keys: ticket_api.read_url, monitor.stale_alert_days, monitor.stale_ticket_hours. All are optional.
Replaced an — in the alert count notice.
Checks
414 tests pass (15 new: ticket list paging and failure, sync throttling, get_cleared_tickets grouping, status API flags, config threshold, out-of-date list, panel rendering).
flake8 and bandit are clean, eslint shows only the 21 existing warnings.
get_cleared_tickets was also run against a real MariaDB.
Gandalf's prod key was confirmed able to read the open ticket list (read only).
No horizontal scroll at 390px, and no console errors other than the preview's avatar 404.
Screenshots
Sample data: micro1 down for 6 days, a cutsheet mismatch whose ticket was closed, a fresh alert, and one ticket left open.
## Why
Gandalf only comments on tickets and never closes them. So a ticket can stay open long after its problem is fixed: the pbs host-unreachable ticket sat open for a month after the host came back. An alert can also stay active for days once everyone has stopped looking at it.
## What
- **Open ticket sync (monitor):** every 15 minutes the monitor reads Tinker's open ticket list (`api/tickets_api.php`, statuses Open, Pending and In Progress, read scope only) and saves it to `monitor_state`. A failed read keeps the previous list, and the dashboard ignores a list older than 2 hours instead of guessing.
- **Stale badge:** an active alert older than `monitor.stale_alert_days` (default 3) gets a ⏳ badge with its age in days.
- **Ticket closed badge:** shown when an alert is still active but its ticket was closed in Tinker.
- **Needs Follow-up panel:** open tickets whose every alert cleared at least `monitor.stale_ticket_hours` (default 24) ago. Hidden when empty.
- **Status chip:** "⏳ N TO FOLLOW UP" counts both, and links to the panel or to the alert table.
- Both the server render and the 30 second JS refresh produce the badges, chip and panel.
- New config keys: `ticket_api.read_url`, `monitor.stale_alert_days`, `monitor.stale_ticket_hours`. All are optional.
- Replaced an `—` in the alert count notice.
## Checks
- 414 tests pass (15 new: ticket list paging and failure, sync throttling, `get_cleared_tickets` grouping, status API flags, config threshold, out-of-date list, panel rendering).
- flake8 and bandit are clean, eslint shows only the 21 existing warnings.
- `get_cleared_tickets` was also run against a real MariaDB.
- Gandalf's prod key was confirmed able to read the open ticket list (read only).
- No horizontal scroll at 390px, and no console errors other than the preview's avatar 404.
## Screenshots
Sample data: micro1 down for 6 days, a cutsheet mismatch whose ticket was closed, a fresh alert, and one ticket left open.
Desktop, dark:


Phone, light:


🤖 Generated with [Claude Code](https://claude.com/claude-code)
Gandalf only comments on tickets, so a ticket can stay open long after its
alert cleared (pbs's ticket sat open for a month), and an alert can stay
active for days once nobody is looking.
- The monitor reads Tinker's open ticket list (tickets_api.php, read scope)
every 15 minutes and saves it. A failed read keeps the previous list.
- Active alerts get a stale badge after monitor.stale_alert_days (3), and a
"ticket closed" badge when their ticket was closed while still active.
- A Needs Follow-up panel lists open tickets whose every alert cleared at
least monitor.stale_ticket_hours (24) ago.
- A "TO FOLLOW UP" status chip counts both. If the open ticket list is over
2 hours old, the ticket flags are left off rather than guessed.
- Replaced an — in the alert count notice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jared
scheduled this pull request to auto merge when all checks succeed 2026-11-14 16:16:26 -05:00
jared
merged commit 0631de74c7 into main2026-11-14 16:16:30 -05:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
Gandalf only comments on tickets and never closes them. So a ticket can stay open long after its problem is fixed: the pbs host-unreachable ticket sat open for a month after the host came back. An alert can also stay active for days once everyone has stopped looking at it.
What
api/tickets_api.php, statuses Open, Pending and In Progress, read scope only) and saves it tomonitor_state. A failed read keeps the previous list, and the dashboard ignores a list older than 2 hours instead of guessing.monitor.stale_alert_days(default 3) gets a ⏳ badge with its age in days.monitor.stale_ticket_hours(default 24) ago. Hidden when empty.ticket_api.read_url,monitor.stale_alert_days,monitor.stale_ticket_hours. All are optional.—in the alert count notice.Checks
get_cleared_ticketsgrouping, status API flags, config threshold, out-of-date list, panel rendering).get_cleared_ticketswas also run against a real MariaDB.Screenshots
Sample data: micro1 down for 6 days, a cutsheet mismatch whose ticket was closed, a fresh alert, and one ticket left open.
Desktop, dark:


Phone, light:


🤖 Generated with Claude Code