Date: Tue, 15 Sep 2026 09:15:21 +0000
Subject: [PATCH 09/14] docs(monitors): use the real English UI strings for the
trigger-mode sentences
---
en/monitors/quickstart/quickstart.mdx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/en/monitors/quickstart/quickstart.mdx b/en/monitors/quickstart/quickstart.mdx
index 6ef86626..7cf41896 100644
--- a/en/monitors/quickstart/quickstart.mdx
+++ b/en/monitors/quickstart/quickstart.mdx
@@ -141,8 +141,8 @@ The settings are grouped into cards: except on the **Missing data** tab, each ta
| Trigger mode | Meaning | Trigger condition sentence |
|--------------|---------|----------------------------|
-| **Consecutive** (default) | Alerts after the set number of consecutive matches | `连续 N 次检测都满足条件才告警` — the rule alerts only after N consecutive checks meet the condition, where N is the **Matches** count, default 3 |
-| **Cumulative** | Alerts when enough of the last checks match, even if not consecutive | `最近 M 次检测中,有 N 次满足条件就告警` — the rule alerts when N of the last M checks meet the condition, where M is the **Checks** count, defaulting to `max(Matches, 5)` when you switch to cumulative |
+| **Consecutive** (default) | Alerts after the set number of consecutive matches | `alert after N consecutive checks all match` — the rule alerts only after N consecutive checks meet the condition, where N is the **Matches** count, default 3 |
+| **Cumulative** | Alerts when enough of the last checks match, even if not consecutive | `alert once N of the last M checks match` — the rule alerts when N of the last M checks meet the condition, where M is the **Checks** count, defaulting to `max(Matches, 5)` when you switch to cumulative |
- Under **Cumulative**, the match count cannot exceed the check count, and the check count cannot be lower than the match count. Neither can exceed 10000; going over is reported as a validation error rather than being silently clamped to the maximum
- The two modes are mutually exclusive: after switching back to **Consecutive**, the check count is no longer submitted with the rule (the server tells the modes apart by whether that field is present), so the "N of the last M checks" semantics cannot linger
From c6c71c93635c9670b29dc5077073585ab11b4add Mon Sep 17 00:00:00 2001
From: pijiang <419471640@qq.com>
Date: Wed, 16 Sep 2026 15:17:43 +0800
Subject: [PATCH 10/14] docs: add aliyun dataworks op integration guide
---
docs.json | 2 +
.../alert-sources/aliyun-dataworks-op.mdx | 179 ++++++++++++++++++
integration-docs/src/doc-map.mjs | 1 +
.../alert-sources/aliyun-dataworks-op.mdx | 179 ++++++++++++++++++
4 files changed, 361 insertions(+)
create mode 100644 en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
create mode 100644 zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
diff --git a/docs.json b/docs.json
index aa7e0476..ba716c72 100644
--- a/docs.json
+++ b/docs.json
@@ -1695,6 +1695,7 @@
"zh/on-call/integration/alert-integration/alert-sources/aliyun-cm-metrics",
"zh/on-call/integration/alert-integration/alert-sources/aliyun-sls",
"zh/on-call/integration/alert-integration/alert-sources/aliyun-prometheus",
+ "zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op",
"zh/on-call/integration/alert-integration/alert-sources/aws-cloudwatch",
"zh/on-call/integration/alert-integration/alert-sources/aws-eventbridge",
"zh/on-call/integration/alert-integration/alert-sources/azure-monitor",
@@ -3064,6 +3065,7 @@
"en/on-call/integration/alert-integration/alert-sources/aliyun-cm-metrics",
"en/on-call/integration/alert-integration/alert-sources/aliyun-sls",
"en/on-call/integration/alert-integration/alert-sources/aliyun-prometheus",
+ "en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op",
"en/on-call/integration/alert-integration/alert-sources/aws-cloudwatch",
"en/on-call/integration/alert-integration/alert-sources/aws-eventbridge",
"en/on-call/integration/alert-integration/alert-sources/azure-monitor",
diff --git a/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx b/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
new file mode 100644
index 00000000..1593d8d8
--- /dev/null
+++ b/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
@@ -0,0 +1,179 @@
+---
+title: "Alibaba Cloud DataWorks Integration"
+description: "Sync alert events from Alibaba Cloud DataWorks Intelligent Monitoring (Operation Center) to Flashduty On-call through a custom webhook, with automated alert noise reduction"
+keywords: ["alert integration", "Alibaba Cloud DataWorks", "DataWorks Intelligent Monitoring", "Operation Center", "monitoring alerts", "data ingestion"]
+---
+
+
+
+
+## In Flashduty On-call
+---
+You can obtain an integration push URL in either of the following two ways.
+
+### Use an exclusive integration
+
+Choose this option when you do not need to route alert events to different collaboration spaces. It is simpler.
+
+
+
+
+ 1. Go to the Flashduty console, select **Collaboration Spaces**, and open a space's detail page
+ 2. Select the **Integrated Data** tab, click **Add an integration**, and open the add-integration page
+ 3. Select the **Alibaba Cloud DataWorks** integration and click **Save** to generate a card
+ 4. Click the card to view the **push URL**, copy it for later use, and you are done
+
+
+
+
+
+### Use a shared integration
+
+Choose this option when you need to route alerts to different collaboration spaces based on the alert payload.
+
+
+
+
+ 1. Go to the Flashduty console and select **Integration Center => Alert Events** to open the integration selection page
+ 2. Select the **Alibaba Cloud DataWorks** integration:
+ - **Integration name**: define a name for this integration
+ 3. Configure the default route and select the corresponding collaboration space (after creation, you can go to `Routing` to configure more routing rules)
+ 4. Click **Save**, then copy the newly generated **push URL** on the current page for later use
+ 5. Done
+
+
+
+
+
+## In Alibaba Cloud DataWorks
+---
+**Step 1: Create a custom webhook**
+
+
+
+1. Log in to the Alibaba Cloud console and open the **DataWorks** product
+2. Go to **DataStudio** or **Operation Center** and open the **Intelligent Monitoring** page
+3. Open the alarm receiver configuration (the custom webhook entry) and create a new webhook
+4. Set the request URL to the Flashduty integration push URL copied above; the request method is POST
+5. After saving, you can click **Send test message**. DataWorks pushes a connectivity test message (`message.content`); Flashduty returns success without creating an alert event
+
+
+
+**Step 2: Enable the webhook in monitoring rules**
+
+
+
+1. In **Intelligent Monitoring**, open the **custom rules** (instance status alerts, resource group alerts), **baseline management**, or **event management** page
+2. Create or edit a rule, and select the custom webhook created above as an alarm channel
+3. Save the rule. Alerts triggered by this rule are pushed to Flashduty in real time
+
+
+
+## Supported alert types
+---
+
+
+DataWorks Intelligent Monitoring wraps every custom webhook message in a `message` field, distinguished by `message.title`. This integration supports the following three alert families:
+
+| message.title | Alert family | Description |
+| ------------- | ------------ | ----------- |
+| `DataWorks_Remind` | Custom alert | Instance status alerts (remind_unit: Task, Baseline, Project, BizProcess) and resource group alerts (ScheduleResourceGroup, DiResourceGroup) |
+| `DataWorks_Baseline_Alert` | Baseline alert | Baseline warning (dangerous) and SLA breach (overSla) |
+| `DataWorks_Event_Remind` | Event alert | Task error (ERROR) and task slowdown (SLOW) |
+
+The connectivity test message (`message.content`) is used only to verify the push URL and never creates an alert event.
+
+
+
+## Severity mapping
+---
+
+
+Mapping from custom alert `remind_type` to Flashduty severity:
+
+| DataWorks remind_type | Flashduty | State |
+| --------------------- | --------- | ----- |
+| error | Critical | Critical |
+| exhausted error | Critical | Critical |
+| uncompleted | Warning | Warning |
+| cycle uncompleted | Warning | Warning |
+| run over time | Warning | Warning |
+| resGroup use ratio | Warning | Warning |
+| the number of waiting task in resGroup | Warning | Warning |
+| completed | Info | Info |
+| empty or unknown value | Warning | Warning |
+
+Mapping from baseline alert `status`:
+
+| DataWorks status | Flashduty | State |
+| ---------------- | --------- | ----- |
+| overSla (SLA breach) | Critical | Critical |
+| dangerous (warning) | Warning | Warning |
+| empty or unknown value | Warning | Warning |
+
+Mapping from event alert `event_type`:
+
+| DataWorks event_type | Flashduty | State |
+| -------------------- | --------- | ----- |
+| ERROR | Critical | Critical |
+| SLOW | Warning | Warning |
+| empty or unknown value | Warning | Warning |
+
+
+
+## Alert Key and alert merging
+---
+
+
+DataWorks Intelligent Monitoring webhooks are **one-shot events**: the official protocol defines alert notifications only, with **no recovery** or update semantics, and it provides no vendor-level deduplication ID or fingerprint field. Therefore this integration never automatically recovers (closes) any alert; every event is delivered in a triggered state.
+
+So that repeated triggers from the same rule and the same monitored object can be merged for noise reduction, Flashduty derives the Alert Key from immutable identity fields in the message:
+
+| Alert family | Alert Key components |
+| ------------ | -------------------- |
+| Custom alert (task-based) | title + remind_name + node_id_list |
+| Custom alert (resource group) | title + remind_name + resource_group_name |
+| Baseline alert | title + baseline_name + key_instance |
+| Event alert | title + task_name + event_type |
+
+Note: `event_name` contains the business date and cycle ID (different every cycle), so it is excluded from the Alert Key; consecutive failures of the same task across cycles merge into one alert. Fields that change on every delivery, such as `occur_time` and `number_of_alerts`, are excluded as well.
+
+
+
+## Field label mapping
+---
+
+
+Key fields from the push message are preserved as labels on the alert event and can be used for routing, silencing, and template rendering:
+
+| Label | Source field | Description |
+| ----- | ------------ | ----------- |
+| alert_type | title | Alert family (DataWorks_Remind, etc.) |
+| remind_name | remind_name | Rule name |
+| remind_unit | remind_unit | Monitoring granularity (Task, ScheduleResourceGroup, etc.) |
+| remind_type | remind_type | Raw trigger condition |
+| occur_time | occur_time | Raw occurrence time string |
+| remind_founder | remind_founder | Rule creator |
+| more_information | more_information | Operation Center instance URL |
+| task_size / number_of_alerts | same-name fields | Task count / nth alert notification |
+| node_id_list / node_name_list / node_owner_list | same-name fields | Node IDs / names / owners (comma-separated, up to 5) |
+| resource_group_name / threshold / duration | same-name fields | Resource group name / threshold / duration (minutes), resource group monitoring only |
+| baseline_name / baseline_owners | same-name fields | Baseline name / baseline owners |
+| cycle_number / key_instance / sla_time / buffer / status | same-name fields | Cycle number / key instance / SLA time / buffer (minutes) / baseline status |
+| task_name / task_owner_name / event_type / event_name | same-name fields | Task name / owner / event type / event name |
+
+
+
+## FAQ
+---
+
+
+**Why are alerts never automatically recovered?**
+
+The DataWorks Intelligent Monitoring webhook protocol defines no resolve message; it is a one-shot notification with no recovery semantics. To close an alert, handle it manually in the Flashduty console or configure alert convergence policies for the rule.
+
+**Why is no alert visible after sending a test message?**
+
+The DataWorks connectivity test message (`message.content`) only verifies that the push URL is reachable. Flashduty returns success without creating an alert event. Trigger a real rule to verify the end-to-end flow.
+
+
diff --git a/integration-docs/src/doc-map.mjs b/integration-docs/src/doc-map.mjs
index c570094b..362e04db 100644
--- a/integration-docs/src/doc-map.mjs
+++ b/integration-docs/src/doc-map.mjs
@@ -66,6 +66,7 @@ export const docMap = {
Datadog: `${alertBase}/datadog.mdx`,
NewRelic: `${alertBase}/new-relic.mdx`,
AliyunPrometheus: `${alertBase}/aliyun-prometheus.mdx`,
+ AliyunDataWorksOp: `${alertBase}/aliyun-dataworks-op.mdx`,
HttpPull: `${alertBase}/http-pull.mdx`,
DbPull: `${alertBase}/db-pull.mdx`,
Emqx: `${alertBase}/emqx.mdx`,
diff --git a/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx b/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
new file mode 100644
index 00000000..c80789ee
--- /dev/null
+++ b/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
@@ -0,0 +1,179 @@
+---
+title: "阿里云 DataWorks 集成"
+description: "通过自定义 Webhook 的方式同步阿里云 DataWorks 智能监控(运维中心)告警事件到 Flashduty On-call,实现告警事件自动化降噪处理"
+keywords: ["告警集成", "阿里云 DataWorks 集成", "DataWorks 智能监控", "运维中心", "监控告警", "数据接入"]
+---
+
+
+
+
+## 在 Flashduty On-call
+---
+您可通过以下2种方式,获取一个集成推送地址,任选其一即可。
+
+### 使用专属集成
+
+当您不需要将告警事件路由到不同的协作空间,优先选择此方式,更简单。
+
+
+
+
+ 1. 进入 Flashduty 控制台,选择 **协作空间**,进入某个空间的详情页面
+ 2. 选择 **集成数据** tab,点击 **添加一个集成**,进入添加集成页面
+ 3. 选择 **阿里云 DataWorks** 集成,点击 **保存**,生成卡片。
+ 4. 点击生成的卡片,可以查看到 **推送地址**,复制备用,完成。
+
+
+
+
+
+### 使用共享集成
+
+当您需要根据告警事件的 Payload 信息,将告警路由到不同的协作空间,优先选择此方式。
+
+
+
+
+ 1. 进入 Flashduty 控制台,选择 **集成中心=>告警事件**,进入集成选择页面。
+ 2. 选择 **阿里云 DataWorks** 集成:
+ - **集成名称**:为当前集成定义一个名称。
+ 3. 配置默认路由,并选择对应的协作空间(集成创建后可以前往 `路由` 进行更多路由规则的配置)。
+ 4. 点击 **保存** 后,复制当前页面的新生成的 **推送地址** 备用。
+ 5. 完成。
+
+
+
+
+
+## 在阿里云 DataWorks
+---
+**步骤 1:创建自定义 Webhook**
+
+
+
+1. 登录阿里云控制台,进入 **DataWorks** 产品
+2. 进入 **数据开发(DataStudio)** 或 **运维中心**,打开 **智能监控** 页面
+3. 进入 **报警接收配置**(或 **自定义 webhook** 配置入口),新建一个 Webhook
+4. `请求地址` 填写 Flashduty 集成的推送地址(上一步复制),`请求方法` 为 POST
+5. 保存后,可点击 **发送测试消息**,DataWorks 会推送一条连通性测试消息(`message.content`),Flashduty 收到后返回成功但不产生告警事件
+
+
+
+**步骤 2:在监控规则中启用 Webhook**
+
+
+
+1. 进入 **智能监控** 的 **自定义规则**(周期实例状态告警、资源组告警)、**基线管理** 或 **事件管理** 页面
+2. 创建或编辑规则,在 **报警方式** 中勾选上一步创建的自定义 Webhook
+3. 保存规则,完成。此后该规则触发的告警会实时推送到 Flashduty
+
+
+
+## 支持的告警类型
+---
+
+
+DataWorks 智能监控自定义 Webhook 推送的消息统一包裹在 `message` 字段中,通过 `message.title` 区分类型,本集成支持以下三类告警:
+
+| message.title | 告警类型 | 说明 |
+| ------------- | -------- | ---- |
+| `DataWorks_Remind` | 自定义告警 | 周期实例状态告警(remind_unit 为 Task、Baseline、Project、BizProcess)与资源组告警(ScheduleResourceGroup、DiResourceGroup) |
+| `DataWorks_Baseline_Alert` | 基线告警 | 基线预警(dangerous)与破线(overSla) |
+| `DataWorks_Event_Remind` | 事件告警 | 任务出错(ERROR)与变慢(SLOW) |
+
+连通性测试消息(`message.content`)仅用于验证推送地址,不会产生告警事件。
+
+
+
+## 严重程度对照
+---
+
+
+DataWorks 自定义告警 `remind_type` 到 Flashduty 告警等级(Severity)映射关系:
+
+| DataWorks remind_type | Flashduty | 状态 |
+| --------------------- | --------- | ---- |
+| error(出错) | Critical | 严重 |
+| exhausted error(自动重跑仍出错) | Critical | 严重 |
+| uncompleted(未完成) | Warning | 警告 |
+| cycle uncompleted(周期未完成) | Warning | 警告 |
+| run over time(运行超时) | Warning | 警告 |
+| resGroup use ratio(资源组利用率) | Warning | 警告 |
+| the number of waiting task in resGroup(资源组等待资源实例数) | Warning | 警告 |
+| completed(完成) | Info | 提醒 |
+| 空值或未知值 | Warning | 警告 |
+
+基线告警 `status` 映射关系:
+
+| DataWorks status | Flashduty | 状态 |
+| ---------------- | --------- | ---- |
+| overSla(破线) | Critical | 严重 |
+| dangerous(预警) | Warning | 警告 |
+| 空值或未知值 | Warning | 警告 |
+
+事件告警 `event_type` 映射关系:
+
+| DataWorks event_type | Flashduty | 状态 |
+| -------------------- | --------- | ---- |
+| ERROR(出错) | Critical | 严重 |
+| SLOW(变慢) | Warning | 警告 |
+| 空值或未知值 | Warning | 警告 |
+
+
+
+## Alert Key 与告警合并
+---
+
+
+DataWorks 智能监控 Webhook 属于**一次性事件**(one-shot):官方协议只定义告警通知,**不恢复**、无更新语义,也没有提供厂商级别的去重 ID 或指纹字段。因此本集成不会自动恢复(关闭)任何告警,所有事件均以触发状态投递。
+
+为了让同一规则、同一监控对象的重复触发能够自动合并降噪,Flashduty 从消息的不可变身份字段派生 Alert Key:
+
+| 告警类型 | Alert Key 组成 |
+| -------- | -------------- |
+| 自定义告警(任务类) | title + remind_name + node_id_list |
+| 自定义告警(资源组类) | title + remind_name + resource_group_name |
+| 基线告警 | title + baseline_name + key_instance |
+| 事件告警 | title + task_name + event_type |
+
+注意:`event_name` 包含业务日期与周期 ID(每个周期不同),不参与 Alert Key 计算;因此同一任务连续多个周期失败会合并到同一条告警中。`occur_time`、`number_of_alerts` 等每次推送都会变化的字段也不参与计算。
+
+
+
+## 字段标签对照
+---
+
+
+推送消息中的主要字段会以标签(Labels)形式保留在告警事件中,可用于路由、静默与模板渲染:
+
+| 标签 | 来源字段 | 说明 |
+| ---- | -------- | ---- |
+| alert_type | title | 告警类型(DataWorks_Remind 等) |
+| remind_name | remind_name | 规则名称 |
+| remind_unit | remind_unit | 监控粒度(Task、ScheduleResourceGroup 等) |
+| remind_type | remind_type | 触发条件原始值 |
+| occur_time | occur_time | 发生时间原文 |
+| remind_founder | remind_founder | 规则创建人 |
+| more_information | more_information | 运维中心周期实例链接 |
+| task_size / number_of_alerts | 同名字段 | 任务数量 / 第几次告警 |
+| node_id_list / node_name_list / node_owner_list | 同名字段 | 节点 ID / 名称 / 责任人列表(英文逗号分隔,最多 5 个) |
+| resource_group_name / threshold / duration | 同名字段 | 资源组名 / 阈值 / 持续时间(分钟),资源组监控特有 |
+| baseline_name / baseline_owners | 同名字段 | 基线名 / 基线责任人 |
+| cycle_number / key_instance / sla_time / buffer / status | 同名字段 | 周期号 / 关键实例 / 承诺时间 / 余量(分钟)/ 基线状态 |
+| task_name / task_owner_name / event_type / event_name | 同名字段 | 任务名 / 责任人 / 事件类型 / 事件名称 |
+
+
+
+## 常见问题
+---
+
+
+**为什么告警不会自动恢复?**
+
+DataWorks 智能监控 Webhook 协议没有定义恢复(resolve)消息,属于一次性通知。如需关闭告警,请在 Flashduty 控制台手动处理,或为规则配置告警收敛策略。
+
+**发送测试消息后为什么看不到告警?**
+
+DataWorks 的连通性测试消息(`message.content`)仅用于验证推送地址可达,Flashduty 收到后返回成功但不生成告警事件。请通过真实触发规则来验证端到端链路。
+
+
From 1cfc7e38447cb4d4c4b04bac686142142134f592 Mon Sep 17 00:00:00 2001
From: "flashduty[bot]"
Date: Wed, 16 Sep 2026 08:08:04 +0000
Subject: [PATCH 11/14] =?UTF-8?q?docs(api):=20daily=20audit=202026-09-16?=
=?UTF-8?q?=20=E2=80=94=20repair=20the=20investigation=5Ftargets=20drill-d?=
=?UTF-8?q?own=20contract,=20cap=20the=20Automation=20rule=20list=20page?=
=?UTF-8?q?=20size?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Two evidence-backed fixes, no operation added or removed (338 public
operations before and after).
1. Monitors, investigation_targets (hard breakage). monit-webapi reworked the
drill-down contract after this spec was last regenerated (2026-09-10), so the
documented shape is now rejected by the server: InvestigationTarget
unmarshals with DisallowUnknownFields, and time_range is mandatory.
- InvestigationTarget: kind enum gains query; time_range added and required;
query payload added (query kind).
- DashboardInvestigationTarget: variable_bindings replaced by the variables
string map that now carries the same event-label templates.
- New: InvestigationTimeRange, QueryInvestigationTarget, DashboardQuery.
- Removed: InvestigationVariableBinding (orphaned by the change).
- AlertRuleV2.investigation_targets: maxItems 20.
This was the flag raised by the earlier Monitors doc review as a
must-fix-by-api-review item; doc-following requests were being rejected.
2. AI SRE, POST /safari/automation/rule/list. AutomationRuleListRequest
.properties.limit gains maximum 200 and a description stating the real
bounds, matching the explicit cap in fc-safari logic/automation/service.go.
Diff: 4 files, +376/-68. Key order preserved everywhere (verified: the
relative order of every pre-existing key is byte-identical to HEAD; no
reordering noise). docs.json and both api-catalog.mdx untouched.
---
api-reference/monitors.openapi.en.json | 111 ++++++++++++++++++++----
api-reference/monitors.openapi.zh.json | 111 ++++++++++++++++++++----
api-reference/openapi.en.json | 114 +++++++++++++++++++++----
api-reference/openapi.zh.json | 114 +++++++++++++++++++++----
api-reference/safari.openapi.en.json | 3 +-
api-reference/safari.openapi.zh.json | 3 +-
6 files changed, 384 insertions(+), 72 deletions(-)
diff --git a/api-reference/monitors.openapi.en.json b/api-reference/monitors.openapi.en.json
index 145d7dab..bb59ed9f 100644
--- a/api-reference/monitors.openapi.en.json
+++ b/api-reference/monitors.openapi.en.json
@@ -5923,6 +5923,7 @@
"items": {
"$ref": "#/components/schemas/InvestigationTarget"
},
+ "maxItems": 20,
"description": "Drill-down entries linked from the alert event detail page; at most 20 items, duplicates rejected. On update the field is presence-based: omit it to keep the current value, pass `[]` to clear.",
"x-flashduty-preserve-absence": true
},
@@ -6223,14 +6224,23 @@
},
"InvestigationTarget": {
"type": "object",
- "description": "Drill-down entry linked to alert events. A deliberately closed tagged union: new kinds require explicit server support.",
+ "description": "Alert-event drill-down entry. A deliberately closed tagged union: new kinds require explicit server support, and unknown fields inside a target are rejected.",
"properties": {
"kind": {
"type": "string",
"enum": [
- "dashboard"
+ "dashboard",
+ "query"
],
- "description": "Entry type; currently only `dashboard` is supported."
+ "description": "Entry kind: `dashboard` opens a dashboard panel, `query` opens an Explore query. It decides whether `dashboard` or `query` must be supplied; supplying the other one is rejected."
+ },
+ "time_range": {
+ "$ref": "#/components/schemas/InvestigationTimeRange",
+ "description": "Window around the event time, required on every saved entry. A zero-length window is rejected; defaults belong to the editor."
+ },
+ "query": {
+ "$ref": "#/components/schemas/QueryInvestigationTarget",
+ "description": "Configuration for the `query` kind; required when `kind` is `query`, and rejected when `kind` is `dashboard`."
},
"dashboard": {
"$ref": "#/components/schemas/DashboardInvestigationTarget",
@@ -6238,7 +6248,8 @@
}
},
"required": [
- "kind"
+ "kind",
+ "time_range"
]
},
"DashboardInvestigationTarget": {
@@ -6253,37 +6264,103 @@
"type": "string",
"description": "Panel ID inside the dashboard; must be a canonical UUIDv7. Optional."
},
- "variable_bindings": {
+ "variables": {
"type": "object",
"additionalProperties": {
- "$ref": "#/components/schemas/InvestigationVariableBinding"
+ "type": "string"
},
- "description": "Dashboard variable bindings, keyed by dashboard variable name."
+ "description": "Dashboard variable values, keyed by variable name. Values may reference event labels through `{{ }}` templates; defaults to an empty object."
+ }
+ },
+ "required": [
+ "dashboard_id",
+ "variables"
+ ]
+ },
+ "InvestigationTimeRange": {
+ "type": "object",
+ "description": "Window around the alert event time, expressed as two offsets. Both directions must be non-negative and at least one must be greater than zero, so an entry never resolves to an empty window.",
+ "properties": {
+ "before_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "Seconds to look back from the event time."
+ },
+ "after_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "Seconds to look forward from the event time, so behaviour after the event stays visible."
}
},
"required": [
- "dashboard_id"
+ "before_seconds",
+ "after_seconds"
]
},
- "InvestigationVariableBinding": {
+ "QueryInvestigationTarget": {
"type": "object",
- "description": "Binding between a dashboard variable and alert event data.",
+ "description": "Explore query used by a `query` drill-down entry. The expression may reference event labels through `{{ }}` templates, while `args` values may not.",
"properties": {
- "source": {
+ "datasource_id": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740991,
+ "description": "Data source the query runs against."
+ },
+ "query": {
+ "$ref": "#/components/schemas/DashboardQuery",
+ "description": "Query payload."
+ }
+ },
+ "required": [
+ "datasource_id",
+ "query"
+ ]
+ },
+ "DashboardQuery": {
+ "type": "object",
+ "description": "Query payload shared by dashboards and drill-down entries.",
+ "properties": {
+ "mode": {
"type": "string",
"enum": [
- "event_label"
+ "instant",
+ "range",
+ "window"
],
- "description": "Where the bound value comes from; currently only `event_label` (the alert event's label value) is supported."
+ "description": "Evaluation mode: `instant` evaluates at a single timestamp, `range` evaluates a stepped series, `window` returns raw rows inside a time window."
},
- "key": {
+ "expr": {
"type": "string",
- "description": "Alert event label name; must follow Prometheus label naming rules and must not be a reserved label."
+ "description": "Query expression in the target data source's language. May reference event labels through `{{ }}` templates."
+ },
+ "args": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Named query arguments; defaults to an empty object. Values are passed through verbatim and must not contain `{{ }}` templates."
+ },
+ "min_step_seconds": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740,
+ "description": "Minimum step, in seconds. Only accepted when `mode` is `range`, and must be greater than zero; omit or pass null to let the server decide."
}
},
"required": [
- "source",
- "key"
+ "mode",
+ "expr",
+ "args"
]
}
}
diff --git a/api-reference/monitors.openapi.zh.json b/api-reference/monitors.openapi.zh.json
index 4cea844d..d5aa2d4d 100644
--- a/api-reference/monitors.openapi.zh.json
+++ b/api-reference/monitors.openapi.zh.json
@@ -5923,6 +5923,7 @@
"items": {
"$ref": "#/components/schemas/InvestigationTarget"
},
+ "maxItems": 20,
"description": "告警事件详情页关联的排障入口列表,最多 20 项,不允许重复。更新接口中该字段按 presence 处理:省略时保留原配置,传 `[]` 清空。",
"x-flashduty-preserve-absence": true
},
@@ -6223,14 +6224,23 @@
},
"InvestigationTarget": {
"type": "object",
- "description": "告警事件的关联排障入口,为封闭的 tagged union:新增类型需服务端显式支持。",
+ "description": "告警事件的关联排障入口,为封闭的 tagged union:新增类型需服务端显式支持,入口内出现未知字段会被拒绝。",
"properties": {
"kind": {
"type": "string",
"enum": [
- "dashboard"
+ "dashboard",
+ "query"
],
- "description": "排障入口类型,目前仅支持 `dashboard`。"
+ "description": "入口类型:`dashboard` 打开仪表盘面板,`query` 打开 Explore 查询。它决定必须提供 `dashboard` 还是 `query`,提供另一个会被拒绝。"
+ },
+ "time_range": {
+ "$ref": "#/components/schemas/InvestigationTimeRange",
+ "description": "事件时间前后的取数窗口,每个已保存的入口都必填。长度为 0 的窗口会被拒绝;默认值由前端编辑器提供。"
+ },
+ "query": {
+ "$ref": "#/components/schemas/QueryInvestigationTarget",
+ "description": "`query` 类型的入口配置;`kind` 为 `query` 时必填,`kind` 为 `dashboard` 时不允许出现。"
},
"dashboard": {
"$ref": "#/components/schemas/DashboardInvestigationTarget",
@@ -6238,7 +6248,8 @@
}
},
"required": [
- "kind"
+ "kind",
+ "time_range"
]
},
"DashboardInvestigationTarget": {
@@ -6253,37 +6264,103 @@
"type": "string",
"description": "仪表盘内目标面板 ID,须为规范的 UUIDv7;可选。"
},
- "variable_bindings": {
+ "variables": {
"type": "object",
"additionalProperties": {
- "$ref": "#/components/schemas/InvestigationVariableBinding"
+ "type": "string"
},
- "description": "仪表盘变量绑定,键为仪表盘变量名。"
+ "description": "仪表盘变量取值,键为变量名。值可通过 `{{ }}` 模板引用事件标签;默认空对象。"
+ }
+ },
+ "required": [
+ "dashboard_id",
+ "variables"
+ ]
+ },
+ "InvestigationTimeRange": {
+ "type": "object",
+ "description": "以两个偏移量表示告警事件时间前后的取数窗口。两个方向都必须非负,且至少一个大于 0,因此入口不会解析出空窗口。",
+ "properties": {
+ "before_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "相对事件时间向前回溯的秒数。"
+ },
+ "after_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "相对事件时间向后延伸的秒数,用于保留事件发生后的表现。"
}
},
"required": [
- "dashboard_id"
+ "before_seconds",
+ "after_seconds"
]
},
- "InvestigationVariableBinding": {
+ "QueryInvestigationTarget": {
"type": "object",
- "description": "仪表盘变量与告警事件数据的绑定。",
+ "description": "`query` 类型入口使用的 Explore 查询。表达式可通过 `{{ }}` 模板引用事件标签,`args` 的值不允许包含模板。",
"properties": {
- "source": {
+ "datasource_id": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740991,
+ "description": "查询所用的数据源。"
+ },
+ "query": {
+ "$ref": "#/components/schemas/DashboardQuery",
+ "description": "查询内容。"
+ }
+ },
+ "required": [
+ "datasource_id",
+ "query"
+ ]
+ },
+ "DashboardQuery": {
+ "type": "object",
+ "description": "仪表盘与排障入口共用的查询内容。",
+ "properties": {
+ "mode": {
"type": "string",
"enum": [
- "event_label"
+ "instant",
+ "range",
+ "window"
],
- "description": "绑定值来源,目前仅支持 `event_label`(取告警事件的标签值)。"
+ "description": "求值模式:`instant` 在单个时间点求值,`range` 求值一条按步长采样的曲线,`window` 返回时间窗口内的原始数据。"
},
- "key": {
+ "expr": {
"type": "string",
- "description": "告警事件标签名,须符合 Prometheus 标签命名规则,且不能使用保留标签。"
+ "description": "目标数据源语法下的查询表达式,可通过 `{{ }}` 模板引用事件标签。"
+ },
+ "args": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "命名查询参数,默认空对象。值按原样透传,不允许包含 `{{ }}` 模板。"
+ },
+ "min_step_seconds": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740,
+ "description": "最小步长(秒)。仅在 `mode` 为 `range` 时可用,且必须大于 0;省略或传 null 由服务端决定。"
}
},
"required": [
- "source",
- "key"
+ "mode",
+ "expr",
+ "args"
]
}
}
diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json
index 6f739801..9dd1b6dc 100644
--- a/api-reference/openapi.en.json
+++ b/api-reference/openapi.en.json
@@ -3494,7 +3494,8 @@
},
"limit": {
"default": 20,
- "description": "Page size.",
+ "description": "Page size. Values below 1 fall back to 20; values above 200 are capped at 200.",
+ "maximum": 200,
"type": "integer"
},
"p": {
@@ -28641,6 +28642,7 @@
"items": {
"$ref": "#/components/schemas/InvestigationTarget"
},
+ "maxItems": 20,
"description": "Drill-down entries linked from the alert event detail page; at most 20 items, duplicates rejected. On update the field is presence-based: omit it to keep the current value, pass `[]` to clear.",
"x-flashduty-preserve-absence": true
},
@@ -28941,14 +28943,23 @@
},
"InvestigationTarget": {
"type": "object",
- "description": "Drill-down entry linked to alert events. A deliberately closed tagged union: new kinds require explicit server support.",
+ "description": "Alert-event drill-down entry. A deliberately closed tagged union: new kinds require explicit server support, and unknown fields inside a target are rejected.",
"properties": {
"kind": {
"type": "string",
"enum": [
- "dashboard"
+ "dashboard",
+ "query"
],
- "description": "Entry type; currently only `dashboard` is supported."
+ "description": "Entry kind: `dashboard` opens a dashboard panel, `query` opens an Explore query. It decides whether `dashboard` or `query` must be supplied; supplying the other one is rejected."
+ },
+ "time_range": {
+ "$ref": "#/components/schemas/InvestigationTimeRange",
+ "description": "Window around the event time, required on every saved entry. A zero-length window is rejected; defaults belong to the editor."
+ },
+ "query": {
+ "$ref": "#/components/schemas/QueryInvestigationTarget",
+ "description": "Configuration for the `query` kind; required when `kind` is `query`, and rejected when `kind` is `dashboard`."
},
"dashboard": {
"$ref": "#/components/schemas/DashboardInvestigationTarget",
@@ -28956,7 +28967,8 @@
}
},
"required": [
- "kind"
+ "kind",
+ "time_range"
]
},
"DashboardInvestigationTarget": {
@@ -28971,37 +28983,103 @@
"type": "string",
"description": "Panel ID inside the dashboard; must be a canonical UUIDv7. Optional."
},
- "variable_bindings": {
+ "variables": {
"type": "object",
"additionalProperties": {
- "$ref": "#/components/schemas/InvestigationVariableBinding"
+ "type": "string"
},
- "description": "Dashboard variable bindings, keyed by dashboard variable name."
+ "description": "Dashboard variable values, keyed by variable name. Values may reference event labels through `{{ }}` templates; defaults to an empty object."
}
},
"required": [
- "dashboard_id"
+ "dashboard_id",
+ "variables"
]
},
- "InvestigationVariableBinding": {
+ "InvestigationTimeRange": {
"type": "object",
- "description": "Binding between a dashboard variable and alert event data.",
+ "description": "Window around the alert event time, expressed as two offsets. Both directions must be non-negative and at least one must be greater than zero, so an entry never resolves to an empty window.",
"properties": {
- "source": {
+ "before_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "Seconds to look back from the event time."
+ },
+ "after_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "Seconds to look forward from the event time, so behaviour after the event stays visible."
+ }
+ },
+ "required": [
+ "before_seconds",
+ "after_seconds"
+ ]
+ },
+ "QueryInvestigationTarget": {
+ "type": "object",
+ "description": "Explore query used by a `query` drill-down entry. The expression may reference event labels through `{{ }}` templates, while `args` values may not.",
+ "properties": {
+ "datasource_id": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740991,
+ "description": "Data source the query runs against."
+ },
+ "query": {
+ "$ref": "#/components/schemas/DashboardQuery",
+ "description": "Query payload."
+ }
+ },
+ "required": [
+ "datasource_id",
+ "query"
+ ]
+ },
+ "DashboardQuery": {
+ "type": "object",
+ "description": "Query payload shared by dashboards and drill-down entries.",
+ "properties": {
+ "mode": {
"type": "string",
"enum": [
- "event_label"
+ "instant",
+ "range",
+ "window"
],
- "description": "Where the bound value comes from; currently only `event_label` (the alert event's label value) is supported."
+ "description": "Evaluation mode: `instant` evaluates at a single timestamp, `range` evaluates a stepped series, `window` returns raw rows inside a time window."
},
- "key": {
+ "expr": {
"type": "string",
- "description": "Alert event label name; must follow Prometheus label naming rules and must not be a reserved label."
+ "description": "Query expression in the target data source's language. May reference event labels through `{{ }}` templates."
+ },
+ "args": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Named query arguments; defaults to an empty object. Values are passed through verbatim and must not contain `{{ }}` templates."
+ },
+ "min_step_seconds": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740,
+ "description": "Minimum step, in seconds. Only accepted when `mode` is `range`, and must be greater than zero; omit or pass null to let the server decide."
}
},
"required": [
- "source",
- "key"
+ "mode",
+ "expr",
+ "args"
]
},
"MemberNotifyRequest": {
diff --git a/api-reference/openapi.zh.json b/api-reference/openapi.zh.json
index 401b058d..bf27ecab 100644
--- a/api-reference/openapi.zh.json
+++ b/api-reference/openapi.zh.json
@@ -3494,7 +3494,8 @@
},
"limit": {
"default": 20,
- "description": "每页数量。",
+ "description": "每页数量。小于 1 时回退为 20,大于 200 时按 200 处理。",
+ "maximum": 200,
"type": "integer"
},
"p": {
@@ -28641,6 +28642,7 @@
"items": {
"$ref": "#/components/schemas/InvestigationTarget"
},
+ "maxItems": 20,
"description": "告警事件详情页关联的排障入口列表,最多 20 项,不允许重复。更新接口中该字段按 presence 处理:省略时保留原配置,传 `[]` 清空。",
"x-flashduty-preserve-absence": true
},
@@ -28941,14 +28943,23 @@
},
"InvestigationTarget": {
"type": "object",
- "description": "告警事件的关联排障入口,为封闭的 tagged union:新增类型需服务端显式支持。",
+ "description": "告警事件的关联排障入口,为封闭的 tagged union:新增类型需服务端显式支持,入口内出现未知字段会被拒绝。",
"properties": {
"kind": {
"type": "string",
"enum": [
- "dashboard"
+ "dashboard",
+ "query"
],
- "description": "排障入口类型,目前仅支持 `dashboard`。"
+ "description": "入口类型:`dashboard` 打开仪表盘面板,`query` 打开 Explore 查询。它决定必须提供 `dashboard` 还是 `query`,提供另一个会被拒绝。"
+ },
+ "time_range": {
+ "$ref": "#/components/schemas/InvestigationTimeRange",
+ "description": "事件时间前后的取数窗口,每个已保存的入口都必填。长度为 0 的窗口会被拒绝;默认值由前端编辑器提供。"
+ },
+ "query": {
+ "$ref": "#/components/schemas/QueryInvestigationTarget",
+ "description": "`query` 类型的入口配置;`kind` 为 `query` 时必填,`kind` 为 `dashboard` 时不允许出现。"
},
"dashboard": {
"$ref": "#/components/schemas/DashboardInvestigationTarget",
@@ -28956,7 +28967,8 @@
}
},
"required": [
- "kind"
+ "kind",
+ "time_range"
]
},
"DashboardInvestigationTarget": {
@@ -28971,37 +28983,103 @@
"type": "string",
"description": "仪表盘内目标面板 ID,须为规范的 UUIDv7;可选。"
},
- "variable_bindings": {
+ "variables": {
"type": "object",
"additionalProperties": {
- "$ref": "#/components/schemas/InvestigationVariableBinding"
+ "type": "string"
},
- "description": "仪表盘变量绑定,键为仪表盘变量名。"
+ "description": "仪表盘变量取值,键为变量名。值可通过 `{{ }}` 模板引用事件标签;默认空对象。"
}
},
"required": [
- "dashboard_id"
+ "dashboard_id",
+ "variables"
]
},
- "InvestigationVariableBinding": {
+ "InvestigationTimeRange": {
"type": "object",
- "description": "仪表盘变量与告警事件数据的绑定。",
+ "description": "以两个偏移量表示告警事件时间前后的取数窗口。两个方向都必须非负,且至少一个大于 0,因此入口不会解析出空窗口。",
"properties": {
- "source": {
+ "before_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "相对事件时间向前回溯的秒数。"
+ },
+ "after_seconds": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 0,
+ "maximum": 9007199254740,
+ "description": "相对事件时间向后延伸的秒数,用于保留事件发生后的表现。"
+ }
+ },
+ "required": [
+ "before_seconds",
+ "after_seconds"
+ ]
+ },
+ "QueryInvestigationTarget": {
+ "type": "object",
+ "description": "`query` 类型入口使用的 Explore 查询。表达式可通过 `{{ }}` 模板引用事件标签,`args` 的值不允许包含模板。",
+ "properties": {
+ "datasource_id": {
+ "type": "integer",
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740991,
+ "description": "查询所用的数据源。"
+ },
+ "query": {
+ "$ref": "#/components/schemas/DashboardQuery",
+ "description": "查询内容。"
+ }
+ },
+ "required": [
+ "datasource_id",
+ "query"
+ ]
+ },
+ "DashboardQuery": {
+ "type": "object",
+ "description": "仪表盘与排障入口共用的查询内容。",
+ "properties": {
+ "mode": {
"type": "string",
"enum": [
- "event_label"
+ "instant",
+ "range",
+ "window"
],
- "description": "绑定值来源,目前仅支持 `event_label`(取告警事件的标签值)。"
+ "description": "求值模式:`instant` 在单个时间点求值,`range` 求值一条按步长采样的曲线,`window` 返回时间窗口内的原始数据。"
},
- "key": {
+ "expr": {
"type": "string",
- "description": "告警事件标签名,须符合 Prometheus 标签命名规则,且不能使用保留标签。"
+ "description": "目标数据源语法下的查询表达式,可通过 `{{ }}` 模板引用事件标签。"
+ },
+ "args": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "命名查询参数,默认空对象。值按原样透传,不允许包含 `{{ }}` 模板。"
+ },
+ "min_step_seconds": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "format": "int64",
+ "minimum": 1,
+ "maximum": 9007199254740,
+ "description": "最小步长(秒)。仅在 `mode` 为 `range` 时可用,且必须大于 0;省略或传 null 由服务端决定。"
}
},
"required": [
- "source",
- "key"
+ "mode",
+ "expr",
+ "args"
]
},
"MemberNotifyRequest": {
diff --git a/api-reference/safari.openapi.en.json b/api-reference/safari.openapi.en.json
index 8c513b5e..f47afcc5 100644
--- a/api-reference/safari.openapi.en.json
+++ b/api-reference/safari.openapi.en.json
@@ -5816,7 +5816,8 @@
"limit": {
"type": "integer",
"default": 20,
- "description": "Page size."
+ "description": "Page size. Values below 1 fall back to 20; values above 200 are capped at 200.",
+ "maximum": 200
},
"scope": {
"type": "string",
diff --git a/api-reference/safari.openapi.zh.json b/api-reference/safari.openapi.zh.json
index be93ac17..98bd246b 100644
--- a/api-reference/safari.openapi.zh.json
+++ b/api-reference/safari.openapi.zh.json
@@ -5816,7 +5816,8 @@
"limit": {
"type": "integer",
"default": 20,
- "description": "每页数量。"
+ "description": "每页数量。小于 1 时回退为 20,大于 200 时按 200 处理。",
+ "maximum": 200
},
"scope": {
"type": "string",
From cc40de6a4a5e9ec14f5fc764410908b1a76d0d9d Mon Sep 17 00:00:00 2001
From: pijiang <419471640@qq.com>
Date: Wed, 16 Sep 2026 16:34:08 +0800
Subject: [PATCH 12/14] docs: update aliyun dataworks op alert key semantics
and display name
---
.../alert-sources/aliyun-dataworks-op.mdx | 15 +++------------
.../alert-sources/aliyun-dataworks-op.mdx | 17 ++++-------------
2 files changed, 7 insertions(+), 25 deletions(-)
diff --git a/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx b/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
index 1593d8d8..c865c0f3 100644
--- a/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
+++ b/en/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
@@ -20,7 +20,7 @@ Choose this option when you do not need to route alert events to different colla
1. Go to the Flashduty console, select **Collaboration Spaces**, and open a space's detail page
2. Select the **Integrated Data** tab, click **Add an integration**, and open the add-integration page
- 3. Select the **Alibaba Cloud DataWorks** integration and click **Save** to generate a card
+ 3. Select the **Alibaba Cloud DataWorks Operation Center** integration and click **Save** to generate a card
4. Click the card to view the **push URL**, copy it for later use, and you are done
@@ -35,7 +35,7 @@ Choose this option when you need to route alerts to different collaboration spac
1. Go to the Flashduty console and select **Integration Center => Alert Events** to open the integration selection page
- 2. Select the **Alibaba Cloud DataWorks** integration:
+ 2. Select the **Alibaba Cloud DataWorks Operation Center** integration:
- **Integration name**: define a name for this integration
3. Configure the default route and select the corresponding collaboration space (after creation, you can go to `Routing` to configure more routing rules)
4. Click **Save**, then copy the newly generated **push URL** on the current page for later use
@@ -127,16 +127,7 @@ Mapping from event alert `event_type`:
DataWorks Intelligent Monitoring webhooks are **one-shot events**: the official protocol defines alert notifications only, with **no recovery** or update semantics, and it provides no vendor-level deduplication ID or fingerprint field. Therefore this integration never automatically recovers (closes) any alert; every event is delivered in a triggered state.
-So that repeated triggers from the same rule and the same monitored object can be merged for noise reduction, Flashduty derives the Alert Key from immutable identity fields in the message:
-
-| Alert family | Alert Key components |
-| ------------ | -------------------- |
-| Custom alert (task-based) | title + remind_name + node_id_list |
-| Custom alert (resource group) | title + remind_name + resource_group_name |
-| Baseline alert | title + baseline_name + key_instance |
-| Event alert | title + task_name + event_type |
-
-Note: `event_name` contains the business date and cycle ID (different every cycle), so it is excluded from the Alert Key; consecutive failures of the same task across cycles merge into one alert. Fields that change on every delivery, such as `occur_time` and `number_of_alerts`, are excluded as well.
+Every webhook delivery receives a fresh random UUID as its Alert Key, so each push creates an independent alert event and repeated triggers are not merged automatically. To reduce noise, configure alert grouping or convergence policies in Flashduty.
diff --git a/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx b/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
index c80789ee..6088caf0 100644
--- a/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
+++ b/zh/on-call/integration/alert-integration/alert-sources/aliyun-dataworks-op.mdx
@@ -1,5 +1,5 @@
---
-title: "阿里云 DataWorks 集成"
+title: "DataWorks 运维中心集成"
description: "通过自定义 Webhook 的方式同步阿里云 DataWorks 智能监控(运维中心)告警事件到 Flashduty On-call,实现告警事件自动化降噪处理"
keywords: ["告警集成", "阿里云 DataWorks 集成", "DataWorks 智能监控", "运维中心", "监控告警", "数据接入"]
---
@@ -20,7 +20,7 @@ keywords: ["告警集成", "阿里云 DataWorks 集成", "DataWorks 智能监控
1. 进入 Flashduty 控制台,选择 **协作空间**,进入某个空间的详情页面
2. 选择 **集成数据** tab,点击 **添加一个集成**,进入添加集成页面
- 3. 选择 **阿里云 DataWorks** 集成,点击 **保存**,生成卡片。
+ 3. 选择 **DataWorks 运维中心** 集成,点击 **保存**,生成卡片。
4. 点击生成的卡片,可以查看到 **推送地址**,复制备用,完成。
@@ -35,7 +35,7 @@ keywords: ["告警集成", "阿里云 DataWorks 集成", "DataWorks 智能监控
1. 进入 Flashduty 控制台,选择 **集成中心=>告警事件**,进入集成选择页面。
- 2. 选择 **阿里云 DataWorks** 集成:
+ 2. 选择 **DataWorks 运维中心** 集成:
- **集成名称**:为当前集成定义一个名称。
3. 配置默认路由,并选择对应的协作空间(集成创建后可以前往 `路由` 进行更多路由规则的配置)。
4. 点击 **保存** 后,复制当前页面的新生成的 **推送地址** 备用。
@@ -127,16 +127,7 @@ DataWorks 自定义告警 `remind_type` 到 Flashduty 告警等级(Severity)
DataWorks 智能监控 Webhook 属于**一次性事件**(one-shot):官方协议只定义告警通知,**不恢复**、无更新语义,也没有提供厂商级别的去重 ID 或指纹字段。因此本集成不会自动恢复(关闭)任何告警,所有事件均以触发状态投递。
-为了让同一规则、同一监控对象的重复触发能够自动合并降噪,Flashduty 从消息的不可变身份字段派生 Alert Key:
-
-| 告警类型 | Alert Key 组成 |
-| -------- | -------------- |
-| 自定义告警(任务类) | title + remind_name + node_id_list |
-| 自定义告警(资源组类) | title + remind_name + resource_group_name |
-| 基线告警 | title + baseline_name + key_instance |
-| 事件告警 | title + task_name + event_type |
-
-注意:`event_name` 包含业务日期与周期 ID(每个周期不同),不参与 Alert Key 计算;因此同一任务连续多个周期失败会合并到同一条告警中。`occur_time`、`number_of_alerts` 等每次推送都会变化的字段也不参与计算。
+每次 webhook 投递都会生成一个全新的随机 UUID 作为 Alert Key,即每条推送都会创建一条独立的告警事件,重复触发不会自动合并。如需降噪,请在 Flashduty 中配置告警聚合或收敛策略。
From f0a44c585e2f0f4d5beae8033d081329144a5e85 Mon Sep 17 00:00:00 2001
From: "flashduty[bot]"
Date: Wed, 16 Sep 2026 08:44:16 +0000
Subject: [PATCH 13/14] =?UTF-8?q?docs:=20daily=20doc-review=202026-09-16?=
=?UTF-8?q?=20=E2=80=94=2031=20findings=20(4=20high=20/=2015=20medium=20/?=
=?UTF-8?q?=2012=20low)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Window: 2026-09-15T08:18:21Z -> 2026-09-16T08:05Z (diff mode, scope all).
Covers the AI SRE paid launch, the plugin-catalog/connect-dialog rework,
edge engine server-pushed auto-upgrade, incident-timeline 接续对话 entry,
and the on-call war-room switch / datasource ${env:} coverage fixes.
zh first, en derived; no file renames, so no redirects needed.
---
en/ai-sre/apps.mdx | 2 +-
en/ai-sre/artifacts.mdx | 2 ++
en/ai-sre/automations.mdx | 2 +-
en/ai-sre/im.mdx | 15 ++++++++
en/ai-sre/knowledge.mdx | 17 +++++++--
en/ai-sre/mcp.mdx | 33 ++++++++++-------
en/ai-sre/overview.mdx | 15 +++++++-
en/ai-sre/sessions.mdx | 36 ++++++++++++++++++-
en/ai-sre/skills.mdx | 29 ++++++++-------
en/changelog/changelog.mdx | 31 ++++++++++++++++
en/monitors/data-sources/data-sources.mdx | 10 ++++++
en/monitors/engine/engine.mdx | 28 +++++++++++++++
en/on-call/advanced/war-room.mdx | 2 +-
en/on-call/channel/escalation-rule.mdx | 2 +-
en/on-call/configuration/schedule.mdx | 2 +-
en/on-call/configuration/templates.mdx | 8 +++--
.../incident/escalate-dispatch-incident.mdx | 2 +-
en/on-call/incident/search-view-incident.mdx | 9 +++++
en/on-call/quickstart/mobile-app.mdx | 2 ++
zh/ai-sre/apps.mdx | 2 +-
zh/ai-sre/artifacts.mdx | 2 ++
zh/ai-sre/automations.mdx | 2 +-
zh/ai-sre/im.mdx | 15 ++++++++
zh/ai-sre/knowledge.mdx | 17 +++++++--
zh/ai-sre/mcp.mdx | 33 ++++++++++-------
zh/ai-sre/overview.mdx | 15 +++++++-
zh/ai-sre/sessions.mdx | 36 ++++++++++++++++++-
zh/ai-sre/skills.mdx | 27 ++++++++------
zh/changelog/changelog.mdx | 31 ++++++++++++++++
zh/monitors/data-sources/data-sources.mdx | 10 ++++++
zh/monitors/engine/engine.mdx | 28 +++++++++++++++
zh/on-call/advanced/war-room.mdx | 2 +-
zh/on-call/channel/escalation-rule.mdx | 2 +-
zh/on-call/configuration/schedule.mdx | 2 +-
zh/on-call/configuration/templates.mdx | 8 +++--
.../incident/escalate-dispatch-incident.mdx | 2 +-
zh/on-call/incident/search-view-incident.mdx | 9 +++++
zh/on-call/quickstart/mobile-app.mdx | 2 ++
38 files changed, 419 insertions(+), 73 deletions(-)
diff --git a/en/ai-sre/apps.mdx b/en/ai-sre/apps.mdx
index 7961befe..6f1edfb4 100644
--- a/en/ai-sre/apps.mdx
+++ b/en/ai-sre/apps.mdx
@@ -31,7 +31,7 @@ AI SRE sessions run in a **Flashduty cloud sandbox** by default. The sandbox is
---
-Go to **Plugins → Apps**. Apps is the **first and default** tab in the Plugins area — opening Plugins lands you here.
+Go to **Plugins → Apps**. Opening the Plugins area lands on the **Overview** tab by default; Apps is one of its tabs (the tab order is Overview / Apps / Skill / MCP / Agents).
Viewing the Apps tab requires the appropriate permission; without it, the tab is hidden. Authorizing, disconnecting / revoking, and enabling / disabling each require their own action permission — when you lack one, the corresponding button is shown disabled.
diff --git a/en/ai-sre/artifacts.mdx b/en/ai-sre/artifacts.mdx
index 852600d7..448be8fd 100644
--- a/en/ai-sre/artifacts.mdx
+++ b/en/ai-sre/artifacts.mdx
@@ -60,6 +60,8 @@ The top-right of the list page offers a **Card view / List view** toggle; your c
The **Created at** and **Updated at** columns support header sorting (ascending / descending toggle); sorting is executed server-side, with **Updated at descending** as the default.
+Scope, search term, sorting, and page number are all reflected in the page URL (for example `?scope=team&teams=1,2&q=rebuild&page=2`), so copying the address shares or bookmarks a **filtered** list; returning from an artifact's detail page also lands back on the same filters and position instead of resetting to the default view.
+
### Artifact cards
Each card shows:
diff --git a/en/ai-sre/automations.mdx b/en/ai-sre/automations.mdx
index aa3fd513..ca06040f 100644
--- a/en/ai-sre/automations.mdx
+++ b/en/ai-sre/automations.mdx
@@ -170,7 +170,7 @@ If you create or update a rule through the API, use these fields:
When a matching event arrives, the system creates a run with `trigger_kind: "oncall_incident"` and passes event context such as `incident_id`, `channel_id`, and `severity` into the session. The same trigger and the same `incident_id` reuse the same run, avoiding duplicate hidden sessions for one incident.
-When the run finishes, AI SRE writes one summary comment back to the incident that triggered it: conclusion first, body kept concise, with a link to the full session at the end. The comment travels through the incident's existing notification chain (for example, incident card refreshes and thread replies in IM), so whoever is watching the incident sees the analysis without opening the console. This applies to every rule with the On-call incident trigger enabled — including rules with custom prompts — with no extra configuration.
+When the run finishes, AI SRE writes one summary comment back to the incident that triggered it: conclusion first, body kept concise, with a link to the full session at the end. That write-back record also carries a persistent **Continue conversation** entry, so you can open that session straight from the conclusion on the incident timeline — see [Incident Timeline · AI SRE Action Records](/en/on-call/incident/search-view-incident#ai-sre-action-records). The comment travels through the incident's existing notification chain (for example, incident card refreshes and thread replies in IM), so whoever is watching the incident sees the analysis without opening the console. This applies to every rule with the On-call incident trigger enabled — including rules with custom prompts — with no extra configuration.
## Run History
diff --git a/en/ai-sre/im.mdx b/en/ai-sre/im.mdx
index ac98587b..caeb7410 100644
--- a/en/ai-sre/im.mdx
+++ b/en/ai-sre/im.mdx
@@ -120,6 +120,21 @@ While any standing task is alive, the IM session's root message stays open (the
Notification rounds follow a silent "no message = no news" semantics: if a notification round has nothing new to deliver, AI SRE closes that round silently — **no placeholder receipt** is posted to the chat, and the monitoring card is not re-posted either. A new message appears in the chat only when there is a real new finding.
+## Connections and Authorization
+
+---
+
+When a credential is missing, the console renders inline cards (**"Authorize [resource name] to continue"**, **"Connect [vendor] to continue"** — see [Console](/en/ai-sre/sessions#when-authorization-is-required)). **IM and API channels get no card** — the agent hands the matter to you according to this session's channel, as follows:
+
+| Situation | Behavior on IM / API channels |
+| --- | --- |
+| Your OAuth authorization is missing (`per_user_oauth`) | The agent pastes the authorize link into the chat as a plain message (not a card); open it in a **desktop / PC browser** to complete the authorization, then reply **"已授权"** (or `authorized` in an English session) to continue. Continuing is your explicit action — a successful OAuth callback does not resume the task by itself |
+| Your secret-type credential is missing (`per_user_secret`) | There is no safe way to collect it over IM: the agent simply tells you to open **this same session in the web console** and complete it there. It never asks you to paste the secret into the chat, and never points you at a settings page instead |
+| The whole connection is missing (in the marketplace catalog, not connected in the account) | The agent gives the connect URL (a deep link into the console's plugins page) as a plain link; connect, then reply **"继续"** (or `continue`) to carry on |
+| A shared server's own credentials (environment variables / headers) | Not any of the above: fill them in under **Plugins → MCP** (that server), then tell the agent to retry |
+
+On the automation channel nobody is watching and no reply will ever arrive: the agent does not wait and does not phrase anything as a question — it **records the missing connection or authorization as a blocker** in its final report and delivers whatever the evidence already supports.
+
## In-session Switch Commands
---
diff --git a/en/ai-sre/knowledge.mdx b/en/ai-sre/knowledge.mdx
index 36c7b0cd..c9008d08 100644
--- a/en/ai-sre/knowledge.mdx
+++ b/en/ai-sre/knowledge.mdx
@@ -71,11 +71,24 @@ After reading `DUTY.md`, the agent decides which `@references` to expand based o
---
-Go to the **Knowledges** management page to create, edit, enable/disable, or delete Knowledge Packs for your account or teams. The list shows each pack's **Name / Scope / Files / Status / Actions**, and a scope filter at the top lets you switch between Shared and Team views.
+Go to the **Knowledges** management page to create, edit, enable/disable, or delete Knowledge Packs for your account or teams. Once packs exist, the list shows each pack's **Name / Scope / Files / Status / Actions**, and a scope filter at the top lets you switch between Shared and Team views.
+
+**First visit (empty state)**: when the current scope has no Knowledge Pack and the account has none at all, the page is taken over by the empty state. It lists five sources that can be drafted automatically — **Code repositories** (services, dependencies, tech stack), **Deployment topology** (environments, clusters, workloads), **Infrastructure** (cloud accounts, databases, middleware), **Changes** (releases and config changes), and **Monitoring** (metrics, logs, alert rules) — each showing how much has already been read from your connected tools and from Flashduty (labels like "N repositories", "N clusters", "N connections", "N in the last 30 days"); a source with nothing yet shows **Connect →**, which jumps to the plugins page to connect it. Below the cards the page notes that unconnected parts are left blank and can be filled in later, and that schedules, escalation rules, and handling records are read straight from Flashduty with no connection needed.
+
+While the empty state owns the page, the only two ways to start a pack are its own buttons:
+
+| Entry | Behavior |
+| --- | --- |
+| **Initialize AI-SRE** | Opens a new AI SRE session and **sends** `/init` immediately: the agent drafts content from those five sources and saves it after confirming each item with you |
+| **Upload existing documents** | Opens a new AI SRE session with `/init` **pre-filled** in the input box (not sent) and the attachment picker open, so you can hand existing documents to the agent for distillation |
+
+**While the empty state owns the page, the 创建 (Create) button in the page header, the scope switcher, and the search box all disappear**: there is nothing to filter over, and a second entry point would only compete with the two buttons in the empty state. Once a pack exists the page returns to its regular layout — **Create** in the top-right corner, the scope filter and search at the top. When you enter within a team scope, the two empty-state entries bind the new session to that selected team.
+
+If you lack account-level edit permission, account scope shows a one-liner — "no account knowledge base yet" — instead of the full empty state; the toolbar stays, so you can switch to a team scope and inspect that team's pack.
- Click **Create** in the top-right corner of the page to open the "Create knowledge base" dialog. A Knowledge Pack has no editable name of its own — it's a singleton resource per target (account or team), so the dialog only asks you to choose a **Scope**: Shared or a specific team. To create a team-level pack, you must belong to the target team; Shared-scope creation is limited to the Account Owner or admins. Each target can own only one pack. Accounts and teams that already have a pack remain in the dropdown and are marked as having an existing Knowledge Pack; after you select one, the primary button becomes **Open knowledge base** and opens that pack instead of creating another. Choose a scope without a pack and click **Create** to make one. The console checks again immediately before creation, so if someone else has just created a pack for that scope, it opens the existing pack instead. The console uses the scope (Shared / team name) as the pack's display identifier.
+ Click **Create** in the top-right corner of the page (this button appears only once a pack already exists — see the empty-state note above) to open the "Create knowledge base" dialog. A Knowledge Pack has no editable name of its own — it's a singleton resource per target (account or team), so the dialog only asks you to choose a **Scope**: Shared or a specific team. To create a team-level pack, you must belong to the target team; Shared-scope creation is limited to the Account Owner or admins. Each target can own only one pack. Accounts and teams that already have a pack remain in the dropdown and are marked as having an existing Knowledge Pack; after you select one, the primary button becomes **Open knowledge base** and opens that pack instead of creating another. Choose a scope without a pack and click **Create** to make one. The console checks again immediately before creation, so if someone else has just created a pack for that scope, it opens the existing pack instead. The console uses the scope (Shared / team name) as the pack's display identifier.
Click any row in the list to open the inspector. The left panel shows the file tree; the right panel is an inline editor. Click **New File** to enter a filename (e.g., `runbook.md`), or use **Upload** to import a local file. Markdown files support both **Preview** and **Source** views. Click **Save** after editing.
diff --git a/en/ai-sre/mcp.mdx b/en/ai-sre/mcp.mdx
index 8ae3b3d6..a68e5500 100644
--- a/en/ai-sre/mcp.mdx
+++ b/en/ai-sre/mcp.mdx
@@ -43,38 +43,43 @@ In AI SRE, MCP extends an agent's capability from "built-in tools" to "any exter
---
-Go to **Plugins → MCP** and click **Browse Marketplace** to open the **MCP Directory**, where you can browse Flashduty's curated selection of third-party MCP server templates.
+Go to **Plugins → Overview** to see Flashduty's curated catalog of third-party MCP templates. The catalog is grouped into category tabs (All / Observability / Cloud & Infrastructure / Database & Middleware / Code & Collaboration / Skill), and the search box in the top-right corner filters it by name or description.
+
+The **Recommended** block above the catalog ("Recommended from your alert sources and common usage. Once connected, AI SRE can use them during investigations.") picks the templates that match the **alert integrations already configured** in your account (ranked by alert count over the last 30 days), then fills in the picks promoted for your current locale, showing at most 3. Installed templates, templates that need a Runner, and templates you may not install never appear here.
-
- Click **Browse Marketplace** on the MCP list page to open a directory dialog that displays all available MCP server templates in a card grid. Each card shows the MCP server name, author, description, and tags.
+
+ Each catalog row shows the template name and description; when MCP / App / Skill rows are mixed on the same screen, the row also carries a kind tag. An uninstalled row has a round **+** button on its right: clicking **+** or clicking the row itself opens the **Connect** dialog. When a template needs a self-hosted Runner and the account has no Runner available, the row's tag reads **Requires a self-hosted runner**; for a template you may not install, the row shows no **+** and is not clickable.
-
- Click any MCP server card to open the detail view, which shows the full description, transport, authorization mode, whether a BYOC Runner is required, the vendor, connection parameter documentation, and a link to the vendor's official docs. Cards for already-installed MCP servers display a gear icon; clicking it takes you directly to that server's edit form.
+
+ The dialog first shows the template's details: the vendor ("Official Datadog · MCP" or "Community · MCP"), a link to its official docs, its description, and a set of "**Ask things like this once connected**" example questions. Then come the connection parameters the template declares — URL / endpoint placeholders and environment variables. **Shared** fields (shared account-wide under service authorization) are labelled "Shared by the whole account."; in **Member authorization (key)** mode there is also a "**Your API token**" field (a password input) labelled "Only for your own use — other members fill in their own the first time they use it.", with a "How to get one" docs link beside it.
-
- For MCP servers not yet installed, click the **Install** button on the card. The system opens a new AI SRE session and injects the server's template metadata. The agent then guides you through entering the endpoint URL, completing credential authorization, and calls `tool_search` (probing the server's tools by name) to verify connectivity — the entire install flow happens **inside the conversation**, not through a one-click write to the database.
+
+ Choose the **execution environment** this connection should be made from — "Connects in the session's own environment by default."; for a template that needs a self-hosted Runner, the hint reads "If 〈name〉 is only reachable on your internal network, pick a self-hosted Runner on that network." The primary button is **Connect**; for a **Member authorization (OAuth)** template it reads "**Authorize 〈name〉**" and creates the connector first, then opens the browser authorization window (OAuth discovery, Dynamic Client Registration, and token exchange all run from the chosen environment).
-
- Once the agent verifies connectivity, it writes the MCP server into the account via the `/safari/mcp/server/create` endpoint. The server then appears in the MCP list and is marked as "Installed" on the catalog card.
+
+ On submit, the system creates the connector and runs one connection test against it. On success the dialog shows "**〈name〉 connected**" plus the example questions: click **Done** to close it, or click an example question to open a new chat with that question **prefilled** (it is not sent automatically). On failure it shows "**The connection test failed**" with the raw error: click **Retry** to re-run the test; for a template that needs a Runner, a non-cloud environment also offers a "Let AI SRE install it on the Runner" entry, which opens a new chat that carries no token and asks the agent to install the missing command-line tools (`npx`'s Node.js, `uvx`'s uv) on the self-hosted Runner.
-The marketplace directory is **browse-only** — there is no one-click install endpoint. This is intentional: installing an MCP server must involve credential entry and connectivity verification. Skipping those steps would leave dead configurations in the account that can never actually connect. Conversational install ensures every MCP server has been validated by a real agent invocation before it is considered ready.
+The dialog creates the connector on the **first submit only**. After that its connection parameters are locked, and it shows "This connector already exists, created from the values you first submitted. To change them, edit it under Plugins → MCP." When the name collides with a connector that already exists, the dialog no longer echoes the backend error and instead shows "This account already has a connector named “〈name〉”. If that is the one you want, finish authorizing it under Plugins → MCP; otherwise an account owner or admin has to rename or delete it there first, then connect again."
Installed MCP servers record a `source_template_name` field that points back to the originating template, making it easy to trace the server's provenance later. **Marketplace-installed MCP servers are fixed to Shared scope** (account-level, `team_id` is 0) and available to all members of the account; no team owner can be chosen at install time, and the same template can only produce one instance per account.
-MCP servers marked **requires Runner** (shown by the `requires_runner` flag in the detail view; `requires_runner` is independent of transport, and the entire current curated catalog is HTTP Streaming and needs no Runner) can only be used in environments where you have a BYOC Runner deployed; cloud Sandboxes do not support them. Before installing, confirm your account has a working BYOC Runner configured. See [Environments (BYOC)](/en/ai-sre/environments).
+A template that **requires a Runner** (the `requires_runner` flag in its details) can only be used in an environment where you have deployed a BYOC Runner; cloud Sandboxes do not support it. `requires_runner` is independent of transport, and today's 55-template catalog contains both kinds: 27 **HTTP Streaming** templates that need no Runner, and 28 **stdio** templates that do — including Alibaba Cloud OpenAPI, Alibaba Cloud Observability, Nightingale (n9e), Gitee, GreptimeDB, Prometheus, Grafana (Self-Hosted), Kafka (Confluent), AWS, ClickHouse, MySQL, PostgreSQL, Alibaba Cloud RDS, Redis, and MongoDB. Those stdio templates are launched locally on each environment via `uvx` / `npx`, and a cloud Sandbox cannot launch local subprocesses; confirm your account has a working BYOC Runner configured before installing. See [Environments (BYOC)](/en/ai-sre/environments).
## Adding an MCP Server
---
-Go to **Plugins → MCP**, click **Add Server** in the top-right corner, and fill in the form to define an MCP server.
+Go to **Plugins → MCP**. The list page has two entries in the top-right corner:
+
+- **Add MCP**: opens a form for defining an MCP server by hand (its fields are listed under "Basic Fields" below).
+- **Add in chat**: opens a new AI SRE session with this prompt prefilled — "I want to add an MCP server. First ask whether I want to connect my own service or install an existing one. If it is an existing one, ask which system I want to connect. If the plugin catalog has it, install it; if not, search the web and show me a few to pick from. Install the one I choose." The agent first asks whether you want to connect your own service or install an existing one; for an existing one it checks the plugin catalog first and only searches the web for candidates when the catalog has none, then completes the connection once you pick (nothing is sent automatically — you can edit the prompt first). The button appears only when there is an unambiguous scope to write into: always when you can author at account scope, otherwise when the current scope filter selects exactly one team you belong to (or you belong to exactly one team).
### Basic Fields
@@ -176,6 +181,8 @@ The MCP list displays each server's **name** (including its AI description), **s
Toggle the switch in the list. Only **enabled** servers are available to the agent; disabled servers are invisible to agents and cannot be called.
+
+ A disabled connector (any status other than `enabled`) is **not reported as connected** by the connect entry point: opening its **Connect** dialog shows "**Connector disabled**" and "This connector is disabled, so AI SRE can't use it. An account owner or admin has to re-enable it under Plugins → MCP.", with an **Open Plugins → MCP** button that jumps to that connector's row. An account owner or admin re-enables it there with the **Enable** toggle. Disabled connectors also drop out of the **Enabled** strip on Plugins → Overview.
Click the edit button (or click the row) to open the form. You can modify the name, transport, description, endpoint/command, authorization mode, and scope. If you do not have edit permission, the form opens in **read-only** mode with an explanation.
@@ -210,7 +217,7 @@ MCP shares the same **two-level scope** model as other resources (Skills, Knowle
**Edit permissions**: team-level MCP servers can be acted on only by members of that team — organization admins must join the team first; Shared-scope MCP servers can be acted on only by the account owner or admins. There is no creator-retains-rights exception. When you lack edit permission, the toggle and action buttons for that row appear as **read-only**.
-**Create and reassign**: to create a new team-level MCP server, you must belong to the target team; Shared-scope creation is limited to the account owner or admins. **Marketplace installs are the exception**: they are fixed to Shared scope, and any account member can install one (no owner/admin permission required). When editing an existing MCP server, the account owner or admins can move it to any team to recover resources left behind by empty teams or departed members; regular members can move it only to teams they belong to. However, **Marketplace-installed MCP servers cannot be reassigned to a team** — their scope is shown as a fixed Shared value in the edit form. A small number of legacy team-scoped Marketplace rows from earlier versions can still be changed back to Shared scope; the reverse is not allowed. **Promoting to Shared scope carries the same gate as Shared-scope creation: only the account owner or admins can do it** — a regular member is denied even for servers belonging to their own team, and the prompt now reads "ask an admin to make it shared" instead of naming the owning team.
+**Create and reassign**: to create a new team-level MCP server, you must belong to the target team; Shared-scope creation is limited to the account owner or admins. **Marketplace installs are the exception**: they are fixed to Shared scope and started by the installer, and any account member can install an ordinary template (no owner/admin permission required). One class of template is the exception to that exception: when a template in a **member authorization** mode (key or OAuth) also asks for a free-form address / host parameter, the installer would effectively decide where other members' credentials are sent — so, to keep other members' credentials from flowing to a host the installer chose, installing and connecting that template is **limited to the account owner or admins**. A regular member sees no **+** on that row (and cannot click it), and opening its **Connect** dialog directly says "You don't have permission to install this. Ask your account owner or an admin." When editing an existing MCP server, the account owner or admins can move it to any team to recover resources left behind by empty teams or departed members; regular members can move it only to teams they belong to. However, **Marketplace-installed MCP servers cannot be reassigned to a team** — their scope is shown as a fixed Shared value in the edit form. A small number of legacy team-scoped Marketplace rows from earlier versions can still be changed back to Shared scope; the reverse is not allowed. **Promoting to Shared scope carries the same gate as Shared-scope creation: only the account owner or admins can do it** — a regular member is denied even for servers belonging to their own team, and the prompt now reads "ask an admin to make it shared" instead of naming the owning team.
**Runtime visibility**: At session start, the agent is offered only **Shared-scope** MCP servers and servers belonging to the **team bound to the current session**. Once the agent reads a team's knowledge during an investigation, that team's MCP servers and Skills are mounted into the session on demand. **The account is the only security boundary at runtime; the team is an ownership and editing tag only.**
diff --git a/en/ai-sre/overview.mdx b/en/ai-sre/overview.mdx
index b7fe196d..d8d6a6fc 100644
--- a/en/ai-sre/overview.mdx
+++ b/en/ai-sre/overview.mdx
@@ -53,17 +53,30 @@ AI SRE is more than a chat box in the console — it covers multiple collaborati
---
-AI SRE is available to accounts on an On-call Pro or higher subscription, with no application needed.
+AI SRE is available to accounts holding a **valid (enabled)** On-call Pro or higher subscription, with no application needed.
AI SRE is billed on actual usage starting September 16, 2026, 08:00 Beijing time, settled in credits (1 credit = ¥1); usage before that date isn't charged. Metered items are model usage, sandbox online time, and web search. Activation is free, eligible accounts get gift credits each billing period, and you can also buy credit packages (1,000 / 5,000 / 20,000 credits for ¥950 / ¥4,500 / ¥17,000, valid 365 days from payment). Pay-as-you-go is off by default; an admin can turn it on and optionally set a per-period cap. Full terms: [AI SRE Credit Package Purchase Agreement](/en/compliance/ai-sre-credit-package-purchase-agreement).
+
+ When the gift credits, credit packages, and wallet balance are all used up, AI SRE refuses new conversation requests: the composer is disabled and a **non-dismissible** notice stays pinned above it (the text comes from the server and covers all three shapes — "not activated yet", "this period's allowance is spent", and "the wallet is empty"), with a **Go to AI SRE billing** button that opens the billing center (`/wallet/plan?product=ai-sre`). An admin turns on pay-as-you-go, buys a credit package, or tops up the wallet there; once the state recovers, you can continue the conversation.
Production changes, restarts, rollbacks, and external notifications all require your confirmation before they execute.
+### When the subscription lapses
+
+Every request re-checks the account's On-call subscription, so a subscription that lapses pauses AI SRE immediately. The interface shows the server's own sentence, and distinguishes two cases whose remedies differ — don't apply the wrong one:
+
+| Case | Notice | Remedy |
+|------|--------|--------|
+| The subscription's tier is Pro or higher, but the subscription isn't enabled (expired, or disabled for any other reason) | "This account's On-call subscription is no longer active (expired or disabled), so AI SRE is paused. It resumes automatically once the On-call subscription is renewed." | Renew the On-call subscription |
+| The account has no subscription, or its subscription is below Pro (whether or not it is enabled) | "AI SRE requires the On-call Professional plan. Upgrade the subscription to continue." | Upgrade to Pro or higher |
+
+The notice also appears in the console chat page (pinned above the composer, with a **Go to AI SRE billing** entry on its right), in IM sessions, in automation run records, and in A2A call errors; the credits overview reports the same sentence as `blocked_reason=no_license`. Recovery needs no re-activation: once the renewal or upgrade lands, the next request is admitted automatically.
+
## Core Capabilities
---
diff --git a/en/ai-sre/sessions.mdx b/en/ai-sre/sessions.mdx
index 9175641a..e07c6715 100644
--- a/en/ai-sre/sessions.mdx
+++ b/en/ai-sre/sessions.mdx
@@ -137,7 +137,11 @@ 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, or monitor target 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, 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. 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.
+ 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.
+
+ **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.
+
+ **A multi-object batch handoff pre-fills nothing**: when you click **AI analysis** on several incidents from the incident list, the input box gets no default question (it may stay empty) and no reference capsule lands in it — those references travel with the message instead. 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.
When a session starts, the knowledge packs and skills for the bound team are loaded automatically. See Knowledges and Skills for details.
@@ -221,6 +225,36 @@ When a tool or MCP call is blocked because it lacks credentials or has not compl
OAuth authorization links expire. After expiry, the card shows "Authorization link expired, please retrigger the task" — you need to start a new task to get a fresh authorization link.
+
+Channel differences: only the console (`web`) renders this card. IM and API channels get no card — the agent pastes the OAuth authorize link into its reply as plain text, and you open it in a desktop browser, complete the authorization, then reply "authorized" or "已授权" to continue (continuing is your explicit action, not an automatic OAuth callback side effect); for a secret-type credential there is no safe way to collect it over IM, so the agent tells you to open **this same session in the web console** and **never** asks you to paste the secret into the chat. On the automation channel nobody is watching, so the agent does not wait — it records the missing authorization as a blocker and delivers what it can. See [IM Platforms](/en/ai-sre/im#connections-and-authorization).
+
+
+### When a Connection Is Required
+
+When the agent searches for a capability to fulfil your request (`tool_search`), that search matches no tool at all, and the query happens to name a vendor that **exists in the marketplace catalog but your account has not connected**, a **"Connect [vendor] to continue"** card appears inline in the chat stream: the vendor's icon and name on the left, a **Connect** button on the right, and nothing else.
+
+This means you **don't have to go hunting in the plugins marketplace first**: name the vendor right in the conversation (for example, "connect Datadog for me") and you reach the connection step from there. If the catalog has no connector for that vendor at all, the agent just says so instead of showing a card.
+
+Clicking **Connect** opens that vendor's connect dialog (the same one as in the plugins marketplace: enter credentials, complete authorization and the connection test). Once the connection succeeds, the card flips in place:
+
+| Phase | Card state |
+|---|---|
+| Not connected | Title **"Connect [vendor] to continue"**, the vendor's description underneath, button **Connect** |
+| Connected | Title **"[vendor] connected"**, subtitle "Click Continue task and AI SRE will pick up where it left off", button **Continue task** |
+
+Clicking **Continue task** makes the console send "连接已完成,请继续之前的任务。" to the agent on your behalf so it resumes the original task — **closing the connect dialog does not resume the turn by itself**; resuming is always an explicit click from you. After a page reload the card still shows as connected: the console re-derives that from the template's own install state in the account, not from temporary browser state.
+
+In the following cases **no card** appears and the agent just says so in one sentence:
+
+- The account already has a connector for that vendor (in any team, in any environment): the agent says it is connected (or that it must be enabled or its credentials re-entered).
+- Only an account Owner or admin may connect that vendor: the agent says an admin has to do it.
+- The vendor's template requires a self-hosted Runner and this session has no Runner available.
+- The search matched a connected tool — a connect card only appears for "zero matches + the query names an unconnected marketplace template".
+
+
+Channel differences: only the console (`web`) renders this card. IM and API channels get no card — the agent gives the connect URL as a plain link and asks you to reply "继续" or "continue" once connected, then carries on; on the automation channel nobody is watching, so the agent does not wait — it records the missing connection as a blocker and delivers what it can. The full per-channel behavior is in [IM Platforms](/en/ai-sre/im#connections-and-authorization).
+
+
### Subagents
When the agent delegates a subtask, a clickable **dispatch reference line** appears in the conversation: a status ring, a type badge (Agent / A2A), the subtask's name and current intent, and right-aligned status and elapsed time; once finished it adds the tool-call count / token usage / total duration, and on failure a red reason line appears underneath. The reference line is a compact single row and carries **no stop button** — stopping lives in the task panel's detail header (see "Task Panel and Background Tasks" below). Clicking the line opens a subagent session panel on the right, side by side with the main conversation — the main chat area shrinks accordingly rather than being covered by a modal. The panel can be expanded to fill the main area, or collapsed back to the side-by-side layout.
diff --git a/en/ai-sre/skills.mdx b/en/ai-sre/skills.mdx
index 164cc4c5..b70d55a9 100644
--- a/en/ai-sre/skills.mdx
+++ b/en/ai-sre/skills.mdx
@@ -1,6 +1,6 @@
---
title: Skills
-description: A Skill is a reusable capability bundle — a SKILL.md instruction file plus a declared set of allowed tools — that the AI SRE agent can invoke on demand during a conversation. Install from the Marketplace, upload your own, or create one in conversation with skill-creator.
+description: A Skill is a reusable capability bundle — a SKILL.md instruction file plus a declared set of allowed tools — that the AI SRE agent can invoke on demand during a conversation. Install from the Marketplace, upload your own, or have skill-creator add one in a conversation — either authored from scratch or found online.
keywords: ["AI SRE", "Skill", "SKILL.md", "Marketplace", "skill-creator", "agent", "resources"]
sidebarTitle: Skills
---
@@ -48,6 +48,9 @@ tags:
- tag2
author: author-name
license: MIT
+examples:
+ - zh: 帮我看看这个服务最近的延迟为什么升高
+ en: Why has this service's latency gone up recently?
allowed-tools: bash, read, task
---
@@ -68,6 +71,7 @@ Frontmatter fields:
| `license` | string | No | License identifier. |
| `allowed-tools` | string[] | No | List of tools this skill is allowed to use. Leave empty for no additional restrictions. |
| `venues` | string[] | No | Restricts this skill to specific kinds of execution environment. Accepts `cloud` (Cloud Sandbox) and `byoc` (self-hosted Runner); multiple values allowed. Leave empty to make it available everywhere. Values are validated at upload time and an invalid one is rejected. |
+| `examples` | object[] (`{zh, en}`) | No | "Try asking" sample questions. At most **10** entries, and both the Chinese and the English text are required. Each is validated under the same rule as `description` (no angle brackets `<` / `>`, at most 1024 characters), and an oversized or invalid entry is **rejected at upload time**. |
Use `venues` for skills that structurally depend on one kind of environment — for example, a skill that needs a local binary, local files, or a private-network service on the environment's host simply cannot work inside a Cloud Sandbox. With `venues: [byoc]` declared, the skill neither appears in the agent's available-skills list nor can be triggered by `/` in a Cloud Sandbox session; only sessions bound to a self-hosted Runner can see and call it.
@@ -86,25 +90,22 @@ The AI SRE runtime bundles a few skills that are available without installation.
---
-Go to **Plugins → Skill** and click **Browse Marketplace** to open the skill **catalog**, where you can browse and install skill templates provided by Flashduty and Anthropic.
+The skill catalog is part of the plugin catalog on **Plugins → Overview**: skill templates are listed alongside MCP templates and the built-in Apps, grouped by category, with skills in their own **Skill** category (they also appear under the "All" tab, tagged `Skill`). The search box above the catalog filters by name or description, the tabs narrow the list to one category, and "See all N" next to a category heading expands that category; the search term and the selected tab live in the page URL, so leaving and coming back lands you where you were.
-
- On the skill list page, click **Browse Marketplace** to open the catalog dialog, which displays all available skill templates in a card grid.
-
-
- Use the search box at the top to search by name or description. The **Filter** in the top-right corner lets you view only "Installed" or "Not Installed" skills; **Sort** supports "Installed First" or "Name A–Z".
+
+ On **Plugins → Overview**, find the template under the **Skill** category; each row shows the template name and description.
- Click the **+** button on any uninstalled card to open the `Install skill ""` confirmation dialog, which notes "Installs to the account — available to all members": Marketplace installs are always **shared scope** (shared = account level), with no owner selection. Click **Install** to actually call the install endpoint — this copies the template content into your account as a regular skill entry and marks its source template (shown as a `v` badge on the card to indicate "from Marketplace").
+ An uninstalled row has a round **+** button on its right; clicking **+** or the row itself opens the `Install skill ""` confirmation dialog: "Installs to the account — available to all members." Marketplace installs are always **shared scope** (shared = account level), with no owner selection. Click **Install** to actually call the install endpoint — this copies the template content into your account as a regular skill entry and marks its source template (shown on the list as a `From Marketplace — v` tooltip). A successful install reports `"" installed`.
-
- An installed card shows a gear icon in the top-right corner. Click it to open that skill's detail panel for management.
+
+ An installed row no longer shows **+**; it shows **Enabled**. Managing and updating it happens on the **Plugins → Skill** list — see "Management and Inspection" and "Automatic and Manual Updates" below.
-New accounts are automatically pre-installed with a set of official Marketplace templates: `browser-automation` (a browser automation CLI for operating websites, dashboards, and monitoring UIs), `mcp-builder` (guides you through building an MCP server), `monit-query` (Monit data source queries), and `skill-creator` (see "Create in conversation" below). These pre-installed skills behave exactly like manually installed skills — you can enable/disable, uninstall, or update them to the latest version under "Management and Inspection" below.
+New accounts are automatically pre-installed with a set of official Marketplace templates: `browser-automation` (a browser automation CLI for operating websites, dashboards, and monitoring UIs), `mcp-builder` (guides you through building an MCP server), `monit-query` (Monit data source queries), and `skill-creator` (see "Add in conversation" below). These pre-installed skills behave exactly like manually installed skills — you can enable/disable, uninstall, or update them to the latest version under "Management and Inspection" below.
@@ -156,11 +157,14 @@ When you want to replace an existing skill with a new version, the upload endpoi
Both modes return the updated skill object on success. If the target skill does not exist, a 404 error is returned — neither mode silently creates a new skill. **Without the `replace` parameter (the default), a name collision is rejected outright**; the upload endpoint never implicitly overwrites an existing skill.
-### Create in conversation (skill-creator)
+### Add in conversation (skill-creator)
Besides uploading a zip, you can **create and refine skills right inside an AI SRE session**. `skill-creator` is a Flashduty-provided Marketplace skill, pre-installed into your account by default, that exists specifically to "build skills." Trigger it with `/skill-creator` in any session, or just describe what you want in natural language:
+**Add in conversation** at the top right of the skill list page opens a new session with a pre-filled brief: "I want to add a Skill. First ask me whether I'm authoring it myself or installing an existing one from the web. For an existing one, search a few candidates for me to pick from, and install the one I choose." In other words the agent first asks whether you want to **author a new one** or **install an existing one**; for an existing one it checks the plugin catalog / Marketplace first, searches the web only when the catalog has nothing, and installs what you pick. The prompt is only pre-filled, never sent automatically. The button appears only when you have a scope you can author into: always when you can author at account scope, otherwise when the current scope filter selects exactly one team you belong to (or you belong to only one team).
+
- **Create from scratch**: say "help me create a skill for troubleshooting X," or after an investigation, "turn that workflow into a skill." skill-creator clarifies your intent, drafts the `SKILL.md`, optionally sets up test cases and iterates on them, and saves the result as a skill in your account once you're happy.
+- **Find an existing one online**: when you enter through "Add in conversation" and choose to install an existing skill, the agent checks the plugin catalog first and searches the web only when the catalog has nothing; once you pick one it completes the install, which becomes a regular skill entry.
- **Rewrite & optimize**: click **"Edit in Chat"** in a skill's detail panel to have skill-creator rewrite that skill; it can also tune the `description` to improve triggering accuracy.
Once the draft is ready, the agent saves it as a skill with one click. If the name conflicts with an existing skill, a "Replace" confirmation dialog appears — under the hood this invokes the replace-by-name mode (`replace=true`, no `skill_id`).
@@ -201,6 +205,7 @@ Click any row in the list to open the skill's **detail panel**:
- **Right side**: content preview of the selected file, with the skill description shown at the top.
- **Header area**: skill name (short reference in the form `skill-xxxxxx`), scope label (shared / team name), source template version badge (hover to see "From Marketplace — template name `v`"), **Update available** marker, author, `version`, and the full SkillID.
- **Actions**: try in chat (injects `/` into a new session), update to latest version, edit in chat, replace, download, uninstall.
+- **Try asking**: if the skill declares `examples` in the `SKILL.md` frontmatter, the detail panel lists up to 2 sample questions; clicking one opens a new session with that skill plus the question pre-filled (never sent automatically).
When a skill package is **too large to preview**, the detail panel displays the file size and suggests using "Download" instead.
diff --git a/en/changelog/changelog.mdx b/en/changelog/changelog.mdx
index 582081d8..3ecca226 100644
--- a/en/changelog/changelog.mdx
+++ b/en/changelog/changelog.mdx
@@ -4,6 +4,37 @@ description: "This page documents important updates and feature releases for Fla
keywords: ["Changelog", "Product Release", "Feature Updates", "Flashduty", "Version History"]
---
+
+
+### AI SRE billing goes live
+
+AI SRE becomes a paid product on **September 16, 2026, 08:00 Beijing time**: usage is metered in credits for model usage, sandbox online time, and web search (1 credit = ¥1), and usage before that date isn't charged. Activation is free, eligible accounts get gift credits each billing period, and you can also buy credit packages (1,000 / 5,000 / 20,000 credits); pay-as-you-go is off by default, and an admin can turn it on with a per-period cap.
+
+- When the gift credits, credit packages, and wallet balance are all spent, the session is refused: the composer is disabled with a **non-dismissible** notice pinned above it and a "Go to AI SRE billing" entry. An admin turning on pay-as-you-go, buying a package, or topping up the wallet restores it
+- A lapsed On-call subscription (expired or disabled) pauses AI SRE the same way, with the notice "This account's On-call subscription is no longer active (expired or disabled), so AI SRE is paused" — it **resumes automatically on renewal**, with no re-activation; a subscription below Pro is told to upgrade
+
+See [AI SRE Overview · Activation and billing](/en/ai-sre/overview#activation-and-billing) and the [AI SRE Credit Package Purchase Agreement](/en/compliance/ai-sre-credit-package-purchase-agreement).
+
+### Plugin catalog consolidates onto Overview; marketplace access is now the "Connect" dialog
+
+**Plugins → Overview** is now a full plugin catalog: MCP templates, the built-in Apps (GitHub / GitLab / Kubernetes), and marketplace skills are listed together under category tabs, with search and "See all N" — the search term and the selected tab live in the page URL.
+
+- Connecting a marketplace MCP template is now the round **+** on its row → the **Connect** dialog (fill in the connection parameters, pick the environment, run the connection test); installs no longer happen inside a conversation
+- For a skill template, **+** opens the "Install skill" confirmation, which installs at account (shared) scope; an installed row shows "Enabled"
+- The conversational entry on the skill list page changed from "Create in conversation" to "**Add in conversation**": it opens a session with a pre-filled brief that first asks whether you're authoring a skill yourself or installing an existing one, and for an existing one checks the plugin catalog before searching the web
+
+See [MCP (External Tools)](/en/ai-sre/mcp) and [Skills](/en/ai-sre/skills).
+
+### Edge alerting engine supports server-pushed automatic upgrades
+
+A Linux (systemd) alerting engine receives its target version from the platform in the heartbeat response, downloads and verifies the artifact, and atomically swaps the binary; the replaced process then enters a probation window of about 180 seconds — the first successful heartbeat commits the upgrade, and otherwise it rolls back to the previous version. Docker and Kubernetes deployments do not take part and are still upgraded by changing the image version; the `--alerter.disableAutoUpdate` startup flag opts a single instance out. See [Alerting Engine](/en/monitors/engine/engine#automatic-upgrades).
+
+### New "Continue conversation" entries on the incident timeline
+
+Actions AI SRE performed on a member's behalf (for example, an automation rule finishing an investigation and writing its conclusion back to the incident) are recorded on the incident timeline under a joint signature of `{{name}} and AI SRE`: every such row now carries a persistent **Continue conversation** entry that reopens that session in the AI SRE panel, and the hover card on the AI SRE part of the signature offers the same button — relabelled from "View session" to "Continue conversation". See [Viewing incidents](/en/on-call/incident/search-view-incident#ai-sre-action-records).
+
+
+
### Cloud-log data sources no longer support per-series no-data detection
diff --git a/en/monitors/data-sources/data-sources.mdx b/en/monitors/data-sources/data-sources.mdx
index b13f6f79..11a48d14 100644
--- a/en/monitors/data-sources/data-sources.mdx
+++ b/en/monitors/data-sources/data-sources.mdx
@@ -125,6 +125,8 @@ Data sources have two independent switches, controlling business execution and a
| **Minimum / Maximum TLS version** | Options: TLS 1.0, 1.1, 1.2, 1.3; defaults to system default. The minimum version must not be higher than the maximum version |
| **Skip server certificate verification** | When checked, the server certificate is not verified |
+When **Basic Authentication** is enabled, **Username** and **Password** accept `${env:NAME}` references, resolved locally by each Edge (see [Reference credentials locally in Edge](#reference-credentials-locally-in-edge)); the **Server URL** and **Params** do not support this syntax.
+
### MySQL / Oracle / PostgreSQL
Relational databases share a similar configuration structure:
@@ -141,6 +143,8 @@ Relational databases share a similar configuration structure:
In addition to the basic connection settings above, Oracle supports multiple key-value **Options**. MySQL and PostgreSQL additionally support TLS/SSL encrypted connections, selected via the **TLS/SSL mode** dropdown.
+In the table above, **Username** and **Password** accept `${env:NAME}` references, resolved locally by each Edge (see [Reference credentials locally in Edge](#reference-credentials-locally-in-edge)); the connection address does not support this syntax.
+
#### TLS/SSL modes for MySQL
| Mode | Description |
@@ -186,6 +190,8 @@ Elasticsearch supports Cloud and Self-Managed deployments. Cloud is selected by
| **CA certificate** | - | Optional | - |
| **Certificate fingerprint** | - | Optional | - |
+In Cloud mode, **Cloud ID** and **API Key** accept `${env:NAME}` references; in Self-Managed mode, **Username / Password** and **Service Token** do. Each Edge resolves the reference locally (see [Reference credentials locally in Edge](#reference-credentials-locally-in-edge)).
+
### Loki / VictoriaLogs
Loki and VictoriaLogs use the same HTTP connection structure as Prometheus: server URL, Headers, Params, Basic Authentication, and TLS settings such as a custom CA, mTLS, server name, TLS versions, and skipping certificate verification.
@@ -197,6 +203,8 @@ Loki and VictoriaLogs use the same HTTP connection structure as Prometheus: serv
These addresses are input examples; the form does not save them as defaults automatically.
+When **Basic Authentication** is enabled, **Username** and **Password** likewise accept `${env:NAME}` references (see [Reference credentials locally in Edge](#reference-credentials-locally-in-edge)); the server URL and **Params** do not support this syntax.
+
### ClickHouse
| Config Item | Description | Default |
@@ -213,6 +221,8 @@ These addresses are input examples; the form does not save them as defaults auto
After you enable **TLS**, you can configure a custom CA, mTLS, server name, minimum / maximum TLS versions, and skipping server certificate verification. Disabling TLS clears these TLS fields from the form.
+**Username / Password** accept `${env:NAME}` references, resolved locally by each Edge (see [Reference credentials locally in Edge](#reference-credentials-locally-in-edge)); the connection address does not support this syntax.
+
### Aliyun SLS
| Config Item | Description |
diff --git a/en/monitors/engine/engine.mdx b/en/monitors/engine/engine.mdx
index b531f3ed..bf4b8a7a 100644
--- a/en/monitors/engine/engine.mdx
+++ b/en/monitors/engine/engine.mdx
@@ -63,6 +63,25 @@ The page automatically generates install and upgrade commands based on your sele
| **Docker** | Containerized deployment for environments with Docker already set up |
| **Kubernetes** | Cloud-native environments, deployed as a Deployment |
+### Automatic upgrades
+
+The alert engine on a Linux deployment supports server-pushed automatic upgrades. When you pick **Linux** as the deployment method, the page shows this note:
+
+> The alert engine on Linux supports server-pushed automatic upgrades. When enabled, no manual upgrade command is needed; the command above remains available as a manual fallback.
+
+Whether a version is pushed is decided platform-side — the console has no switch. Once you have deployed with the installation configuration above, a Linux instance upgrades itself when a push arrives; while push upgrades are not enabled, keep copying the generated **upgrade command** and running it on the target machine.
+
+| Item | Description |
+|------|-------------|
+| **Applicable deployment methods** | Linux (systemd) only; Docker and Kubernetes deployments do not take part in automatic upgrades and are still upgraded by changing the image version |
+| **How it runs** | After the engine receives a target version in a heartbeat reply, it downloads and verifies the artifact itself, atomically replaces the binary, and continues running the new version — no command to run on the host at any point |
+| **Upgrade success** | The replaced process enters a probation window of about 180 seconds; the first successful heartbeat counts as a successful upgrade and completes it |
+| **Failure rollback** | If no heartbeat succeeds within the probation window (for example the new version cannot complete authentication or protocol exchange), or the new version keeps starting without committing a heartbeat (at most 3 boot attempts), the engine automatically rolls back to the previous version |
+| **Retry behavior** | A target version that rolled back on this host is not attempted again until a newer version is published; after a failed attempt the same version is not retried for about 30 minutes |
+| **Opting out** | The `--alerter.disableAutoUpdate` startup flag makes a single instance stop accepting automatic upgrades; container environments and unwritable binary directories are skipped automatically as well |
+
+Automatic upgrades require the engine to reach the artifact mirror, which is a public mirror by default; in offline or private-network environments point `--alerter.updateMirror` at an internal mirror. See "Automatic upgrade flags" in [Engine CLI flag reference](#engine-cli-flag-reference).
+
## API Key management
API Keys are used for authentication between the alert engine and the SaaS. You can click **Manage API Key** on the engine installation/upgrade page to open the management panel.
@@ -123,3 +142,12 @@ Earlier versions used `alerter.serverConcurrency` and `alerter.serverRetry` to c
- **High-throughput deployments** (many alert rules, high alert frequency): increase `alerter.alertRuleDeliveryWorkers` (e.g. 128) to reduce event queue backlog; raise `alerter.alertRuleEventQueueSize` as well if needed.
- **Constrained network or CPU**: lower `alerter.alertRuleDeliveryWorkers` (e.g. 16–32) to limit outbound connections and avoid competing with other traffic.
- **High packet-loss or unreliable networks**: consider a larger `alerter.serverSleep` (e.g. 10s) so backoff starts from a longer initial interval, reducing futile requests during congestion.
+
+### Automatic upgrade flags
+
+| Flag | Default | Description |
+|------|---------|-------------|
+| `alerter.disableAutoUpdate` | `false` | Disables server-pushed automatic upgrades. Set to `true` and the instance no longer performs automatic upgrades; container environments are detected and skipped automatically, and this flag takes precedence |
+| `alerter.updateMirror` | `https://static.flashcat.cloud/monitedge` | Mirror root URL for automatic upgrade artifacts. The engine downloads the artifact and checksum file from `/releases/download//`; offline or private-network environments must point this at an internal mirror |
+
+Automatic upgrades take effect on Linux (systemd) deployments only and require the engine to reach the artifact mirror. If these conditions are not met, copy the **upgrade command** in the console and upgrade manually.
diff --git a/en/on-call/advanced/war-room.mdx b/en/on-call/advanced/war-room.mdx
index 93dcc72b..3ed1aee3 100644
--- a/en/on-call/advanced/war-room.mdx
+++ b/en/on-call/advanced/war-room.mdx
@@ -61,7 +61,7 @@ Flashduty On-call War Room is an automated collaboration feature designed for in

- For Feishu/Lark app notifications, the **👥 Create War Room** button at the bottom of the incident card is controlled by a switch in the notification template: edit the Feishu/Lark app template under **Template Management** and turn on **Create War Room** in the card-fields panel of the **Additional info** tab (off by default). Only then does the button appear at the bottom of the card, provided the group-creation conditions are met. The card's **More Actions** area is now a dropdown menu (custom actions, snooze durations, and unacknowledge), and the war room is no longer one of its entries.
+ When notifying through the Feishu/Lark, Dingtalk, or Slack app, the **👥 Create War Room** button at the bottom of the incident card is controlled by a switch in the notification template: edit the app template for that channel under **Template Management** and turn on **Create War Room** in the card-fields panel of the **Additional info** tab (off by default). Only then does the button appear at the bottom of the card, provided the group-creation conditions are met. The card's **More Actions** area is now a dropdown menu (custom actions, snooze durations, and unacknowledge), and the war room is no longer one of its entries.