Преглед изворни кода

Fix offline reference checks and preserve native pack inputs

Tianyi Cui пре 2 недеља
родитељ
комит
b905d399df
21 измењених фајлова са 74 додато и 36 уклоњено
  1. 2 2
      .agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml
  2. 1 1
      .agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.md
  3. 1 1
      .agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.zh.md
  4. 2 2
      .agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml
  5. 1 1
      .agents/notes/implemented/process/2026-09-12-maintained-repository-references.md
  6. 1 1
      .agents/notes/implemented/process/2026-09-12-maintained-repository-references.zh.md
  7. 2 2
      .agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml
  8. 3 3
      .agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.md
  9. 3 3
      .agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.zh.md
  10. 2 2
      .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml
  11. 3 3
      .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md
  12. 3 3
      .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md
  13. 2 2
      .agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml
  14. 1 1
      .agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.md
  15. 1 1
      .agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.zh.md
  16. 1 1
      native/system/docs/packaging.md
  17. 2 0
      native/system/scripts/pack-release.mjs
  18. 22 5
      native/system/test/release-packing.test.js
  19. 2 2
      scripts/rescope-vendor.ts
  20. 18 0
      scripts/verify-repository-references.spec.ts
  21. 1 0
      scripts/verify-repository-references.ts

+ 2 - 2
.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.md
-2026-09-06-node-compatibility-selfhosted.md: 046b9aab7a35b2398e7ed99262bb2208d0857a5f
-2026-09-06-node-compatibility-selfhosted.zh.md: 1a37f3a14306de2551dbd484772b71146f02624d
+2026-09-06-node-compatibility-selfhosted.md: 0ed422711426268efcb3b7cf37b6e19c52feba55
+2026-09-06-node-compatibility-selfhosted.zh.md: 2e58e3e7983b370050484bb8455cfa8554af494e

+ 1 - 1
.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.md

@@ -32,4 +32,4 @@ The pool receives three additional jobs per trusted PR; each retains gate concur
 
 The focused [workflow regression](../../../../scripts/ci-compatible-selfhosted.spec.ts) executes the actual routing expressions and environment setup. A negative control removing the fork condition fails the hosted-fallback assertion. It checks Dependabot reruns by a maintainer, repository mismatch, fork flags, disabled variables, and runner-scoped cache paths.
 
-Successful standby run 33984559660 at the implementation base supplies Linux Node 24.19.0 and Windows Node 24.20.0 baseline evidence. Linux job 101359402557 uses runner-specific temporary and tool directories on the data volume. Read-only capability probe 34012679056 (job 101431064925) reports Linux x64, 192 online logical CPUs, GCC/G++ 13.3, Make 4.3, and Python 3.12.3. Python 3.10 is absent, reinforcing the separate SDK provisioning requirement. PR run 34013779750 at `282519d2` verifies Node 22.19.0, 24.9.0, and 26.8.1 on self-hosted Linux, including setup, executable-path checks, compatibility tests, and post actions. The executables reside under each runner’s `_temp/node-compat-toolcache/node/<version>/x64/bin`; the completed jobs take 228s, 94s, and 101s respectively. These observations establish version and path compatibility, not an exclusive-host capacity guarantee.
+Successful standby run 33984559660 at the implementation base supplies Linux Node 24.19.0 and Windows Node 24.20.0 baseline evidence. Linux job 101359402557 uses runner-specific temporary and tool directories on the data volume. Read-only capability probe 34012679056 (job 101431064925) reports Linux x64, 192 online logical CPUs, GCC/G++ 13.3, Make 4.3, and Python 3.12.3. Python 3.10 is absent, reinforcing the separate SDK provisioning requirement. PR run 34013779750 verifies Node 22.19.0, 24.9.0, and 26.8.1 on self-hosted Linux, including setup, executable-path checks, compatibility tests, and post actions. The executables reside under each runner’s `_temp/node-compat-toolcache/node/<version>/x64/bin`; the completed jobs take 228s, 94s, and 101s respectively. These observations establish version and path compatibility, not an exclusive-host capacity guarantee.

+ 1 - 1
.agents/notes/implemented/process/2026-09-06-node-compatibility-selfhosted.zh.md

@@ -32,4 +32,4 @@ Status: implemented
 
 聚焦的[工作流回归测试](../../../../scripts/ci-compatible-selfhosted.spec.ts) 执行真实的路由表达式和环境设置。移除 fork 条件的负对照使托管回退断言失败。它检查维护者重跑 Dependabot PR、仓库不匹配、fork 标志、禁用变量以及运行器范围内的缓存路径。
 
-实施基线上的成功热备运行 33984559660 提供 Linux Node 24.19.0 和 Windows Node 24.20.0 基线证据。Linux 作业 101359402557 使用数据卷上运行器专属的临时目录和工具目录。只读能力探测 34012679056 (job 101431064925) 报告 Linux x64、192 个在线逻辑 CPU、GCC/G++ 13.3、Make 4.3 和 Python 3.12.3。Python 3.10 缺失,进一步说明 SDK 需要单独配置。`282519d2` 上的 PR 运行 34013779750 验证了自托管 Linux 上的 Node 22.19.0、24.9.0 和 26.8.1,包括设置、可执行文件路径检查、兼容性测试和 post actions。可执行文件位于各运行器的 `_temp/node-compat-toolcache/node/<version>/x64/bin` 下;完成的作业分别耗时 228s、94s 和 101s。这些观测证明版本与路径兼容性,而非独占主机的容量保证。
+实施基线上的成功热备运行 33984559660 提供 Linux Node 24.19.0 和 Windows Node 24.20.0 基线证据。Linux 作业 101359402557 使用数据卷上运行器专属的临时目录和工具目录。只读能力探测 34012679056 (job 101431064925) 报告 Linux x64、192 个在线逻辑 CPU、GCC/G++ 13.3、Make 4.3 和 Python 3.12.3。Python 3.10 缺失,进一步说明 SDK 需要单独配置。PR 运行 34013779750 验证了自托管 Linux 上的 Node 22.19.0、24.9.0 和 26.8.1,包括设置、可执行文件路径检查、兼容性测试和 post actions。可执行文件位于各运行器的 `_temp/node-compat-toolcache/node/<version>/x64/bin` 下;完成的作业分别耗时 228s、94s 和 101s。这些观测证明版本与路径兼容性,而非独占主机的容量保证。

