refactor(cli): ship one Eval runtime in the npm CLI package - #3946
Conversation
2927cd0 to
1f5e94d
Compare
7b230a8 to
76d4f20
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for tracing the Eval packaging consumers and reducing the duplicated payload.
I reviewed the exact head. The current 16-file inventory matches the existing container entry points, their import closure, and the Harbor/egress assets they consume. I did not find a P0 or P1 correctness issue in the current artifact.
I left one P2 inline about the architectural end state. The change reduces packaged bytes, but it retains the mirror and introduces substantial machinery to keep that second representation synchronized. I think the simplification should aim for one physical Eval runtime and strictly fewer maintained concepts, unless the old container path has a demonstrated external compatibility obligation.
AI-assisted review disclosure: Codex assisted with tracing the exact-head packaging, mount, experiment-config, and release-validation paths. I reviewed the recommendation and own this review.
76d4f20 to
a4c58c8
Compare
copyEvalMirror() copied the whole staged node_modules/@maka/eval tree into packages/eval, so every install carried the Eval runtime twice and the two copies could diverge between releases. Ship the runtime once. The CLI package root is bind-mounted read-only at /opt/maka-agent inside eval containers (eval-bundle-path.ts sets MAKA_EVAL_MAKA_BUNDLE_PATH to the package root; the experiment mount resolves in harness-executor.ts), and the canonical runtime already ships at node_modules/@maka/eval via the eval package's releaseFiles (the whole dist plus the harbor assets). So the container-facing paths are repointed from /opt/maka-agent/packages/eval/... to /opt/maka-agent/node_modules/@maka/eval/...: the two container entry points (harbor-external-subject.js / harbor-maka-subject.js, named by an experiment's args[0] / shimPath), the codex model catalog and the deepseek-harness profile the external subject reads, and the egress compose/network-policy resolved from the bundle. eval-bundle-path.ts keys its installed-CLI guard on node_modules/@maka/eval. With every consumer pointed at the canonical runtime, the mirror and the machinery that proved it are deleted outright: copyEvalMirror/stageEvalMirror, the acorn-based import-closure and path analyzer, the mirror inventory and the packed-tarball reconciliation, the acorn devDependency, and the mirror synchronization tests. The release packs node_modules/@maka/eval and no longer stages a packages/eval copy; validateStaging and the installed smoke test assert the container entry point, relay_agent.py, the egress compose, and the network-policy ship under node_modules/@maka/eval. maka eval remains the only public Eval CLI. Generated-by: Claude Opus
a4c58c8 to
78e56a7
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for taking this through to the single-runtime end state.
I independently rechecked exact head 78e56a7882110657fb61b75c5eae286a49d9d26d against the current main. The Eval mirror and its synchronization machinery are gone, the internal consumers now use the packaged @maka/eval runtime, the prior thread is resolved, and the exact-head required checks are green. I found no remaining P0-P3 issue.
Please do push back if there is a deployment or compatibility consumer that is not visible from the checked-in production paths; the conclusion here is based on the repository and hosted evidence available at this head.
中文对照
感谢将改动收敛到单一 Eval runtime。已独立复核当前 exact head 与 current main;旧镜像及同步机制已删除,内部消费者统一使用打包的 @maka/eval,旧线程已解决,当前提交的必要检查均通过,未发现剩余 P0-P3。若存在仓库生产路径之外的部署或兼容消费者,也欢迎补充或反驳。
AI-assisted review disclosure: Codex ran independent analysis lanes; Astro-Han independently verified the exact head, current-main integration, production ownership, and merge gates, and owns this review.
) copyEvalMirror() copied the whole staged node_modules/@maka/eval tree into packages/eval, so every install carried the Eval runtime twice and the two copies could diverge between releases. Ship the runtime once. The CLI package root is bind-mounted read-only at /opt/maka-agent inside eval containers (eval-bundle-path.ts sets MAKA_EVAL_MAKA_BUNDLE_PATH to the package root; the experiment mount resolves in harness-executor.ts), and the canonical runtime already ships at node_modules/@maka/eval via the eval package's releaseFiles (the whole dist plus the harbor assets). So the container-facing paths are repointed from /opt/maka-agent/packages/eval/... to /opt/maka-agent/node_modules/@maka/eval/...: the two container entry points (harbor-external-subject.js / harbor-maka-subject.js, named by an experiment's args[0] / shimPath), the codex model catalog and the deepseek-harness profile the external subject reads, and the egress compose/network-policy resolved from the bundle. eval-bundle-path.ts keys its installed-CLI guard on node_modules/@maka/eval. With every consumer pointed at the canonical runtime, the mirror and the machinery that proved it are deleted outright: copyEvalMirror/stageEvalMirror, the acorn-based import-closure and path analyzer, the mirror inventory and the packed-tarball reconciliation, the acorn devDependency, and the mirror synchronization tests. The release packs node_modules/@maka/eval and no longer stages a packages/eval copy; validateStaging and the installed smoke test assert the container entry point, relay_agent.py, the egress compose, and the network-policy ship under node_modules/@maka/eval. maka eval remains the only public Eval CLI. Generated-by: Claude Opus
Summary
copyEvalMirror()inscripts/release-cli-package.mjscopied the entire stagednode_modules/@maka/evaltree intopackages/evalinside the published CLI package, so every install carried the Eval runtime twice and the two copies could diverge between releases.The mirror is not pure redundancy. Eval containers bind-mount the CLI package root read-only at
/opt/maka-agent(packages/cli/src/eval-bundle-path.tssetsMAKA_EVAL_MAKA_BUNDLE_PATHto the package root; the experiment mount resolves inpackages/eval/src/harness-executor.ts), so/opt/maka-agent/packages/eval/...resolves to the mirror. Only a small container-facing subset is actually read from it; the host Eval runtime is read once fromnode_modules/@maka/eval.stageEvalMirror()now ships only that subset (16 files, down from the whole runtime tree):dist/harbor-external-subject.js,dist/harbor-maka-subject.js.dist/*.js).harbor/deepseek-codex-models.json, theharbor/deepseek-harness-profiledirectory,harbor/docker-compose-egress-proxy.yaml,harbor/egress-proxy/network-policy.Dropped from the mirror (all remain in
node_modules/@maka/evalviareleaseFiles): the host-onlydist/*.jsmodules; the harbor Python launchers (read fromnode_modules/@maka/eval/harborviaBUNDLED_HARNESS_RELAY_ROOT, not through the mount); and the egress image-build inputs (CI-only). Therelay_agent.py/run_trial.pyrelease guards move from the mirror tonode_modules/@maka/eval, matching where the runtime resolves them.maka evalremains the only public Eval CLI. Behavior, standalone packaging, and every container path the experiments depend on are unchanged.Fixes #3933
The reduction is proven structurally, not by text heuristics
acorn, so imports split across comments are followed and a string that merely containsimport(is not mistaken for a dependency. A dynamicimport()with a computed specifier is refused (fail closed) because its closure cannot be resolved.JSON.parsed and every string value is checked; eachpackages/evalreference is normalized (resolving./..) and rejected if it escapes the mirror, so neither path traversal (.../deepseek-harness-profile/../secret.json) nor a JSON-escaped slash (packages\/eval\/...) can name an unshipped file undetected.deepseek-harness-profileis declared once, as a directory, in the eval package'sreleaseFiles; staging and the mirror both copy it whole, so a newly required profile file cannot reach the runtime yet be missed by the mirror.validatePackedFilesrecomputes the mirror inventory from the staged runtime independently ofcopyEvalMirrorand asserts the packedpackages/evalfiles match it exactly — so reverting to a whole-tree copy, or dropping a required file, fails the release. The installed smoke test additionally asserts no host-only file appears under the mirror.Verification
node --test scripts/release-cli-file-policy.test.mjs— 24/24 pass, incl. comment-split imports, computed-import()rejection, path-traversal and JSON-escape rejection, the exact fixture inventory (a whole-tree copy fails it), andassertPackedEvalMirrorrejecting a reintroduced host-only file. Affected suites together: 32/32.node scripts/release-cli-package.mjs --development) succeeded end to end: the profile directory is copied whole intonode_modules/@maka/eval, the mirror stages to exactly 16 files, andvalidatePackedFiles(with the new packed-mirror assertion) passed. Tarball: 13.7 MiB compressed, 6408 files.biome check(lint + format) clean on all changed files.release-cli-eval-package.mjs, which installs the tarball and runs real Harbor + Pier Docker cells. Please confirm therelease:cli:evaljob on CI.Dependency
Adds
acorn(already present transitively) as a direct devDependency so the release script can depend on it for parsing.AI use
Select exactly one:
Tool(s) and scope: Claude Code (Opus) — mapped the runtime consumption of the mirror, implemented
stageEvalMirrorand its tests, and drafted this description. A human contributor reviewed and owns the change. The commit carries aGenerated-by: Claude Opustrailer.Checklist
Does this PR entail a change in behavior?