@skillbuilder/miniapp-simulator 0.2.2 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/assets/audit-auto-stop-config-2026-10-21.jpg +0 -0
- package/docs/assets/audit-balanced-panel-2026-10-16.jpg +0 -0
- package/docs/assets/audit-lcp-input-2026-10-20.jpg +0 -0
- package/docs/assets/audit-paint-game3d-2026-10-16.jpg +0 -0
- package/docs/assets/audit-paint-webgl-2026-10-16.jpg +0 -0
- package/docs/assets/audit-paint-webgl-apm-excerpt-2026-10-16.json +397 -0
- package/docs/assets/audit-poetry-2026-10-16.jpg +0 -0
- package/docs/assets/audit-remaining-results-2026-10-16.json +2749 -0
- package/docs/assets/miniapp-audit-risk-review-2026-10-13.png +0 -0
- package/docs/assets/miniapp-audit-runtime-hung-2026-10-13.png +0 -0
- package/docs/audit-data-collection.codex.md +105 -0
- package/docs/audit-local-validation.codex.md +165 -0
- package/docs/audit-score-design.codex.md +222 -0
- package/docs/audit-score-design.md +832 -0
- package/docs/audit-score-tech-plan.md +450 -0
- package/docs/audit-tech-design.codex.md +485 -0
- package/docs/electron-review.md +223 -12
- package/docs/quality-evaluation-redoc.xml +163 -0
- package/docs/tracker.md +3 -2
- package/lib/client-BjYHK9LR.mjs +1220 -0
- package/lib/{index-D5AYVv8s.mjs → index-CqClPZVv.mjs} +230 -184
- package/lib/index.js +2204 -1999
- package/lib/remote-client.js +2 -2
- package/lib/types/host/shadow-host.d.ts +10 -0
- package/lib/types/injection/registry.d.ts +5 -0
- package/lib/types/remote/audit-controller.d.ts +61 -0
- package/lib/types/remote/audit-leave-monitor.d.ts +12 -0
- package/lib/types/remote/audit-package-sources.d.ts +9 -0
- package/lib/types/remote/audit-telemetry.d.ts +36 -0
- package/lib/types/remote/audit-watchdog.d.ts +14 -0
- package/lib/types/remote/client.d.ts +25 -1
- package/lib/types/remote/load-timing.d.ts +5 -0
- package/lib/types/remote/protocol.d.ts +162 -1
- package/lib/types/remote/runtime.d.ts +2 -0
- package/lib/types/remote-client.d.ts +2 -2
- package/lib/types/runtime/jsapi-modules/interaction.d.ts +1 -1
- package/lib/types/runtime/jsapi-modules/local-media.d.ts +4 -0
- package/lib/types/runtime/jsapi-modules/media.d.ts +1 -1
- package/lib/types/runtime/jsapi-modules/note-publish-media.d.ts +9 -0
- package/lib/types/sw/service-worker-host.d.ts +15 -0
- package/lib/types/tracker/constants.d.ts +1 -1
- package/lib/types/tracker/default-tracker.d.ts +9 -1
- package/lib/types/types/options.d.ts +24 -0
- package/lib/workbench.js +1 -1
- package/package.json +1 -1
- package/lib/client-_vNHVHSm.mjs +0 -775
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# 小工具体验评测 APM 上报契约
|
|
2
|
+
|
|
3
|
+
## 1. 应用与点位
|
|
4
|
+
|
|
5
|
+
- 应用:`skillbuilder-miniapp`。
|
|
6
|
+
- 点位:`miniapp_simulator_event`。
|
|
7
|
+
- `event_name`:miniapp_audit_session、miniapp_audit_paint、miniapp_audit_incident、miniapp_audit_package、miniapp_audit_result。
|
|
8
|
+
|
|
9
|
+
## 2. 显式上报字段
|
|
10
|
+
|
|
11
|
+
每个业务上报位置直接指定公共数值字段。指标名是明确写出的业务名称,不通过字段名前后缀判断类型或单位。
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
{ name: 'zip_size', size: pkg.zipBytes, score: zipScore, weight: zipWeight }
|
|
15
|
+
{ name: 'unpacked_size', size: unpackedBytes }
|
|
16
|
+
{ name: 'fcp', time: paint.fcpMs }
|
|
17
|
+
{ name: 'peak_heap', memory: metrics.peakHeapBytes }
|
|
18
|
+
{ name: 'fps_median', value: metrics.fpsMedian, unit: 'fps' }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| 公共字段 | 类型 | 固定语义 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| name | STRING | 指标或事件名称 |
|
|
24
|
+
| time | FLOAT64 | 耗时或相对时间,毫秒 |
|
|
25
|
+
| memory | FLOAT64 | 内存,字节;保留 P95 插值精度 |
|
|
26
|
+
| size | FLOAT64 | 包体、文件和资源体积,字节 |
|
|
27
|
+
| score | FLOAT64 | 得分 |
|
|
28
|
+
| weight | FLOAT64 | 生效权重 |
|
|
29
|
+
| ratio | FLOAT64 | 比例,coverage 为 0~1 |
|
|
30
|
+
| count | INT64 | 次数、数量、会话阶段序号或事故序号;布尔标记使用 0/1 |
|
|
31
|
+
| value | FLOAT64 | 需要额外单位的观测值,与 unit 同时明确赋值 |
|
|
32
|
+
| unit | STRING | value 的单位,如 fps、MB/min |
|
|
33
|
+
| result | STRING | scored/unscorable/loadFailed、采集状态、风险码或框架分类值 |
|
|
34
|
+
| stage | STRING | 会话阶段、采样阶段、首屏收口状态或停止原因 |
|
|
35
|
+
| duration | FLOAT64 | 事件距评测启动的毫秒数 |
|
|
36
|
+
| source | STRING | 事故来源 |
|
|
37
|
+
| message | STRING | 有界诊断 JSON;事故摘要最多 200 字符;框架数量、证据条数和单条长度分别限制 |
|
|
38
|
+
|
|
39
|
+
无实测值时省略数值字段。零是有效数值,不代替缺失。清理函数只过滤缺失和非有限数值,不生成字段映射。布尔标记由业务调用处显式转换为 0/1。
|
|
40
|
+
|
|
41
|
+
## 3. 公共上下文与登记
|
|
42
|
+
|
|
43
|
+
公共上下文固定为 audit_session_id、attempt_no、simulator_session_id、app_type、policy_version、rules_version、probe_version、review_task_id、package_version、package_hash、runtime_version。
|
|
44
|
+
|
|
45
|
+
tracker 补充 event_name、timestamp、business_line、sdk_version、renderer、app_id;审核员沿用顶层 context_userId。任务和包版本由接入方提供时记录;ID 和哈希只用于精确查询,不用于看板分组。
|
|
46
|
+
|
|
47
|
+
APM 现有 28 个基础字段可以复用。固定新增登记项共 18 个:
|
|
48
|
+
|
|
49
|
+
- FLOAT64:time、memory、size、score、weight、ratio、value。
|
|
50
|
+
- INT64:attempt_no。
|
|
51
|
+
- STRING:unit、audit_session_id、simulator_session_id、app_type、policy_version、rules_version、probe_version、review_task_id、package_version、package_hash。
|
|
52
|
+
|
|
53
|
+
新增指标使用现有公共数值字段,并在业务上报位置明确赋值。诊断信息不上传代码、输入内容、坐标、完整错误堆栈、任意文件路径清单或截图。
|
|
54
|
+
|
|
55
|
+
## 4. 事件与频率
|
|
56
|
+
|
|
57
|
+
| event_name | 上报方式 |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| miniapp_audit_session | 每阶段一条,name/stage 为阶段,count 为序号,result 为原因码,message 记录计划时长、预热和离开倒计时等会话信息 |
|
|
60
|
+
| miniapp_audit_paint | FCP 首次实测立即上报;LCP 收口后上报一次;stage=finalized 且 result=measured 的 LCP 才进入首屏分布统计 |
|
|
61
|
+
| miniapp_audit_incident | 事故发生时一条,name/result 为事故类型,source 为来源,message 为摘要 |
|
|
62
|
+
| miniapp_audit_package | 每会话一个记录组,体积直接放入 size,文件数量和能力标记放入 count |
|
|
63
|
+
| miniapp_audit_result | 每会话最多 20 条。每个指标在同一条记录中显式携带实测值、得分和权重;total_score 同时记录总分、覆盖率、有效时长、风险数量及诊断 JSON |
|
|
64
|
+
|
|
65
|
+
本地保持完整 1 Hz 采集,评分和峰值/P95/增长速率使用完整样本。运行期样本只在本地参与评分和交互观察。完整终态分别上报纹理、缓冲、WASM 和 Worker 等派生指标。终态包含 16 个评分指标、heap_p95、buffer_watermark、fps_p5,以及一条 total_score 摘要,合计最多 20 条;只有缺失数值、得分和权重时省略该指标。
|
|
66
|
+
|
|
67
|
+
tracker 满 10 条或等待 10 秒触发发送,每个请求最多 10 条,50 条分为 5 个请求,尾批按实际条数发送。同一 SDK 模块内的 tracker 共用有序发送队列,每批完成(含重试)后发送下一批;每次请求尝试最多等待 5 秒,网络错误、超时及 5xx 最多尝试三次,4xx 结束该批。FCP 首次实测和 LCP 收口及时 flush,终态在最后一条记录统一 flush,然后发布业务报告。
|
|
68
|
+
|
|
69
|
+
阈值校准优先使用完整终态派生指标,并按运行环境、形态和策略版本分组。Runtime 失联时,宿主发送失败终态并冲刷已收到的数据;缺失指标不视为零风险。
|
|
70
|
+
|
|
71
|
+
## 5. 请求示例与查询
|
|
72
|
+
|
|
73
|
+
请求 Header 为 Content-Type: application/json、Biz-Type: apm_fe、Batch: true;请求体是 metric 数组,顶层信封由 tracker 统一生成。
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"context_artifactName": "skillbuilder-miniapp",
|
|
78
|
+
"measurement_name": "miniapp_simulator_event",
|
|
79
|
+
"measurement_data": {
|
|
80
|
+
"event_name": "miniapp_audit_result",
|
|
81
|
+
"business_line": "mars",
|
|
82
|
+
"app_id": "<app-id>",
|
|
83
|
+
"audit_session_id": "<audit-session-uuid>",
|
|
84
|
+
"attempt_no": 1,
|
|
85
|
+
"policy_version": "<policy-version>",
|
|
86
|
+
"app_type": "tool",
|
|
87
|
+
"name": "peak_heap",
|
|
88
|
+
"memory": 104857600,
|
|
89
|
+
"result": "scored",
|
|
90
|
+
"stage": "manual"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- 首屏:按 name=fcp/lcp 查询 time;LCP 仅统计 paint 事件中 stage=finalized、result=measured 的记录。
|
|
96
|
+
- 包体:name=zip_size/unpacked_size,size 为原始字节数;score/weight 为对应评分及权重。
|
|
97
|
+
- 内存:name=peak_heap/heap_p95 查询 memory;name=heap_growth 查询 value,unit=MB/min。
|
|
98
|
+
- 流畅度:name=fps_median/fps_p5 查询 value,unit=fps;name=long_task_max 查询 time。
|
|
99
|
+
- 摘要:name=total_score 的 score 为总分、ratio 为覆盖率、time 为有效采集毫秒数、count 为风险数量;message.result_record_count 为该终态预期记录条数;message.quality 记录样本数、交互数、完整性、证据充足和探针饱和等状态。
|
|
100
|
+
- 事故和分类:total_score 的 message.failure_code 为主要风险码,message.classification 为引擎、框架、置信度和有界证据,message.category_scores 为分类得分。
|
|
101
|
+
- 证据:正常 Runtime 与宿主失败补报均直接使用公共字段;同一 audit_session_id + attempt_no 关联记录,终态去重并整组冲刷。
|
|
102
|
+
|
|
103
|
+
## 6. 发送端与版本核对
|
|
104
|
+
|
|
105
|
+
评测采集和记录生成由 Runtime 执行;APM 网络发送由宿主 SDK 执行。Runtime 发布与宿主 SDK 升级分别生效。核对发送行为时检查 sdk_version,核对采集和记录结构时检查 runtime_version。APM 仅有请求发出或 HTTP 成功不能证明完整入库;按 context_sdkSessionId + context_sdkSeqId 检查连续性,按 audit_session_id + attempt_no 检查摘要及核心指标是否齐全。
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# 小工具体验评测本地验证
|
|
2
|
+
|
|
3
|
+
## 验证结论
|
|
4
|
+
|
|
5
|
+
一期可在本地模拟 Mars 队列逐包采集、真实操作、停止评测和结算,并产出 `scored`、`unscorable` 或 `loadFailed` 三态报告。2026-10-16 输入目录共 13 个 ZIP:已有 5 个首屏验证记录,本轮检查其余 8 个;其中 7 个实际操作后出分,森林游戏仅到选关地图,受浏览器操作工具限制,未完成主循环验证。不能将这 13 个包表述为全部通过当前策略实操验收。
|
|
6
|
+
|
|
7
|
+
当前策略为 `enforce: false`。报告用于观察、排序和人工复核,不作为自动放行结论。出现 `contextLost`、持续堆增长、显存超线或 guest crash 时,面板统一显示红色“需复核”;总分不能覆盖硬性风险。JS 异常默认权重为 0.5,`blocking.jsFatal: false`,保留异常数量与事故证据。
|
|
8
|
+
|
|
9
|
+
审核队列的平均处理时间约为 1 分钟,不是固定 1 分钟倒计时。可评分的最低证据是 30 秒有效采集、30 个快照、至少 1 次真实输入,并满足最低指标覆盖度、采集完整且无基础设施异常;策略最长时钟为 2 分钟。审核员按既有节奏实际体验,离开整个模拟器容器(含留白与评测面板) 30 秒后自动结束并上报,也可手动停止。证据不足时保留数据,不为等分延长审核。OOM、泄漏、晚发 JS 异常等疑点可进入专项复测。
|
|
10
|
+
|
|
11
|
+
## 离开区域自动结束验证(2026-10-21)
|
|
12
|
+
|
|
13
|
+
Mars 策略配置 `autoStopOnLeaveMs: 30000`;默认策略版本 `phase1-fps-priority-v6-2026-10-23`。离开自动结束、移回取消、真实输入延后、重复停止、guest reload、销毁及禁用分支通过定向自动化验证;联动测试确认正常停止产生一份终态报告,保留 `unscorable`,并映射 `stop_reason` 与 `auto_stop_on_leave_ms`。
|
|
14
|
+
|
|
15
|
+
在 5286/5284 模拟器整页刷新后加载真实 `瀑布流页面.zip`,搜索 `124917` 显示 1 张封面。边界使用完整的 `miniapp-simulator-host`,覆盖设备、蓝色留白和评测侧栏。点击手机右侧蓝色留白后,采集从第 15 秒持续到第 28 秒,未显示离开倒计时;再次停在留白处,采集从第 94 秒持续到第 107 秒。
|
|
16
|
+
|
|
17
|
+
会话 `05b5c521-4526-48c8-b5f4-2627babcf5a1` 在 120 秒上限正常结束:有效采集约 115 秒、116 样本、1 次输入,报告 `scored`。策略版本 `phase1-fps-priority-v4-2026-10-21`,报告携带 `stopReason: duration_limit` 和 `autoStopOnLeaveMs: 5000`,终态附近 `trackerDelivery` 为 HTTP 200。不代表 APM 后台已完成字段登记或入库验证。
|
|
18
|
+
|
|
19
|
+
模拟器定向测试 44 项、插件测试 69 项通过,两个包的类型检查、模拟器 npm 构建和远程开发构建通过。自动化点击容器外部后,浏览器的实际 `:hover` 状态仍在容器内,因此完整的移出、返回链路尚不能据此视为浏览器验收通过。真实 Mars 联调需覆盖:手机、留白与面板之间移动继续采集,移到外层审核表单开始倒计时,30 秒内返回取消,连续离开到期只上报一次,以及到期前切换队列按中断处理。
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
## LCP 输入边界验证(2026-10-20)
|
|
24
|
+
|
|
25
|
+
使用 `/Users/wangchen1/Downloads/小工具测试包/瀑布流页面.zip`,每轮完整刷新 5286/5284 模拟器,开启 Mars 模式、加载真实 ZIP 并点击开始审核。策略 `phase1-fps-priority-v3-2026-10-19`,规则 `1.2.0`,探针 `1.1.1`。
|
|
26
|
+
|
|
27
|
+
| 操作路径 | FCP / LCP | 首次收口事件 / 导航时间 | 有效采集 / 样本 / 输入 | 结果 |
|
|
28
|
+
| --- | --- | --- | --- | --- |
|
|
29
|
+
| 先搜索 124101 命中 1 张,清空搜索,切换古风分类,翻到第 2/2 页,停止评测 | 44ms / 52ms | input / 7730ms | 51s / 52 / 2 | scored,100 分 |
|
|
30
|
+
| 先点击古风分类,搜索 124917 命中 1 张,清空搜索,恢复全部 32 张,停止评测 | 32ms / 40ms | touchstart / 7118.5ms | 70s / 71 / 3 | scored,100 分 |
|
|
31
|
+
|
|
32
|
+
两轮候选元素均为 `img`;首次输入固定截止时间,后续业务重绘不改变首屏 LCP,停止评测保留首次收口原因。数值为本机浏览器的 guest 导航观测,不代表移动端实测结果。输入次数按 200ms 去重,不等于操作步骤数。
|
|
33
|
+
|
|
34
|
+
自动化验证覆盖 `input/change/click` 单独触发、截止前待派发候选、截止后候选、迟到的较早记录,以及停止请求保留首次截止时间。插件 69 项、上报及宿主链路 24 项测试通过;插件和模拟器类型检查、远程开发构建通过。
|
|
35
|
+
|
|
36
|
+
两轮终态投递均返回 HTTP 200。`miniapp_audit_paint` 和 `miniapp_audit_result` 的字段映射已核对,包含 `lcp_finalized_at_ms`、`paint_finalize_event`、`lcp_element_tag`、`lcp_element_size`;APM 后台入库和字段可检索性未在此验证中确认。
|
|
37
|
+
|
|
38
|
+
第一轮会话:`bf0fe988-395b-4e00-ae2c-c9ddeb5301b1`;第二轮会话:`c5811fff-02ea-4cb4-8078-df80e53b76ab`。
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
## 面板与长任务验证(2026-10-16)
|
|
43
|
+
|
|
44
|
+
当前默认策略为 `phase1-balanced-v2-2026-10-16`,规则版本 `1.1.2`,探针版本 `1.1.0`。分类汇总与明细按运行性能、包体积、稳定性、内存排列,稳定性当前只有 JS 异常,单独上报 `score_stability`。
|
|
45
|
+
|
|
46
|
+
长任务权重为 1,≤500ms 为 100 分,500~3000ms 线性递减,≥3000ms 为 0 分。定向核验:500ms 为 100 分、567ms 为 97 分、1000ms 为 80 分、3000ms 为 0 分。
|
|
47
|
+
|
|
48
|
+
真实 `生化危机.zip` 实操记录(策略 `phase1-balanced-2026-10-16`、规则 `1.1.1`):已执行开始剧情、跳过演出、移动、转向、举枪、攻击和放下;有效采集 38s、39 个样本、7 次操作。最长任务 598ms 得 96 分;稳定性汇总为 1/1,内存汇总为 26/26。报告为 scored、99 分,命中 `contextLost`,面板保留需复核与硬风险提示。
|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
## FCP/LCP 真实包验证(2026-10-16)
|
|
53
|
+
|
|
54
|
+
环境:独立 worktree,页面 `http://127.0.0.1:5286/simulator?server=http://127.0.0.1:5284/simulator-dev/`。策略 `phase1-paint-2026-10-16`,规则/探针 `1.1.0`。逐包完整刷新模拟器、加载目录中的真实 ZIP 并执行实际功能;下表不包含 SDK 示例包。
|
|
55
|
+
|
|
56
|
+
| ZIP | 实际操作 | 有效采集 / 样本 / 操作 | FCP / LCP | 结果 |
|
|
57
|
+
| --- | --- | --- | --- | --- |
|
|
58
|
+
| 编钟模拟器.zip | 进入五音章节,敲青钟、赤钟,画面和文字切换 | 44s / 45 / 3 | 13252ms / N/A | scored,74 分;没有 LCP 候选,未补零 |
|
|
59
|
+
| 像素旅行游戏.zip | 开始闯关、选天坛关卡与领队、关闭教学、瞄准并发射弹珠 | 50s / 51 / 6 | 224ms / 324ms | scored,91 分;LCP 首次操作收口 |
|
|
60
|
+
| mbti算命.zip | 完成 28 题并进入 ESTJ 结果页 | 78s / 79 / 29 | 128ms / 128ms | scored,89 分;首屏项均为 100 分 |
|
|
61
|
+
| webgl-中秋赏月.zip | 启程、打开夜色选择、填写测试愿望并进入封灯步骤 | 77s / 78 / 7 | 228ms / 228ms | scored,94 分;WebGL 内存与首屏均有读数 |
|
|
62
|
+
| 生化危机.zip | 开始剧情、跳过演出、移动、转向、举枪、攻击和放下 | 43s / 44 / 8 | 128ms / 128ms | scored,95 分;命中 contextLost,需复核 |
|
|
63
|
+
|
|
64
|
+
FCP/LCP 是本地已装载包的 guest 导航绘制值,不包含 ZIP 上传与解压。编钟包本次 FCP 在进入章节附近出现,LCP 没有原生候选;该值仅作为当次观测,不据此认定包普遍存在 13 秒首屏问题。游戏封面/文字的 LCP 不代表 Canvas 游戏主循环就绪,核心场景仍由真实操作确认。
|
|
65
|
+
|
|
66
|
+
WebGL 包已核对真实发送路径的 APM 请求体:`measurement_name=miniapp_simulator_event`,`event_name=miniapp_audit_paint`;result 同时携带 `fcp_ms/lcp_ms`、状态、`lcp_finalized: 1`、`score_fcp/score_lcp: 100`、`fcp_threshold_ms: 1800`、`lcp_threshold_ms: 2500` 和版本字段。所有布尔语义均为 0/1。首屏发送与终态发送均观测到 HTTP 200;APM 平台落入和可检索性需通过平台查询确认。
|
|
67
|
+
|
|
68
|
+
[真实 APM 请求摘录](./assets/audit-paint-webgl-apm-excerpt-2026-10-16.json)
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+

|
|
73
|
+
|
|
74
|
+
## 审核员操作 SOP
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
进入队列项
|
|
78
|
+
→ 完整重载模拟器,隔离上一个包的 Realm、计时器和资源
|
|
79
|
+
→ 点击开始审核,先安装 document-start 探针再加载小工具
|
|
80
|
+
→ 真实使用主要功能:输入、选择、跳转、计算、播放或游戏操作
|
|
81
|
+
→ 检查结果页、主要功能输出或游戏中的操作响应
|
|
82
|
+
→ 移向 Mars 审核表单;离开整个模拟器容器(含留白与评测面板) 30 秒后自动结束并上报
|
|
83
|
+
→ 30 秒内移回可继续评测;也可点击“停止评测”,最长 2 分钟自动结算
|
|
84
|
+
→ 查看三态结果、硬性风险和证据质量
|
|
85
|
+
→ 保存结果并进入下一队列项,重新完整重载模拟器
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
只打开页面、等待计时或仅点击“开始审核”不构成有效评测。没有可操作控件的静态诊断包应得到 `unscorable`,而不是为了出分伪造一次点击。
|
|
89
|
+
|
|
90
|
+
审核员无需额外确认停止。手机、内部留白和评测面板之间移动不会自动结束,鼠标在外但仍用键盘操作小工具时会延后倒计时;停止不代表功能检查通过,点击数也不自动证明业务流程完成。样本、时长、交互或覆盖度不足时保留数据和具体原因,审核员可按现有业务规则提交并继续下一项。自动结束与上报不依赖 Mars 接口;倒计时到期前就刷新时按中断处理。报告等待或投递失败不得阻塞队列。
|
|
91
|
+
|
|
92
|
+
## 剩余 8 个 ZIP 实操验证(2026-10-16)
|
|
93
|
+
|
|
94
|
+
目录:`/Users/wangchen1/Downloads/小工具测试包/`。环境同本页 5286/5284 模拟器;策略 `phase1-balanced-v2-2026-10-16`、规则 `1.1.2`、探针 `1.1.0`。每包均完整刷新宿主模拟器,再选择真实 ZIP、开始审核;除标明的森林 PC 复试外,设备为 iPhone 15 Pro。测试期间不调整策略。
|
|
95
|
+
|
|
96
|
+
| ZIP | 实际操作与覆盖范围 | 有效秒 / 样本 / 输入 | FCP / LCP(ms) | 结果 |
|
|
97
|
+
| --- | --- | --- | --- | --- |
|
|
98
|
+
| 拜月亮.zip | 地点与角色、摆案、五类供品、点烛起香、念祝词与叩拜;流程到第 5/9 阶段,未走完全部仪式 | 115 / 116 / 12 | 132 / 168 | scored,100 分;2 分钟上限自动结算 |
|
|
99
|
+
| 深夜读信人-windows黑屏.zip | 打开来信、点击“83天”线索、逐段读完一封信、进入隐私编辑、暂缓保存草稿,返回案头 | 56 / 57 / 8 | 72 / 140 | scored,98 分;解码图片约 24MB,未公开信件 |
|
|
100
|
+
| 九霄宗门模拟器.zip | 创建测试家族、派遣 4 名游手、族议、灵田升 2 级、任命薛鸿为掌门、查看弟子 | 67 / 68 / 6 | 104 / 140 | scored,100 分;出现 SDK 剪贴板桥异常,见下表 |
|
|
101
|
+
| jianshouji-minitool-20260730-v10.zip | 用户确认协议后创建虚构角色、指定“我”、生成 1 条虚构聊天、命名保存,退出后在草稿箱核对作品 | 62 / 63 / 15 | 104 / 104 | scored,100 分;未点击对外发布 |
|
|
102
|
+
| 瀑布流页面.zip | 搜索 124101 命中 1 张、古风分类 9 张、全部 32 张逐页翻到第 4/4 页并返回、空分类与恢复全部 | 41 / 42 / 10 | 96 / 4196 | scored,87 分;LCP 单项 45 分,长任务 62ms 不扣分 |
|
|
103
|
+
| 答题错题页面滚动.zip | 填写测试姓名、逐题完成 15 题、进入成绩单(5 对 10 错)、End 键使 body 滚动 1149.5px 查看错题 | 67 / 68 / 18 | 96 / 96 | scored,100 分;业务答题成绩 34 分不是质量评分 |
|
|
104
|
+
| forest-fire-water-rafloop-fix.zip | 竖屏点击开始到选关地图;完整刷新 PC 复试;嵌套缩放 iframe 的坐标操作被浏览器工具拒绝,未进入关卡 | 97 / 98 / 1;PC 41 / 42 / 1 | 96 / N/A;PC 140 / N/A | 两次 unscorable,核心场景未确认;不计为已完成游戏实操 |
|
|
105
|
+
| 诗云星图-试用版.zip | 显示全部、搜索李白(11 关系)、点击结果、开始/停止巡游、自动播放并看到诗人高亮切换、停止 | 50 / 51 / 5 | 160 / 160 | scored,100 分;31 次长任务,最长 433ms;FPS P5 21.5 |
|
|
106
|
+
|
|
107
|
+
“捡手机”接受协议前另有一次 34 秒、35 样本、0 输入、未确认核心场景的试跑,结果为 `unscorable`。它验证证据门槛,不计入实际创作完成数。输入数按探针去重口径记录,不等于所有点击和按键次数。
|
|
108
|
+
|
|
109
|
+
7 个出分报告均未观察到业务 JS 异常,未命中硬风险。这个样本集不能用于证明 JS 异常权重已完成实证校准,也不能证明不存在晚发异常或手机 OOM。各次终态附近的 `trackerDelivery` 均记录 HTTP 200;该回执不能代替 APM 平台落库查询。
|
|
110
|
+
|
|
111
|
+
[本轮 10 次有留存的报告、操作路径与回执](./assets/audit-remaining-results-2026-10-16.json)(8 个包,含协议门槛试跑和森林两种设备;JSON 中 `report.versions` 保留版本)。
|
|
112
|
+
|
|
113
|
+

|
|
114
|
+
|
|
115
|
+
## 指标与评分待处理项
|
|
116
|
+
|
|
117
|
+
本轮 7 个可评分样本中,5 个为 100 分、1 个 98 分、1 个 87 分。首屏评分能区分较慢的 LCP,但当前总分主要反映所测窗口内的技术预算,不等于全部功能、持续流畅性或长时内存安全验收。
|
|
118
|
+
|
|
119
|
+
| 优先级 | 实测证据与代码口径 | 调整方向 |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| 高 | 星图是诗人关系可视化,报告识别为 `game3d`、`tagMismatch=true`;`rules/applicable.ts` 将声明 tool 且检测到 WebGL 的包改判 game3d。7.6MB 包因采用游戏 profile 的 12MB 满分阈值得 100 分 | WebGL 能力与业务类型分别判断;支持关系图、地图等非游戏场景,避免仅按技术栈放宽包体和内存预算 |
|
|
122
|
+
| 高 | 5/7 个出分包的 `peakHeapBytes=0`。`rules/derive.ts` 使用 `max(0, heapP95-baseline)`;基线在 Runtime 读取、样本在 guest 读取。校正结果为 0 不代表实际不占内存 | 面板明确基线校正口径;终态同时保留原始 P95、基线与校正值,验证跨 Realm/共享进程及 GC 的影响,再用于阈值校准 |
|
|
123
|
+
| 高 | 星图 `fpsP5=21.5`、`fpsMedian=30`;`rules/evaluate.ts` 面板项使用中位数,但 `panel/copy.ts` 描述为 P5 | 统一面板标签、取值和说明;APM 的 P5 与中位数明确区分;FPS 权重保持 0 时仅作观察 |
|
|
124
|
+
| 中 | 星图约 50 秒内有 31 次长任务,最长 433ms,长任务单项仍为 100 分;当前只按最长一次计分 | 保持长任务权重 1;结合次数、持续交互场景观察,评估补充累计阻塞时长/占比,不能只凭最长任务合格认定持续流畅 |
|
|
125
|
+
| 中 | 九霄等包控制台出现 `installPageClipboardBridge` 的 `Cannot redefine property: clipboard`;探针按精确特征忽略该 SDK 错误,业务 JS 与基础设施错误计数均为 0 | SDK 问题单独诊断上报,不扣业务 JS 分;已知可忽略错误保留计数,避免基础设施故障完全不可见 |
|
|
126
|
+
| 中 | 拜月亮在第 5/9 阶段达到 2 分钟上限;`quality.complete=true` 但业务流程未全部覆盖 | 区分采集完整和业务路径完成;复杂包记录阶段覆盖,必要时追加专项长跑,不延长所有队列项 |
|
|
127
|
+
| 待补测 | 森林两次均未进入关卡,LCP 无原生候选;首屏 96ms 不能代表游戏就绪 | 使用可操作该画布的浏览器或人工选关后,补测移动、跳跃和关卡交互;在此之前不做该游戏评分合理性的结论 |
|
|
128
|
+
|
|
129
|
+
内存短窗口正斜率不是泄漏的充分证据,面板中的“长会话必然 OOM”“唯一真正可信”表述不适合作为审核结论。以上为待实施项,本轮未改评分代码或评分策略。
|
|
130
|
+
|
|
131
|
+
## 一期已覆盖的指标
|
|
132
|
+
|
|
133
|
+
| 维度 | 当前采集与处理 |
|
|
134
|
+
| ---------- | ------------------------------------------------------------------------------------------ |
|
|
135
|
+
| JS 内存 | 峰值堆、稳定段最小二乘增长速率;样本不足时不计算斜率 |
|
|
136
|
+
| 图形内存 | WebGL texture/buffer/renderbuffer 配对记账水位、Canvas 后备缓冲、图片解码内存 |
|
|
137
|
+
| 运行稳定性 | JS error/unhandled rejection、`webglcontextlost`、guest crash、Runtime hang |
|
|
138
|
+
| 运行性能 | Guest FCP/LCP、rAF 窗口 FPS P5 与中位数、采集期最长单次 Long Task 与次数 |
|
|
139
|
+
| 能力资源 | WASM Memory、存活 Worker 数;不适用项明确为 N/A,不进入总分分母 |
|
|
140
|
+
| 包体 | 解压总体积、最大单图、单个未压缩 JS |
|
|
141
|
+
| 证据质量 | 有效时长、样本数、真实操作次数、首次操作时间、覆盖度、采集是否完整、探针是否饱和 |
|
|
142
|
+
|
|
143
|
+
一期无法用桌面浏览器直接证明真实手机 OOM,`performance.memory` 也只覆盖 JS 堆。因此一期输出风险信号,不把“桌面未 OOM”写成“移动端安全”。二期需要关联真机 RSS/PSS、GPU 驱动占用、系统内存告警、进程终止/崩溃原因和低中高端机型分层样本。
|
|
144
|
+
|
|
145
|
+
## 一期上线前置项
|
|
146
|
+
|
|
147
|
+
| 前置项 | 验收结果 |
|
|
148
|
+
| --------- | ------------------------------------------------------------------------------------------- |
|
|
149
|
+
| 逐包隔离 | 队列切换必须整页重载模拟器,不能复用上一个 guest Realm |
|
|
150
|
+
| 有效使用 | 至少 1 次输入到达 guest;审核员按 SOP 检查主要功能,静态无交互包不出分 |
|
|
151
|
+
| 异常收口 | Runtime 12 秒无进度产生 `loadFailed:RUNTIME_HUNG`;熔断和失联产生 `unscorable` 或结构化失败 |
|
|
152
|
+
| 结论显示 | 硬风险统一为“需复核”,总分红色显示,不允许只按分数放行 |
|
|
153
|
+
| APM 上报 | 上报任务、应用、包版本、策略版本、终态派生指标、FCP/LCP、包体摘要、操作证据、三态终态和风险 |
|
|
154
|
+
| Mars 集成 | 在真实审核队列完成连续 20 包回归,确认切换、超时、刷新和结果保存不阻塞审核员 |
|
|
155
|
+
| 策略状态 | 保持 `enforce: false`,完成真机相关性与阈值回放后再评估自动卡口 |
|
|
156
|
+
|
|
157
|
+
## 验证命令
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pnpm --dir packages/miniapp-audit-plugin test
|
|
161
|
+
pnpm --dir packages/miniapp-audit-plugin typecheck
|
|
162
|
+
pnpm --dir packages/miniapp-simulator exec vitest run tests/remote-audit-watchdog.test.ts tests/remote-audit-lazy-load.test.ts
|
|
163
|
+
pnpm --dir packages/miniapp-simulator typecheck
|
|
164
|
+
pnpm --dir packages/miniapp-simulator build:remote:dev
|
|
165
|
+
```
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# 小工具体验评测与准入设计
|
|
2
|
+
|
|
3
|
+
## 目标与边界
|
|
4
|
+
|
|
5
|
+
小工具是开发者自带构建产物的 Web 内容,评测形态包括工具、2D 游戏和 3D 游戏。评测需要在 Mars 远程模拟器中识别内存增长、图形资源高水位、运行异常、主线程卡顿和包体问题,并给审核员可解释、可复核的证据。
|
|
6
|
+
|
|
7
|
+
一期采用 Web 侧动态采集,默认 `enforce: false`,用于观察和人工复核。它不能等价替代真机 OOM 结论:浏览器 JS 堆不包含原生 RSS/PSS、GPU 驱动、媒体解码器和系统内存压力。二期将 Web 风险信号与真机进程、崩溃和机型数据关联后再校准自动卡口。
|
|
8
|
+
|
|
9
|
+
## 审核队列模型
|
|
10
|
+
|
|
11
|
+
审核员在队列中逐个处理小工具,每个队列项都创建独立会话并完整重载模拟器:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
队列项进入
|
|
15
|
+
→ Mars Runtime 建连,按需加载独立评测插件
|
|
16
|
+
→ 审核员开始审核
|
|
17
|
+
→ document-start 探针先注册,小工具后加载
|
|
18
|
+
→ 审核员真实操作主要功能并检查结果
|
|
19
|
+
→ 离开整个模拟器容器(含留白与评测面板) 30 秒后自动结束并上报,或点击“停止评测”
|
|
20
|
+
→ 最长 2 分钟自动结算
|
|
21
|
+
→ 保存报告并完整重载模拟器
|
|
22
|
+
→ 下一队列项
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
平均处理时间约为 1 分钟,不是固定时限。策略默认最低有效时长 30 秒、最低 30 个快照、至少 1 次真实输入、覆盖度不低于 0.6;正常完整采集且无基础设施异常时可出分,最长会话时钟为 120 秒。审核员可随时停止评测,证据不足时保留数据和原因,不为等待出分延长队列处理时间。OOM、泄漏和晚发异常风险较高的内容可安排专项复测。
|
|
26
|
+
|
|
27
|
+
交互计数只记录实际到达 guest 的输入事件,不保存输入文本和屏幕坐标。审核员按 SOP 检查主要功能或结果,游戏需进入主循环并实际操作。离开整个模拟器容器(含留白与评测面板) 30 秒自动结束;倒计时内移回取消,区域外仍有真实输入时延后,手机、内部留白与面板间移动不结束。面板保留“停止评测”按钮,Apollo 通过 `autoStopOnLeaveMs` 调整延迟,0 表示关闭。自动结束和上报由模拟器内部完成,不要求 Mars 接口。停止不表示功能或审核通过,也不伪造业务完成证据;提前刷新按中断处理,上报失败不阻塞队列。
|
|
28
|
+
|
|
29
|
+
## 报告状态与消费顺序
|
|
30
|
+
|
|
31
|
+
| 状态 | 含义 | 审核处理 |
|
|
32
|
+
| ------------ | ----------------------------------------- | -------------------------------- |
|
|
33
|
+
| `scored` | 采集完整,时长、采样、交互和覆盖度均满足,且无基础设施异常 | 查看风险、分项和总分,保留体验反馈 |
|
|
34
|
+
| `unscorable` | 证据不足,或采集被资源熔断/失联截断 | 人工复核,不可按分数放行 |
|
|
35
|
+
| `loadFailed` | ZIP 无法启动,或 Runtime/guest 主线程卡死 | 展示结构化失败码并进入下一队列项 |
|
|
36
|
+
|
|
37
|
+
消费顺序固定为:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
status === scored
|
|
41
|
+
→ quality.complete === true
|
|
42
|
+
→ blocking.passed === true
|
|
43
|
+
→ 再消费总分和分项建议
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
只要命中硬性风险,面板显示红色“需复核”,总分同步使用风险色,并提示“不能仅按分数放行”。`enforce: false` 只表示不自动拒绝,不表示风险通过。
|
|
47
|
+
|
|
48
|
+
## 采集指标
|
|
49
|
+
|
|
50
|
+
面板分类汇总与指标明细的展示顺序为:运行性能 → 包体积 → 稳定性 → 内存。稳定性当前包含 JS 异常,内存分类只展示内存和资源占用指标;硬风险单独提示。
|
|
51
|
+
|
|
52
|
+
### 运行期
|
|
53
|
+
|
|
54
|
+
| 指标 | 口径 | 权重 | 当前用途 |
|
|
55
|
+
| ----------- | -------------------------------------------------------- | ---: | ------------------------------- |
|
|
56
|
+
| 峰值 JS 堆 | guest `performance.memory` 有效样本最大值 | 6 | 分数;识别异常高占用 |
|
|
57
|
+
| JS 堆变化速率 | 排除前 20% 样本后的最小二乘斜率,MB/min | 0 | 观察、上报和复测选样,不单独判定泄漏 |
|
|
58
|
+
| 显存水位 | WebGL texture/buffer/renderbuffer 存活字节配对记账的 P95 | 6 | 分数 + profile 硬风险 |
|
|
59
|
+
| Canvas 缓冲 | 存活 canvas 像素后备缓冲峰值 | 3 | 分数 |
|
|
60
|
+
| 解码图片 | 存活图片像素字节峰值 | 4 | 分数 |
|
|
61
|
+
| WASM 内存 | `WebAssembly.Memory` 已分配页峰值 | 3 | 能力存在时计分 |
|
|
62
|
+
| Worker 数 | 存活 Worker 峰值 | 2 | 能力存在时计分 |
|
|
63
|
+
| JS 异常 | `error` 与 `unhandledrejection` 计数 | 0.5 | 低权重风险信号;默认不触发硬卡口 |
|
|
64
|
+
| FCP | guest 导航到首次内容绘制 | 4 | 首屏分数 + 独立 APM 观测 |
|
|
65
|
+
| LCP | guest 导航到最大内容绘制,交互或结束时收口 | 10 | 首屏分数 + 独立 APM 观测 |
|
|
66
|
+
| 帧率 | rAF 采样窗口 FPS 中位数;P5 单独上报 | 5 | 流畅度评分,结合实际操作解释 |
|
|
67
|
+
| 长任务 | 采集期最长一次主线程 Long Task | 1 | 低权重;500ms以内不扣分,3000ms为0分 |
|
|
68
|
+
| 上下文丢失 | `webglcontextlost` 任意发生 | — | 硬风险 |
|
|
69
|
+
| guest crash | guest 崩溃/失联 | — | 硬风险或结构化失败 |
|
|
70
|
+
|
|
71
|
+
不适用项明确标为 N/A,不进入总分分母。探针记账达到上限时设置 `probeSaturated`,受影响的显存和 Canvas 项降级为 N/A,不使用偏低读数出分。
|
|
72
|
+
|
|
73
|
+
### 首屏评分与观测
|
|
74
|
+
|
|
75
|
+
FCP/LCP 使用 Lighthouse mobile 的对数正态评分曲线作为种子曲线,单项满分 100:
|
|
76
|
+
|
|
77
|
+
| 指标 | 良好边界,约 90 分 | 50 分控制点 | 默认权重 |
|
|
78
|
+
| --- | ---: | ---: | ---: |
|
|
79
|
+
| FCP | 1800ms | 3000ms | 4 |
|
|
80
|
+
| LCP | 2500ms | 4000ms | 10 |
|
|
81
|
+
|
|
82
|
+
依据:[FCP](https://web.dev/articles/fcp)、[LCP](https://web.dev/articles/lcp)、[Lighthouse 评分机制](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring)。曲线控制点见 Lighthouse 的 [FCP 实现](https://github.com/GoogleChrome/lighthouse/blob/main/core/audits/metrics/first-contentful-paint.js)与 [LCP 实现](https://github.com/GoogleChrome/lighthouse/blob/main/core/audits/metrics/largest-contentful-paint.js)。桌面模拟器使用这组用户体验参考值,不代表移动设备实测或完整 Lighthouse 得分。
|
|
83
|
+
|
|
84
|
+
探针从 document-start 监听浏览器 Paint Timing,使用 buffered observer 补取启动记录,不等待 3 秒预热。时钟起点为小工具 guest 导航,不包含 ZIP 上传、解压和 Runtime 建连。LCP 候选在首次输入、滚动、页面隐藏、pagehide 或停止审核时收口;停止时排空 observer 待处理记录,插件最多等待 150ms 确认,未确认的候选不参与评分。
|
|
85
|
+
|
|
86
|
+
不支持 API、首屏前已隐藏或没有合格绘制时显示 N/A,不以 0ms 补齐。Canvas/WebGL 画面不属于 LCP 主内容,游戏中的 DOM 标题也不能证明游戏核心场景已经可用;可玩性由审核员通过实际操作检查。FCP 首次实测和 LCP 收口独立触发 APM flush,即使有效时长不足,也保留首屏数据。看板按 `policy_version`、设备/环境和形态分组,使用已收口且实测的 LCP 计算 P75,不混入缺失或失效 attempt。
|
|
87
|
+
|
|
88
|
+
运行过程相对权重为 FPS 5 > 长任务 1 > JS 异常 0.5。JS 异常完整累计并保留代表性事故证据,默认 `blocking.jsFatal: false`。错误数量不直接证明功能损坏;功能是否受影响需结合真实操作反馈、失联/崩溃等证据判断。APM 使用 `name=fps_median/fps_p5` 和 `value` 记录帧率,单位明确为 fps;得分和权重直接填写 `score/weight`,按策略版本分析。
|
|
89
|
+
|
|
90
|
+
### 静态包
|
|
91
|
+
|
|
92
|
+
| 指标 | 口径 | 权重 |
|
|
93
|
+
| --- | --- | ---: |
|
|
94
|
+
| ZIP 压缩体积 | `loadZip` 收到的 ZIP 二进制 `byteLength` | 5 |
|
|
95
|
+
| 解压总体积 | ZIP 内全部文件解压后字节和 | 3 |
|
|
96
|
+
| 最大单图 | 单个图片文件最大字节数 | 1 |
|
|
97
|
+
| 未压缩 JS | 单文件超过 `uncompressedJsKB` 的 JS 字节数之和 | 1 |
|
|
98
|
+
|
|
99
|
+
ZIP 使用统一评分线:≤2MiB 得 100 分,5MiB 得 60 分,≥10MiB 得 0 分,两个区间内线性插值;由 `strategy.size.zip` 配置。解压体积由 `strategy.profiles.<形态>.size` 独立配置,工具类默认 2/4/9MiB,2D 游戏 6/12/24MiB,3D 游戏 12/20/32MiB,分别对应 100/60/0 分。上述数值为产品初始预算,按 APM 实测分布校准。
|
|
100
|
+
|
|
101
|
+
面板按 ZIP、解压体积、单图、JS 顺序展示;包体权重合计 10,四项由 `strategy.weights` 配置。APM 使用 `name=zip_size/unpacked_size`,分别直接填写 `size`、`score`、`weight`。MiB 为 1024² 字节,评分使用原始字节数,面板显示时取小数。
|
|
102
|
+
|
|
103
|
+
包体指标用于质量排序。无法解析或超过加载安全限制的 ZIP 由加载链路返回 `loadFailed`,不生成伪分数。
|
|
104
|
+
|
|
105
|
+
## 采集与业务隔离
|
|
106
|
+
|
|
107
|
+
探针在 guest document-start 注入,hook 先调用原始实现,再在隔离的 `try/catch` 中记账,保留业务函数的 `this`、参数、返回值和异常语义。WebGL 对象创建、覆盖上传和删除均配对记账;场景释放后水位可以下降。
|
|
108
|
+
|
|
109
|
+
插件构建为独立浏览器 ESM。仅 `businessLine === mars` 动态加载,普通预览链路不请求探针、规则和面板资源。截图失败属于证据附件失败,不中断指标采集。
|
|
110
|
+
|
|
111
|
+
## 卡死、熔断与队列恢复
|
|
112
|
+
|
|
113
|
+
评测期间 Runtime 持续向宿主发送进度。宿主每次收到进度都重置 12 秒静默计时器;连续 12 秒没有进度时,立即发布:
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
status: loadFailed
|
|
117
|
+
loadFailure.code: RUNTIME_HUNG
|
|
118
|
+
source: host-watchdog
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
总时钟仍保留“策略最长时长 + 35 秒收口余量”,用于防止 Runtime 持续发空进度却不结算。评测模式的 guest 堆熔断线为 3GiB;触发时报告为采集中断,保留已观测到的硬风险。审核员对下一队列项执行完整页面刷新,避免复用卡死 Realm。
|
|
122
|
+
|
|
123
|
+
## 默认 profile
|
|
124
|
+
|
|
125
|
+
所有 profile 均保持 observe-only:
|
|
126
|
+
|
|
127
|
+
| profile | peakHeapMB | textureMB | canvasMB | imageMB | wasmMB | 包体 ideal / accept / max MB |
|
|
128
|
+
| -------- | ---------: | --------: | -------: | ------: | -----: | ---------------------------- |
|
|
129
|
+
| `tool` | 32 | 48 | 32 | 48 | 32 | 2 / 4 / 9 |
|
|
130
|
+
| `game2d` | 96 | 96 | 64 | 96 | 64 | 6 / 12 / 24 |
|
|
131
|
+
| `game3d` | 200 | 48 | 32 | 32 | 64 | 12 / 20 / 32 |
|
|
132
|
+
|
|
133
|
+
形态由静态指纹和运行能力共同推断;申报形态不一致时保留 `tagMismatch` 供人工复核。`game2d` 样本不足,不开启自动卡口。包内媒体文件作为资源特征记录,业务形态仍使用工具类或游戏类。
|
|
134
|
+
|
|
135
|
+
框架指纹单独记录 PixiJS、Phaser、Cocos、Unity、Three.js、Babylon.js、PlayCanvas、LayaAir、Egret。文件名为候选,脚本标识与特有 API 共同命中或完整构建结构命中为强指纹;支持改名脚本及多个框架,面板显示包内框架,APM 保留命中规则与扫描完整性。指纹用于识别技术栈,业务玩法及 2D/3D 维度需要独立证据。
|
|
136
|
+
|
|
137
|
+
## 策略配置
|
|
138
|
+
|
|
139
|
+
服务端 key 为 `miniappSimulatorAuditPolicies`。每条 `strategy` 都必须是一份完整策略;可按 `businessLines`、`appIds`、`userIds` 命中,命中多条时选择 `priority` 最大的一整份,不做字段合并。服务端只校验外层 JSON、scope 和 priority 结构,不校验审核策略字段。
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
[
|
|
143
|
+
{
|
|
144
|
+
"priority": 0,
|
|
145
|
+
"scope": { "businessLines": ["mars"] },
|
|
146
|
+
"strategy": {
|
|
147
|
+
"policyVersion": "phase1-zip-priority-v9-2026-10-29",
|
|
148
|
+
"enforce": false,
|
|
149
|
+
"minCoverage": 0.6,
|
|
150
|
+
"defaultProfile": "tool",
|
|
151
|
+
"profiles": {
|
|
152
|
+
"tool": {
|
|
153
|
+
"peakHeapMB": 32, "textureMB": 48, "canvasMB": 32,
|
|
154
|
+
"imageMB": 48, "wasmMB": 32,
|
|
155
|
+
"size": { "idealMB": 2, "acceptMB": 4, "maxMB": 9 }
|
|
156
|
+
},
|
|
157
|
+
"game2d": {
|
|
158
|
+
"peakHeapMB": 96, "textureMB": 96, "canvasMB": 64,
|
|
159
|
+
"imageMB": 96, "wasmMB": 64,
|
|
160
|
+
"size": { "idealMB": 6, "acceptMB": 12, "maxMB": 24 }
|
|
161
|
+
},
|
|
162
|
+
"game3d": {
|
|
163
|
+
"peakHeapMB": 200, "textureMB": 48, "canvasMB": 32,
|
|
164
|
+
"imageMB": 32, "wasmMB": 64,
|
|
165
|
+
"size": { "idealMB": 12, "acceptMB": 20, "maxMB": 32 }
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"size": { "zip": { "idealMB": 2, "acceptMB": 5, "maxMB": 10 }, "singleImageKB": 300, "uncompressedJsKB": 1024 },
|
|
169
|
+
"minSamplesForSlope": 30,
|
|
170
|
+
"minEffectiveMs": 30000,
|
|
171
|
+
"minSamplesForScoring": 30,
|
|
172
|
+
"minInteractionsForScoring": 1,
|
|
173
|
+
"evaluationDurationMs": 120000,
|
|
174
|
+
"autoStopOnLeaveMs": 30000,
|
|
175
|
+
"auditModeHeapLimitBytes": 3221225472,
|
|
176
|
+
"weights": {
|
|
177
|
+
"peakHeap": 6, "heapGrowth": 0, "texWatermark": 6,
|
|
178
|
+
"canvasBuffer": 3, "decodedImages": 4, "wasmMemory": 3,
|
|
179
|
+
"workerCount": 2, "jsError": 0.5, "fps": 5, "longTask": 1,
|
|
180
|
+
"fcp": 4, "lcp": 10,
|
|
181
|
+
"zipSize": 5, "unpackedSize": 3, "singleImage": 1, "uncompressedJs": 1
|
|
182
|
+
},
|
|
183
|
+
"scoreRanges": {
|
|
184
|
+
"heapGrowth": { "good": 4, "bad": 16, "threshold": 8 },
|
|
185
|
+
"workerCount": { "good": 4, "bad": 12, "threshold": 4 },
|
|
186
|
+
"jsError": { "good": 0, "bad": 5, "threshold": 0 },
|
|
187
|
+
"fps": { "good": 50, "bad": 20, "threshold": 30 },
|
|
188
|
+
"longTask": { "good": 500, "bad": 3000, "threshold": 500 }
|
|
189
|
+
},
|
|
190
|
+
"loadingScoreRanges": {
|
|
191
|
+
"fcp": { "p10": 1800, "median": 3000 },
|
|
192
|
+
"lcp": { "p10": 2500, "median": 4000 }
|
|
193
|
+
},
|
|
194
|
+
"blocking": {
|
|
195
|
+
"textureWatermark": true,
|
|
196
|
+
"contextLost": true,
|
|
197
|
+
"jsFatal": false,
|
|
198
|
+
"crash": true
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
外层 JSON、scope 或 priority 结构无法解析时继续使用 Apollo 的 last-known-good;`strategy` 内的审核字段不做业务校验。
|
|
206
|
+
|
|
207
|
+
规则包内置一份完整的 `enforce: false` 默认策略。Apollo 未命中或没有取得 audit 配置时使用本地默认;只要服务端返回了 audit 配置,Runtime 就整份直接采用,不校验策略字段,也不与本地默认逐字段拼接。评分公式、采集方式和指标 ID 固定在规则包,profile 预算、评分区间、权重、证据门槛和卡口开关由 Apollo 调整。
|
|
208
|
+
|
|
209
|
+
## 一期交付与二期输入
|
|
210
|
+
|
|
211
|
+
一期交付:
|
|
212
|
+
|
|
213
|
+
- Mars 独立插件与常驻侧栏;
|
|
214
|
+
- document-start 动态采集与静态包指标;
|
|
215
|
+
- 真实交互次数、首次操作时间和采集完整性;
|
|
216
|
+
- 三态报告、N/A 覆盖度与硬风险“需复核”;
|
|
217
|
+
- 12 秒进度静默看门狗、3GiB 熔断和会话中断收口;
|
|
218
|
+
- 20 个本地 ZIP 的逐包真实交互结果,详见 [audit-local-validation.codex.md](./audit-local-validation.codex.md)。
|
|
219
|
+
|
|
220
|
+
一期接入 Mars 队列时,模拟器内部采集的评测数据统一上报 APM:审核任务、应用、包版本、策略/规则/探针版本、开始/首次操作/结算时间、FCP/LCP 首屏事件、包体摘要、交互次数、三态终态和硬风险。事件契约、异常收口和指标校准流程详见 [audit-data-collection.codex.md](./audit-data-collection.codex.md)。
|
|
221
|
+
|
|
222
|
+
二期输入:真机 RSS/PSS、GPU 驱动内存、媒体解码内存、系统内存告警、进程终止与崩溃原因、机型/系统/WebView 版本。通过同包同脚本的 Web 与真机对照,计算误报/漏报和分机型阈值,再决定哪些硬风险可以从“需复核”升级为自动卡口。
|