+ 2 - 2
.agents/notes/implemented/process/2026-09-12-maintained-repository-references.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-09-12-maintained-repository-references.md
-2026-09-12-maintained-repository-references.md: c65f8b984c147bd323dd6fbd865402c07c0f4ad8
-2026-09-12-maintained-repository-references.zh.md: e613f332d4d3338e44acd8a1f55271ca044f06eb
+2026-09-12-maintained-repository-references.md: b2bc750100e1aaf2ff63ffc773bbd54997fdf355
+2026-09-12-maintained-repository-references.zh.md: 99216e8105af9d159f6f371c9e31fec6d75a0e75

+ 1 - 1
.agents/notes/implemented/process/2026-09-12-maintained-repository-references.md

@@ -26,6 +26,6 @@ Native source manifests identify the public source home. During workflow packing
 
 ## Consequences
 
-The gate performs no network fetch. Local shallow checkouts can identify only objects they contain; CI static checks use full history. Reference validation establishes the maintained-file policy, not remote tag immutability or historical compatibility.
+The gate disables network fetching, including Git partial-clone lazy fetching. It checks all locally available commit objects, including unreachable historical PR heads; absent objects cannot match. A checkout with extra PR objects can therefore detect references absent from CI’s full-history clone. Reference validation establishes the maintained-file policy, not remote tag immutability or historical compatibility. Published native tarballs expose the workflow repository in npm’s Repository metadata; source manifests retain the public source home.
 
 Vendored notices link checked-in source locations while retaining upstream names, licenses, and the unchanged vendor manifest.

+ 1 - 1
.agents/notes/implemented/process/2026-09-12-maintained-repository-references.zh.md

@@ -26,6 +26,6 @@ Status: implemented
 
 ## 影响
 
-检查器不进行网络获取。本地浅检出只能识别其包含的对象;CI 静态检查使用完整历史。引用校验建立维护中文件的策略,不证明远端 tag 不可变或历史兼容性。
+检查器禁止网络获取,包括 Git 部分克隆的延迟获取。它检查本地所有可用的提交对象,包括不可达的历史 PR 头;缺失的对象无法匹配。因此,包含额外 PR 对象的工作区可能检测到 CI 完整历史克隆中不存在的引用。引用校验建立维护中文件的策略,不证明远端 tag 不可变或历史兼容性。已发布的原生 tarball 在 npm 的 Repository 元数据中显示工作流仓库;源码清单保留公开源码主页。
 
 Vendored 声明链接仓库内的源码位置,同时保留上游名称、许可证和未变的 vendor 清单。

+ 2 - 2
.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.md
-2026-09-06-agent-request-freeze-evidence.md: e370b2556f212455239bceca70ec2661ce7787e0
-2026-09-06-agent-request-freeze-evidence.zh.md: 970e5f84f2593be738388aad828a2a83146a3a34
+2026-09-06-agent-request-freeze-evidence.md: 6603a728c3dd2acc87902169bb07a67bde0be2a4
+2026-09-06-agent-request-freeze-evidence.zh.md: a5ba15ac139d647755f9c039847acbb642d214d3

+ 3 - 3
.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.md

