Skip to content

K1-S0.4: 启动与开发打包性能稳定化 (#19) - #29

Open
Dylan5237 wants to merge 5 commits into
develop/kcc-1.0from
fix/k1-startup-package-performance
Open

K1-S0.4: 启动与开发打包性能稳定化 (#19)#29
Dylan5237 wants to merge 5 commits into
develop/kcc-1.0from
fix/k1-startup-package-performance

Conversation

@Dylan5237

@Dylan5237 Dylan5237 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

K1-S0.4 — Startup & Development Package Performance Stabilization

Closes #19. Frozen taskbook: docs/tasks/kimicode/K1-S0.4-performance-stabilization.md.
Full evidence: docs/performance/K1-S0.4-performance-report.md (in this PR).

Exact refs

  • Implementation baseline: 682a0df5e2935836e7e4bafae1883b799ca9f103 (= origin/develop/kcc-1.0, verified at run start)
  • HEAD: 7da49bb (3 commits, see below)
  • Machine: Windows 11 26200, i9-12900H, 32 GB, Node v22.22.1, npm 10.9.4, Electron 43.2.0, electron-builder 26.15.3

Changed files

  • src/viewer/server.cjs — Viewer server readiness decoupled from initial watcher/snapshot; whenWatcherReady(); generation/closed guards
  • src/main/main.js — opt-in KCC_PROFILE_STARTUP=1 profiling marks
  • scripts/package-dev.ps1-Fast unpacked iteration mode; -ForceInstall; lockfile-fingerprint dependency reuse
  • test/viewer-server.test.js, test/viewer-realtime.test.js — timing-assumption fixes + 2 new regression tests
  • docs/performance/K1-S0.4-performance-report.md — full evidence report
  • docs/DEVELOPMENT_PACKAGING.md, AGENTS.md — usage docs sync

Startup

Baseline (5 runs, in-process ms to main-window-shown): median 708 (range 651–978); wall-to-ready median 1205.

Phase breakdown (median): Electron bootstrap ~101 · config/quota/migration ~50 · Viewer listener+snapshot/watcher ~90 (64–76 ms at 102-entry root; 152–329 ms at 521-entry root) · window+shell load ~350 · shell→shown ~130.

After (5 runs): median 622 (range 524–894)−86 ms / −12.1% median (best run −19.5%). Large stored root (521 entries/71 docs/1.24 MB): 329 ms scan now completes in background at 522 ms; shown 717 ms vs modeled-baseline ≈1040 ms → ≈−31% at that root scale. The win grows with root size and I/O load.

Confirmed startup root cause: C (window/renderer/shell creation ~68%) dominates; A (Viewer stored-root scan) was the largest controllable critical-path blocker and is removed. 20% median gate not met at small roots because baseline is already 708 ms and the remainder is Electron-inherent (shell rewrite is out of scope) — absolute savings documented per the taskbook's alternative clause.

Packaging

Baseline (package-dev.ps1, frozen SHA): total 278.5 s (fetch 1.1 · worktree 0.8 · npm ci 25.8 · test 13.5 · pack 235.8); zip 416.3 MB.

pack decomposition: staging (--dir) 179 s cold / 98 s warm; full 311 s → zip ≈ 130 s (~40–45%); unpacked 1302 MB (asar 227 MB + asarUnpack 728 MB, mostly CloudCLI runtimes @openai 410 MB + @Anthropic-AI 270 MB).

Confirmed packaging root cause: staging (B) + zip compression (A) co-dominate; npm ci (D) minor.

After (same deterministic path, same worktree):

  • Fast local iteration (-Fast): 153.4 s stamp-reuse / 196.1 s cold-install → −45% / −30% vs baseline total; artifact dist-fast/win-unpacked (1302 MB runnable) + build-info.json
  • Full zip (default): 355.8 s (install 1.1 via stamp reuse; pack 332.9 — same code path as baseline 235.8, pure machine variance; zip byte-size identical 416.3 MB). Not claimed as optimized; both metrics reported per taskbook.

Deterministic proof: dist/build-info.json and dist-fast/build-info.json both record sourceCommit: 682a0df5e2935836e7e4bafae1883b799ca9f103; packaging worktree detached+clean at that SHA every run; dirty-guard fail-closed unchanged. Dependency reuse only via node_modules/.kcc-dep-stamp = SHA-256(package-lock.json)+node/npm/os-arch, written solely by successful npm ci; -ForceInstall bypasses; no bare node_modules-exists check.

Regression

Limitations / remaining bottlenecks

  • Startup: ~480 ms window/first-renderer creation and ~450–500 ms pre-JS spawn/bootstrap are Electron-inherent; engine-view deferral rejected (cosmetic gain, tab/IPC risk)
  • Packaging staging (~98–179 s) is dominated by materializing the 728 MB asarUnpack closure (CloudCLI runtimes); shrinking requires externalization — out of scope, not attempted
  • Dev-only compression=store zip probe inconclusive (electron-builder network timeout); -Fast already removes zip from the loop
  • Startup probes used a cloned profile (--user-data-dir) seeded with the real stored Viewer root because the default profile was held by a running instance (single-instance lock); phases measured in-process with monotonic marks
  • The taskbook's full fresh-Kimi-session E2E (whole task without opening Viewer) is covered at mechanism level (session-arm + realtime + new same-root deferred-baseline tests + real arm log), not by a new end-to-end task run

Do not merge before ChatGPT Architecture Review.


Note

Medium Risk
Deferring the initial viewer snapshot changes startup ordering; correctness depends on new pendingWatcher / generation guards in session context paths. Packaging stamp reuse is dev-only but must stay fingerprint-accurate to avoid wrong dependencies.

Overview
Addresses #19 (K1-S0.4) by shortening the startup critical path and speeding local deterministic packaging, with a full performance report in docs/performance/K1-S0.4-performance-report.md.

Startup: The Viewer server now becomes ready when the HTTP listener is up; the stored-root snapshot and file watcher run in the background via launchWatcher(). Callers that need a baseline use whenWatcherReady(); setRoot / setConversationContext still wait for in-flight baselines (including same-root session arm) so changes are not dropped. KCC_PROFILE_STARTUP=1 adds opt-in [kcc-profile] timing marks in main.js and the viewer server.

Packaging: scripts/package-dev.ps1 adds -Fast (unpacked dist-fast/, skips tests and zip while keeping frozen SHA, detached worktree, and build-info.json), -ForceInstall, and stamp-validated node_modules reuse (node_modules/.kcc-dep-stamp keyed on lockfile hash plus node/npm/os). Docs in AGENTS.md and DEVELOPMENT_PACKAGING.md are updated accordingly.

Tests: Viewer tests await whenWatcherReady() where timing matters; two new tests cover deferred HTTP readiness and same-root session arm after a deferred baseline.

Reviewed by Cursor Bugbot for commit 7da49bb. Configure here.

wushengzhi and others added 3 commits September 8, 2026 20:30
原因: 实测启动关键路径上 startViewerServer 在 createMainWindow 前 await 初始 snapshot/watcher(102 项根 64-76ms, 521 项根 152-329ms, 随根规模与 I/O 放大), 直接阻塞首窗
改动: T1: startServer 在 HTTP listener 就绪即返回, 初始存储根扫描后台完成; T2: setRoot/setConversationContext 同根时 await 在途基线(pendingWatcher), 代际守卫防旧扫描覆盖新基线, closed 守卫防关闭后泄漏定时器, 保 #23 正向武装不丢变更; T3: 新增 whenWatcherReady() 就绪句柄与 KCC_PROFILE_STARTUP 剖面埋点(仅本地诊断); T4: realtime/轮询测试显式等待基线, 新增解耦契约与同根武装回归测试

Co-Authored-By: Kimicode <noreply@kimicode.com>
原因: 实测确定性打包 total 278.5s 中 zip 阶段约 130s、npm ci 26-47s; 本地迭代不需要 zip 产物, lockfile 未变时无条件 npm ci 是纯浪费
改动: T1: -Fast 走 npm run pack -- fast 产出 dist-fast unpacked(免 zip/免测试), 冻结源 SHA/detached worktree/build-info provenance 不变, 全量 zip 仍为默认; T2: npm ci 成功后写 node_modules/.kcc-dep-stamp(package-lock SHA-256+node/npm 版本+os/arch), 指纹精确匹配才复用, -ForceInstall 强制重装, 禁止裸 node_modules 存在即复用; T3: 同步 DEVELOPMENT_PACKAGING.md 与 AGENTS.md 用法

Co-Authored-By: Kimicode <noreply@kimicode.com>
原因: #19 要求性能结论必须有真实 Windows 实测证据, baseline/根因/改动/回归需落盘可复查
改动: 记录 baseline SHA/机器工具链/启动 5 轮表/打包阶段分解/根因分类/实现项/after 对比/回归结果/拒绝的优化

Co-Authored-By: Kimicode <noreply@kimicode.com>

Copy link
Copy Markdown
Owner Author

Architecture Review — REQUEST_CHANGES (R1)

Reviewed HEAD: 7da49bbfe0b1678ce573ef31be45d20b5120020e

Accepted and not to be reworked:

  • profiling-first methodology and before/after measurements;
  • Viewer HTTP/listener readiness decoupled from the initial stored-root snapshot/watcher;
  • generation/closed guards and explicit whenWatcherReady() seam;
  • deterministic -Fast unpacked local iteration mode while preserving the full zip default;
  • measured result: startup median 708ms -> 622ms (-12.1%, absolute win accepted because baseline is already sub-second); fast local packaging 278.5s -> 153.4–196.1s (-45% / -30%); full zip is explicitly not claimed as optimized;
  • no [K1-S0.4][P2] Replace KCC 1.0 app identity with Arckeep name/logo only #20 branding / updater / Electron rewrite / CloudCLI externalization.

R1 blocker 1 — dependency reuse must preserve npm-ci source validation

Current dependency stamp keys reuse on SHA-256(package-lock.json) + node/npm + os/arch only. This is insufficient for deterministic packaging.

Counterexample: a new develop commit changes package.json dependency/override metadata but forgets to update package-lock.json. A normal npm ci would reject the inconsistent source. With the current stamp, the unchanged lockfile can match and the script skips npm ci, silently packaging a source commit that should have failed validation.

Required narrow repair:

  • include a cryptographic hash of the frozen source's package.json in the dependency fingerprint in addition to package-lock.json;
  • keep node/npm/platform compatibility in the fingerprint;
  • a changed package.json with unchanged lockfile must invalidate reuse and execute npm ci (which may then fail as intended);
  • add a focused deterministic regression proving this invalidation behavior.

Do not redesign caching beyond this.

R1 blocker 2 — real #23 regression gate was not executed

The PR changes Viewer startup ordering, and the delivery report explicitly states that the full fresh-Kimi-session E2E was not rerun. Taskbook acceptance requires preserving the product contract:

fresh Kimi session -> do the work without ever opening Viewer -> first review at the end already contains the session changes.

Mechanism/unit tests and viewer-context.log arm evidence are necessary but not sufficient for this particular timing change.

Required real Windows smoke after the R1 code fix:

  1. launch KCC normally;
  2. enter a fresh Kimi session bound to a small disposable fixture project;
  3. during the work phase, never activate/open Viewer;
  4. create + modify at least one MD/JSON artifact (and preferably one delete, matching the accepted [K1-P1] Viewer recording must arm on session change without opening Viewer #23 pattern);
  5. only after the work is complete, inspect Viewer/API state and prove the session changes were already recorded;
  6. record evidence that Viewer was not active during the work phase and that context/session/root correspond to the fresh session.

If an existing KCC instance/profile lock blocks the probe, do not kill it. STOP HUMAN_ACTION_REQUIRED and ask the user to close the relevant app/process.

Process safety rule from this run

The previous probe terminated a pre-existing process tree and accidentally killed the hosting Agent session. From now on:

  • an Agent may terminate only PIDs it spawned during the current probe and explicitly tracked;
  • pre-existing KCC/Electron/Node/Agent processes are never force-killed automatically;
  • pre-existing single-instance/profile locks => HUMAN_ACTION_REQUIRED.

R1 delivery

Keep the same branch/PR. Rerun focused tests + npm test; one real fast/full package smoke is sufficient only if cache code changed; rerun the real fresh-session Viewer E2E above. Update the performance report if needed. Do not start #20/dogfood. STOP for incremental Architecture Review.

wushengzhi and others added 2 commits September 8, 2026 21:20
原因: R0 stamp 指纹只含 package-lock.json 哈希+node/npm/os, package.json 单独漂移(lockfile 未同步)时 lock 哈希不变, 会错误复用旧 node_modules, 绕过 npm ci 的 manifest/lockfile 一致性检查
改动: T1: package-dev-lib 新增 makeDependencyFingerprint 与 dep-fingerprint CLI, 指纹=SHA-256(package.json)+SHA-256(package-lock.json)+node/npm/os-arch; T2: package-dev.ps1 install 块改用新指纹比对与写 stamp; T3: 新增 A/B/C 回归(同输入可复用/仅 package.json 变失效/lockfile 变失效)与 CLI-库一致性测试; T4: DEVELOPMENT_PACKAGING.md 同步指纹描述

Co-Authored-By: Kimicode <noreply@kimicode.com>
原因: R1 评审两个 blocker 需要落盘证据(依赖指纹缺 package.json 哈希、缺真实 #23 fresh-session E2E), 且"剩余启动时间 Electron inherent"属未证明判断需收敛
改动: T1: 报告新增 R1 章节, 含指纹修正说明/A-B-C 回归/三次真实 package-dev.ps1 -Fast smoke(旧 stamp 重装/新 stamp 复用 0.5s/ForceInstall 强制重装); T2: 落真实 fresh-session Viewer E2E 证据(session_de26fd73-27cf-4206-b57e-892c2e96d6f0, 工作期间 active tab 始终 kimi 未开 Viewer, notes.md created+modified 与 data.json created+deleted 全记录); T3: "Electron-inherent/只能 rewrite"表述收敛为"本 WP 未继续优化, 进一步拆解收益不足以证明扩大范围"

Co-Authored-By: Kimicode <noreply@kimicode.com>
@Dylan5237

Copy link
Copy Markdown
Owner Author

K1-S0.4 R1 — 两个 blocker 已处理

  • Previous reviewed HEAD: 7da49bbfe0b1678ce573ef31be45d20b5120020e
  • New HEAD: 1717714d833740a8edee6371b136521f73fac6a3
  • Commits: f4c0f98 fix(打包) 指纹修正 + 1717714 docs(性能) R1 证据

Changed files

  • scripts/package-dev-lib.mjs — 新增 makeDependencyFingerprint + dep-fingerprint CLI
  • scripts/package-dev.ps1 — install 块改用新指纹
  • test/package-dev-lib.test.js — A/B/C 确定性回归
  • docs/DEVELOPMENT_PACKAGING.md — 指纹描述同步
  • docs/performance/K1-S0.4-performance-report.md — R1 章节 + E2E 证据 + 措辞收敛

Blocker 1 — dependency fingerprint

新指纹形状:

package=<sha256(package.json)>|lock=<sha256(package-lock.json)>|node=<v>|npm=<v>|os=<platform-arch>
  • package.json 任何变化(即使 lockfile 不变)→ stamp mismatch → npm ci;manifest/lockfile 不一致时由 npm ci fail closed,不做自动修 lockfile。
  • 回归(test/package-dev-lib.test.js):A 同输入同指纹可复用;B 仅 package.json 变 → 失效;C lockfile 变 → 失效;另有 runtime 漂移与 CLI/库一致性。
  • npm test:160/160 通过。
  • npm run build:通过(dist/win-unpacked 产出,签名步骤 OK)。

真实 packaging smoke(package-dev.ps1 -Fast,三次):

run 场景 结果 timings
1 旧格式 stamp mismatch → npm ci,重写新 stamp(含 package=…|lock=…) install 57s, total 151.2s, EXIT=0
2 R1 stamp 匹配 复用 node_modules,无 npm ci install 0.5s, total 72.3s, EXIT=0
3 -ForceInstall stamp 匹配仍强制 npm ci install 30.5s, total 103.4s, EXIT=0

三次均:source ref origin/develop/kcc-1.0 frozen @ 682a0df5e2935836e7e4bafae1883b799ca9f103、dedicated detached packaging worktree、build-info.json sourceCommit 同为 frozen SHA。

Blocker 2 — 真实 fresh-session Viewer E2E(#23 merge gate)PASS

真实 Windows 运行(2026-09-08),worktree 代码 + 全新 --user-data-dir profile,CDP 驱动;只终止了 probe 自己 spawn 的实例(PID 157856)。

  • fresh session:session_de26fd73-27cf-4206-b57e-892c2e96d6f0(真实 API 创建,workspace wd_e2e-fixture_4102075853c5
  • project root:C:\Users\howyo\AppData\Local\Temp\kcc-perf\e2e-fixture(disposable fixture)
  • 真实 turn:通过真实 Kimi Web UI 发送 prompt,assistant 回复 OK(消息 msg_01M20JH19EYP3HG98BH54F96Z0 / …_000002
  • arm 证据:viewer-context.log context-applied(13:14:09 / 13:15:10 / 13:16:10),source: kimi-apifallback: false,sessionId 与 projectDirectory 均匹配
  • 工作期间 Viewer 从未打开:工作前后 shell active tab 断言均为 kimi;全程唯一 Viewer 接触是全部工作完成后的一次 same-origin /api/artifacts 读取
  • artifacts first look:id = kimi:session_de26fd73…root = fixture;changes 含 notes.md created + modifieddata.json created + deleted(4 条全在首次查看前已记录)

caveat:文件写入由 harness 直接写入 session 绑定的 root(watcher 层面与 agent 工具写入等价;session 自身 turn 为真实执行)。通过权限审批 UI 驱动 agent 工具写入可作为后续增强,非本 gate 必需。

文档

  • 性能报告新增 R1 章节(指纹修正、A/B/C 回归、三次 smoke、E2E 全证据)。
  • "剩余启动时间 Electron-inherent / 只能 rewrite" 已收敛为 "本 WP 未继续优化,进一步拆解收益不足以证明值得扩大范围;仍是可测量的后续项,而非已证实的死路"。

Limitations

  • full zip 路径未宣称优化(zip 阶段机器 I/O 方差大),R1 未改动该路径。
  • E2E 的 agent 工具写入未走权限审批 UI(见上 caveat)。
  • 原始 probe 日志未入库(按要求不提交巨型 raw logs)。

等待 incremental Architecture Review;未 merge、未动 #20、未 dogfood。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant