feat(cli): coordinate npm-global Runtime Host updates - #3925
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found no blocking issues.
Implements npm-global Host update coordination via bootstrap→coordinator→activator with verified archive, integrity-checked local npm install, prepare-then-reconcile transaction checks, lease FD heredity and triple identity verification; hosted test/windows_recovery/audit/owner checks SUCCESS.
No P0-P3.
简体中文
该头无阻断。Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.
jackwener
left a comment
There was a problem hiding this comment.
I reviewed exact head c68327b27ead94469cbf2b47fc98aaf7042417a2 and found one blocking issue.
P2 — The verified archive has no extracted-size or file-count budget
validateArchive() limits only the compressed .tgz to 256 MiB. The same archive is then passed to npm install once for staging (packages/cli/src/runtime-host-update-package.ts:141-168) and again for the npm-global switch (packages/cli/src/runtime-host-installed-update-coordinator.ts:259-300) without any bound on extracted bytes, entry count, or filesystem consumption.
SHA-512 integrity proves that the archive matches the registry metadata; it does not make the archive's expansion safe. A broken or compromised official publish can therefore use a small valid archive to exhaust the user's disk during the explicit update. If this happens during the final global switch, the target Host has already been activated and the durable handoff remains incomplete while the installed CLI switch has failed.
Please enforce a total uncompressed-byte and entry-count budget before or during extraction, apply the same bound to the final npm-global installation, and add a regression using a small compressed archive with excessive expansion. The exact-head hosted checks succeeded, but the package tests cover archive integrity and release identity rather than this resource boundary.
Posted by an automated review agent operated by @WAWQAQ. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.
简体中文
本条评论由 @WAWQAQ 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。
c68327b to
e583c5b
Compare
|
This is a synthesis of the independent blind review by @未开智选手 at exact head What I checked myself:
Findings from the reviewer's report (file:line anchored): Overall — CODE NO-GO — 3×P1 — should not be merged as npm-global coordination.
What was proven green: hosted What I did not judge: end-to-end npm-global switch with a real staged candidate on Windows/macOS/Linux was not executed — verification was by code inspection against the exact head and the three fault-chain reproductions noted above. Gate: 3×P1 remain; despite all 16 hosted checks green, head
|
jackwener
left a comment
There was a problem hiding this comment.
I re-reviewed exact head 7e292bd3805378f7eecd40b03345269c2847db56. This head remains NO-GO with three P1 issues and one P2. I independently confirmed the three P1 paths already described in the issue discussion and found the additional PAX bypass below.
-
P1 — the archive preflight rejects ordinary valid packages.
assertRuntimeHostArchiveExpansionBudget()advances past an entry's entire declared body even when the current gunzip chunk contains only part of it. The next chunk therefore starts in the middle of the body but is parsed as another tar header. A valid archive containing a 128 KiB file is rejected as a malformed header before either staging or the final global install can run. The scanner needs to retain body/padding state across chunks, with a cross-chunk regression at both npm seams. -
P1 — a crash retry can restore durable ownership to the retired source Host. After target activation but before
commit_handoff, retry preparation does not recognize that the observed Host already has the staged target generation. It re-runs retirement against that Host. If the target has work, generic rollback restores the oldselectedsource record even though that source was retired and the target remains live; if the target is idle, it is unnecessarily retired and restarted. Please identify the exact staged target by root and launch generation and cover idle and active crash-retry cases. -
P1 — the process-lifetime authority lease stops at the activator. The coordinator passes the lease descriptor to the activator, but the detached target-launch contract has no lease field and starts the Host with only the three ordinary stdio descriptors. If the coordinator or activator dies after the target is live but before the durable record commits, the target can survive without the lease while another coordinator acquires authority over the unresolved handoff. The descriptor must reach the detached target, or failure must guarantee that the target cannot survive; add a parent/activator-death test.
-
P2 — PAX size overrides bypass the extraction budget. The scanner charges only each raw header's octal size, while npm's tar extractor honors a standard PAX extended header's effective
sizefor the following file. I reproduced this through the production helper with a valid 226-byte npm package tarball: the raw file header declared zero, PAX declared 2,048 bytes, the helper accepted it under a 1,024-byte budget, andnpm installwrote the full 2,048-byte file. The same structure scales past the production 2 GiB limit while remaining highly compressible. Parse the archive with the extractor's PAX/global-PAX and sparse-file semantics—or reject unsupported extensions—and prove with a real PAX fixture that npm is never spawned.
The current-main synthetic merge is clean. The exact-head hosted checks succeeded where they ran; the Eval installation check was skipped and is not counted as green. The focused archive/coordinator tests passed 7/7 locally, but they exercise only tiny fixed-octal entries and miss both scanner failures.
Posted by an automated review agent operated by @WAWQAQ. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.
简体中文
本条评论由 @WAWQAQ 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。
Registry integrity binds the downloaded .tgz to its metadata but says nothing about how far it expands: a small valid archive could exhaust the user's disk during staging or the final npm-global switch. Scan the tar headers (one pass over the compressed stream, nothing written) and refuse archives whose entries exceed a 2 GiB / 100k-entry budget before npm install consumes them, at both the verified-artifact seam and the global switch itself. Regression tests pin over-budget, over-crowded, non-gzip, and truncated archives.
7e292bd to
3716688
Compare
|
Addressed the latest review on exact head The four findings were valid:
The main conflicts were resolved by retaining current-main's managed activation/managed launch claim and shared npm deployment-layout authority alongside this PR's installed-update path. Post-rebase evidence:
简体中文四条 finding 均确认成立并已修复:tar scanner 现在正确跨 chunk 跳过 payload;crash retry 会识别并续接同一 staged target;现有 authority lease 已继续继承到真正的 target Candidate,launch owner 异常退出时先关闭 Host 再释放 lease;PAX、GNU sparse/long-name 等会改写 tar 语义的扩展在两处 npm extraction 前统一拒绝。 PR 已 rebase 到当前 main,冲突解决时保留了主线新增的 managed activation、managed launch claim 与共享 npm deployment-layout authority。终态双重审查未发现第二份 lock、journal、owner state 或可删除的重复机制。 Generated-by: Codex |
Summary
maka update --target <next|latest|version>path for an npm-global CLI and its local Runtime HostUser-visible behavior
The command is deliberately explicit: direct
npx/development launches, downgrades, remote Hosts, and operator-managed services fail closed. Active work is refused by default;--allow-interrupt-active-tasksis required to authorize interruption.This preserves the existing ownership boundary: local npm-global deployments can be coordinated by the installed CLI, while remote and service-managed Hosts remain operator-updated.
Why this is one vertical PR
The shared registry-artifact seam and deployment-source finalization now each have a concrete production consumer. Splitting them before the caller would leave speculative abstractions or an incomplete transaction. The implementation still keeps three small process roles because each has a distinct compatibility constraint:
There remains one durable owner record, one handoff transaction, and one authority lock. No scheduler, second deployment journal, or parallel ownership state is introduced.
Failure and recovery
Validation
@maka/core,@maka/storage,@maka/mcp,@maka/runtime,@maka/runtime-host,@maka/eval,@maka/computer-use, andmaka-agentcli-coreprocess probe passedgit diff --checkpassedmaka-agent@nexttarball into an isolated npm-global prefix with offline/script-disabled settings and verified the installed version and binaryThe full
check:releasecommand was not used as evidence because its repository-wide stale-dist preflight requires unrelated UI/Desktop build outputs; the scoped release-policy tests above pass.Follow-ups outside this slice
npxownership and lifecycleRefs #3231
Refs #3243
Refs #3245
Refs #3709
中文说明
本 PR 为 npm 全局安装的 CLI 增加显式
maka update --target <next|latest|version>:复用现有 owner authority、handoff 事务和锁,依次完成旧 Host 退场、目标版本精确 Ready、npm 全局包切换与 owner 提交。默认拒绝中断活跃工作;只有用户显式传入
--allow-interrupt-active-tasks才允许。直接 npx、开发环境、降级、remote Host 和由服务管理器托管的 Host 都会 fail closed,继续由用户或运维方主动更新。三进程并非重复设计:native-free bootstrap 解决 Windows 自替换;当前包 coordinator 负责当前协议;目标包 activator 负责跨 epoch 的目标协议。系统仍只有一份持久 owner 状态、一条 handoff 事务和一把 authority 锁,没有新增 scheduler 或第二套恢复日志。
终审已按 simplify-audit 与第一性原理/奥卡姆剃刀完成,结论为 GO。
Generated-by: Codex