@@ -18,7 +18,7 @@ This specializes request construction, not Session ownership or general `deepFre
 
 ## Measurement evidence
 
-Apple M4 Pro, macOS arm64, Node 24.19.0; independent worktree dependencies and built artifacts. The exact parent Agent source at 1dc3296eba is rebuilt for the negative control, then the optimized source is restored and rebuilt. Each row retains all five fresh-process totals in sampling order; all timings are milliseconds. Exclusive slots do not overlap repository builds or sibling benchmarks.
+Apple M4 Pro, macOS arm64, Node 24.19.0; independent worktree dependencies and built artifacts. The exact parent Agent source from run 34017868081 is rebuilt for the negative control, then the optimized source is restored and rebuilt. Each row retains all five fresh-process totals in sampling order; all timings are milliseconds. Exclusive slots do not overlap repository builds or sibling benchmarks.
 
 | Implementation and UTC interval (2026-09-06) | Request-history raw totals | Median | 175 ms verdict |
 |---|---|---:|---|
@@ -36,9 +36,9 @@ An earlier original-code run at 06:58:28 UTC overlaps a sibling build because of
 
 ### Standard hosted CI calibration
 
-The standard two-CPU `ubuntu-24.04` lane runs Node 24.20.0. Run 34033336380, job 101487280801 measures the optimized request path at merge commit `8fba64d9ae06d1a9a778a95487bb915d24cb0644` in Azure eastus: 183.355397, 184.468253, 185.042397, 182.160790, 182.924728 ms; median 183.355397 ms. Every sample completes the same 40 requests and 13,923 events. All five exceed the historical 175 ms budget without changing the WeakSet implementation or workload.
+The standard two-CPU `ubuntu-24.04` lane runs Node 24.20.0. Run 34033336380, job 101487280801 measures the optimized request path in Azure eastus: 183.355397, 184.468253, 185.042397, 182.160790, 182.924728 ms; median 183.355397 ms. Every sample completes the same 40 requests and 13,923 events. All five exceed the historical 175 ms budget without changing the WeakSet implementation or workload.
 
-A second hosted run of the same request implementation, run 34033336246, job 101487216170, records 145.644577, 144.204300, 143.072572, 145.985903, 146.834474 ms; median 145.644577 ms. It uses the same Ubuntu image and Node version but a different worker in Azure westus3 at merge commit `c366e49`. This faster run does not replace the eastus evidence or establish why the workers differ. The older self-hosted `VM-7-113-ubuntu-ci-9` run with Node 24.18.1 (run 34021903421, job 101456015028) records 110.025154, 119.958978, 108.266860, 107.557950, 108.538902 ms; median 108.538902 ms. Its runner and Node version do not calibrate the standard hosted lane.
+A second hosted run of the same request implementation, run 34033336246, job 101487216170, records 145.644577, 144.204300, 143.072572, 145.985903, 146.834474 ms; median 145.644577 ms. It uses the same Ubuntu image and Node version but a different worker in Azure westus3. This faster run does not replace the eastus evidence or establish why the workers differ. The older self-hosted `VM-7-113-ubuntu-ci-9` run with Node 24.18.1 (run 34021903421, job 101456015028) records 110.025154, 119.958978, 108.266860, 107.557950, 108.538902 ms; median 108.538902 ms. Its runner and Node version do not calibrate the standard hosted lane.
 
 The current request-history median limit is 297 ms. It is the largest integer within a 25% increase from the initial 238 ms limit: `floor(238 × 1.25) = 297`, an increase of 24.79%. This allowance belongs only to `agent-continuation/request-history`; the shared time scale, variance headroom, other time limits, memory limits, sample count, and workload remain unchanged.
 

+ 3 - 3
.agents/notes/implemented/simplification/2026-09-06-agent-request-freeze-evidence.zh.md

@@ -18,7 +18,7 @@ Status: implemented
 
 ## 测量证据
 
-Apple M4 Pro、macOS arm64、Node 24.19.0;worktree 使用独立依赖和构建产物。负对照重新构建 1dc3296eba 中精确的父版本 Agent 源码,随后恢复并重新构建优化源码。每行按采样顺序保留全部五个新进程总耗时;时间单位均为毫秒。独占时段不与仓库构建或其他基准重叠。
+Apple M4 Pro、macOS arm64、Node 24.19.0;worktree 使用独立依赖和构建产物。负对照重新构建运行 34017868081 中精确的父版本 Agent 源码,随后恢复并重新构建优化源码。每行按采样顺序保留全部五个新进程总耗时;时间单位均为毫秒。独占时段不与仓库构建或其他基准重叠。
 
 | 实现与 UTC 时段(2026-09-06) | 请求历史原始总耗时 | 中位数 | 175 ms 判定 |
 |---|---|---:|---|
@@ -36,9 +36,9 @@ Apple M4 Pro、macOS arm64、Node 24.19.0;worktree 使用独立依赖和构建
 
 ### 标准托管 CI 校准
 
-标准双 CPU `ubuntu-24.04` 测试通道运行 Node 24.20.0。运行 34033336380、任务 101487280801在 Azure eastus 上测量合并提交 `8fba64d9ae06d1a9a778a95487bb915d24cb0644` 的优化请求路径:183.355397, 184.468253, 185.042397, 182.160790, 182.924728 ms;中位数 183.355397 ms。每个样本都完成相同的 40 个请求和 13,923 个事件。在 WeakSet 实现与工作负载未变的情况下,全部五个样本均超过历史 175 ms 预算。
+标准双 CPU `ubuntu-24.04` 测试通道运行 Node 24.20.0。运行 34033336380、任务 101487280801 在 Azure eastus 上测量优化请求路径:183.355397, 184.468253, 185.042397, 182.160790, 182.924728 ms;中位数 183.355397 ms。每个样本都完成相同的 40 个请求和 13,923 个事件。在 WeakSet 实现与工作负载未变的情况下,全部五个样本均超过历史 175 ms 预算。
 
-相同请求实现的另一次托管运行,运行 34033336246、任务 101487216170,记录了 145.644577, 144.204300, 143.072572, 145.985903, 146.834474 ms;中位数 145.644577 ms。它在合并提交 `c366e49` 上使用相同的 Ubuntu 镜像和 Node 版本,但运行于 Azure westus3 的另一台工作机。较快的运行不能替代 eastus 证据,也不能证明工作机差异的原因。较早的自托管 `VM-7-113-ubuntu-ci-9` 运行使用 Node 24.18.1(运行 34021903421、任务 101456015028),记录了 110.025154, 119.958978, 108.266860, 107.557950, 108.538902 ms;中位数 108.538902 ms。其运行器和 Node 版本不能校准标准托管通道。
+相同请求实现的另一次托管运行,运行 34033336246、任务 101487216170,记录了 145.644577, 144.204300, 143.072572, 145.985903, 146.834474 ms;中位数 145.644577 ms。它使用相同的 Ubuntu 镜像和 Node 版本,但运行于 Azure westus3 的另一台工作机。较快的运行不能替代 eastus 证据,也不能证明工作机差异的原因。较早的自托管 `VM-7-113-ubuntu-ci-9` 运行使用 Node 24.18.1(运行 34021903421、任务 101456015028),记录了 110.025154, 119.958978, 108.266860, 107.557950, 108.538902 ms;中位数 108.538902 ms。其运行器和 Node 版本不能校准标准托管通道。
 
 当前请求历史中位数上限为 297 ms。这是在最初 238 ms 上限基础上增加不超过 25% 的最大整数:`floor(238 × 1.25) = 297`,增加 24.79%。该余量仅属于 `agent-continuation/request-history`;共享时间系数、波动余量、其他时间上限、内存上限、采样次数与工作负载均保持不变。
 

+ 2 - 2
.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md
-2026-09-06-backend-continuation-performance.md: a78dcb8bcc51b106123071951363090c20b98820
-2026-09-06-backend-continuation-performance.zh.md: 66f10d0b811cc354c18f0f59c6407b4d56de0723
+2026-09-06-backend-continuation-performance.md: a30c7a47a93f0a8827d1cb4d0857aeabe9dd2fee
+2026-09-06-backend-continuation-performance.zh.md: c703ea70e496d279e5965295d308a2919ed2b445

+ 3 - 3
.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.md

@@ -45,13 +45,13 @@ A separate plain-Node request-history CPU profile attributes 132.876 ms of sampl
 
 The shipped SDK variant completes 100 turns, 200 requests, and 800 real file reads. Its five-sample smoke totals are 1,521.773, 1,463.465, 1,689.701, 1,365.485, and 1,417.106 ms (median 1,463.465 ms); a full-suite repeat reports 1,596.183, 1,784.536, 2,120.082, 1,405.365, and 1,355.894 ms (median 1,596.183 ms). Its 1,700 ms reference expectation yields a 4,250 ms CI budget. The repeat also slows the unchanged service cases, so it is validation under variable host load rather than evidence to relax their exclusive calibration. The SDK process receives an allowlisted environment and private home/workspace. A 40-second deadline starts SDK shutdown; every path awaits the same memoized close promise before the outer worker’s 60-second deadline. Profile timing includes boot, all turns, and shutdown, reported separately; no parent-process CPU or heap metric is presented as server memory. The adapter does not serialize requests for an external model provider.
 
-The first Linux x64 CI measurement at commit `1dc3296eba631d51fbb3bb50e249bf3cc0fce9f6` ran on `VM-7-113-ubuntu-ci-10` with Node 24.18.1 (run 34017868081, attempt 1, job 101444810498). The SDK median was 2,753.441 ms against its 4,250 ms budget, and tool-continuation retained-heap median was 22.274 MiB against 28.75 MiB. Request-history and tool-continuation time budgets failed: 785.498 ms against 550 ms and 1,077.285 ms against 850 ms, respectively. The unchanged Session-reopen open phase also failed at 31.6 ms against 30 ms. Attempt 2, job 101447076381 (run 34017868081) passed every benchmark on the same commit and unchanged budgets, but used `VM-7-113-ubuntu-ci-29` with Node 24.19.0. The gate runner suppressed successful child output, so that attempt supplies a passing verdict rather than raw medians. The changed runner and Node version prevent attributing the difference solely to contention or claiming stable repeated CI calibration; neither the budgets nor the shared scale are changed on this evidence.
+The first Linux x64 CI measurement ran on `VM-7-113-ubuntu-ci-10` with Node 24.18.1 (run 34017868081, attempt 1, job 101444810498). The SDK median was 2,753.441 ms against its 4,250 ms budget, and tool-continuation retained-heap median was 22.274 MiB against 28.75 MiB. Request-history and tool-continuation time budgets failed: 785.498 ms against 550 ms and 1,077.285 ms against 850 ms, respectively. The unchanged Session-reopen open phase also failed at 31.6 ms against 30 ms. Attempt 2, job 101447076381 (run 34017868081) passed every benchmark on the same commit and unchanged budgets, but used `VM-7-113-ubuntu-ci-29` with Node 24.19.0. The gate runner suppressed successful child output, so that attempt supplies a passing verdict rather than raw medians. The changed runner and Node version prevent attributing the difference solely to contention or claiming stable repeated CI calibration; neither the budgets nor the shared scale are changed on this evidence.
 
 Catalog uses an explicit 900 ms expected CI duration and only the existing 1.25× headroom, yielding 1,125 ms without applying the reference-machine scale again. The standard two-CPU hosted `ubuntu-24.04` run 34033336380, job 101487280801 reports five unchanged-catalog totals of 797.374, 883.157, 858.364, 790.569, and 904.579 ms: median 858.364 ms exceeds the historical 800 ms budget. The 320 ms M4 expectation above remains historical evidence, not a CI measurement. This follows the explicit-CI calibration used by Session reopening (50 ms expected CI); shared factors, workloads, timing endpoints, and product implementations remain unchanged. Deterministic controls use the same assertion as the measured verdict: the unrounded recorded median passes 1,125 ms and fails 800 ms, while a synthetic 1,400 ms median fails 1,125 ms. A passing run on a faster host does not calibrate the standard hosted runner.
 
-Tool continuation also uses a 900 ms expected CI duration with 1.25× headroom (1,125 ms). At unchanged implementation `79c052ab29`, standard two-CPU hosted run 34034524265, job 101490056074 reports totals of 917.007, 892.091, 887.839, 905.659, and 898.252 ms: median 898.252 ms exceeds the historical 850 ms budget. The 340 ms M4 expectation remains historical evidence. The same measured-verdict assertion accepts the recorded unrounded median under 1,125 ms, rejects it under 850 ms, and rejects a synthetic 1,400 ms regression. Workload, timing, product code, and the 28.75 MiB retained-heap budget remain unchanged.
+Tool continuation also uses a 900 ms expected CI duration with 1.25× headroom (1,125 ms). With unchanged implementation, standard two-CPU hosted run 34034524265, job 101490056074 reports totals of 917.007, 892.091, 887.839, 905.659, and 898.252 ms: median 898.252 ms exceeds the historical 850 ms budget. The 340 ms M4 expectation remains historical evidence. The same measured-verdict assertion accepts the recorded unrounded median under 1,125 ms, rejects it under 850 ms, and rejects a synthetic 1,400 ms regression. Workload, timing, product code, and the 28.75 MiB retained-heap budget remain unchanged.
 
-Baseline request history uses a 600 ms expected CI duration with 1.25× headroom (750 ms). At unchanged implementation `54d1190a75`, standard two-CPU hosted run 34035306987, job 101492163630 reports totals of 618.598, 618.606, 582.035, 582.304, and 581.832 ms: median 582.304 ms exceeds the historical 550 ms budget. The 220 ms M4 expectation remains historical evidence. The same measured-verdict assertion accepts the recorded unrounded median under 750 ms, rejects it under 550 ms, and rejects a synthetic 900 ms regression. This calibrates the unoptimized baseline only; workload, timing, product code, and memory budgets remain unchanged.
+Baseline request history uses a 600 ms expected CI duration with 1.25× headroom (750 ms). With unchanged implementation, standard two-CPU hosted run 34035306987, job 101492163630 reports totals of 618.598, 618.606, 582.035, 582.304, and 581.832 ms: median 582.304 ms exceeds the historical 550 ms budget. The 220 ms M4 expectation remains historical evidence. The same measured-verdict assertion accepts the recorded unrounded median under 750 ms, rejects it under 550 ms, and rejects a synthetic 900 ms regression. This calibrates the unoptimized baseline only; workload, timing, product code, and memory budgets remain unchanged.
 
 ## Alternatives considered
 

+ 3 - 3
.agents/notes/implemented/testing/2026-09-06-backend-continuation-performance.zh.md

@@ -45,13 +45,13 @@ SDK fixture 通过 profile patch 显式插入 `fs-local` 和 `str_replace_editor
 
 已发布 SDK 变体完成 100 个轮次、200 次请求和 800 次真实文件读取。五样本 smoke 总时间为 1,521.773、1,463.465、1,689.701、1,365.485 和 1,417.106 ms(中位数 1,463.465 ms);完整套件重复运行报告 1,596.183、1,784.536、2,120.082、1,405.365 和 1,355.894 ms(中位数 1,596.183 ms)。1,700 ms 参考期望对应 4,250 ms CI 预算。重复运行中未改变的服务用例也变慢,因此这是可变主机负载下的验证,不是放宽其独占校准预算的依据。SDK 进程使用白名单环境和私有主目录/工作区。40 秒截止时间启动 SDK 关闭;所有路径等待同一个记忆化 close Promise,并早于外层 worker 的 60 秒截止时间。Profile 时间包含启动、全部轮次和关闭,分别报告;不把父进程 CPU 或堆指标当作服务端内存。适配器不为外部模型服务商序列化请求。
 
