Skip to content

docs: % change and anomaly alerts on a KPI, compared with previous checks (CUB-5218) - #12306

Merged
mngr merged 2 commits into
masterfrom
docs/cub-5218
Oct 23, 2026
Merged

mngr merged 2 commits into
masterfrom
docs/cub-5218

Conversation

@mngr

@mngr mngr commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Depends on cubedevinc/cubejs-enterprise#16509 and its part PRs cubedevinc/cubejs-enterprise#16507 (chat tools), cubedevinc/cubejs-enterprise#16508 (public API alert), and cubedevinc/cubejs-enterprise#16825 (sidebar status retry). Do not merge this before cubedevinc/cubejs-enterprise#16509 merges. Before that, the page describes % change and Anomaly on a KPI, which the product does not yet offer.

Summary

Data alerts' % change and Anomaly rules now work on a chart or KPI with no time dimension. On such a chart the alert remembers the value each check reads and compares with those values: % change with the previous check, Anomaly with the normal range of the earlier checks, once there are 8. The chat agent can list, create, change and delete a dashboard's scheduled refreshes together with their alert. The public notifications API takes an alert field.

  • docs/explore-analyze/data-alerts.mdx

    • % change / Anomaly: what each compares with on a chart with and without a time dimension, and the "vs the previous period" / "vs the previous check" suffix.
    • Which charts support which rule: a chart without a time dimension now supports every rule type (it used to say Threshold only). It quotes the dialog's checks line.
    • What an alert checks: the single-value paragraph names the comparison with previous checks.
    • New Comparing with previous checks section:
      • what is remembered: the last 30 checks; Threshold alerts and time charts remember nothing;
      • the first check's "no earlier check" line and the Anomaly "Needs 8 earlier checks, has N." count (only the creator sees the count; anyone else reads "Needs 8 earlier checks.");
      • Run now is a check, compared and remembered like a scheduled one;
      • what remembers nothing: no number read, or a fire that reached no one;
      • what keeps the remembered values and what discards them; republishing keeps them.
    • When an alert notifies: turning the schedule off still resets the notify-once state, but keeps the remembered values.
    • The notification: the email's previous-check and earlier-checks lines, and a check-based Slack sentence.
    • Following an alert in the sidebar: rebased onto master's CUB-5559 rewrite (docs: timezone in schedules, time to next run, short last check on scheduled refreshes and tasks (CUB-5559) #12283, the short "Last check: 3 minutes ago, …" line with the full check on hover), kept as merged. Added: the "vs the previous check" ending of the "Condition:" summary, and the hover's "Previous check …" / "Normal range of the earlier checks" lines on a chart without a time dimension, and that after Run now the open card shows the new check by itself (a run can take a few minutes).
    • When a check can't run: the check-based reasons, and that such a check still remembers a value it read.
    • New Managing alerts from chat and Managing alerts through the API sections.
      Managing alerts from chat says the agent never makes an alert on a chart of a published dashboard into a scheduled task with a condition: the alert belongs to that dashboard's scheduled refresh.
  • docs/explore-analyze/scheduled-refreshes.mdx:

    • Managing schedules → Next run: until an enabled schedule's status has been read (loading, or the read failing), a placeholder stands in for Next run and Last check, and the card asks again every few seconds.
    • Managing schedules → Schedule: a custom cron that matches no preset is now described in full ("At 09:00 AM, Monday through Friday UTC"), not shown as written. This sentence was made false by cubedevinc/cubejs-enterprise#16776 (CUB-5994, already on master: describeSchedule → cronSentence, cronstrue; node -e "require('cronstrue').toString('0 9 * * 1-5')" → "At 09:00 AM, Monday through Friday"), corrected here as an adjacent defect.
    • new Managing schedules from chat section, covering:
    • what the agent can do;
    • email to Cube users only (Slack, groups and control values stay in the dialog);
    • Edit/Manage needed to change a schedule;
    • last-check values shown to the creator only; recipients told only to those who can edit the schedule, anyone else told they are hidden;
    • no tools in published-dashboard or embedded chat.
  • docs/explore-analyze/scheduled-tasks.mdx → Managing tasks from chat: when data alerts are on, an alert on a chart of a published dashboard is not a task; it belongs to that dashboard's scheduled refresh, and the agent doesn't create a task for it.

  • api-reference/api.yaml: mirrors the regenerated public spec's change only:

    • the DataAlertRule / DataAlertRuleInput schemas and their enums;
    • alert on NotificationDto and UpdateNotificationInput;
    • the create and update notification descriptions.

    I produced it by running scripts/extract-api.mjs on master's open-api-spec-public-v3.1.yaml and on the head's, then applying the difference (6 hunks). That keeps it independent of master's other unreleased spec changes, which api.yaml (synced per platform-client release) does not carry yet.

Verified against the code

  • Form. On the round-2 hand-off walk (staging-mngr-6, handoff-run-r2.log, 2026-10-19; unchanged on the round-3 and round-4 walks, handoff-run-r3.log / handoff-run-r4.log, 2026-10-21/22), a KPI with no time axis showed:

    • all three rule-type tabs enabled;
    • the suffix "vs the previous check";
    • the checks line "Compares with the values this alert read on its previous checks.";
    • the anomaly hint;
    • no checks line under Threshold.

    The rule saved as timeColumn: null, grain: null.

  • Comparison. evaluateAgainstChecks (ai-engineer/.../alerts/evaluate-alert-rule.ts):

    • % change takes the last remembered point;
    • a previous 0 gives previous-zero;
    • Anomaly needs DATA_ALERT_ANOMALY_MIN_POINTS (8) and uses medianMadBand over the remembered values.
  • What is remembered. alert-history.ts:

    • checkPointOf remembers only a check-based verdict that read a number;
    • appendCheckPoint keeps DATA_ALERT_CHECK_HISTORY_MAX = 30;
    • historyFor / keepsHistory key on rule id, series and filterParams.

    prepareDataAlertRule keeps the rule id unless dataAlertConditionKey changes (chart, report, measure, type, direction, percent).

  • Live checks (walk log):

    • first check: line "Last check: less than a minute ago, could not check", hover "… could not check. There is no earlier check to compare with yet. Nothing sent.";
    • Anomaly: "Needs 8 earlier checks, has 0." and then "has 1." for the creator; "could not check. Needs 8 earlier checks. Nothing sent." for a non-creator on the same card (round-3 walk, run 4452);
    • after Run now with the sidebar left open, the card showed the new check with no reload; the round-3 walk measured 21–224 s from press to card, hence "a run can take a few minutes";
    • after republishing the KPI: line "Last check: less than a minute ago, Count decreased by 50%, notified", hover "Last check Oct 19, 2026, 3:05 PM GMT+1: Count 20,003. Previous check Oct 19, 2026, 3:04 PM GMT+1: 40,000, -50%. Condition met, notified." This shows that republishing keeps the remembered values;
    • after a cron edit the last check is unchanged;
    • summary "Condition: Count decreases by ≥ 10% vs the previous check · Orders count".

    Pause and resume keeping the values: AC-5c, verify-5-kept-through-edit-and-pause-has-3.png.

  • Email and Slack. The en-US email keys alertPreviousCheckValue, alertNormalRangeOfChecks and alertComparedWithPreviousChecks (cloud-router). The Slack sentence comes from alertStatement's basis === 'checks' branch; its format is pinned by alert-notification.spec.ts.

  • Sidebar strings. en-US creatorMode.json: summary*Checks, lastCheckPreviousCheck, lastCheckBandChecks, reasonNoEarlierCheck, reasonTooFewChecks, reasonPreviousCheckZero.

  • Chat tools. DashboardScheduledRefreshToolsFactory.ts:

    • email to recipientUserIds, or the current user when none are named; no Slack, groups or control values;
    • bound when useScheduledRefreshes, which AiEngineerService sets off for an embed session;
    • stripped from published-dashboard chat through publishedDashboardUnsafeTools;
    • writes need WorkbookEdit (verify-11-read-only-user-refused.png);
    • list values are withheld for a non-creator (alertCheckForViewer);
    • a caller who cannot edit the run gets recipientsWithheld: true instead of a recipient list (describeRecipients; console-server's serializeScheduledRun nulls the ids unless viewer.canEdit), and the description says never to report that as no recipients. Round-3 walk: the non-creator's chat reply named no "no recipients".
  • Status placeholder. NextRunCell / the last-check cell render Placeholder while run.isEnabled && run.isStatusPending && !run.hasStatus; a failed read leaves the run pending and joins the 5 s status poll (use-scheduled-refreshes.ts, cubedevinc/cubejs-enterprise#16825, spec AC-6g in ScheduledRefreshSidebar.spec.tsx).

  • Run now on the open card. use-scheduled-refreshes.ts keeps polling a Run now's status until it reports the run finished, then up to RUN_NOW_CHECK_WAIT_MS (60 s) more for the stored check.

  • Chat routing of a dashboard alert (cubedevinc/cubejs-enterprise#16507, 730cdb4add):

    • createDashboardScheduledRefresh's description says an alert on a published dashboard's chart is always set up there;
    • createScheduledTask's says a task condition watches a measure outside any dashboard. It adds that clause only when useScheduledRefreshes && useDataAlerts, hence "when data alerts are turned on";
    • the Chassis schedule-tasks skill says such an alert "is a scheduled notification on that dashboard, not a task" and points to the dashboard's schedule settings. So the page promises "never a task", not that the agent always creates the refresh itself;
    • round-4 hand-off walk (handoff-run-r4.log, [WALK 12], 2026-10-22): "Email me when the Orders count KPI … goes above 1000. Check every day at 9:00 UTC." made createDashboardScheduledRefresh 1 call and createScheduledTask 0. It created refresh 5050 with a threshold/gt/1000 alert on the KPI (timeColumn: null), and its card read "Condition: Orders Count is above 1,000 · Orders count".
  • Public API. The regenerated open-api-spec-public-v3.1.yaml on the feature branch.

Feature PR: https://github.com/cubedevinc/cubejs-enterprise/pull/16509
Linear: https://linear.app/cube-d3/issue/CUB-5218/data-alerts-percent-change-and-anomaly-rules-for-kpi-charts

@mngr
mngr requested a review from keydunov as a code owner October 17, 2026 05:19
@github-actions github-actions Bot added the docs Issues that require a documentation improvement label Oct 17, 2026
@claude

claude Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @mngr's task in 1m 18s —— View job


Approve once cubedevinc/cubejs-enterprise#16509 merges. 0 high, 0 medium, 2 low.

Review details
  • Read diff and changed files
  • Check links and cross-page consistency
  • Review threads
  • Post review

Findings

Severity Location Issue
Low docs-mintlify/docs/explore-analyze/data-alerts.mdx:277 The same check is shown as 04:56 UTC in the Slack example (line 235) and 5:56 AM in the sidebar example. Nothing says the sidebar uses local time, so the two examples appear to contradict each other.
Low docs-mintlify/docs/explore-analyze/data-alerts.mdx:174 "Pressing it twice…" repeats the sentence before it. "History" at lines 202–210 can now be read as either the notify-once state or the new remembered values.

Checked, no issues

  • All new link targets resolve:
    • /docs/explore-analyze/analytics-chat exists.
    • /api-reference/notifications/update-a-scheduled-notification matches the Update a scheduled notification summary under the Notifications group in docs.json.
    • #managing-schedules-from-chat and #comparing-with-previous-checks match their new headings.
    • #control-values already existed.
  • The rules for keeping and discarding remembered values agree with "When an alert notifies":
    • Turning the schedule off resets the notify-once state but keeps the values.
    • Changing the condition or the control values discards them.
  • These match the PR description's account of dataAlertConditionKey and filterParams.
  • "When a check can't run" and the "Comparing with previous checks" section agree: a check remembers a value only if it read a number.
  • In api.yaml:
    • alert on UpdateNotificationInput repeats the page's preview note.
    • The 400 rule (notifications on, at least one recipient) is the same in the endpoint description, the field description and the "Managing alerts through the API" section.
  • The chat permissions (Edit or Manage on the workbook) match the page's existing <Info> callout.

Review threads

The listing returned 0 of my own threads (no prior threads), so nothing was resolved or re-affirmed.

@github-actions github-actions Bot added the pr:community Contribution from Cube.js community members. label Oct 17, 2026
@mintlify

mintlify Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cubed3 🟢 Ready View Preview Oct 22, 2026, 1:23 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@mintlify

mintlify Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cubed3 🟡 Building – Oct 17, 2026, 5:19 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

Comment thread docs-mintlify/docs/explore-analyze/data-alerts.mdx Outdated
Comment thread docs-mintlify/docs/explore-analyze/data-alerts.mdx
@claude

claude Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @mngr's task in 59s —— View job


Verdict: no blocking issues. 0 high, 0 medium, 1 low. Merge only after cubedevinc/cubejs-enterprise#16509, as the PR says.

Review details
  • Read diff and changed files
  • Check links, anchors, api.yaml
  • Review threads
  • Post review

Checked

  • Links resolve.
    • /docs/explore-analyze/analytics-chat exists.
    • #managing-schedules-from-chat and #control-values exist in scheduled-refreshes.mdx.
    • /api-reference/notifications/update-a-scheduled-notification matches the Update a scheduled notification summary under the Notifications tag, the same slug pattern api-reference/introduction.mdx:92 uses.
  • The new sections agree with each other. None of these contradict:
    • "When a check can't run" says such a check still remembers a value it read.
    • "Comparing with previous checks" says no number read, or a met condition that reached no one, remembers nothing.
    • The first check remembers its value.
    • Turning the schedule off resets the notify-once state but keeps the remembered values.
    • Changing control values discards them, both here and in "When an alert notifies".
  • api.yaml.
    • alert on UpdateNotificationInput is nullable, and the description gives the 400 conditions and says null removes the alert.
    • The create description says to create the notification, add recipients, then update it with alert. That matches "Managing alerts through the API" in data-alerts.mdx.

Low (not posted inline: this PR fixes only medium and high findings)

  • docs-mintlify/docs/explore-analyze/data-alerts.mdx:237 and :292: the Slack and sidebar examples show the same values (20,003 against 40,000), but the previous check is at different times. Slack says 2026-10-17 04:56 UTC and the sidebar says Oct 19, 2026, 3:04 PM GMT+1. A reader comparing the two may expect them to be the same check. Using Oct 17, 2026, 5:56 AM GMT+1 in the sidebar example, as in the walk log, would line them up.

Review threads

The listing returned 0 of my own unresolved threads, so none were resolved or re-affirmed.

…ks; manage alerts from chat and the API (CUB-5218)
@claude

claude Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @mngr's task in 1m 35s —— View job


No blocking issues: 0 high, 0 medium, 2 low (not posted inline, since the author fixes only medium and high findings on this PR).

Review details
  • Gather context (diff, changed files)
  • Review data-alerts.mdx
  • Review scheduled-refreshes.mdx
  • Review api.yaml
  • Resolve stale threads / dedupe
  • Post review

Low

  1. docs-mintlify/docs/explore-analyze/data-alerts.mdx:259: the page says a % change summary "ends with" "vs the previous check". It doesn't. The chart name still follows, as in the PR's own walk log: "Condition: Count decreases by ≥ 10% vs the previous check · Orders count". "includes" or "the condition reads … vs the previous check" would be accurate.
  2. docs-mintlify/docs/explore-analyze/data-alerts.mdx:158-160: "on a daily schedule, a check compares with yesterday's" is only true when nothing else got in between. A Run now (line 175) or a check that remembered nothing (line 179) changes which value counts as previous. The paragraphs below do say this, so this is just a wording nit. "compares with the last remembered check, normally the previous scheduled run" would fit both cases.

Checked, no issues

  • Both new link targets resolve:
    • /api-reference/notifications/update-a-scheduled-notification comes from the Update a scheduled notification summary under the Notifications group in docs.json:988.
    • /docs/explore-analyze/analytics-chat exists.
  • #comparing-with-previous-checks and #managing-schedules-from-chat match their headings.
  • The api.yaml changes are limited to the alert schemas, the alert fields and the two endpoint descriptions. The create description ("create, add recipients, then set alert with an update") agrees with the prose at data-alerts.mdx:350-356 and with the 400 precondition on UpdateNotificationInput.alert.
  • "Remembered values" and the notify-once "history" stay consistent across sections:
    • Turning the schedule off resets the notify-once state but keeps the values (data-alerts.mdx:184-190, 207-215).
    • A check that can't run still remembers a value it read (When a check can't run).
    • The creator-only and non-creator strings match in the sidebar section and the new section.
  • scheduled-refreshes.mdx: the chat section's rules agree with the data-alerts.mdx chat section and with the Info box's Edit/Manage requirement. These rules are email to Cube users only, Edit/Manage for writes, recipients withheld from non-editors, and no tools in published or embedded chat. The cron sentence correction is consistent with the presets listed above it.

Review threads

The listing returned 0 of my own threads (no prior threads), so none were resolved or re-affirmed.

@claude

claude Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @mngr's task in 1m 32s —— View job


No issues found (0 high, 0 medium, 0 low posted)

Review details
  • Read diff and changed files
  • Review docs for accuracy and consistency
  • Handle prior review threads
  • Post review

Checked

  • Anchors and links. #comparing-with-previous-checks matches the new heading. [ref-control-values], [ref-chat], [ref-chat-schedules] and [ref-scheduled-tasks] all point to pages or sections that exist. [ref-api-update] (/api-reference/notifications/update-a-scheduled-notification) follows the same pattern as the other Platform API links: tag Notifications plus the summary "Update a scheduled notification" (docs-mintlify/api-reference/api.yaml:2195), with the endpoint listed in docs.json.
  • Internal consistency across data-alerts.mdx. I checked these against each other and found nothing contradictory:
    • the "remembered values" kept/discarded list in Comparing with previous checks;
    • the notify-once reset rules in When an alert notifies, where turning the schedule off resets notify-once and keeps the values;
    • When a check can't run, where a check still remembers a value it read;
    • the cases where nothing is remembered: no number read, or a notification that reached no one.
  • API. The guide's "create → add recipients → update with alert" order and the 400 without recipients match the endpoint descriptions and UpdateNotificationInput.alert in api.yaml. The page's preview <Warning> covers the new API section.
  • Example numbers. 20,003 vs 40,000 rounds to −50%. The Slack example's 04:56 UTC matches the GMT+1 times used elsewhere.
  • Cross-page wording. scheduled-tasks.mdx and scheduled-refreshes.mdx say what data-alerts.mdx says about chat routing: an alert on a published dashboard's chart is never a scheduled task.

I raised no low-severity editorial points, following the author's stated policy on this PR.

Review threads

The listing returned 0 of my own threads, so I resolved none and re-affirmed none (no prior threads).

@mngr
mngr merged commit 6c06cf7 into master Oct 23, 2026
8 checks passed
@mngr
mngr deleted the docs/cub-5218 branch October 23, 2026 17:09
igorlukanin added a commit that referenced this pull request Oct 24, 2026
## Summary

#12306 already added "Managing schedules from chat" to Scheduled
refreshes and "Managing alerts from chat" to Data alerts. This PR now
adds only what those sections leave out:

- **Scheduled refreshes:** the intro links to "Managing schedules from
chat". That section now says the agent needs the Explorer role as well
as Edit or Manage permission on the workbook, and that it can't run a
schedule now.
- **Analytics Chat:** a "Schedule dashboards" line in the key features
links to the section.

## Test plan

- The Explorer role check: the agent's routes call the same workbook
access check as the sidebar, and that check requires the Explorer role
for Edit.
- `mint broken-links`: no broken links on the changed pages. The one
broken link it reports is in `api-reference/introduction.mdx` and is
already on master.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: igorlukanin <3852894+igorlukanin@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
staging - docs-mintlify — 91a09c63 Deployed Oct 22, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Issues that require a documentation improvement pr:community Contribution from Cube.js community members.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant