Repository navigation
[PR] feat(perf): realtime telemetry into perf.sqlite — DB modes only, serving-immune (#5460 P1) - #5461
[PR] feat(perf): realtime telemetry into perf.sqlite — DB modes only, serving-immune (#5460 P1)#5461ranxianglei wants to merge 16 commits into
Conversation
(ai: vllm-qwen/qwen3.8-27b) 查重:不重复——按失败/功能签名(perf.sqlite、telemetry、性能采集、指标、#5460 关键词)检索了可访问的 open+closed issue/PR,无同方向线程;本 PR 是 #5460 下 P1 实时采集层的唯一实现。 初审已读完全部 diff(6 文件 +395,基线为当前 master,无落后),方向判定:单一观测点接在
下一步:worktree 定向验证(unused-exports gate、lifecycle guard、本 PR 的 8 个测试、tsc)→ 上述修复进 PR 分支 → 推上去看 CI → 发完整八问结论。 |
ranxianglei
left a comment
There was a problem hiding this comment.
(ai: vllm-qwen/qwen3.8-27b)
结论:APPROVE(可合)
注:本 bot 以 PR 作者账号身份运行,GitHub 禁止自我 approve,故以 comment 型 review 提交本结论;正式 approve/merge 由 owner 执行。。#5460 P1 实时采集层,方向与 owner 约束一致,代码隔离干净、服务免疫成立、测试有牙。
kernel/未触碰(无需决策门禁)。本地复核:tests/issue5460-perf-telemetry.test.ts8/8、tsc --noEmit0 error、lifecycle-ledger-guard/unused-exportsgate 全绿。
结构化八问
- 是什么:给 DB 存储模式加一层实时性能遥测——每请求落一行 + 每 30s 一条内存水位采样,写进 index.db 旁的独立小库
perf.sqlite,让性能回归在用户踩到之前就可查。 - 为什么做:近期所有性能事故(#5403 OOM×6、#5428 主线程卡死十几秒、#5385 缓存前缀钉死)全是用户先发现,CI 零预警、线上零可查指标——根因是根本没有遥测。本 PR = 采集层(P1),夹具/bench/基线/面板归 P2–P5。
- 影响面 / 严重程度:纯新增能力。波及所有 DB 存储模式(sqlite/mysql)会话:sessions 目录旁多一个小文件;纯 JSON 模式冻结零足迹(测试钉死)。唯一风险面是「遥测会不会危及服务」——判定否:所有写入被守卫,失败只降级停采(一次性 warn + dead 标记),绝不向请求路径抛。
- 怎么做:独立
perf.sqlite(WAL + ts 索引 + 200k 行摊销保留窗,LIMIT -1 OFFSET惯用法正确 + 500 行内存环);每请求行接在logRequestCost(#5408 单一观测点,10 个调用点含 passthrough 零改动全覆盖);persist.ts 两条 DB 侧车打开路径各自武装、JSON 分支显式 off;init 幂等(三分支互斥,无重复武装);BILI_PERF_TELEMETRY=0整体关。 - 回归审查(逐点过触碰路径的既有行为):
logRequestCost(src/server.ts:4569 附近):仅在原日志行之前加一个受守卫的 record 调用,人类可读行字节不变(测试断言了原始行仍在);SessionStore构造器(src/persist.ts:596/619/623):三个 init 调用落在互斥分支(mysql 异步 / sqlite 同步 / json off),shadow/store 逻辑零改动;- LIFECYCLE / CHANGELOG:纯追加。
高危模式逐项过:无 fail-fast→吞错、无阈值/时序/输出格式漂移、未触碰缓存/重试/游标。服务路径行为不变。
- 是否破缓存:不涉及——纯观测层,不碰 cache/retry/cursor/dedup。
- 设计方向:新增观测层,无架构/边界/数据流转向;刻意不动用户自有库 schema(独立文件 = 崩溃/体积隔离),符合 owner 硬约束①。
- 新配置:是——新增 env-only 开关
BILI_PERF_TELEMETRY(默认开;0/false 关)。迁移:无需(纯 opt-out)。已登记 LIFECYCLE.md §2.4 + CONFIGURATION.md en+zh(后者本次补上)。
诚实边界(作者已声明,认可,不拦):parse_ms 本轮恒 null(精确切分归 P1b,避免热路径计时污染);lane/wire-shape 细分归 P2 bench 层。合理。
已顺手修(两处小问题,均非阻断,已推到 PR 分支):
- 已顺手修:perf-telemetry 的降级告警原本走
console.error—— launcher 派生的子进程 stderr 被物理重定向到临时端口日志(#2864),这条唯一的「遥测已降级」信号进不了主 bili.log(正是本特性要喂的观测面),且违反 AGENTS「服务端模块禁 console.error」。改走 tee logger(loggerLog),与 mem-sample 路径本就用的通道一致,三处统一。commit 9438e41 - 已顺手修:新开关
BILI_PERF_TELEMETRY只登记在 LIFECYCLE.md、漏了 CONFIGURATION.md en+zh(违反 env-var「document or don't ship」纪律,reference/env-vars.md hard rule 4;同类 env-only 旋钮都在表里)。补进两语言 Environment-only 表。commit e6eb5e2
(ai: vllm-qwen/qwen3.8-27b) 审核完成。共 6 个标注 ① 是什么问题:本 PR 的 P1 遥测层方向正确(单一观测点 logRequestCost + 独立 sidecar 文件 + kill switch),但审核发现 6 处缺陷——其中两处是破坏 owner 约束/文档契约的真 bug:纯 JSON 模式没有真正冻结、降级契约没有真正执行;其余为工程卫生(fsyc 成本、文档登记、重复计算、死代码)。 ② 什么原因导致的:
③ 影响范围与严重程度:
④ 怎么修复的:
⑤ 是否有回归问题:逐条过了 diff 触碰路径的既有行为:
⑥ 是否破坏缓存:不涉及。前缀缓存/会话缓存/更新节流均未触碰;perf.sqlite 是独立文件,不进任何缓存键。 ⑦ 是否改了设计方向:没有。仍在 #5460 P1 范围内:同表形、同内存环、同观测点;P1b(parse_ms)/P2(bench)/P4(面板)边界不变。 ⑧ 是否引入了新的配置: 行为变更披露(旧→新):
并发说明:审核期间作者并行推了 2 个 commit(9438e41 降级日志走 tee loggerLog;e6eb5e2f0 CONFIGURATION 双语文档),与我的 B/D 两项重叠。处理:rebase 到 e6eb5e2 之上 + 并集解决(保留其 loggerLog 路由 + 我的 dead check;丢弃我的重复文档 commit),全程非 force push。 验证证据(均在 head 4548676 本地跑):tests/issue5460-perf-telemetry.test.ts 11/11(新增 3 个:open-fail 降级 / legacy 接线零足迹 / retention 200k 端到端);tsc --noEmit clean;unused-exports gate clean;lifecycle-ledger-guard OK;定向 persist/storage 套件 17/17。全量套件 = 远程 CI(当前 head 运行中)。 判定:CI 转绿后即可合并。方向与 owner 四约束全部成立,两处真 bug(约束②违背、降级契约)已修复并有回归钉。 |
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.9207-pr.5461.435f98bThis exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr5461.tgz
npm install -g packageInstall instructions are refreshed on each push. |
ranxianglei
left a comment
There was a problem hiding this comment.
(ai: vllm-qwen/qwen3.8-27b)
PR 审核结论:可合(APPROVE-ready)— 建议 owner 人工合并
(bot 身份 == PR author,GitHub 禁止自评 approve,故以 review-comment 形式给出结论;合并需人工。)
范围与独立性
- 独立通读 PR 正文、tracking issue #5460、全量 diff,并对最新 head 逐段做本地定向验证(tsc + 定向套件 + 两条 gate)。
- 诚实更正:本线程我此前留过一条「APPROVE(可合)」初评(review id 5728367137),那基于早期 head、仅覆盖 2 处小修,是不完整结论。此后另一条 review 车道在分支上连续落地了实质性修复;我逐一复核这些修复,并独立定位了其中一处测试缺陷(保留策略测试,已被并发车道等价修复)。本条为更正后的最终结论。
已核实(本地,head f05e6e8)
tsc --noEmit干净;tests/issue5460-perf-telemetry.test.ts11/11 绿;lifecycle-ledger-guardOK(BILI_PERF_TELEMETRY 已登记);check-unused-exportsclean。- 无
kernel/改动、无 kernel-change 声明 → 不受内核授权门禁约束。 mergeable=true(与 master 无冲突);CI 因并发多次 push 仍在重跑(mirror 缓存为瞬时态,非稳定红)。
逐项发现(均已在分支解决并被我复核)
- 【P1·最关键】原稿模块顶层
import { DatabaseSync } from "node:sqlite":该 builtin 仅 Node≥22.5 存在,而 package.json 声明 engines>=20 → 静态导入会在进程加载期让整个 CLI 崩溃(Node<22.5 上全部 bili 不可用,而非仅遥测降级),直接违反 serving-immune / 可用性大于性能。已修(f05e6e87):改走共享驱动接缝openSqliteDatabase(#2833 顺序 builtin→better-sqlite3→自下载),老 Node 落原生引擎、全缺时一次性警告只降级遥测;满足 dist 自包含门禁(零新增外部 specifier)。✔ - 【#5460 约束②】纯 JSON(legacy) 存储模式被误武装 sqlite 遥测,会在纯 JSON 模式创建 perf.sqlite。已修(1d792f8c3):按解析后的 storageMode 判定(含 mysql 异步分支),legacy→inert "json" 引擎;并有真实 SessionStore 接线级回归钉死零足迹。✔
- 打开失败后未真正「永久降级」——ensureDb 每次仍重试建连。已修(3f77f2280):dead 守卫一次失败即永久停用 + 注入 logger 落到 state;有一次性告警回归钉。✔
- perf.sqlite 只设 WAL 未设 synchronous=NORMAL → WAL 默认 FULL = 每请求一次 full fsync(热路径)。已修(174d791be):与 index.db 对齐 synchronous=NORMAL。✔
- BILI_PERF_TELEMETRY 只在 LIFECYCLE.md、缺 CONFIGURATION.md en+zh(document-or-don't-ship)。已修(e6eb5e2f0,我提交)。✔
- logRequestCost 对 outbound 重复算两次 Buffer.byteLength。已修(26c9b1efa):提升为单次计算。✔
- 测试中空的 before() 死代码 → 已删。✔
- 【本轮我独立定位】保留策略测试确定性红且根本没触发删除:amortized sweep 每 500 次插入才跑一次,仅插 200_001 行时 count 越 cap 后下一次 sweep 要到第 200500 次才触发 ⇒ 从未删除、count=200001≠200000;且精确等值断言对 amortized 设计本就为假。已由并发车道等价修复(45486763d:插到恰好一个 sweep 边界 200_500,末次 sweep 确定 trim 到 200000);我在其版本上复验 11/11 绿。✔
行为变更披露(旧值→新值 + 原因,均为有意、与 PR 既有契约一致,非无意漂移)
- 纯 JSON/legacy 模式:遥测从「被误武装、会写 perf.sqlite」→「完全 inert 零足迹」(对齐 owner 约束②)。
- perf.sqlite 写入:每请求 full fsync → synchronous=NORMAL 批量 fsync(遥测数据可重采,热路径不再每请求同步盘)。
- Node<22.5:CLI 启动即崩 → 正常加载、遥测按既有契约降级(可用性恢复)。
八问
- 是什么问题:给 DB 类存储加一条实时性能遥测(perf.sqlite,WAL + retention 封顶),要求纯 JSON 模式零足迹、任何失败都不得影响服务(serving-immune)。
- 什么原因导致(原稿的坑):静态导入 node:sqlite 在老 Node 崩全进程;遥测武装条件没看解析后的 storageMode;降级不是一次性;热路径 fsync 策略没和主库对齐;文档与小优化遗漏。均已定位到机制层并修复。
- 影响范围与严重程度:原稿在 Node<22.5(engines>=20 支持面)会整个 CLI 不可用(P1 可用性);纯 JSON 模式会被误写文件(违反 owner 硬约束②)。当前 head 已全部消除。
- 怎么修复的:引擎改走共享驱动接缝(复用 #2833 回退链);武装判定绑定解析后 storageMode;ensureDb dead 守卫永久降级;synchronous=NORMAL 对齐主库;补文档 + 小优化 + 修正保留策略测试。
- 是否有回归问题:审过的既有行为——纯 JSON 冻结、kill switch、idempotent init、ring buffer、mem sampler、logRequestCost 单点接线——均保持或增强;无 fail-fast 变吞错、无线上协议/消息形状改动、无阈值静默漂移。遥测全程 try/catch 兜底,异常不进请求路径。
- 是否破坏缓存:不涉及前缀缓存/重试/增量游标/去重键;perf.sqlite 是独立观测库(与 index.db 物理隔离、零 schema-version 耦合),不影响会话缓存。
- 是否改了设计方向:否。新增观测面,严格限定「DB 模式 only + serving-immune」,与 #5460 P1 方向一致。
- 是否引入新配置:新增 env-only kill switch
BILI_PERF_TELEMETRY(默认开,=0 关闭),已登记 LIFECYCLE.md §2.4 + CONFIGURATION.md en+zh;无持久化格式/版本变化。
判定:代码正确、serving-immune、定向测试 11/11 绿、两条 gate 全过、无 kernel/ 触碰、行为变更已披露。可合(APPROVE-ready);因 bot 无法自评 approve,请 owner 人工合并。分支仍在并发收敛,我验证到的最新 head=f05e6e87;其后若再有 push,以 CI 结果为准。
(ai: vllm-qwen/qwen3.8-27b) |
(ai: vllm-qwen/qwen3.8-27b) 补充:首轮八问之后新发现并闭环的 p1 问题(dist 打包面,非代码行为面) 是什么:perf-telemetry.ts 顶层静态 怎么修的(时间线):我先推了 489b5a219(createRequire 惰性 probe-once,缺失即一次性降级停采);随后你在 f05e6e8 对同一根因做了更彻底的收敛——改走共享存储驱动 seam( 行为披露(旧→新):无 node:sqlite 的 Node 运行时:「bili 无法启动」→「自动选用可用引擎(better-sqlite3);全无可用时遥测静默 off + 一条 warn,服务正常」。 CI 状态(head f05e6e8,镜像缓存 14:55Z):total 30 / failed 0 / pending 0——mysql-contract、gates×10、unused-exports 全 success,e2e/test 车道按各自 path 门跳过;mergeable_state=blocked 是等待人工侧状态,不是 CI 红。#4599 已留一行结论(根因+修复+非继承,master 760c24c 绿)。 更新判定:代码侧全部闭环(六处审核缺陷 + 本 p1 打包面问题均修复并有回归钉),CI 无红项,可合并。 |
…only, serving-immune) - src/perf-telemetry.ts: perf_events table (WAL, retention cap 200k rows, ring buffer), kill switch BILI_PERF_TELEMETRY, pure-JSON mode frozen/off, degrade-not-throw discipline (#5327 culture) - src/server.ts logRequestCost: structured mirror row through the single observation point every lane already flows through (#5408) - src/persist.ts: arm sqlite/mysql lanes at the two sidecar-open paths, explicit json-mode off - LIFECYCLE.md §2.4: BILI_PERF_TELEMETRY registered - tests/issue5460-perf-telemetry.test.ts: 8 cases incl. pinned DDL/WAL golden
The open-failure and insert-failure one-time warnings fell back to raw console.error, which bypasses bili's tee logger. For launcher-spawned children (#2864) stderr is physically redirected to a temp port-log, so the single 'telemetry degraded' signal never reached the main bili.log - exactly the observation surface this feature exists to feed. Route all degrade paths through loggerLog (the same channel the mem-sample path already used). No behavior/serving change; AGENTS no-console.error-in-server-modules.
[ework] CI fix verified green ✓ |
…n, zero footprint The sqlite arming branch runs for EVERY enabled store, including storage.unified=legacy deployments where maybeOpen() returns null — so a pure-JSON install would still create perf.sqlite on first record, violating owner constraint ② (#5460: JSON mode frozen). Gate both DB branch arming sites on the RESOLVED mode: legacy → init("json") (permanently inert), shadow/full → arm as before. A configured DB-mode store whose sidecar transiently failed to open still arms (observability is most needed while degraded); only an explicit legacy choice freezes.
…en failure ensureDb() set state.dead on open failure but never checked it back, so a permanently broken dir retried new DatabaseSync on EVERY request and every 30s mem tick — contradicting the module's documented contract (one warn + permanent stop, serving untouched). Add the dead check at the top. The open-failure warn keeps the tee-logger routing landed upstream (9438e41) and additionally honors the caller-supplied logger (state.log) so tests can pin the one-shot behavior; production callers pass baseLog either way. Regression pins (both previously uncovered — the serving-immunity claim had no negative-direction test at all): * open failure (garbage file at the db path) → exactly ONE degrade warn, no throw through perfRecordRequest/perfRecordMemSample, no rows recorded; * storage.unified=legacy SessionStore → arms the frozen engine, creates NO perf.sqlite (wiring-level pin of the previous commit's constraint ② gate). Also drops the empty before() hook left in the test file.
…h fsync parity with index.db) WAL was set but synchronous stayed at the SQLite default FULL: every request row pays an fsync per commit on the request path. index.db sets journal_mode=WAL + synchronous=NORMAL together (src/storage/schema.ts); match that pair and pin the pragma in the schema golden test.
…ogRequestCost The PR's telemetry line and the pre-existing human-log line each ran Buffer.byteLength(outbound) — a second O(n) scan over potentially large response strings on every request. Hoist to one const.
The amortized sweep (DELETE ... ORDER BY id DESC LIMIT -1 OFFSET cap every 500th insert) is what keeps perf.sqlite bounded per owner constraint ① (crash/size isolation from index.db); an off-by-one in that SQL would let the file grow unbounded with zero other signal. Drive 200_001 real inserts through the public API and assert exactly 200_000 rows remain, newest kept.
… boundary The previous commit asserted exactly 200_000 rows after 200_001 inserts, which lands one insert past the last sweep boundary: the amortized sweep (every 500th insert) legitimately leaves up to cap+period-1 rows between sweeps, so 200_001 is correct behavior, not a cap violation. Drive to an exact multiple of the sweep period past the cap (200_500) so the final sweep deterministically trims the table to precisely the 200k window.
… driver seam — CLI stays loadable on Node <22.5
…he table row is generated (#5460 P1) check-coverage requires every process.env read in src to have a seed entry in website/config-reference/*.yaml, and docs-sync regenerates the CONFIGURATION tables strictly from those seeds. P1 hand-wrote its row into both files instead, so regeneration deleted it -> drift -> red docs-coverage + docs-sync on the stacked head. Seed added with P1's exact wording; regenerated row lands at the same table position (default column normalized to the seed's "on"). EN file ends byte-identical to before; zh picks up the normalization. (cherry picked from commit 24cf7e8)
…ox teardown (#5460 P1) The persistent WAL handle perf.sqlite keeps open in EVERY process that ever constructed a SessionStore makes Windows runners refuse the suite's standard sandbox teardown (EBUSY …/sessions/perf.sqlite, rimraf) — it took down all four w22 shards. Same discipline as the BILI_MESSAGE_ TIMESTAMPS pin: production default stays on; tests that need telemetry opt in explicitly by deleting the key.
f2dc47c added the explanatory comment but dropped the assignment line, so every test process armed telemetry by default and its persistent WAL handle kept Windows teardown failing (EBUSY …/sessions/perf.sqlite in the after() hooks of ALL w22 shards). One line closes the gap: production default stays on; tests opt in by deleting the key.
…r rebase onto master (#5460 P1) Post-rebase artifact sync: master moved the CONFIGURATION tables into docs/configuration.{md,zh-CN.md} (generated strictly from website/config-reference/*.yaml by tools/gen-config-docs.mjs). The P1 row now lands via its seed entry (commit a2b2dfc) at the same table position; this commit carries the regenerated rows so the docs-sync drift guard passes.
…er/request-cost.js
Master extracted logRequestCost out of src/server.ts into
src/server/request-cost.ts; the P1 choke-point test still imported it from
the old location ('logRequestCost is not a function'). Mechanical rebase
retarget only — no behavior change.
44b6023 to
75bfbb9
Compare
[bot] 🏷 Conflict rebase completed and pushed (auto-fix lane attempt 1/3). What conflicted and how each was resolved — every conflict was a mechanical retarget caused by master moves, none required a design decision:
Two extra labeled commits carry the rebase artifacts (regenerated config-docs rows; test import retarget) alongside the original 13. Local targeted verification (all green): Live status at push time: mirror cache shows No kernel/ touch, no PR-body edits, no authorization gates hit. 八问(中文结论,供人工 reviewer)
判定:冲突已全部解决并推送,本地定向验证全绿;待新 head 上 CI 跑完 + 人工合并。CI 结果下一轮跟进。 |
[ework] CI fix verified green ✓ |
# Conflicts: # CHANGELOG.md
[bot] 🏷 Second conflict pass done and pushed. Since the first rebase landed, master advanced again ( What I did:
Live status at post time (honest, per status-freshness rule): the mirror cache still shows the previous head No design decisions were needed — the only conflict was a textual section-order collision, resolved as union. No authorization gates hit; this branch touches no 八问(中文结论,供人工 reviewer)
判定:第二轮冲突已解决并推送( |
[bot] 🏷 CI 跟进完成(第二轮 head 现状(镜像缓存 fetched_at 2026-11-11 20:15Z,恰好覆盖本 head):
八问(简版)
判定:CI 车道工作全部闭环——两轮冲突处理(第一轮 rebase |
[ework] CI fix verified green ✓ |
…e extra payload perfRecordRequest built payload_json via JSON.stringify OUTSIDE any guard, so a BigInt / circular value in the exported `extra` field would throw synchronously out of the request hot path (logRequestCost) — violating the module's stated "degrades, never throws" / serving-immune contract (#5327/#5460). DORMANT today (request-cost passes no extra) but the exported API invites it. Wrap both record functions in try/catch that degrades telemetry (one-shot warn, state.dead) rather than propagating into the caller. Matches the existing ensureDb/insertRow degrade style. Adds a regression test pinning the never-throw behavior (a BigInt extra must not reach the caller).
(ai: vllm-qwen/qwen3.8-27b) Verdict: APPROVE / 可合 — end-to-end review of the P1 realtime-telemetry layer (head What I independently verified (re-read every changed file, traced code paths, ran tests — not inherited from prior threads):
已顺手修: --- 八问(中文,供人工 reviewer) ---
行为变更披露(旧→新):DB 模式部署默认开始在会话目录生成 验证证据(本地定向,head 判定:可合(APPROVE)。唯一发现已在分支上修掉并带回归钉;无 kernel/ 触碰、无授权门禁。注:bot 身份 == author,GitHub 不允许自评 approve,故以本评论给出明确批准结论,待 owner 人工合并 #5461 。 |
[ework] CI fix verified green ✓ |
问题
近期所有性能事故(#5403 OOM×6、#4528 主线程卡死十几秒、#5385 缓存前缀钉死)全部由用户先发现——CI 零预警,线上连一条可查的指标都没有。跟踪单 #5460(owner 已批方向与约束),本 PR = P1 实时采集层。
改动
src/perf-telemetry.ts(新):perf_events表(WAL、ts 索引、200k 行摊销保留窗、500 行内存环)。两类行:req(每请求:会话号/消息数/进出字节/本地总耗时/parse_ms 预留)+mem(30s 采样 rss/heap/external/arrayBuffers)。纪律:[PR] Repeated invocation guard: on the 5th occurrence, warn only without killing the turn; terminate on the next violation (# | 重复调用守卫:第 5 次只警告不杀回合,再犯一次才终止 (#5225) #5327 同款「观测不得危及服务」——打开/插入任何失败 → 一次性 warn + 永久降级停采,绝不向请求路径抛;BILI_PERF_TELEMETRY=0整体关闭;初始化幂等(二次 init 任何模式都 no-op,防降级覆盖运行中实例)。src/server.ts:logRequestCost(每条车道必经的单一观测点,[Bug][dsh][storage] Compression permanently fails for a session: frozen ingest watermark, requests no longer observed, and no warning until the host dies with CONTEXT_WINDOW_EXCEEDED #5408)顺路落结构化行——10 个调用点零改动全覆盖,含 passthrough。src/persist.ts:两条 DB 侧车打开路径(sqlite 同步 / mysql 异步)各自武装;纯 JSON 存储模式显式 off。LIFECYCLE.md§2.4:登记BILI_PERF_TELEMETRY。owner 硬约束落实(#5460)
① 指标只进 SQLite 文件(
perf.sqlite,与 index.db 同目录、独立文件=崩溃/体积隔离,不动用户自己的库 schema);② 纯 JSON 存储模式冻结:零足迹(init("json") 永久 inert,测试钉死);③ Web 面板观测页 = P4 必做项(本 PR 的内存环/stats/面板直接消费);④ CI:普通 PR CI 零性能 job,bench 门禁在 FULL + 夜间(P3 接线)。测试判定
tests/issue5460-perf-telemetry.test.ts8/8:落库往返 / DDL+WAL+索引金样钉 / JSON 模式冻结 / kill switch / 幂等 / 内存采样器 / 环缓冲 / logRequestCost 接线(真实导入 server.js)已知边界(诚实声明)
parse_ms列本 PR 为 null:主解析点的精确切分是 P1b(需要解析点改造,避免在热路径加计时污染);total_ms已是 [Bug][dsh] Plugin lane performs a full re-parse and resends the entire body every round (81 MiB → hundreds of MB AST), w | [Bug][dsh] plugin 车道每轮全量解析重发 body(81 MiB→数百 MB AST)是 #5403 OOM 的生产者:用水位线断言替换逐条复核,服务端只解析新增尾段 #5418 指出的整段本地耗时。