diff --git a/docs.json b/docs.json
index f37d2ede6..2284d1960 100644
--- a/docs.json
+++ b/docs.json
@@ -3680,6 +3680,13 @@
"zh/monitors/explore/explore"
]
},
+ {
+ "group": "仪表盘",
+ "icon": "chart-line",
+ "pages": [
+ "zh/monitors/dashboards/dashboards"
+ ]
+ },
{
"group": "实体树",
"icon": "sitemap",
@@ -5316,6 +5323,13 @@
"en/monitors/explore/explore"
]
},
+ {
+ "group": "Dashboards",
+ "icon": "chart-line",
+ "pages": [
+ "en/monitors/dashboards/dashboards"
+ ]
+ },
{
"group": "Entity Tree",
"icon": "sitemap",
diff --git a/en/ai-sre/apps.mdx b/en/ai-sre/apps.mdx
index d305bf604..1049e34e6 100644
--- a/en/ai-sre/apps.mdx
+++ b/en/ai-sre/apps.mdx
@@ -27,6 +27,10 @@ AI SRE sessions run in a **Flashduty cloud sandbox** by default. The sandbox is
**BYOC (self-hosted Runner) generally doesn't need it.** A Runner runs on your own machine, which usually **already has `gh` / `glab` / `git` credentials configured** (you work with repositories on it every day). In that case the agent just uses the host's own credentials — **no App authorization needed**. (If the host happens to have no credentials configured, authorizing the App lets BYOC sessions use it too.) For the differences between environments, see [Environments (BYOC)](/en/ai-sre/environments).
+
+A RUM application can also record the repositories that build it (several may be linked; the first one is the primary), so that AI goes straight to the code when it analyses a RUM problem — see [Application Management · Code repositories](/en/rum/quickstart/app-management#code-repositories). Linking a repository there **grants no access by itself**: what a cloud AI session can read is still only what is authorized for the account here.
+
+
## Where to Find It
---
diff --git a/en/ai-sre/sessions.mdx b/en/ai-sre/sessions.mdx
index fe2d45b4f..19ce42456 100644
--- a/en/ai-sre/sessions.mdx
+++ b/en/ai-sre/sessions.mdx
@@ -138,9 +138,9 @@ When the console publishes a new version, a **version update notice** appears ab
**Inline truncation of large files**: apart from archives (which are not parsed — the agent gets only their sandbox path), attachments reach the agent as extracted text. When the extracted text exceeds **64 KB**, only the first **32 KB** is inlined (cut at a valid UTF-8 boundary), and the attachment envelope carries a pointer to the full file staged in the sandbox (like `~/.flashduty/attachments/...`) — if the full content matters, ask the agent to read the file from the sandbox with the read / bash tools; nothing is lost. In addition, PDFs larger than **3 MB** are no longer passed natively to the model; they fall back to text extraction under the same truncation rule.
- When you enter AI SRE from an incident, alert, monitor rule, monitor target, or datasource page, the related object is embedded into the input box as a **reference capsule** — a small inline tag indicating the kind of object referenced — an incident, alert event, alert, monitor rule, host, monitor target, datasource, or on-call analytics — that travels with the message so the agent can start its analysis from that object directly. Click the capsule to open the referenced object in a new tab, or click its close button to remove the reference before sending.
+ When you enter AI SRE from an incident, alert, monitor rule, monitor target, datasource, or RUM issue detail page (its **AI fix** button at the top right), the related object is embedded into the input box as a **reference capsule** — a small inline tag indicating the kind of object referenced — an incident, alert event, alert, monitor rule, host, monitor target, datasource, on-call analytics, or RUM issue — that travels with the message so the agent can start its analysis from that object directly. Click the capsule to open the referenced object in a new tab, or click its close button to remove the reference before sending.
- **These entry points also carry a default question**, and the capsule sits at the spot the entry marks inside that sentence. Entering from a monitor target page, for instance, pre-fills "请分析这个监控对象 〈reference capsule〉:基于真实观测数据判断当前是否有问题或隐患,说明依据与影响面,并给出下一步排查或处置建议。请区分已确认事实、合理推断和待确认项;证据不足时明确说明不确定,不要过度归因"; entering from the datasource list pre-fills "调用 〈reference capsule〉 的 overview tool,校验 overview tool 是否可用". The prefill is only a draft — edit it, delete it, or send it as-is.
+ **These entry points also carry a default question**, and the capsule sits at the spot the entry marks inside that sentence. Entering from a monitor target page, for instance, pre-fills "请分析这个监控对象 〈reference capsule〉:基于真实观测数据判断当前是否有问题或隐患,说明依据与影响面,并给出下一步排查或处置建议。请区分已确认事实、合理推断和待确认项;证据不足时明确说明不确定,不要过度归因"; entering from the datasource list pre-fills "调用 〈reference capsule〉 的 overview tool,校验 overview tool 是否可用"; entering from a RUM issue detail page by clicking **AI fix** pre-fills "Use the rum skill to fix this RUM issue 〈reference capsule〉: follow the issue-fix workflow to fetch the issue context, then locate the failing code in the repositories linked to the application. Only when the root cause is confirmed and you are confident in the change, create a branch and open a Draft PR that links this issue in its description; otherwise give the analysis and fix suggestions without opening a PR. Never push directly to the default branch. Distinguish confirmed facts, reasonable inferences, and items to confirm.", and that button only appears when AI SRE is enabled for the account. The prefill is only a draft — edit it, delete it, or send it as-is.
**A handoff carrying exactly one reference pre-fills its question**: when the merged context refs resolve to a single ref that carries the entry's default question, the input box is pre-filled with that question and the `[[ref]]` placeholder becomes the reference capsule. Clicking **AI analysis** on several incidents from the incident list, for example, pre-fills "Batch-analyze these incidents 〈reference capsule〉: first determine how they relate to each other (a shared root cause, a cascading chain, or fully independent) and group them accordingly; then give the likely root cause and impact for each group; finally give an overall remediation recommendation with priority. Fetch a single incident's details with tools only when needed, rather than expanding every incident up front. Separate confirmed facts, reasonable inferences, and open questions; state clearly when the evidence is insufficient, and never claim to have performed actions that were not performed.", with the capsule titled "Incident list (N)". A handoff carrying several references pre-fills nothing and leaves the input box as it is. A single message can carry multiple references. Besides objects carried in automatically from a related page, you can also type `@` directly in any session's input box to trigger an incident search dropdown (supporting fuzzy keyword search and a list of recent incidents); selecting one inserts the same kind of reference capsule — a standalone entry point available at any time. Typing an email address does not false-trigger it: when the `@` directly follows an email-address character (a letter, a digit, or one of `._%+-`), the picker does not open; an `@` after a space or adjacent to Chinese text still triggers it.
diff --git a/en/changelog/changelog.mdx b/en/changelog/changelog.mdx
index 5a69f1dfb..44a528eb5 100644
--- a/en/changelog/changelog.mdx
+++ b/en/changelog/changelog.mdx
@@ -4,17 +4,41 @@ description: "This page documents important updates and feature releases for Fla
keywords: ["Changelog", "Product Release", "Feature Updates", "Flashduty", "Version History"]
---
+
+
+### Monitors dashboards: comparisons, cross-panel cursor linking and point-value filtering
+
+A dashboard panel's query options gain **Compare** (period-over-period): "Previous 1 day / Previous 1 week" re-runs the same query over the window one period earlier — a time-series panel overlays a same-colour dashed line (the legend reads "N days ago / N weeks ago") and a stat panel shows the change against that period; only time-series and stat panels offer the setting, and a failed comparison query only drops the comparison line without affecting the current result. Time-series panels on one dashboard now share a cursor: moving the pointer over any of them draws the vertical line and dots at the same timestamp on all of them, with the tooltip only on the hovered panel (panels with a relative time or a time shift do not take part). When a data point's label — or a table's label column — has the same name as a dashboard variable, the click menu offers "Filter by k = v", which is the same as selecting that value in the variable bar and refreshes the whole dashboard (datasource variables are excluded); version history now matches an alert rule's change log — tick two versions, **Compare** their saved JSON, then restore. See [Dashboards](/en/monitors/dashboards/dashboards).
+
+### RUM applications can link to code repositories
+
+The RUM application detail page gains a **Code repositories** tab that links an application to the GitHub repositories that build it, so AI analysis can go straight to the code: up to 10 repositories, kept in order with the first one primary (use **Set as primary** to reorder), each entered as `owner/name` (a GitHub web or clone URL is accepted too) plus the directory holding the app inside that repository (defaults to `.`, at most 255 characters). Linking **grants no access by itself**: cloud AI sessions can only read repositories granted to the account's GitHub App installations, entries outside that grant carry a warning and a link to grant more, and manually entered repositories only help local (BYOC) AI; the tab appears only when AI SRE is enabled for the account. See [Application Management](/en/rum/quickstart/app-management#code-repositories).
+
+### Remote Configuration opens to every account
+
+The RUM application **Remote Configuration** tab is now open to every account instead of rolling out account by account: the account-level switch that decided which accounts could see the tab has been removed, and whether the tab appears depends only on whether the application's platform supports that channel. The previous advice to contact support when the tab is missing no longer applies. See [Application Management](/en/rum/quickstart/app-management#remote-configuration).
+
+### AI SRE sessions understand RUM issues as context
+
+AI SRE sessions gain a **RUM issue** context-ref kind (bug icon): entering a session through the **AI fix** button at the top right of a RUM issue detail page carries that capsule into the input box and pre-fills a fix question — fetch the issue's context through the issue-fix flow, then locate the failing code in the repositories linked to the application; when the root cause is confirmed and the change is safe, create a branch and submit a Draft PR that links the issue, and otherwise report only the analysis and recommendation, never pushing to the default branch. See [Sessions · Attachments and Context References](/en/ai-sre/sessions#attachments-and-context-references).
+
+### On-premises License expiry reminders
+
+Before an on-premises License expires, the platform reminds the contacts registered for the deployment: once each when **10, 3 and 1 days** remain (at most three per License), every contact's email address receives the reminder email and contacts with a valid mainland China phone number also receive an SMS, sent only between **08:00 and 22:00 Beijing time**, and Licenses that expired more than 7 days ago are skipped. The reminder email is fixed Chinese copy, and once the License expires the platform **stops ingesting data**; to renew, paste the new License into the License prompt in the console sidebar — the console reports "License updated, will take effect in 5 minutes" — with no service restart. See [Pricing · On-Premises License expiry and renewal](/en/platform/pricing#on-premises-license-expiry-and-renewal).
+
+### 46 new alert sources and 9 new change integrations
+
+This window registered **46 alert sources** (CrowdStrike, BigPanda, Monte Carlo, Falco, Gatus, OpenSearch and more) and **9 change integrations** (Argo Rollouts, Azure DevOps, Bitbucket, CircleCI, Flagsmith, Gitea, Octopus Deploy, Rundeck and Unleash). How to connect them and what they map are covered by [Alert sources](/en/on-call/integration/alert-integration/alert-sources/standard-alert) and [Change integrations](/en/on-call/integration/change-integration/custom-event).
+
+
+
-### RUM: unsampled sessions now upload once they error
-On the **Remote Configuration** tab of a Browser application, the section that used to hold only the sampling rates is now titled **Data collection** and carries two three-state switches (on / off / empty, which keeps the SDK setting):
-- **Error session capture** — a session the session sample rate did not draw is no longer dropped; it is buffered on the client, and when the SDK detects an error it uploads the data covering up to one minute before the error and keeps uploading what follows. A session that never errors is never uploaded, never stored, and never billed. It only applies to the sessions the sample rate missed, so it does nothing when that rate is 100
-- **Error session replay capture** — the same for Session Replay: a session the replay sample rate did not draw is still recorded locally and uploaded only once it errors, and how far back it reaches depends on view switches and buffer capacity. It is set separately from the session-events switch because replay is billed and masked on its own
-- Such a session is an **error-captured session**, with detail starting at the buffered window before the error. The full timeline in the session detail inserts a boundary row marking that start, so a list that reads shorter than the counts above it is not mistaken for missing data
+
-With these two switches you can keep your sampling rate at its usual value and let only the sessions that error send extra data, instead of pushing the rate to 100 to preserve errors. Both appear for Browser applications only. See [Application management](/en/rum/quickstart/app-management) and [Sampling strategy](/en/rum/best-practices/sampling).
+
### AI SRE queries Monitors data sources directly
@@ -92,7 +116,6 @@ A new Checkly synthetic-monitoring alert integration is available, so Checkly ch
See [Checkly alert integration](/en/on-call/integration/alert-integration/alert-sources/checkly) for the full setup and troubleshooting steps.
-
diff --git a/en/monitors/dashboards/dashboards.mdx b/en/monitors/dashboards/dashboards.mdx
new file mode 100644
index 000000000..1672c3242
--- /dev/null
+++ b/en/monitors/dashboards/dashboards.mdx
@@ -0,0 +1,288 @@
+---
+title: "Dashboards"
+description: "Turn queries into dashboard panels in Flashduty Monitors: folder organisation, template variables, period-over-period comparison, cross-panel cursor linking, click-to-filter, version history and restore."
+keywords: ["dashboard", "panel", "template variables", "comparison", "version history", "drill-down"]
+---
+
+A dashboard turns queries into charts: it is made of tabs, sections and panels, and each panel binds one data source with a set of queries, evaluated live for the current time range and variable selections every time it opens. It is the right place to pin down the few charts you keep opening for routine inspection and incident review, instead of rewriting the queries in the [Query Workbench](/en/monitors/explore/explore) every time.
+
+## Overview and entry points
+
+- **Menu entry**: **Visualization → Dashboards** in the left menu (frontend route `/monit/dashboards`). Both the menu item and the page routes are gated on the "Datasource Visit" permission, so anyone who can see data sources can see the dashboard entry.
+- **From the Query Workbench**: a query that has produced a result can be saved straight to a dashboard through **Save to dashboard**, see [Create and save a dashboard](#create-and-save-a-dashboard).
+
+Access to a dashboard is decided by the **folder** it lives in, not by the dashboard itself: reads inherit the folder read permission, while write operations require the "Dashboard Manage" permission plus read access to the folder. See [Permissions](#permissions).
+
+## List and folders
+
+**Menu entry**: Visualization → Dashboards
+
+The left side is the folder tree shared with alert rules (the same `/monit/folder/list` API), and the right side lists the dashboards in the selected folder. Creating, renaming, moving and deleting folders all happen on that tree, and are governed by folder permissions — see [Folder management](/en/monitors/folders/folders).
+
+| Column | Description |
+|--------|-------------|
+| **Title** | Dashboard name; click to open the viewer |
+| **Updated by** | The user who last saved this dashboard |
+| **Updated at** | Time of the last save |
+| **Actions** | Shown with the "Dashboard Manage" permission: edit, delete, and the **More** menu (Move to another folder / Clone in this folder / Clone to another folder) |
+
+- **The search box only searches the current folder**, never across folders. Input is debounced by 300 ms, and the folder, search term and page number are all reflected in the URL (`folder_id`, `q`), so a list link can be shared and survives a refresh. Clicking the breadcrumb in the viewer returns you to the list with the same conditions you left it in.
+- **Paging** defaults to 20 rows per page.
+- An empty folder shows "No dashboards in this folder yet", and users with manage permission can create one straight from that empty state.
+
+## Create and save a dashboard
+
+**Create**: **New dashboard** at the top right of the list page (manage permission required), which opens `/monit/dashboards/new?edit=1`. A new dashboard starts with the title "Untitled dashboard", a default time range of the last hour, auto-refresh off, a single tab titled `Overview`, and no panels.
+
+**Save from the Query Workbench**: the workbench's **Save to dashboard** button turns the current query into a panel. In the dialog you can choose:
+
+| Option | Description |
+|--------|-------------|
+| **New dashboard** | Pick a folder and type a dashboard title; the dashboard is really created in that folder first, then opened in edit mode |
+| **Existing dashboard** | Pick a folder, then pick one of the dashboards in it; the dashboard opens in edit mode with this panel appended to the bottom of its first tab — **nothing is written until you save** |
+| **Panel title** | Panel name; empty means "Untitled panel" |
+| **Visualization** | Recommended from the last successful result (logs → Logs, sampled time series → Time series, otherwise → Table), and changeable |
+
+Prometheus runs both a range and an instant query in the workbench (Both); when the panel is saved it is stored as `Range` with the notice "Query type Both was saved as Range" — dashboards do not accept Both.
+
+**Edit mode** works on a whole-dashboard draft kept in the browser:
+
+- The header lets you change the folder (new dashboards only) and the title; on the right are the time range, undo / redo (`⌘Z` / `⌘⇧Z`), cancel and save.
+- Every change (adding a panel, dragging the layout, editing variables or configuration) goes into the draft, one undo step per action, and is **lost when you refresh** (there is no server-side draft); leaving the page with unsaved changes is intercepted with "The draft is not saved. Leave anyway?".
+- **Save**: the title is required, and a new dashboard also requires a folder. The dialog takes an optional **version message** (up to 1024 characters) and states "The full definition will be submitted as a new revision (current vN)". The whole definition is submitted and a successful save creates a new revision; when the server finds nothing changed it reports "No changes". For an existing dashboard with no changes the save button is disabled.
+- **Use the current time range as the dashboard default**: when the range you browsed with is one of the relative presets (15m / 30m / 1h / 3h / 6h / 12h / 24h / 7d) and differs from the stored default, the save dialog offers the checkbox "Set current time range (…) as dashboard default".
+- **Concurrent edits**: if someone saved while you were editing, the save fails with "Dashboard was updated by someone else" and three options: **Save as copy…** (pick a folder and save a second copy), **Discard draft and load latest** (drop your draft and return to the viewer), or **Keep editing** (keep the draft — it is never merged automatically).
+- **Validation failure**: a "Save failed: definition validation errors" dialog lists each offending JSON Pointer path with its reason.
+
+**The remaining list actions**:
+
+| Action | Description |
+|--------|-------------|
+| **Clone in this folder / Clone to another folder** | Builds a second dashboard from the full definition (new ID, title suffixed with "(copy)") and **does not carry history** |
+| **Move to another folder** | Changes the folder; the destination must be readable |
+| **Edit** | Opens the dashboard in edit mode |
+| **Delete** | See [Delete and trash](#delete-and-trash) |
+
+## Tabs, sections and panel layout
+
+- **Tabs** are the top-level divisions of a dashboard: one by default, at most 10. Double-click a tab title to rename it; deleting a tab asks for confirmation first and reports "Contains N sections and M panels."
+- **Sections** sit inside a tab, like Grafana rows: the title row is always visible and the section can be collapsed. **A collapsed section loads no data**, and its header reads "(N panels · collapsed, not loading)". A tab holds at most 10 sections.
+- **Panels** are laid out on a 24-column grid. A new panel is `12×8` and lands at the bottom of its container; on the canvas you can drag, resize, duplicate (the copy is inserted below the original) and delete them.
+- A tab holds at most 30 panels and a whole dashboard at most 100.
+- A panel can carry a description next to its title: by default it is tucked into the ⓘ tooltip, and the panel option **Use as subtitle** moves it below the title. Descriptions render Markdown like text panels do, without images or raw HTML.
+- An empty canvas points you at "Start with your first chart / Pick a datasource, write a query, and refine with live preview", with **Add panel** and **New section** buttons.
+
+Panels are **lazy-loaded**: only the panels of the active tab and of expanded sections are scheduled, at most 4 queries are in flight at once, and panels inside the viewport go first. While refreshing, the previous chart stays on screen at half opacity; only the very first load shows a skeleton.
+
+## Panel types and queries
+
+The panel editor shows a preview on the left and configuration on the right, grouped like Grafana: panel / legend / graph styles / standard options / thresholds / drill-down. **Visualization** offers seven types:
+
+| Visualization | Description | Selectable |
+|---------------|-------------|-----------|
+| **Time series** | Trends over time; compare multiple series | Yes |
+| **Table** | Rows and columns of details; good for instant queries | Yes |
+| **Stat** | One key number with threshold coloring | Yes |
+| **Text** | Markdown notes, without a data source or queries | Yes |
+| **Bar** | Compare values across categories | Greyed out, marked "Coming in a later release" |
+| **Gauge** | Where a value sits within a range | Greyed out, marked "Coming in a later release" |
+| **Logs** | Stream of log lines | Greyed out, marked "Coming in a later release" |
+
+Bar, gauge and logs are supported by the backend contract but have no renderer in the console yet, so they cannot be selected in the type picker. If you saved a Logs panel through the workbench's "Save to dashboard", the viewer shows "This visualization (logs) will be supported in a later release".
+
+The **datasource** dropdown only lists the types a dashboard can query at runtime — **prometheus, mysql, loki** (the same set as Dashboard Runtime; diagnostic-only data source types never appear) — and a panel can reference either a **fixed datasource** or a **datasource variable** (switch the variable to move every panel that uses it to another datasource).
+
+The **query type** follows from the data source and the visualization and is not chosen by hand: MySQL data sources run a time-window query (`window`), tables take an instant snapshot (`instant`), and time series and stats take a range (`range`).
+
+| Setting | Description |
+|---------|-------------|
+| **Query expression** | Supports `${variable}` templates; PromQL data sources prompt for a PromQL query, other types prompt by type |
+| **Multiple queries** | Queries are labelled `A`~`Z`; only time series support more than one. Switching to any other visualization forces you to pick which one to keep, and the rest are removed |
+| **Series name** | Shown for time series only. Sets the display name used by the legend, tooltip and data links; `{{instance}}` is replaced with that series' `instance` label value, and leaving it empty shows all labels. If both the legend and the tooltip are hidden, the editor tells you the setting is invisible |
+| **Min step** | Shown for Prometheus range queries only. A lower bound for the query step, 15s by default (matching Prometheus' default scrape interval); it is dropped when you switch to a data source or query type that does not accept it |
+| **Value fields** | Which fields a stat panel shows as values (several are shown side by side, names are case-sensitive); a Prometheus result has only `value`, so a Prometheus stat is fixed to it |
+| **Unit / decimals / thresholds** | Threshold direction "Higher is worse / Lower is worse", with warning and critical levels colored as text or as background |
+| **Table column configuration** | Tables configure unit, thresholds and coloring per numeric column; a Prometheus table has only the `value` column to configure. Coloring can be "None / Text / Background", and a background-colored column can be **applied to the entire row** |
+| **Value mappings** | Turn numbers into text and color (e.g. show 0 as "Offline" in red). The first matching mapping from the top wins, and its color overrides threshold colors |
+| **Drill-down** | Panel links and data links, see [Click-to-filter and drill-down links](#click-to-filter-and-drill-down-links) |
+
+### Panel-level query options
+
+**Query options** sit next to the datasource and apply to **every query on the panel** (A / B share them):
+
+| Option | Description |
+|--------|-------------|
+| **Max data points** | Maximum points per series, which sets the query step (time range ÷ max data points). Leave it empty to derive it from the panel width; the placeholder shows the value currently in effect |
+| **Relative time** | This panel always queries the last N and ignores the dashboard time range — e.g. `5m` always shows the last 5 minutes |
+| **Time shift** | Shifts the whole query range back by N, e.g. `1d` to compare with the same time yesterday |
+| **Compare** | Period-over-period comparison, see [Period-over-period comparison](#period-over-period-comparison) |
+
+Durations are always written as a number plus a unit (`s` / `m` / `h` / `d` / `w`), such as `5m`, `1h`, `1d`; an invalid value turns the input red with "Use a duration like 5m, 1h or 1d". A panel with a relative time or a time shift is marked next to its title in blue with the range it actually queries (e.g. "Last 5 minutes · timeshift -1d"), so viewers can tell it does not follow the dashboard time range.
+
+Previewing happens live inside the panel editor: editing the query itself runs it on Enter (or `⌘/Ctrl + Enter`), while changing the datasource, visualization or time re-runs it automatically; display settings (unit, thresholds, alias and so on) apply immediately without re-querying. **Saving does not require a successful preview.** On a new dashboard with no folder selected yet, the preview area shows "Select a folder before previewing".
+
+## Template variables
+
+The variable bar sits above the canvas and uses the same filter control as the rest of the product: each variable is a permanent filter field, single- or multi-select according to its configuration. In edit mode the bar has a **Manage variables** button at the end, opening a drawer where every variable can be added, edited or deleted.
+
+There are three **variable kinds**:
+
+| Kind | Where values come from | Settings |
+|------|------------------------|----------|
+| **Datasource** | One concrete data source | Datasource type (only prometheus / mysql / loki) and default datasource |
+| **Custom** | A hand-written candidate list | Options (one per line, `text=value` or a bare value) |
+| **Query** | Candidates fetched by querying a data source | Datasource (fixed or a datasource variable) + query definition + when to refresh candidates |
+
+A **Query variable's candidate query** has three flavours by data source type: Prometheus needs `label` (required) and `metric` (optional) plus any number of **label filters** using `= / != / =~ / !~`; SQL data sources take an expression and a value field; Loki takes an expression and a field. **Preview candidates** in the drawer fetches candidates once with the current configuration to confirm the datasource and query are right, and shows the failure reason next to the variable when they are not.
+
+**Names and references**: a variable name must match `^[A-Za-z_][A-Za-z0-9_]{0,63}$`, and a name already in use is rejected. Renaming is an atomic frontend refactor — every `${oldName}` reference (query expressions, query args, datasource variable references and the variable's own candidate query) is rewritten, and the editor warns "N references will be rewritten" before doing it. A variable that is still referenced cannot be deleted: "Variable x is referenced in N places; remove the references first." A dashboard holds at most 20 variables.
+
+**Selection mode and the 「All」 option**:
+
+- **Single**: must hold one concrete value, defaulting to the first candidate when the dashboard opens.
+- **Multi**: may be left empty, and **empty means everything**; the control then shows the placeholder "All". "All" is not a candidate — it is the state of having no concrete selection, so candidates added later are not implied by it, and there is no "select all" button.
+- **Clearing means All**: a variable that allows "All" has its own clear affordance (the × on the tag, or "clear" in the dropdown), and clearing writes an explicit All rather than falling back to the default. A variable that does not allow "All" has no clear affordance and must always keep a concrete value.
+- When a dashboard opens, a variable with no value in the URL first takes its default; with no default it falls back to the first candidate (or to All for a variable that allows it), and that selection is written back to the URL.
+- **Values outside the candidate list** (carried in by a URL or by an alert entry point) still run normally: the control shows them as "value (not in candidates)" with a warning, and does not block the query.
+
+The URL is the single source of truth for variable selections: a single value is written as `var-=value`, several values as repeated parameters, and All as `var-=$__all` — the same parameters a dashboard URL uses, so a link can be shared with its variable selections attached.
+
+## Time range and auto-refresh
+
+- The **time range** comes from the URL's `from` / `to`, either absolute milliseconds or a `now-*` relative expression; with no URL parameters the stored **default time range** applies (the last hour for a new dashboard, and one of eight presets — 15m / 30m / 1h / 3h / 6h / 12h / 24h / 7d — when saved, always ending at "now").
+- **Auto-refresh**: the interval stored on the dashboard is one of Off / 30s / 1m / 5m; the viewer's refresh picker offers finer steps (Off / 10s / 30s / 1m / 5m / 15m / 30m / 1h). Picking one writes the `refresh` URL parameter and refreshes immediately rather than waiting a full interval. Relative ranges roll forward with "now" on each refresh, and the refresh button on the left runs a manual refresh at any time, spinning while queries are still running.
+
+## Period-over-period comparison
+
+The **Compare** entry in a panel's **query options** makes the same query run a second time over the period one cycle earlier — "1d before" or "1w before" — and merges both results into the same panel.
+
+- **Supported panels**: only **time series** and **stat** panels have this option; every other visualization has neither the setting nor an extra request.
+- **Available periods**: only "1d before" and "1w before", plus "No comparison"; arbitrary durations are not offered.
+- **Time series**: the comparison run is drawn as a **dashed line in the same color**, and the legend spells out the period, e.g. `series name (1d ago)`.
+- **Stat**: shows the percentage change against the comparison period, e.g. "▲ 12.3% vs 1d ago" (flat values get no arrow, so 0% is not read as a rise); no percentage is shown when the comparison value is 0 or missing.
+- **Failure handling**: if the comparison query fails you only lose the comparison line — the current results still render, and the panel's overall state still reflects the current run.
+
+## Cross-panel cursor linking
+
+Every **time series** panel in a dashboard shares one cursor synchronisation group: moving the mouse over any of them draws the same **vertical line and points** on the others, which makes it easy to line up several metrics at the same instant.
+
+- Only mouse move and mouse leave are synchronised, not press and release (otherwise a drag-zoom would zoom every panel), and the **Y axis is not synchronised** — only the vertical line is drawn.
+- The tooltip stays on the panel under the mouse; a linked cursor does not raise one.
+- **Panels with a relative time or a time shift do not take part** — their time axis differs from the dashboard's, so linking by timestamp would point at the wrong instant.
+- The editor's preview canvas and the panel fullscreen view do not link; only the time series in the dashboard grid do.
+
+## Click-to-filter and drill-down links
+
+**Click-to-filter**: clicking data in a chart (a point on a time series, a stat, a numeric or label cell in a table) opens an overlay. If the clicked data carries a **label — or table column — whose name matches a dashboard variable**, the overlay offers "Filter by `k = v`", which sets that variable to that value and re-queries the whole dashboard.
+
+- The variables that can be set this way are all variables **except datasource variables** (a datasource variable is a single-choice datasource selector and does not take part).
+- When a time series point carries a timestamp, the overlay header shows the series name (with a copy button), the point's time and its value formatted with the panel's unit.
+- Label cells in tables only offer filtering, never drill-down: a drill-down link expands the labels of the whole row or series, so handing it a single label would build a broken URL.
+
+**Drill-down links (data links)**: with data links configured, clicking data can open an `http(s)://` URL or a site-relative `/` URL, carrying the clicked value, labels and time. The rules are:
+
+- A time series panel can enable **One click** on one link (clicking data opens it straight away, with no menu; at most one link per panel). A stat or table panel opens the only available link directly and pops a menu when there are several.
+- Links are expanded **at click time**: dashboard variables and the time range come from the current view context, while point-related placeholders come from the point that was clicked. Inserted values are URL-encoded, and `${xxx:raw}` splices a value in verbatim when it belongs inside a path.
+- Available placeholders: `${__value.raw}` (the point's value), `${__value.time}` (the point's time in ms), `${__series.name}` (series name), `${__field.labels.
diff --git a/zh/monitors/dashboards/dashboards.mdx b/zh/monitors/dashboards/dashboards.mdx
new file mode 100644
index 000000000..0538f2d95
--- /dev/null
+++ b/zh/monitors/dashboards/dashboards.mdx
@@ -0,0 +1,288 @@
+---
+title: "仪表盘"
+description: "在 Flashduty Monitors 中用仪表盘把查询固化成面板:目录组织、模板变量、同环比对比、多图光标联动、点值筛选看板、版本历史与恢复。"
+keywords: ["仪表盘", "Dashboard", "面板", "模板变量", "同环比", "版本历史", "下钻"]
+---
+
+仪表盘(Dashboard)把查询固化成图表:一个仪表盘由页签、分组和面板组成,每个面板绑定一个数据源与一组查询,打开时按当前时间范围和变量选择实时取数。它适合把日常巡检、故障复盘反复要看的几张图固定下来,不必每次去[查询工作台](/zh/monitors/explore/explore)重写查询。
+
+## 概述与入口
+
+- **菜单入口**:左侧菜单 **可视化 → 仪表盘**(前端路由 `/monit/dashboards`)。菜单与页面路由挂的是「数据源查看」权限,所以能看数据源的人就能看到仪表盘入口。
+- **从查询工作台**:工作台里跑出结果的查询可以直接**保存到仪表盘**,固化成一张面板,见[新建与保存](#新建与保存仪表盘)。
+
+仪表盘的读写权限不在面板本身,而在它所属的**目录**:读取继承目录的读权限,写操作要求「仪表盘管理」权限且对所在目录可读。详见[权限模型](#权限模型)。
+
+## 列表与目录
+
+**菜单入口**:可视化 → 仪表盘
+
+页面左侧是与告警规则共用的目录树(同一个 `/monit/folder/list` 接口),右侧是当前目录下的仪表盘列表。目录的创建、重命名、移动、删除都在树上完成,受文件夹权限控制,规则见[文件夹管理](/zh/monitors/folders/folders)。
+
+| 列 | 说明 |
+|----|------|
+| **标题** | 仪表盘名称,点击进入查看页 |
+| **更新人** | 最后一个保存该仪表盘的用户 |
+| **更新时间** | 最后一次保存的时间 |
+| **操作** | 有「仪表盘管理」权限时出现:编辑、删除,以及「更多」菜单(移动到其他分组 / 克隆到本分组 / 克隆到其他分组) |
+
+- **搜索框只搜当前目录**,不跨目录搜索;输入有 300ms 防抖,目录、搜索词、页码都写在 URL 上(`folder_id`、`q`),因此链接可以分享、刷新可保持。从仪表盘的查看页点面包屑返回列表时,会还原你离开时的那一组条件。
+- **分页**默认每页 20 条。
+- 当前目录没有仪表盘时显示「当前目录还没有仪表盘」,有管理权限的用户可以直接在空态里新建。
+
+## 新建与保存仪表盘
+
+**新建**:列表页右上角 **新建仪表盘**(需管理权限),进入 `/monit/dashboards/new?edit=1`。新盘的初始状态是:标题「未命名仪表盘」、默认时间范围「过去 1 小时」、自动刷新关闭、一个标题为 `Overview` 的页签、没有任何面板。
+
+**从查询工作台保存**:工作台的 **保存到仪表盘** 按钮把当前查询固化成面板,弹窗中可选:
+
+| 选项 | 说明 |
+|------|------|
+| **新建仪表盘** | 选目录 + 填仪表盘标题,会先在所选目录真正创建这个仪表盘,再打开它的编辑态 |
+| **现有仪表盘** | 先选目录、再从该目录的仪表盘列表里选一个;会打开该仪表盘的编辑态并把这个面板追加到首个页签底部,**保存前不产生任何数据** |
+| **图表标题** | 面板标题,留空为「未命名图表」 |
+| **图表类型** | 按最近一次成功结果推荐(日志→Logs、采样时序→Time series、其余→Table),可以改 |
+
+Prometheus 在工作台里同时跑区间与即时两条查询(Both),固化到面板时按 `Range` 保存并提示「查询方式 Both 已按 Range 保存」——仪表盘的查询方式不接受 Both。
+
+**编辑态**是一个整盘的浏览器草稿:
+
+- 顶部可改目录(仅新建时)与标题;右侧是时间范围、撤销 / 重做(`⌘Z` / `⌘⇧Z`)、取消、保存。
+- 所有修改(加面板、拖动布局、改变量、改配置)都进草稿,一步一档可撤销,**刷新页面即丢**(服务端没有草稿),带着未保存修改离开页面会被拦截提示「草稿尚未保存,确定离开?」。
+- **保存**:标题必填,新建时必须选目录;弹窗里可填**版本说明**(选填,最多 1024 字符),并提示「将提交完整配置并产生新版本(当前 vN)」。提交的是完整定义,保存成功即产生一个新版本;服务端判定内容没变时提示「没有变化」。已有仪表盘没有改动时保存按钮不可点。
+- **把当前时间范围设为本盘默认**:当你在预览时选择的时间范围是相对档(15m/30m/1h/3h/6h/12h/24h/7d 之一)且与盘上默认值不同,保存弹窗里会出现「将当前时间范围(xx)设为本盘默认」勾选项。
+- **并发冲突**:如果别人在你编辑期间保存过,保存失败并弹出「仪表盘已被他人更新」,三选:**另存为副本…**(选目录另存一份)、**放弃草稿,载入最新**(丢弃你的草稿并回到查看页)、**继续编辑**(保留草稿,不做合并)。
+- **校验失败**:弹出「保存失败:配置校验未通过」,逐条列出出错的 JSON Pointer 路径与原因。
+
+**列表页的其余动作**:
+
+| 动作 | 说明 |
+|------|------|
+| **克隆到本分组 / 克隆到其他分组** | 取完整定义另建一个仪表盘(新 ID、标题加「副本」后缀),**不带历史版本** |
+| **移动到其他分组** | 换目录,需要目标目录可读 |
+| **编辑** | 打开该仪表盘的编辑态 |
+| **删除** | 见[删除与回收站](#删除与回收站) |
+
+## 页签、分组与面板布局
+
+- **页签(Tab)** 是仪表盘的一级分区,默认一个,最多 10 个。页签标题双击即可重命名;删除页签会先确认,并提示「含 N 个分组、M 个图表」。
+- **分组(Section)** 位于页签内,像 Grafana 的 Row:标题行常显,可以折叠;**折叠的分组不加载数据**,折叠中的分组标题会显示「(N 个图表 · 折叠中不加载)」。每个页签最多 10 个分组。
+- **面板**用 24 列网格摆放,新增的面板默认 `12×8`,落在所属容器的最底部;在画布上可拖动、可缩放,也可以复制(复制一份插在原面板下方)和删除。
+- 一个页签最多 30 个面板,整个仪表盘最多 100 个面板。
+- 面板标题旁可以带描述:默认收在标题右侧的 ⓘ 提示里,勾选面板选项**作为副标题**后改为显示在标题下方;描述与文本面板的 Markdown 一样不支持图片与 HTML。
+- 空画布会给出引导「从第一张图表开始 / 选择数据源、写一条查询,边预览边完善」,并提供 **添加图表** 与 **新建分组**。
+
+仪表盘内的面板是**懒加载**的:只调度当前页签和已展开分组里的面板,页面上同时最多 4 个查询在飞,视口内的面板优先;刷新时旧图以半透明保留在页面上,首次加载才用骨架屏。
+
+## 面板类型与查询
+
+面板编辑器左侧是预览,右侧是配置,分组与 Grafana 相近:面板 / 图例 / 图形样式 / 标准选项 / 阈值 / 下钻。**图表类型**里有 7 种:
+
+| 图表类型 | 说明 | 是否可选 |
+|---------|------|---------|
+| **时序** | 随时间变化的趋势,支持多条曲线对比 | 可选 |
+| **表格** | 按行列展示明细,适合即时查询结果 | 可选 |
+| **单值** | 一个关键数字,支持阈值着色 | 可选 |
+| **文本** | Markdown 说明文字,不带数据源与查询 | 可选 |
+| **柱状** | 分类数据的大小对比 | 置灰,标注「后续版本支持」 |
+| **仪表** | 数值在范围内的位置 | 置灰,标注「后续版本支持」 |
+| **日志** | 日志明细流 | 置灰,标注「后续版本支持」 |
+
+柱状、仪表、日志三种类型后端契约已经支持,但前端渲染器尚未落地,因此不能在类型选择器里选中;如果通过查询工作台「保存到仪表盘」存下了 Logs 面板,查看时会显示「该图表类型(logs)将在后续版本支持」。
+
+**数据源**下拉只列仪表盘运行时能查询的类型——**prometheus、mysql、loki**(与 Dashboard Runtime 同口径,诊断类数据源不出现在候选里),并且可以选**固定数据源**,也可以选**数据源变量**(切换变量即换数据源,不必逐个面板改)。
+
+**查询方式**由数据源与图表类型决定,不开放手选:MySQL 数据源用时间窗口查询(`window`),表格取即时快照(`instant`),时序与单值取区间(`range`)。
+
+| 配置项 | 说明 |
+|--------|------|
+| **查询表达式** | 支持 `${variable}` 模板;PromQL 数据源提示「输入 PromQL 查询」,其它数据源按类型提示 |
+| **多查询** | 查询用 `A`~`Z` 编号,只有时序图支持多查询;切到其它图表类型时必须明确选一个保留,其余会被删除 |
+| **序列名称** | 只有时序图显示,写每条序列展示的名字(图例、提示框、数据链接都用它),如 `{{instance}}` 会替换为该序列 `instance` 标签的值,留空显示全部标签;图例与提示框都隐藏时会提示该配置当前看不到效果 |
+| **最小步长** | 只有 Prometheus 的区间查询显示,是查询步长(step)的下限,默认 15s(对齐 Prometheus 默认抓取间隔);切换到不接受该字段的数据源 / 查询方式时会被移除 |
+| **取值字段** | 单值图显示哪些字段(多个字段并排显示,字段名区分大小写);Prometheus 的结果只有 `value` 一个值,单值图的取值字段固定为它 |
+| **单位 / 小数位 / 阈值** | 阈值方向「越高越差 / 越低越差」,可配 warning / critical 两级并按「文字 / 背景」着色 |
+| **表格列配置** | 表格按数值列配置单位、阈值与着色;Prometheus 表格只有 `value` 一列可配。着色可选「不着色 / 文字 / 背景」,选背景时可以把该列的阈值色「应用到整行」 |
+| **值映射** | 把数值换成文字和颜色(如 0 显示为「离线」并标红),从上到下取第一条命中的映射,映射的颜色优先于阈值色 |
+| **下钻** | 面板链接与数据链接,见[点值筛选看板与下钻链接](#点值筛选看板与下钻链接) |
+
+### 面板级查询选项
+
+**查询选项**和数据源放在一起,作用于该面板的**全部查询**(A / B 共用):
+
+| 选项 | 说明 |
+|------|------|
+| **最大点数** | 每条序列最多返回的点数,决定查询步长(时间范围 ÷ 最大点数);留空按面板宽度自动计算,输入框占位符会给出当前实际生效的值 |
+| **相对时间** | 这个面板固定查询「现在往前 N」,不跟随仪表盘的时间范围,例如 `5m` 表示始终看最近 5 分钟 |
+| **时间偏移** | 把查询的时间范围整体往前挪 N,例如 `1d` 可与昨天同一时段对比 |
+| **对比** | 同环比,见[同环比对比](#同环比对比) |
+
+时长一律写作「数字 + 单位」(`s` / `m` / `h` / `d` / `w`),如 `5m`、`1h`、`1d`;格式不对时输入框标红并提示「格式如 5m、1h、1d」。配了相对时间或时间偏移的面板,会在标题旁用蓝字标出实际查询的时间(如「最近 5 分钟 · 偏移 1 天」),提醒查看者它不跟随全局时间。
+
+预览在面板编辑器里实时进行:改查询本身后按回车(或 `⌘/Ctrl + Enter`)才跑,改数据源、图表类型、时间这类上下文会自动重跑;显示层配置(单位、阈值、别名等)改了即时生效不用重查。**保存不要求预览成功**。新建仪表盘时如果还没选保存目录,预览区会提示「先选择保存位置才能预览」。
+
+## 模板变量
+
+变量栏在画布上方,用全站统一的筛选控件呈现:每个变量是一个常驻筛选项,单选 / 多选由变量配置决定。编辑态在变量栏末尾多了 **管理变量**(变量管理抽屉),可以增、改、删全部变量。
+
+**变量类型**有三类:
+
+| 类型 | 取值来源 | 配置项 |
+|------|---------|--------|
+| **Datasource** | 一个具体数据源 | 数据源类型(只列 prometheus / mysql / loki)、默认数据源 |
+| **Custom** | 手写的固定候选列表 | 候选项(每行一个,`显示名=值` 或纯值) |
+| **Query** | 对数据源查询得到候选 | 数据源(固定数据源或数据源变量)+ 查询方式 + 候选刷新时机 |
+
+**Query 变量的候选查询**按数据源类型分三种:Prometheus 需要填 `label`(必填)、`metric`(选填),并可用「标签过滤」逐条添加 `= / != / =~ / !~` 条件;SQL 数据源填表达式与取值字段;Loki 填表达式与字段。抽屉里的 **预览候选** 会带上当前配置试拉一次,用来确认数据源与查询写对了,失败时在变量旁显示错误原因。
+
+**名称与引用**:变量名必须匹配 `^[A-Za-z_][A-Za-z0-9_]{0,63}$`,与已有变量重名会被拒绝;改名是前端的原子重构——会把全部 `${旧名}` 引用(查询表达式、查询 args、数据源变量引用、变量自身的候选查询)一起改掉,改动前提示「将同步更新 N 处引用」。被引用着的变量不能删除,会提示「变量 x 被 N 处引用,请先清理引用」。一个仪表盘最多 20 个变量。
+
+**选择模式与「全部」**:
+
+- **单选**:必须有一个具体值,打开时默认取第一个候选。
+- **多选**:可以不选,**不选即查看全部**;此时控件占位符显示「全部」。「全部」不是候选项,它是「没有具体选择」的状态,因此不会把之后新增的候选也包含进来,也没有「全选」按钮。
+- **清空即全部**:允许「全部」的变量有自己的清除入口(标签上的 × 或下拉里的「清除」),清空会显式写成「全部」,不会回落到默认值;不允许「全部」的变量没有清除入口,必须始终保留一个具体值。
+- 打开仪表盘时,URL 里没有值的变量会先套用默认值,没有默认值的自动取第一个候选(允许「全部」的变量则落到「全部」),并把这个选择写回 URL。
+- **候选外的值**(从 URL 或告警入口带进来)照常参与运行,只是在控件里以「值(不在候选中)」显示并给出警示,不阻断。
+
+URL 是变量选择的唯一事实源:单值写 `var-<名字>=值`,多值重复同名参数,全部写 `var-<名字>=$__all`——与仪表盘 URL 用的是同一套参数,所以链接可以带着变量一起分享。
+
+## 时间范围与自动刷新
+
+- **时间范围**由 URL 的 `from` / `to` 决定,可以是绝对毫秒,也可以是 `now-*` 相对表达式;没有 URL 参数时用盘上保存的**默认时间范围**(新建时为「过去 1 小时」,保存时可在 15m / 30m / 1h / 3h / 6h / 12h / 24h / 7d 八档里固化,且必须以「现在」为终点)。
+- **自动刷新**:盘上保存的频率是 关闭 / 30s / 1m / 5m 四档;查看页的刷新控件提供更细的档位(关闭 / 10s / 30s / 1m / 5m / 15m / 30m / 1h),选择后会写进 URL 的 `refresh` 参数,并立即刷新一次,不必等满一个周期。相对时间档在刷新时会跟着「现在」滚动窗口。左侧的刷新按钮随时可以手动刷新,页面还有查询在跑时图标转圈。
+
+## 同环比对比
+
+面板的**查询选项**里有 **对比** 一栏:选了「前 1 天」或「前 1 周」后,同一条查询会在往前挪一个周期的时间段**再跑一次**,两次结果并进同一张图。
+
+- **支持范围**:只有**时序图**与**单值图**有这一栏,其它图表类型既没有配置入口也不会多发请求。
+- **可选周期**:只开放「前 1 天」与「前 1 周」(外加「不对比」),不开放任意时长。
+- **时序图**:对比那一次画成**同色虚线**,图例写明它是哪个周期,形如「`序列名(1 天前)`」。
+- **单值图**:显示与对比周期的变化百分比,形如「▲ 12.3% 较 1 天前」(持平不带箭头,避免 0% 被读成上涨);对比那一次的值为 0 或缺失时不给百分比。
+- **失败降级**:对比那次查询失败只会少掉一条对比线,本期结果照常渲染;面板整体仍按本期查询的成功 / 失败状态展示。
+
+## 多图光标联动
+
+同一个仪表盘里的**时序图**共享一个光标同步组,鼠标在任意一张时序图上移动时,其它时序图会同步画出**竖线与圆点**,方便对齐同一时刻的多个指标。
+
+- 只同步鼠标移动与移出,异步按下 / 松开(否则框选缩放会在每张图上各放大一次),**纵轴不同步**,只画竖线。
+- 提示框只留在鼠标所在的那张图上,联动过来的光标不弹提示框。
+- **配了相对时间或时间偏移的面板不参与联动**——它的时间轴与看板不一致,按时间戳联动会指错时刻。
+- 编辑态的预览画布与面板全屏视图不开启联动,只有仪表盘网格里的时序图参与。
+
+## 点值筛选看板与下钻链接
+
+**点值筛选看板**:点击图表里的数据(时序图的点、单值图、表格的数值单元格 / 标签单元格),如果被点数据带有的**标签名或表格列名与仪表盘变量同名**,点击浮层里会多出「按 `k = v` 筛选」这一项,点它就把该变量设为这个值,整个看板随之重新取数。
+
+- 参与筛选的变量是**除数据源变量之外**的全部变量(数据源变量在变量栏里是单选的数据源选择,不参与筛选)。
+- 时序图的点带时刻时,浮层头部会显示这条曲线的名字(可一键复制)、该点时刻与按面板单位格式化后的值。
+- 表格的标签单元格只提供筛选,不提供下钻——下钻链接按整行 / 整条曲线的标签展开,只带一个标签会拼出残缺地址。
+
+**下钻链接(数据链接)**:给面板配数据链接后,点数据点可以跳转到 `http(s)://` 或站内 `/` 开头的地址,链接里可以带上被点数据的值、标签与时间。规则如下:
+
+- 时序图可以选择一条链接开启**单击直达**(点数据点直接打开、不弹菜单,同一个面板最多一条开启);单值图与表格只有一条可用的链接时直接打开,多条则弹菜单。
+- 链接是在**点击时**展开的:仪表盘变量与时间范围取当前查看上下文,数据点相关的取被点的那一个点;插入的值一律 URL 编码,写在路径里时用 `${xxx:raw}` 原样拼接。
+- 可用的占位符:`${__value.raw}`(点的值)、`${__value.time}`(点的时间,毫秒)、`${__series.name}`(序列名)、`${__field.labels.<标签名>}`(标签值)、`${__from}` / `${__to}`(当前时间范围的起止毫秒)、`${__url_time_range}`(`from=…&to=…` 时间参数)、`${__all_variables}`(全部仪表盘变量的 URL 参数),以及任意仪表盘变量名。
+
+**面板链接(Panel links)**:配在面板标题旁,一条时直接点开,多条时弹出菜单;默认新标签页打开。取值同上(不涉及数据点)。
+
+## 分享与 URL 状态
+
+仪表盘把状态都放在 URL 上,因此「分享」就是把地址发出去——查看页的 URL 参数有:
+
+| 参数 | 说明 |
+|------|------|
+| `from` / `to` | 时间范围,绝对毫秒或 `now-*` 相对表达式 |
+| `var-<变量名>` | 变量选择;多值重复同名参数,全部为 `$__all` |
+| `target` | 定位到某个页签 / 分组 / 面板,打开后滚动到该对象并短暂高亮;目标已不存在时提示「链接指向的内容已不存在,已为你打开第一个页签」 |
+| `view` | 面板全屏,值为面板 ID |
+| `refresh` | 自动刷新频率 |
+| `edit` | `1` 时进入编辑态(需管理权限,否则回列表页) |
+
+面板全屏弹窗里的 **复制面板链接** 会一次性写好 `target` 与 `view`,复制出来的地址打开就直接是全屏的那张图。
+
+
+仪表盘**没有**匿名或公开分享能力:所有接口都在登录态下校验目录与数据源权限,一条 URL 只能被对目录、数据源都有权限的人看出同样的内容。查不到或无权查看时,页面提示「仪表盘不存在或无权查看」。
+
+
+## 全屏与查询详情
+
+面板标题栏在鼠标悬停时显示操作图标:**编辑**(需管理权限,直接进入编辑态并打开该面板的编辑器)、**全屏**、**重试**(面板已出结果时)。
+
+- **全屏**由 URL 的 `view=<面板ID>` 控制,因此可以分享、刷新保持、按返回键退出;文字面板全屏只展示内容,不提供时间选择与下载。
+- 全屏内可以**单独改时间段**(会话态,不写 URL,也不影响主网格),改完只重跑这一个面板。
+- 全屏里可以 **复制面板链接**、**下载数据 CSV**(文件名取面板标题)。
+- 底部 **查询详情** 逐条列出该面板的查询:`Ref`、表达式(已保存)、`request ID`、状态,以及每条查询右侧的 **在查询工作台打开** 图标——它带着已展开的变量与当前时间(或全屏里改过的时间)跳到[查询工作台](/zh/monitors/explore/explore)单独调试。
+- 键盘快捷键:鼠标悬停的面板(或已全屏的面板)上,`v` 切换全屏,`e` 进入编辑(需管理权限)。输入框聚焦时快捷键不生效。
+
+## 版本历史与恢复
+
+查看页右上角 **⋮ → 版本历史**。列表按版本倒序展示,列为 **版本 / 时间 / 操作人 / 说明**,当前版本带「当前」徽标;打开时默认勾选最新两版。
+
+- **版本对比**:勾选两个版本后点 **对比**,进入版本对比页,左右两侧各自可以选择要比的版本(左侧只能选比右侧旧的),以 **JSON diff** 展示两版保存的定义差异;键顺序不同不算差异,两版内容相同时显示「没有变更」。
+- **恢复**:在对比页点 **恢复到 vN**,二次确认(「恢复会以该版本内容产生一个新版本(当前 vM 仍保留在历史中,可再恢复回来)」)后执行。恢复的实质是用旧版定义走一次保存,因此**会再产生一个新版本**,而且新版本的说明会写成「恢复自 vN」。
+- **保留量**:每个仪表盘只保留最近 **20** 个版本,更早的版本在保存时被淘汰——恢复也只能恢复到还留在历史里的版本。
+
+这与告警规则的[规则变更记录 · 版本对比](/zh/monitors/quickstart/quickstart)是同一套交互。
+
+## 删除与回收站
+
+在列表行点 **删除** 并确认后,仪表盘进入回收站,确认弹窗写明「『标题』将进入回收站,30 天后自动清除」。后端有定时任务按小时清理超过 30 天的回收站数据(连历史版本一起物理删除)。
+
+- 已删除的仪表盘被直接打开时提示「该仪表盘已被删除」。
+- 控制台目前**没有**回收站列表页,也没有恢复入口;后端提供了回收站列表与恢复接口,恢复时可以指定目标目录,而原目录已经不存在时必须显式指定,否则返回「需要指定恢复目录」。
+- 删除需要对该仪表盘所在目录可读且有管理权限;删除请求会带上当前版本号,因此不会误删别人刚保存的新版本。
+
+## 权限模型
+
+| 能力 | 需要的权限 |
+|------|-----------|
+| 看到「仪表盘」菜单、打开列表与查看页 | 「数据源查看」权限;且该目录对你可读 |
+| 新建、编辑、移动、删除、克隆、恢复版本 | 「仪表盘管理」权限(`monitDashboard:manage`),且当前目录可读 |
+| 面板取数(查询数据源) | 对面板引用的数据源有只读(readonly)权限 |
+
+几点实现上的事实,决定了上面的表现:
+
+- **读取没有独立的权限点**:后端对仪表盘的读取继承目录的读权限(Folder Read 过滤),所以前端路由可见性照查询工作台的先例挂在「数据源查看」上。
+- **目录决定可见性**:账号主体账号与 Admin 对所有目录可读;其他成员的可见范围由目录链路上绑定的团队决定(目录或其任一父级绑定了团队时,成员必须属于对应团队;整条链路都没绑团队则所有成员可读)。目录不在可读范围内时,读接口返回「仪表盘不存在」(不暴露是否存在),写接口返回无权限。目录权限的判定规则见[文件夹管理](/zh/monitors/folders/folders)。
+- **写操作的两道门**:既要求管理权限,也要求对目标目录可读——把仪表盘移动 / 克隆到别的目录时,目标目录同样要可读。
+- **取数与数据源授权联动**:面板运行时只把「你当前有权查询的数据源」纳入解析,面板引用的数据源缺失、被停用或你无权查询时,该面板显示「无该数据源权限」,而不是暴露数据源细节。数据源授权配置见[数据源管理](/zh/monitors/data-sources/data-sources)。
+- **公开分享**:不支持。仪表盘没有对外匿名访问的入口或开关,URL 只在登录态下、且校验目录与数据源权限后才有意义(见[分享与 URL 状态](#分享与-url-状态))。
+
+## 导出 JSON
+
+查看页 **⋮ → 导出 JSON** 会把当前版本的定义下载成一个 JSON 文件,文件名取仪表盘标题(没有标题时用 `dashboard`)。文件内容是 `schema_version`、`dashboard_id` 与完整的 `definition`,可以用于备份或提交到版本库对比。控制台**没有**对应的导入入口。
+
+## 面板状态与常见错误
+
+每个面板独立展示自己的运行状态,常用状态如下:
+
+| 状态 / 提示 | 含义 |
+|------------|------|
+| 「查询成功,但该范围内没有数据」 | 查询成功但该时间范围无数据 |
+| **部分失败** 徽标 | 面板的多个查询里只有一部分成功,悬停可看每个失败的 `Ref` 与原因;成功的部分照常渲染 |
+| 「结果与图表配置不匹配」 | 结果形态与该图表类型要求的形态不符(例如表格图拿到了纯时序帧),面板不会自动换渲染方式 |
+| 「变量 x 未解析 / 请先在上方完成选择」 | 面板依赖的变量还没有有效值,该面板**不发请求**,等你在变量栏完成选择 |
+| 「无该数据源权限」 | 面板引用的数据源你无权查询(或已停用 / 不存在) |
+| 「查询超时」 | 运行期查询超时 |
+| 「结果超出大小限制,请缩小时间范围或精简查询」 | 结果体积超限,需要缩小范围或精简查询 |
+| 「查询失败」+ 重试 | 其余查询错误按服务端返回的错误信息展示,可点 **重试** 单独重跑这个面板 |
+
+另外:如果在你浏览期间别人保存了这个仪表盘,页面会检测到版本过期并**静默重新载入最新定义**,不需要你手动刷新。
+
+## 配额与限制
+
+| 限制项 | 上限 |
+|--------|------|
+| 每个仪表盘的页签 | 10 |
+| 每个页签的分组 | 10 |
+| 每个页签的面板 | 30 |
+| 每个仪表盘的面板 | 100 |
+| 每个仪表盘的变量 | 20 |
+| 表格的数据链接(含链接列) | 5 条 |
+| 保留的历史版本 | 20 |
+| 回收站保留时长 | 30 天 |
+| 单个定义(保存时提交的 JSON) | 1 MiB |
+
+超过面板 / 页签 / 变量上限时,页面上会直接提示「图表数量已达上限」「页签数量已达上限」或禁用新增按钮;定义超限时保存会返回超出大小限制的错误。
diff --git a/zh/on-call/integration/change-integration/flagsmith.mdx b/zh/on-call/integration/change-integration/flagsmith.mdx
index fc78c3f31..a6e023fc8 100644
--- a/zh/on-call/integration/change-integration/flagsmith.mdx
+++ b/zh/on-call/integration/change-integration/flagsmith.mdx
@@ -53,6 +53,8 @@ Flagsmith 会把组织下所有项目的审计日志推送到该地址,之后
|---|---|---|
| 审计日志记录(Audit log entry) | 推送内容中的 `data.id` | 每次保存产生一条审计日志,对应一条 Flashduty 变更;同一个开关先打开再关闭是两条变更 |
+审计日志记录的 `data.id` 在一个 Flagsmith 实例内递增。请为每个 Flagsmith 实例单独创建一个集成;多个实例共用一个集成时,不同实例的相同 `id` 会被当作同一条变更。
+
## 状态映射
---
diff --git a/zh/on-call/integration/instant-messaging/slack.mdx b/zh/on-call/integration/instant-messaging/slack.mdx
index bdf5c3f3f..dbf526991 100644
--- a/zh/on-call/integration/instant-messaging/slack.mdx
+++ b/zh/on-call/integration/instant-messaging/slack.mdx
@@ -46,6 +46,9 @@ keywords: ["Slack", "即时消息", "告警通知", "IM集成", "协作工具"]
| `reactions:read` | 读取消息表情反应,用于 AI SRE 处理状态确认 |
| `reactions:write` | 添加或删除消息表情反应,用于 AI SRE 处理状态确认 |
| `files:write` | 上传文件,用于发送复盘报告等附件 |
+| `files:read` | 下载用户上传的私有文件;AI SRE 读取 Slack 会话中上传的文件、图片等附件需要该权限 |
+
+`files:read` 不在控制台**缺少必要权限**检查所校验的清单内——该检查只覆盖上表中的其余 scope,检查通过并不代表已授予此权限。如果 AI SRE 无法读取会话中上传的文件或图片,请确认 Slack 应用已授予 `files:read`。
### User Token Scopes
diff --git a/zh/platform/pricing.mdx b/zh/platform/pricing.mdx
index d0939e6e2..bc6866b9a 100644
--- a/zh/platform/pricing.mdx
+++ b/zh/platform/pricing.mdx
@@ -306,6 +306,35 @@ RUM 采用 **按量付费**模式,根据实际使用的会话数量计费。
---
+## 私有化部署的 License 到期与续签
+
+---
+
+私有化部署的 License 由 Flashduty 签发,带固定到期日。到期前平台会向部署方在合同中登记的联系人发送提醒;到期后平台**停止接收数据**。私有化部署不提供费用中心入口(见[付款与充值](#付款与充值)),续签需联系销售。
+
+### 到期提醒
+
+提醒面向合同中登记的联系人:每位联系人的**邮箱**都会收到提醒邮件,登记了**有效中国大陆手机号**的联系人还会收到**短信**。
+
+- **提醒时点**:License 剩余 **10 天、3 天、1 天** 时各发送一次,每张 License 最多三次。剩余天数按天向上取整,到期时刻归入「1 天」那一次,因此到期后不会补发;License 登记时剩余天数已不足 10 天,则只会收到其中一次。
+- **发送时段**:仅在北京时间 **08:00–22:00** 之间发送(按小时判定,落在区间外的小时不发送)。
+- **不再提醒**:已到期超过 **7 天** 的 License 不再发送提醒。
+- **文案**:提醒邮件为**固定中文文案**(私有化客户均在国内)。到期前主题为「[License 提醒] Flashduty 私有化 License 还剩 N 天到期」,副标题为「到期后将停止接收数据。」,正文含 **到期日** 与 **剩余天数**;到期当天的主题与标题改为「[License 提醒] Flashduty 私有化 License 已到期」,副标题为「数据已停止接收。」。短信文案为「您的 Flashduty 私有化部署(客户名称)License 将于 到期日 到期,还剩 N 天。到期后将停止接收数据,请尽快联系我们续签」,已到期时改为「……已于 到期日 到期,数据已停止接收,请尽快联系我们续签」。
+
+### 到期后的影响与续签
+
+License 到期后平台**停止接收数据**,请尽快续签,避免数据接收长时间中断。
+
+拿到新的 License 后,在控制台**侧边栏的 License 提示中粘贴并激活**,激活成功后控制台提示「License 已更新,将在五分钟内生效」,**无需重启服务**;到期日随之更新,提醒按新的到期日重新开始。(提醒邮件中写的生效时长是约 1–2 分钟,以控制台提示为准。)
+
+
+「[额度提醒](#额度提醒)」与「[余额不足提醒](#余额不足提醒)」面向 **SaaS** 账户;本节针对**私有化部署**的 License 到期与续签,两者相互独立。
+
+
+---
+
+---
+
## 订阅过期后会发生什么
On-call 订阅**已过期或被停用**后,平台会做两件事:**停止接收新的告警事件**,并**冻结所有新建入口**。已有配置和历史数据不会被删除,续费后自动恢复。
diff --git a/zh/rum/explorer/data-query.mdx b/zh/rum/explorer/data-query.mdx
index 6545e398b..638923ede 100644
--- a/zh/rum/explorer/data-query.mdx
+++ b/zh/rum/explorer/data-query.mdx
@@ -192,8 +192,18 @@ source:miniprogram view_first_render:>2s
| `session_id` | 会话 ID |
| `session_view_count` | 会话内的视图访问量 |
| `session_has_replay` | 会话是否包含回放 |
+| `session_sampled_for_error` | 会话是否为异常补采会话:为 `true` 时,该会话的事件在客户端被暂存、直到会话报错才上传,因此明细只从报错前的一小段开始 |
+| `session_sampled_for_error_replay` | 会话回放是否因报错才保留:为 `true` 时,该回放是会话报错后才补充上传的 |
| `rc_version` | 远程配置版本,即会话上报时所使用的远程配置版本号 |
+例如,检索由异常补采上传的会话:
+
+```
+session_sampled_for_error:true
+```
+
+异常补采的开关见应用管理中[远程配置](../quickstart/app-management#远程配置)的 **异常会话补采**(`sessionOnError`)与 **异常回放补采**(`sessionReplayOnError`)。
+
其中 `rc_version` 对应应用管理中[远程配置](../quickstart/app-management)的发布版本,可按配置版本筛选会话,评估远程配置发布(rollout)的生效情况。
## 高级检索技巧
diff --git a/zh/rum/quickstart/app-management.mdx b/zh/rum/quickstart/app-management.mdx
index fa21abde5..19e495b55 100644
--- a/zh/rum/quickstart/app-management.mdx
+++ b/zh/rum/quickstart/app-management.mdx
@@ -293,13 +293,61 @@ Link 集成会从当前事件上下文中提取变量并替换到 URL 模板中
关闭地理位置或 IP 地址采集后,相关筛选和分析维度将不再可用。请根据业务需求和合规要求谨慎调整。
+## 代码仓库
+
+「代码仓库」页签用于把 RUM 应用与构建它的代码仓库关联起来,让 AI SRE 分析问题时可以直接定位到对应代码。该页签本身不采集数据,也不改变 SDK 上报行为。
+
+页签只在账户已开启 AI SRE 时出现(SaaS 环境默认开启,私有化部署由部署配置中的 `enableAiSre` 开关决定)。仓库的授权与访问范围管理在 **插件 → Apps** 中完成,详见 [Apps](/zh/ai-sre/apps)。
+
+### 添加仓库
+
+
+
+在应用详情页选择 **代码仓库** 页签。尚未关联任何仓库时,页面显示「暂未关联代码仓库」空状态。
+
+
+
+点击 **添加仓库**,在 **仓库** 中输入 `owner/name`,或直接粘贴 GitHub 网页链接 / clone 链接(HTTPS 或 SSH 均可)——保存时会统一规范化为 `owner/name`。
+
+输入框的候选分为两组,都只是建议、不会自动填入:**GitHub App 已授权**(账户当前 GitHub App 安装已授权的仓库)与**符号上传记录**(该应用类型的符号上传记录里出现过的仓库,取最近 90 天)。候选中没有目标仓库时,直接输入或粘贴即可。
+
+
+
+在 **目录** 中填写应用在该仓库内的相对路径;仓库根目录填 `.`。
+
+
+
+点击 **保存**。之后可对非首条仓库使用 ↑ **设为主仓库** 调整顺序,或移除条目(移除需在确认弹窗中确认)。
+
+
+
+### 规则与限制
+
+| 项 | 规则 |
+|----|------|
+| 仓库数量 | 最多关联 10 个仓库 |
+| 仓库格式 | GitHub 仓库,`owner/name` 形式(owner 最长 39 个字符且以字母或数字开头;name 最长 100 个字符) |
+| 主仓库 | 列表有序,第一条为主仓库并带「主仓库」标记 |
+| 目录 | 仓库内的相对路径,最长 255 个字符,不能包含 `..` 或反斜杠;保存时会去掉首尾 `/`、忽略 `.` 段,空值规范为 `.` |
+| 重复关联 | 同一仓库 + 同一目录不能关联两次(仓库名比较不区分大小写) |
+| 操作权限 | 新增、移除与设为主仓库需要 **RUM 应用更新** 权限 |
+
+列表中展示的仓库名会链接到 GitHub 上对应的仓库。
+
+### 与 AI SRE 的关系
+
+- 关联仓库本身**不授予任何访问权限**。云端沙箱里的 AI 会话只能读取账户 GitHub App 安装所授权的仓库;手动填写的仓库只对使用宿主机自带凭证的 [BYOC](/zh/ai-sre/environments) 会话有意义。
+- 账户尚未连接任何 GitHub App 安装时,页面顶部提示「尚未连接 GitHub App:手动填写的仓库只能供本地 AI 使用,云端 AI 会话读取不到代码。」,并提供 **去连接** 入口跳转到 **插件 → Apps**。
+- 已连接 GitHub App 时,不在授权范围内的条目旁会出现警告标记,提示「不在 GitHub App 授权范围内,云端 AI 会话读取不到该仓库。」:有 **Apps 插件访问** 权限的成员点击标记可到 **插件 → Apps** 为该安装授权更多仓库,其他成员看到的是「请联系管理员在 GitHub App 中授权该仓库」。
+- 若部署中查询不到 GitHub App 授权信息(例如纯 RUM 的私有化环境),页面不显示「尚未连接」提示,只保留手动填写。
+
## 远程配置
「远程配置」页签允许你在线调整采集与隐私参数,而无需改代码、重新发版。启用后,本页配置覆盖 SDK 初始化设置;停用后,各端恢复使用 SDK 初始化设置,数据采集不会停止。
- 远程配置目前支持 **Browser**、**iOS**、**Android**、**Flutter** 与**微信小程序**类型应用,其他平台类型将随各端 SDK 发布逐步开放。
-- SaaS 环境下该功能按账号逐步放量。如果应用详情页未显示「远程配置」页签,请联系支持团队开通;私有化部署默认可用。
+- 「远程配置」页签对所有账户开放(SaaS 与私有化部署一致),无需联系支持团队开通;页签是否显示只取决于应用类型是否属于上一条列出的受支持平台。
### 配置项