docs: 按真实落地实现更新接入方案第 4-6 章
- 维度字段 is_first_install 改为 app_install_status(normal/new_install/over_written 三值,与 StartManager 安装状态对齐) - 新增 5.1 模块策略下发:链路 B 为策略驱动(无策略时 create/record 空转并打印 eventId has not created!),策略 JSON 对齐 EventStrategyBean.fromJson(config 嵌套 + status/sampling_rate/interval/aggre_time/aggre_count),含字段说明表与判定生效步骤 - §6 补回标题与开头段:链路 A/B 分工、链路 B API 已随 HXLaunchMonitorPlugin 编译验证(不再待确认)、插件形态(仿 HXCrashMonitorPlugin,startPlugin 建指标,APMHelper 注册) - §7 验收标准同步策略激活条件与编译验证状态 - 新增 8.9 真实应用验证:首启 1141ms(new_install)/ 二次 1717ms(normal),链路 B 待策略下发复测;8.8 注明 demo(boolean)与生产(三值)差异 - 新增真机文档 apm_launch_monitor_config.md(真实 workspace 落地配置,含策略 JSON 与链路 A 字段定义) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -44,17 +44,15 @@ time + icon_input_time + start_type + process_name
|
||||
| 模块 | `launch` |
|
||||
| 指标名 | `cold_start_time` |
|
||||
| 指标值 | 冷启动耗时,单位 ms |
|
||||
| 维度 | `start_type`、`entry_page`、`app_version`、`is_first_install` |
|
||||
| 维度 | `start_type`、`entry_page`、`app_version`、`app_install_status` |
|
||||
| 追溯字段 | `response_latency`、`animation_finish_time`、`startability_processstart_dur`、`appattach_to_appforeground_dur`、`git_commit`、`is_backfill` |
|
||||
| 分桶 | `[500, 600, 700, 800, 1000, 1500, 2000, 3000]` |
|
||||
|
||||
追溯通道上传最小必要字段:核心指标、4 个维度(含 `is_first_install`,区分安装后首启的偏高耗时)、启动生命周期各阶段时间(`response_latency`/`animation_finish_time`/`startability_processstart_dur`/`appattach_to_appforeground_dur`,用于劣化分段定位;`response_latency` 需 API 22+,两个 `*dur` 仅冷启动存在)、`git_commit`(代码级追溯)与补报标识。去重为客户端行为(第 3.2 节,进程内存保留最近 20 个事件键),上传负载无需携带去重键与事件时间字段。其余候选字段(`process_name`、`time`/`icon_input_time`、环境 `device_type`/`system_version`/`build_mode`/`target_name`、版本 `bundle_version`/`bundle_name` 等)在系统事件与客户端均可获取,按需加回上传即可,无需改动采集逻辑。
|
||||
上传负载为最小必要集:指标 1、维度 4(含 `app_install_status`)、启动生命周期各阶段时间 4(劣化分段定位)、`git_commit`(代码级追溯)、`is_backfill`(补报标识);去重为客户端行为(第 3.2 节),负载不含去重键。其余候选字段按需加回,无需改动采集逻辑。
|
||||
|
||||
模块名使用小写字母和连字符;指标名不包含连字符。维度控制在必要范围内,避免将用户 ID、完整 URL 等高基数字段作为维度。
|
||||
模块名小写+连字符,指标名不含连字符;维度避免高基数(用户 ID、完整 URL 等)。
|
||||
|
||||
分桶指标通过 `HXEventMonitor`(`@kernel/app_monitor_event`)实现:`LaunchMonitor.init()` 中以 `DataMonitorBuilder` 创建 `launch` 模块的 `cold_start_time` 指标(`setBuckets([500, 600, 700, 800, 1000, 1500, 2000, 3000])`,4 个维度 `start_type`/`entry_page`/`app_version`/`is_first_install`),每次有效冷启动 `record(extendTime)` 原始值,由 SDK 按桶自动归集聚合,无需客户端手动分桶。
|
||||
|
||||
桶边界按实测主体分布(600-800ms)设计:`<500` 无感、`500-600`/`600-700`/`700-800` 在主体区间细分(各 100ms 分辨率)、`800-1000`/`1000-1500`/`1500-2000` 逐级放宽、`2000-3000`/`>3000` 作为劣化与告警锚点。后续以 ElkService 追溯通道的原始值(P25/P50/P75/P95/P99)复核边界;分桶变更会使历史分布不可比,需在后台重建或并档。
|
||||
分桶指标由 `HXEventMonitor` 实现(8 桶、4 维度,与追溯一致),`record(extendTime)` 由 SDK 归桶聚合;桶边界按实测主体(600-800ms)细分、尾部留告警锚点,分桶变更需后台重建并档(历史分布不可比)。维度 `app_install_status` 取值 `normal`/`new_install`/`over_written`(安装状态:常规/全新安装/覆盖安装),与 `StartManager` 安装状态对齐。
|
||||
|
||||
### 4.1 启动时间拆解
|
||||
|
||||
@@ -74,11 +72,74 @@ time + icon_input_time + start_type + process_name
|
||||
|
||||
## 5. 后台与看板配置
|
||||
|
||||
按新增 PDF 的自定义 APM 模块流程,在 APM 后台创建 `launch` 模块并启用:全量采样(`sampling_rate: 1000`)、60 秒聚合(`aggre_time: 60`)、累计 100 条触发上报(`aggre_count: 100`)。客户端 `record` 后由 SDK 本地聚合,达到聚合周期或条数触发条件后自动上报至 APM 平台(发送通道为 `HXMonitor` 注入的 `IElkService`,即 `APMElkService` 所走的 `ElkService` 通道)。随后为该模块补充 ELK 索引模板,在 Grafana 建立按版本、启动类型和时间聚合的 P50/P95、超 2 秒占比及分桶分布面板。
|
||||
### 5.1 模块策略下发(链路 B 激活前提)
|
||||
|
||||
链路 B 是**策略驱动**的:SDK 侧 `HXEventMonitorPlugin.parseMonitorStrategy()` 读取后台策略注入 `EventStrategyBean`,若 `launch` 模块无开启策略,`create()/record()` 一律空转并打印 `Monitor.Event cold_start_time eventId has not created!`,应用侧无法绕开。因此必须在 APM 后台为 **module=`launch`** 下发如下策略:
|
||||
|
||||
```json
|
||||
{
|
||||
"module": "launch",
|
||||
"config": {
|
||||
"status": 1,
|
||||
"sampling_rate": 1.0,
|
||||
"interval": 5000,
|
||||
"aggre_time": 60000,
|
||||
"aggre_count": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段说明(对齐 `EventStrategyBean.fromJson`,仅这些字段生效):
|
||||
|
||||
| 字段 | 取值 | 说明 |
|
||||
|------|------|------|
|
||||
| `module` | `launch` | 必须与代码 `HXEventMonitor.getEventFactory('launch')` 一致 |
|
||||
| `status` | `1` | **必须 `1`(STATUS_OPEN)**;否则 `isOpen()` 为 false,`create/record` 全空转 |
|
||||
| `sampling_rate` | `0~1` | 抽样率,`isOpen()` 需 `status==1` 且抽样通过才生效 |
|
||||
| `interval` | ms | 采集间隔 |
|
||||
| `aggre_time` | ms | 聚合时间阈值,达到即触发一次 push |
|
||||
| `aggre_count` | 条 | 聚合数量阈值,达到即触发一次 push |
|
||||
|
||||
客户端 `record` 后由 SDK 本地聚合,达到聚合周期或条数任一触发条件后自动上报至 APM 平台(发送通道为 `HXMonitor` 注入的 `IElkService`,即 `APMElkService` 所走的 `ElkService` 通道)。
|
||||
|
||||
**判定生效**:后台下发后重启应用,冷启动日志中应消失 `Monitor.Event cold_start_time eventId has not created!`、出现 `Cold start bucket metric recorded: <ms>` 与 SDK 聚合 push 日志,看板出现 `launch` 模块 `cold_start_time` 桶分布。
|
||||
|
||||
随后为该模块补充 ELK 索引模板,在 Grafana 建立看板面板(建议形态):
|
||||
|
||||
```json
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"title": "冷启动 P50/P95",
|
||||
"type": "percentile",
|
||||
"metric": "cold_start_time",
|
||||
"group_by": ["app_version", "start_type"],
|
||||
"window": "1d"
|
||||
},
|
||||
{
|
||||
"title": "超 2 秒占比",
|
||||
"type": "ratio",
|
||||
"condition": "cold_start_time >= 2000",
|
||||
"group_by": ["app_version"],
|
||||
"window": "1d"
|
||||
},
|
||||
{
|
||||
"title": "分桶分布",
|
||||
"type": "bucket_distribution",
|
||||
"metric": "cold_start_time",
|
||||
"buckets": [500, 600, 700, 800, 1000, 1500, 2000, 3000],
|
||||
"group_by": ["entry_page", "app_install_status"],
|
||||
"window": "1d"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
看板按版本、启动类型和时间聚合;`app_install_status` 维度(`new_install`/`over_written`)用于排除安装后首启的偏高数据。
|
||||
|
||||
## 6. 兼容与兜底
|
||||
|
||||
当前通过 `ElkService` 上传 `cold_start_time`、维度和原始系统字段,但它不具备 PDF 所述的指标聚合语义,需要后端补充索引、聚合规则和看板。不要直接复用 Android 文档中的 Java API;后续接入 HarmonyOS 自定义 APM SDK 时,仅替换上传实现。
|
||||
链路 A(`ElkService` 追溯)上传 `cold_start_time`、4 维度和阶段时间字段,不具备分桶聚合语义,由链路 B(`HXEventMonitor` 分桶指标,策略驱动见 5.1)承担看板聚合;后台需补充 ELK 索引模板、聚合规则和看板。链路 B 的 `DataMonitorBuilder`/`record` API 形态以 `@kernel/app_monitor_event` 的 `.d.ts` 为准(已随 `HXLaunchMonitorPlugin` 编译验证),不直接复用 Android 文档中的 Java API。
|
||||
|
||||
`APP_LAUNCH` 的事件解析必须与崩溃事件分开处理:崩溃事件依赖异常和日志字段,启动事件不包含这些字段。上传应异步执行,不阻塞首页渲染;以 `time + icon_input_time + start_type + process_name` 去重,兼容系统重新投递。
|
||||
|
||||
@@ -97,8 +158,8 @@ time + icon_input_time + start_type + process_name
|
||||
|
||||
启动指标同时走两条通道,职责分离:
|
||||
|
||||
- **分桶指标(`HXEventMonitor`,module=`launch`)**:`record(extendTime)` 后由 SDK 按桶聚合,负责看板聚合统计(P50/P95、超 2 秒占比、分桶分布)。`record` 失败不影响启动流程,聚合逻辑在 SDK 侧。
|
||||
- **追溯明细(`ElkService`,biz=`launch`)**:11 字段最小集(指标/4 维度/启动生命周期各阶段时间/`git_commit`/`is_backfill`),负责明细追溯与后端校验;其他字段按需加回。分桶指标同步 4 个维度(`setDimension4Name('is_first_install')`),与追溯维度一致。
|
||||
- **分桶指标(`HXEventMonitor`,module=`launch`)**:`record(extendTime)` 后由 SDK 按桶聚合,负责看板聚合统计(P50/P95、超 2 秒占比、分桶分布)。**策略驱动**:无后台下发策略时 `create()/record()` 空转(见 5.1),`record` 失败/空转不影响启动流程,聚合逻辑在 SDK 侧。实现为 `HXLaunchMonitorPlugin`(仿 `HXCrashMonitorPlugin`,`startPlugin()` 中建指标),在 `APMHelper` 的 `.plugin(...)` 列表注册。
|
||||
- **追溯明细(`ElkService`,biz=`launch`)**:11 字段最小集(指标/4 维度含 `app_install_status`/启动生命周期各阶段时间/`git_commit`/`is_backfill`),负责明细追溯与后端校验;其他字段按需加回。分桶指标同步 4 个维度(`setDimension4Name('app_install_status')`),与追溯维度一致。
|
||||
|
||||
两通道独立失败互不影响;`HXEventMonitor` 的 module 参数为显式传入的 `'launch'`,与文档模块定义一致,不经过 `APMElkService` 固定的 `'apm'` 来源。
|
||||
|
||||
@@ -110,8 +171,8 @@ time + icon_input_time + start_type + process_name
|
||||
4. 页面在系统异步回调前销毁时,不影响已经提交的上报;旧页面不会释放新页面 observer。
|
||||
5. 本地日志与后台数据量级一致;看板可查询 P50、P95、超 2 秒占比及分桶分布。
|
||||
6. 断网或上传失败不影响启动流程,网络恢复后按既有上传机制重试。
|
||||
7. 双通道上传验证:完整 workspace 编译通过(`HXEventMonitor` 的 `DataMonitorBuilder`/`getEventFactory`/`setBuckets`/`record`/`setDimension_4` 与 `.d.ts` 一致);真机冷启动 hilog 出现 `Cold start metric uploaded` 与 `Cold start bucket metric recorded`;ELK 索引可查 `biz='launch'` 的 11 字段记录,APM 平台 `launch` 模块出现分桶分布。
|
||||
8. 维度与分桶:分桶分布可按 4 个维度(`start_type`/`entry_page`/`app_version`/`is_first_install`)分组查询;分桶边界变更需后台重建或并档(历史分布不可比)。
|
||||
7. 双通道上传验证:完整 workspace 编译通过(`HXEventMonitor` 的 `DataMonitorBuilder`/`getEventFactory`/`setBuckets`/`record`/`setDimension_4` 已随 `HXLaunchMonitorPlugin` 编译验证);真机冷启动 hilog 出现 `Cold start metric uploaded`(链路 A)与 `Cold start bucket metric recorded`(链路 B,需后台下发策略,见 5.1);ELK 索引可查 `biz='launch'` 的 11 字段记录,APM 平台 `launch` 模块出现分桶分布。
|
||||
8. 维度与分桶:分桶分布可按 4 个维度(`start_type`/`entry_page`/`app_version`/`app_install_status`)分组查询;分桶边界变更需后台重建或并档(历史分布不可比)。
|
||||
|
||||
## 8. 已验证结果
|
||||
|
||||
@@ -219,4 +280,18 @@ time + icon_input_time + start_type + process_name
|
||||
- **`is_first_install` 维度语义正确**:安装/清数据后首启 = `true`(161~165ms),非首启 = `false`(127~134ms);**首启耗时系统性偏高约 30ms**,该维度可将其从常规分布中区分,避免拉高 P50/P95。
|
||||
- 补报判定 3 组双向正确,拦截保护 3 组 × 3 页无漏防。
|
||||
- 耗时稳定(127~165ms);此前观测到的 `response_latency=5086ms` 异常值本次未复现(偶发)。
|
||||
- 注意:demo 的 `is_first_install` 基于 `preferences` 记录,`bm clean` 清数据后该标记重置(再次显示首启);生产实现 `StartManager.getAppInstallStatus()` 无此行为,语义以生产为准。
|
||||
- 注意:demo 的 `is_first_install`(boolean)基于 `preferences` 记录,`bm clean` 清数据后该标记重置(再次显示首启);生产实现为 `app_install_status`(`normal`/`new_install`/`over_written` 三值,见第 4 节),以生产为准。
|
||||
|
||||
### 8.9 真实应用验证(2026-08-06,完整 workspace,nova 14 Pro)
|
||||
|
||||
在完整 workspace 落地(`HXLaunchMonitorPlugin` 插件 + `APMHelper` 注册)后的真机数据:
|
||||
|
||||
| 场景 | 结果 |
|
||||
|------|------|
|
||||
| 全新安装首启(`new_install`) | 链路 A:`cold_start_time=1141ms`,Entry=Index,Elk 上报 ✅ |
|
||||
| 二次冷启动(`normal`) | 链路 A:`cold_start_time=1717ms`,Elk 上报 ✅ |
|
||||
| 链路 B(分桶) | 待后台下发 `launch` 策略(5.1)后复测 |
|
||||
|
||||
编译:`claude_compile.sh → BUILD_SUCCESS`(链路 B API 随插件编译验证通过)。
|
||||
|
||||
真实应用耗时(1.1~1.7s)远高于 demo(127~165ms),符合生产首页复杂度的预期;`app_install_status` 维度可区分首启与常规启动的耗时差异。
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# 启动性能监控(冷启动耗时)接入配置
|
||||
|
||||
> 作者:cheliangzhao
|
||||
> 日期:2026-08-06
|
||||
> 涉及模块:`entry`(HAP 入口)+ `@kernel/app_monitor_event`(APM 事件 SDK)
|
||||
> 对应需求:冷启动耗时(`cold_start_time`)采集与看板聚合
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
统计同花顺期货鸿蒙版**冷启动耗时**,覆盖三条启动入口(`Index` / `LauncherPage` / `NetworkAnomalyPage`),区分冷启动 / 补投递四种场景,实现启动性能的持续观测与劣化告警。
|
||||
|
||||
采集分两条通道:
|
||||
|
||||
- **链路 A(Elk 追溯,已上线验证)**:把冷启动指标结构化 JSON 经 `ElkService` 异步上报,字段最全,可明细定位。
|
||||
- **链路 B(HXEventMonitor 分桶,需后台策略开启后生效)**:由 SDK 按桶自动归集,负责看板聚合曲线。
|
||||
|
||||
> ⚠️ 链路 B 是**策略驱动**的:SDK 侧在 `EventMonitorStrategy` 找不到 `launch` 模块的开启策略时,`create()/record()` 一律空转并打印 `Monitor.Event cold_start_time eventId has not created!`。应用侧无法绕开,必须由 **APM 后台下发对应模块策略**才能激活。
|
||||
|
||||
---
|
||||
|
||||
## 2. 链路 A:Elk 追溯(已生效,无需后台操作)
|
||||
|
||||
上报字段(`LaunchElkBuilder`,业务来源 `launch`):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `cold_start_time` | number | 冷启动耗时 ms = 系统事件 `extend_time` |
|
||||
| `start_type` | number | 启动类型(当前只统计 `0`=冷启动) |
|
||||
| `entry_page` | string | 入口页(`Index`/`LauncherPage`/`NetworkAnomalyPage`;补投递为 `unknown`) |
|
||||
| `app_version` | string | 应用内部版本号 |
|
||||
| `app_install_status` | string | `normal`/`new_install`/`over_written` |
|
||||
| `response_latency` | number | 离手到动效开始(需 API 22+) |
|
||||
| `animation_finish_time` | number | 动效完成耗时 |
|
||||
| `startability_processstart_dur` | number | 进程创建段(仅冷启动) |
|
||||
| `appattach_to_appforeground_dur` | number | 进程挂载段(仅冷启动) |
|
||||
| `git_commit` | string | 代码级追溯,劣化定位用 |
|
||||
| `is_backfill` | boolean | 是否系统补投递的上次启动遗留事件 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 链路 B:HXEventMonitor 分桶指标(需后台开启)
|
||||
|
||||
### 3.1 后台需下发的模块策略
|
||||
|
||||
SDK 由 `HXEventMonitorPlugin.parseMonitorStrategy()` 读取,注入到 `EventStrategyBean` 后按模块打开。请为 **module=`launch`** 下发如下配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"module": "launch",
|
||||
"config": {
|
||||
"status": 1,
|
||||
"sampling_rate": 1.0,
|
||||
"interval": 5000,
|
||||
"aggre_time": 60000,
|
||||
"aggre_count": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段说明(对齐 `EventStrategyBean.fromJson`,仅这些字段生效):
|
||||
|
||||
| 字段 | 取值 | 说明 |
|
||||
|------|------|------|
|
||||
| `module` | `launch` | 必须与代码 `HXEventMonitor.getEventFactory('launch')` 一致 |
|
||||
| `status` | `1` | **必须 `1`(STATUS_OPEN)**;否则 `isOpen()` 为 false,`create/record` 全空转 |
|
||||
| `sampling_rate` | `0~1` | 抽样率,`isOpen()` 需 `status==1 && 抽样通过` 才生效 |
|
||||
| `interval` | ms | 采集间隔 |
|
||||
| `aggre_time` | ms | 聚合时间阈值,达到即触发一次 push |
|
||||
| `aggre_count` | 条 | 聚合数量阈值,达到即触发一次 push |
|
||||
|
||||
### 3.2 指标定义
|
||||
|
||||
| 项 | 值 |
|
||||
|----|----|
|
||||
| 模块名 `module` | `launch` |
|
||||
| 指标名 `metric` | `cold_start_time` |
|
||||
| 值域 | 冷启动耗时 ms(`extend_time`) |
|
||||
| 分桶 `buckets` | `[500, 600, 700, 800, 1000, 1500, 2000, 3000]`(按实测 600–800ms 主体细分,尾部留劣化锚点) |
|
||||
| 维度1 `start_type` | 冷启动 `0` |
|
||||
| 维度2 `entry_page` | `Index`/`LauncherPage`/`NetworkAnomalyPage`/`unknown`(补投递) |
|
||||
| 维度3 `app_version` | 应用内部版本号 |
|
||||
| 维度4 `app_install_status` | `normal`/`new_install`/`over_written` |
|
||||
|
||||
### 3.3 判定生效
|
||||
|
||||
后台下发后,重启应用,冷启动日志中:
|
||||
|
||||
- ✅ 消失:`Monitor.Event cold_start_time eventId has not created!`
|
||||
- ✅ 出现:`Cold start bucket metric recorded: <ms>` 与 SDK 聚合 push 日志
|
||||
- ✅ 看板出现 `launch` 模块 `cold_start_time` 桶分布
|
||||
|
||||
---
|
||||
|
||||
## 4. 相关代码与文件
|
||||
|
||||
| 文件 | 作用 |
|
||||
|------|------|
|
||||
| `entry/src/main/ets/monitor/LaunchMonitor.ets` | APP_LAUNCH 订阅、Elk 上报、首帧 `reportDrawnCompleted`、桶指标定义与 record |
|
||||
| `entry/src/main/ets/monitor/LaunchMonitor.ets`(`ensureColdStartMetric`) | 创建 `launch/cold_start_time` 桶指标(幂等) |
|
||||
| `entry/src/main/ets/monitor/plugin/HXLaunchMonitorPlugin.ets` | 仿 `HXCrashMonitorPlugin` 接入的启动插件,在 `startPlugin()` 建指标 |
|
||||
| `entry/src/main/ets/monitor/APMHelper.ets` | 注册 `HXLaunchMonitorPlugin` 及配置类、`.plugin(...)` 列表 |
|
||||
| `entry/src/main/ets/entryability/EntryAbility.ets` | `onCreate` 早注册 `LaunchMonitor.init()` |
|
||||
| `entry/src/main/ets/pages/Index.ets` / `LauncherPage.ets` / `network/NetworkAnomalyPage.ets` | 首帧 `HOME_ROOT` 监听 + `reportFirstFrameOnDraw`/`dispose` |
|
||||
|
||||
### 打点时序
|
||||
|
||||
```
|
||||
EntryAbility.onCreate → LaunchMonitor.init()(注册 APP_LAUNCH watcher)
|
||||
入口页 aboutToAppear → reportFirstFrameOnDraw(HOME_ROOT) → 首帧 draw → reportDrawnCompleted()
|
||||
系统产生 APP_LAUNCH 事件(冷启动)→ onReceive
|
||||
├─ 链路A: ElkService 上传冷启动 JSON(字段见 §2)
|
||||
└─ 链路B: HXEventMonitor record(cold_start_time)(依赖 launch 策略,见 §3)
|
||||
补投递:icon_input_time 早于 watcher 注册 > 2000ms → 判为 backfill,entry_page=unknown
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 真机验证结论(2026-08-06,nova 14 Pro)
|
||||
|
||||
| 场景 | 结果 |
|
||||
|------|------|
|
||||
| 全新安装首启(`new_install`) | 链路 A:`cold_start_time=1141ms`,Entry=Index,Elk 上报 ✅ |
|
||||
| 二次冷启动(`normal`) | 链路 A:`cold_start_time=1717ms`,Elk 上报 ✅ |
|
||||
| 链路 B(分桶) | ❌ 待后台下发 `launch` 策略(§3.1)后复测 |
|
||||
|
||||
编译:`./claude_tool/claude_compile.sh → BUILD_SUCCESS`
|
||||
Reference in New Issue
Block a user