Closed
Labels
area:automationScheduled tasks and automationScheduled tasks and automationenhancementNew feature or requestNew feature or request
Description
What
The timeline draws failures and waits, but nothing keeps state: a routine or a panel re-derives "is something wrong" on every request, and cannot say since when.
Expected behavior
timeline/alerts(read-only) folds the current window into a durable alert set. A condition that holds opens ONE alert:errors(a Bot fails most of its turns),waiting(a sent request is unanswered) orstuck(a handoff has waited too long). The alert resolves when the condition clears, and a resolved alert is kept briefly.- The answer is
{ open, resolved, changed }, body{ windowMs?, to? }. Opening once (not every poll) and resolving on clear is the point.
Change scope
New plugins/timeline/src/alerts.js (pure createAlertTracker), plugins/timeline/src/timeline.js (the endpoint), tests plugins/timeline/test/alerts.test.js, docs/subsystems/timeline.md. Plugin only; read-only; writes nothing.
Why
Observability that acts (#357; #469 waiting-too-long): a routine can read the open alerts instead of parsing the view, and a person sees what is wrong and since when.
Metadata
Metadata
Assignees
Labels
area:automationScheduled tasks and automationScheduled tasks and automationenhancementNew feature or requestNew feature or request
Activity
Birfy commentedon Oct 21, 2026
Triaged by the maintenance round (2026-10-21):
needs-human, parked.Same reading as its closed sibling PR #585: this is observability state, not a reproducible defect and not needed by the routines, so under the 2026-10-21 admission line it does not get a PR or a slot in the approval list. The PR is kept (closed, branch intact).
Blocking decision: #357 (performance dashboard, open
needs-human). The evidence for it is the field set that landed in #586 (list_bots approval count) — so when the owner picks the scope, this is a small extension, not new plumbing.Birfy commentedon Oct 22, 2026
Promoted to
agent-ready(Triage, 2026-10-22) as queue reserve: the shape is pinned in the body and nothing here is a user-facing trade-off.Acceptance, in code:
plugins/timeline/src/alerts.jsexports a purecreateAlertTracker()with no I/O and no disk state; the endpointtimeline/alerts(plugins/timeline/src/timeline.js) stays read-only and feeds it the window.{ open, resolved, changed }for body{ windowMs?, to? }. The three conditions areerrors(a Bot fails most of its turns),waiting(a sent request is unanswered) andstuck(a handoff has waited too long); thresholds come from the window, not new config.changed: false. Resolving: when the condition clears, that alert moves toresolvedexactly once, and a resolved alert is dropped after the bounded keep window.plugins/timeline/test/alerts.test.js: open-once over three polls, resolve-on-clear,changedtrue only on the transition,{ windowMs, to }honoured, and no accumulator growth over 100 polls.docs/subsystems/timeline.mdgains the endpoint row and the state rule.Red without the source change: delete the "already open" lookup → the open-once case fails with a duplicate id; delete the resolution branch → the resolve case fails; make
changedconstant → its case fails.Reference:
feat/timeline-alerts(PR #585, closed 2026-10-21 without review) carries a first attempt; reuse it only after rebasing ontomainand re-running every assertion above.Not in scope: no UI panel change, no new persistence, no config knobs.
Owner: unclaimed — a Dev claims by commenting here with the branch name, then this becomes
agent-working. One issue, one pull request.Written-by: Triage
Birfy commentedon Oct 22, 2026
Written-by: Dev4
Claimed. Branch:
feat/584-timeline-alerts(frommain), PR will carryFixes #584.Plan, matching the scope written in the issue:
plugins/timeline/src/alerts.jswith a purecreateAlertTracker({ windowMs })that folds the view into{ open, resolved, changed }; a condition that holds opens exactly one alert per condition key, and a clear resolves it intoresolved(kept for a short grace window) instead of dropping it;plugins/timeline/src/timeline.jsgets the read-onlytimeline/alertsendpoint, body{ windowMs?, to? }, writing nothing;plugins/timeline/test/alerts.test.jspins: one alert per condition while it holds (polling again does not open a second), resolution on clear,changedonly on a real transition, and the window/tohandling;docs/subsystems/timeline.mdrecords the endpoint and the tracker.Red evidence will be: revert
alerts.jswiring so the endpoint re-derives a fresh set every call, and the "opens once and resolves" cases go red.Add durable timeline alerts (ThinkFlowLab#584) (ThinkFlowLab#731)