-提交 `1dc3296eba631d51fbb3bb50e249bf3cc0fce9f6` 的首次 Linux x64 CI 测量使用 `VM-7-113-ubuntu-ci-10` 和 Node 24.18.1(run 34017868081,attempt 1,job 101444810498)。SDK 中位数为 2,753.441 ms,预算为 4,250 ms;工具续聊保留堆中位数为 22.274 MiB,预算为 28.75 MiB。请求历史与工具续聊时间预算失败:分别为 785.498 ms 对 550 ms、1,077.285 ms 对 850 ms。未修改的 Session 重开 open 阶段也以 31.6 ms 对 30 ms 失败。Attempt 2,job 101447076381 (run 34017868081) 在同一提交和未修改预算下通过全部基准,但使用 `VM-7-113-ubuntu-ci-29` 和 Node 24.19.0。门禁运行器隐藏成功子进程的输出,因此该次运行只提供通过结论,不提供原始中位数。Runner 与 Node 版本同时变化,不能把差异仅归因于资源争用,也不能宣称已获得稳定的重复 CI 校准;这些证据不改变预算或共享比例。
+首次 Linux x64 CI 测量使用 `VM-7-113-ubuntu-ci-10` 和 Node 24.18.1(run 34017868081,attempt 1,job 101444810498)。SDK 中位数为 2,753.441 ms,预算为 4,250 ms;工具续聊保留堆中位数为 22.274 MiB,预算为 28.75 MiB。请求历史与工具续聊时间预算失败:分别为 785.498 ms 对 550 ms、1,077.285 ms 对 850 ms。未修改的 Session 重开 open 阶段也以 31.6 ms 对 30 ms 失败。Attempt 2,job 101447076381 (run 34017868081) 在同一提交和未修改预算下通过全部基准,但使用 `VM-7-113-ubuntu-ci-29` 和 Node 24.19.0。门禁运行器隐藏成功子进程的输出,因此该次运行只提供通过结论,不提供原始中位数。Runner 与 Node 版本同时变化,不能把差异仅归因于资源争用,也不能宣称已获得稳定的重复 CI 校准;这些证据不改变预算或共享比例。
 
 目录用例使用显式的 900 ms CI 期望时间,仅乘现有 1.25× 余量,得到 1,125 ms,不再应用参考机器比例。标准双 CPU 托管 `ubuntu-24.04` 的 run 34033336380,job 101487280801 报告未修改目录实现的五个总时间为 797.374、883.157、858.364、790.569 和 904.579 ms:中位数 858.364 ms 超出历史 800 ms 预算。上表 320 ms M4 期望保留为历史证据,不是 CI 测量。此方法与 Session 重开使用的显式 CI 校准一致(CI 期望为 50 ms);共享系数、负载、计时终点和产品实现均不改变。确定性对照与实测判定使用同一断言:未经舍入的录制中位数通过 1,125 ms 并被 800 ms 拒绝,合成的 1,400 ms 中位数则被 1,125 ms 拒绝。更快主机上的通过结果不能校准标准托管 runner。
 
-工具续聊同样使用 900 ms CI 期望时间与 1.25× 余量(1,125 ms)。未修改实现的 `79c052ab29` 在标准双 CPU 托管 run 34034524265,job 101490056074 中报告总时间为 917.007、892.091、887.839、905.659 和 898.252 ms:中位数 898.252 ms 超出历史 850 ms 预算。340 ms M4 期望保留为历史证据。与实测判定相同的断言在 1,125 ms 下接受未经舍入的录制中位数,在 850 ms 下拒绝它,并拒绝合成的 1,400 ms 回退。负载、计时、产品代码和 28.75 MiB 保留堆预算均不改变。
+工具续聊同样使用 900 ms CI 期望时间与 1.25× 余量(1,125 ms)。未修改的实现在标准双 CPU 托管 run 34034524265,job 101490056074 中报告总时间为 917.007、892.091、887.839、905.659 和 898.252 ms:中位数 898.252 ms 超出历史 850 ms 预算。340 ms M4 期望保留为历史证据。与实测判定相同的断言在 1,125 ms 下接受未经舍入的录制中位数,在 850 ms 下拒绝它,并拒绝合成的 1,400 ms 回退。负载、计时、产品代码和 28.75 MiB 保留堆预算均不改变。
 
-基线请求历史使用 600 ms CI 期望时间与 1.25× 余量(750 ms)。未修改实现的 `54d1190a75` 在标准双 CPU 托管 run 34035306987,job 101492163630 中报告总时间为 618.598、618.606、582.035、582.304 和 581.832 ms:中位数 582.304 ms 超出历史 550 ms 预算。220 ms M4 期望保留为历史证据。与实测判定相同的断言在 750 ms 下接受未经舍入的录制中位数,在 550 ms 下拒绝它,并拒绝合成的 900 ms 回退。此校准仅针对未优化基线;负载、计时、产品代码和内存预算均不改变。
+基线请求历史使用 600 ms CI 期望时间与 1.25× 余量(750 ms)。未修改的实现在标准双 CPU 托管 run 34035306987,job 101492163630 中报告总时间为 618.598、618.606、582.035、582.304 和 581.832 ms:中位数 582.304 ms 超出历史 550 ms 预算。220 ms M4 期望保留为历史证据。与实测判定相同的断言在 750 ms 下接受未经舍入的录制中位数,在 550 ms 下拒绝它,并拒绝合成的 900 ms 回退。此校准仅针对未优化基线;负载、计时、产品代码和内存预算均不改变。
 
 ## 考虑过的替代方案
 

+ 2 - 2
.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.md
-2026-09-06-frontend-performance-budgets.md: 349de386521f9ef5642cc808f7d2a9f849299ba4
-2026-09-06-frontend-performance-budgets.zh.md: 6231827472ece3992d994f9f021c0a34c0d398ec
+2026-09-06-frontend-performance-budgets.md: 2ccc992add9a1f7fc7824a3e0ed604a9582def56
+2026-09-06-frontend-performance-budgets.zh.md: bfe31fd4c8c61b3b89336a8d9d8234d1e76ba040

+ 1 - 1
.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.md

@@ -40,7 +40,7 @@ Draft typing spans 124.97–504.96 ms across the three isolated samples; the ref
 
 ### Actual CI runs
 
-Run 34020120425, benchmark job 101451135853 passes the complete benchmark inventory at `6d1ba089e5052680961825c08aa4de19b4fe137a`. The runner is `VM-7-113-ubuntu-ci-19` in `dsh-selfhosted-ci`, using x64 Node 24.19.0 and Chromium 149.0.7827.55. Attempt 2, benchmark job 101453296071 (run 34020120425) also passes the complete inventory at the same commit, on `VM-7-113-ubuntu-ci-25` with the same Node and Chromium versions. The following medians use three fresh samples per scenario in each run and leave the local reference table and source budgets unchanged.
+Run 34020120425, benchmark job 101451135853 passes the complete benchmark inventory. The runner is `VM-7-113-ubuntu-ci-19` in `dsh-selfhosted-ci`, using x64 Node 24.19.0 and Chromium 149.0.7827.55. Attempt 2, benchmark job 101453296071 (run 34020120425) also passes the complete inventory at the same commit, on `VM-7-113-ubuntu-ci-25` with the same Node and Chromium versions. The following medians use three fresh samples per scenario in each run and leave the local reference table and source budgets unchanged.
 
 | Endpoint | First CI median | Second CI median |
 |---|---:|---:|

+ 1 - 1
.agents/notes/implemented/testing/2026-09-06-frontend-performance-budgets.zh.md

@@ -40,7 +40,7 @@ Node 对话折叠很快,并不能证明浏览器能绘制长对话或在流式
 
 ### 实际 CI 运行
 
-运行 34020120425,基准 job 101451135853 在 `6d1ba089e5052680961825c08aa4de19b4fe137a` 上通过完整基准清单。runner 为 `dsh-selfhosted-ci` 中的 `VM-7-113-ubuntu-ci-19`,使用 x64 Node 24.19.0 和 Chromium 149.0.7827.55。第 2 次执行,基准 job 101453296071 (run 34020120425) 在相同 commit 上也通过完整清单,runner 为 `VM-7-113-ubuntu-ci-25`,Node 和 Chromium 版本相同。下列中位数来自每次运行中每个场景的三个全新样本,本地参考表和源码预算保持不变。
+运行 34020120425,基准 job 101451135853 通过完整基准清单。runner 为 `dsh-selfhosted-ci` 中的 `VM-7-113-ubuntu-ci-19`,使用 x64 Node 24.19.0 和 Chromium 149.0.7827.55。第 2 次执行,基准 job 101453296071 (run 34020120425) 在相同 commit 上也通过完整清单,runner 为 `VM-7-113-ubuntu-ci-25`,Node 和 Chromium 版本相同。下列中位数来自每次运行中每个场景的三个全新样本,本地参考表和源码预算保持不变。
 
 | 终点 | 首次 CI 中位数 | 第二次 CI 中位数 |
 |---|---:|---:|

+ 1 - 1
native/system/docs/packaging.md

@@ -21,6 +21,6 @@ The `./landlock-run` API stays importable without native payloads and reports un
 
 Platform tarballs use npm pack to preserve the launcher's executable bit. The entry uses pnpm pack to convert workspace dependency versions. Prepack rejects missing or undeclared payloads, invalid ELF/Mach-O architecture or type, addons without Node-API exports, and launchers without executable permission.
 
-Maintained manifests identify the public source repository. When `GITHUB_REPOSITORY` is set, the release packer copies packages and prepack scripts into a temporary workspace and sets the copied manifests' repository URL from that workflow repository and `GITHUB_SERVER_URL` (default `https://github.com`). This preserves npm trusted publishing's repository identity without changing source manifests. GitHub Actions requires a valid repository identity; local packing without workflow context retains the public source URL. Staging is removed after packing or a prepack failure, and publication consumes the resulting tarballs unchanged.
+Maintained manifests identify the public source repository. When `GITHUB_REPOSITORY` is set, the release packer copies packages and prepack scripts into a temporary workspace and sets the copied manifests' repository URL from that workflow repository and `GITHUB_SERVER_URL` (default `https://github.com`). The published tarballs and npm Repository link identify that workflow repository; source manifests retain the public source home. GitHub Actions requires a valid repository identity; local packing without workflow context retains the public source URL. The temporary workspace also carries the repository root license so pnpm retains its usual inheritance when an entry has no package-local license. Staging is removed after packing or a prepack failure, and publication consumes the resulting tarballs unchanged.
 
 The installed-artifact rehearsal verifies concrete dependency versions and absence of installation hooks, performs an offline npm install from local tarballs, and compares installed bytes with build outputs. It then proves flock contention/close release and probes the installed Landlock launcher; real confinement remains required on enforcing CI kernels.

+ 2 - 0
native/system/scripts/pack-release.mjs

@@ -71,6 +71,8 @@ function stagePackages(staging, repositoryUrl) {
     });
   }
   fs.copyFileSync(path.join(root, 'package.json'), path.join(staging, 'package.json'));
+  // pnpm includes the repository workspace license when an entry has no package-local license.
+  fs.copyFileSync(path.resolve(root, '../../LICENSE'), path.join(staging, 'LICENSE'));
   fs.writeFileSync(path.join(staging, 'pnpm-workspace.yaml'), 'packages:\n  - packages/*\n');
   for (const dir of [...platformDirs(), ...entryDirs()]) {
     const manifestPath = path.join(staging, dir, 'package.json');

+ 22 - 5
native/system/test/release-packing.test.js

@@ -7,12 +7,18 @@ import { fileURLToPath } from 'node:url';
 import { test } from 'node:test';
 
 const publicRepository = 'git+https://github.com/deepseek-ai/deepseek-harness.git';
+const workspaceLicense = 'Fixture workspace license.\n';
 
-/** The real packer and prepack scripts operate on isolated, format-valid pack inputs. */
+/** Real packing uses the repository's nested workspace layout and isolated, format-valid payloads. */
 function fixture(t) {
-  const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'native-packing-test-'));
-  t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
-  const scratch = path.join(dir, 'scratch');
+  const workspace = fs.mkdtempSync(path.join(os.tmpdir(), 'native-packing-test-'));
+  t.after(() => fs.rmSync(workspace, { recursive: true, force: true }));
+  const dir = path.join(workspace, 'native/system');
+  fs.mkdirSync(dir, { recursive: true });
+  fs.writeFileSync(path.join(workspace, 'package.json'), `${JSON.stringify({ private: true, packageManager: 'pnpm@11.7.0' })}\n`);
+  fs.writeFileSync(path.join(workspace, 'pnpm-workspace.yaml'), 'packages:\n  - native/system\n  - native/system/packages/*\n');
+  fs.writeFileSync(path.join(workspace, 'LICENSE'), workspaceLicense);
+  const scratch = path.join(workspace, 'scratch');
   fs.mkdirSync(scratch);
   fs.cpSync(fileURLToPath(new URL('../scripts/', import.meta.url)), path.join(dir, 'scripts'), { recursive: true });
   const writeJson = (file, value) => {
@@ -21,7 +27,6 @@ function fixture(t) {
   };
   const repository = (name) => ({ type: 'git', url: publicRepository, directory: `native/system/packages/${name}` });
   writeJson('package.json', { name: 'native-packing-fixture', private: true, version: '1.2.3', packageManager: 'pnpm@11.7.0' });
-  fs.writeFileSync(path.join(dir, 'pnpm-workspace.yaml'), 'packages:\n  - packages/*\n');
   writeJson('packages/linux-x64/package.json', {
     name: '@fixture/native-linux-x64', version: '1.2.3', repository: repository('linux-x64'),
     os: ['linux'], cpu: ['x64'], files: ['bin/', 'prebuilds.json'],
@@ -60,6 +65,7 @@ function fixture(t) {
     }),
     unchanged() {
       assert.deepEqual(manifests.map(file => fs.readFileSync(path.join(dir, file), 'utf8')), original);
+      assert.equal(fs.readFileSync(path.join(workspace, 'LICENSE'), 'utf8'), workspaceLicense);
       assert.deepEqual(fs.readdirSync(scratch).filter(name => name.startsWith('native-system-pack-')), []);
     },
   };
@@ -97,6 +103,7 @@ for (const workflow of [false, true]) {
     assert.equal(manifests[0].repository.directory, 'native/system/packages/linux-x64');
     assert.equal(manifests[1].repository.directory, 'native/system/packages/entry');
     assert.equal(manifests[1].optionalDependencies['@fixture/native-linux-x64'], '1.2.3');
+    assert.equal(tarFile(f.dir, files[1], 'LICENSE').toString(), workspaceLicense);
     assert.deepEqual(tarFile(f.dir, files[0], 'bin/landlock-run'), f.binary);
     const extracted = path.join(f.dir, 'extracted');
     fs.mkdirSync(extracted);
@@ -105,6 +112,16 @@ for (const workflow of [false, true]) {
   });
 }
 
+test('a package-local license takes precedence over the workspace license during workflow packing', { timeout: 180_000 }, (t) => {
+  const f = fixture(t);
+  const entryLicense = 'Fixture entry license.\n';
+  fs.writeFileSync(path.join(f.dir, 'packages/entry/LICENSE'), entryLicense);
+  completed(f.pack({ GITHUB_REPOSITORY: 'fixture-owner/native-runtime' }));
+  assert.equal(tarFile(f.dir, 'fixture-native-1.2.3.tgz', 'LICENSE').toString(), entryLicense);
+  assert.equal(fs.readFileSync(path.join(f.dir, 'packages/entry/LICENSE'), 'utf8'), entryLicense);
+  f.unchanged();
+});
+
 test('invalid workflow identity fails before deleting existing pack output', (t) => {
   const f = fixture(t);
   fs.mkdirSync(path.join(f.dir, 'output'));

+ 2 - 2
scripts/rescope-vendor.ts

@@ -358,9 +358,9 @@ const VENDORED_LIBRARY = /^@deepseek-ai\\/(cosmokit|schemastery)(\\/|$)/
     find: `| Package | Upstream | License |
 | --- | --- | --- |
 \${vendored.map(row => \`| \\\`\${row.npmName}\\\` | [\${row.upstream.replace('https://', '')}](\${row.upstream}) | MIT |\`).join('\\n')}`,
-    replace: `| Package | Upstream name | Upstream | License |
+    replace: `| Package | Upstream name | Source | License |
 | --- | --- | --- | --- |
-\${vendored.map(row => \`| \\\`\${row.npmName}\\\` | \\\`\${row.upstreamName}\\\` | [\${row.upstream.replace('https://', '')}](\${row.upstream}) | MIT |\`).join('\\n')}`,
+\${vendored.map(row => \`| \\\`\${row.npmName}\\\` | \\\`\${row.upstreamName}\\\` | [\${row.sourceDirectory}](\${row.sourceDirectory}/) | MIT |\`).join('\\n')}`,
     expect: 1,
   },
   {

+ 18 - 0
scripts/verify-repository-references.spec.ts

@@ -69,6 +69,24 @@ describe('maintained repository reference policy', () => {
     ])
   })
 
+  it('does not fetch missing commits from a partial clone\'s promisor remote', (test) => {
+    const remote = repository(test)
+    remote.git(['config', 'uploadpack.allowFilter', 'true'])
+    const clone = join(remote.root, 'partial-clone')
+    remote.git(['clone', '--filter=blob:none', '--no-local', remote.root, clone])
+    const missing = remote.git(['commit-tree', remote.tree, '-p', remote.commit, '-m', 'remote-only fixture'])
+    remote.git(['update-ref', 'HEAD', missing])
+    remote.write('partial-clone/new.md', missing)
+
+    expect(scanRepositoryReferences(clone)).toEqual([])
+    expect(execFileSync('git', ['cat-file', '--batch-check'], {
+      cwd: clone,
+      encoding: 'utf8',
+      env: { ...process.env, GIT_NO_LAZY_FETCH: '1' },
+      input: `${missing}\n`,
+    }).trim()).toBe(`${missing} missing`)
+  })
+
   it('accepts blobs, trees, unknown hex, long digests, and identifiers embedded in alphanumeric words', (test) => {
     const fixture = repository(test)
     const blob = fixture.git(['hash-object', '-w', '--stdin'], 'blob fixture')

+ 1 - 0
scripts/verify-repository-references.ts

@@ -74,6 +74,7 @@ function repositoryCommits(repoRoot: string, sources: Iterable<string>): Set<str
   if (candidates.length === 0) return new Set()
   const results = execFileSync('git', ['cat-file', '--batch-check=%(objectname) %(objecttype)'], {
     cwd: repoRoot,
+    env: { ...process.env, GIT_NO_LAZY_FETCH: '1' },
     encoding: 'utf8',
     input: `${candidates.join('\n')}\n`,
     maxBuffer: gitOutputLimit,