From 3d6de0c4ac67e290dbd0b3caa28ee9cbd5171c41 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 15 Oct 2026 13:53:00 +0000 Subject: [PATCH 1/5] Wire the layered Python environment into service startup Why: The dependency layer already existed in the backend, but service startup never passed it, so the sandbox could not import the packages the host already had. Evidence: SELF go tests recorded on the backend commit. svc.sh only exports the env root after env ensure leaves a current base layer, and a failed download does not block startup. Impact: Instances share runtime/envs. Existing exec= lines are left as stored. Proposal, backend, and frontend gitlinks move to this branch. Refs: .task/feature-layered-python-env.md Co-authored-by: Cursor --- .task/feature-layered-python-env.md | 29 +++++++++++++++++++++++++++++ modules/backend | 2 +- modules/documents | 2 +- modules/frontend | 2 +- scripts/svc.sh | 24 ++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 .task/feature-layered-python-env.md diff --git a/.task/feature-layered-python-env.md b/.task/feature-layered-python-env.md new file mode 100644 index 00000000..f3825807 --- /dev/null +++ b/.task/feature-layered-python-env.md @@ -0,0 +1,29 @@ +# feature/layered-python-env 任务卡 + +状态:实施已落在独立 worktree,未推送、未合入;owner:weichen + +## 基线与授权 + +- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main +- R0:64a50cf(origin/main,Merge PR #569) +- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-layered-python-env +- 分支:feature/layered-python-env(父仓与 backend、frontend、documents 子仓同名) +- 启动检查:/tmp/layered-python-env-precheck.json,退出码 2,结论 SHARED_WORKSPACE_BUSY。共享主检出有未提交 gitlink,且落后 origin/main 60 个提交。因此没有在共享检出写入,也没有运行 make task-start。 +- 授权:用户要求按已附方案实现全部分阶段,不改方案文件本身。不包含推送、合入或重启 8788。 + +## 目标 + +用不可变、按内容哈希命名的 Python 层,替换「每个工作区一个 venv」和「一个可变全局环境」。沙箱保持断网。安装只发生在宿主侧构建器。 + +## 本工作区已落地 + +- 提案:modules/documents/docs/proposals/2026-10-15-layered-python-env.md(documents 945db35),状态仍是待评审。 +- P0:解释器不再解析到被沙箱遮蔽的 linuxbrew 路径;PATH 固定;工具文案和提示词不再要求 pip install --user;svc.sh 在产物支持时调用 env ensure,并把环境根与当前基础层经环境变量交给 serve。 +- P1:execenv 环境根、托管解释器(独立 CPython,失败则一份系统 venv)、锁、层、wheelhouse、agent-system env ensure|lock|gc|doctor|rebase|python。 +- P2:schema v35 的 exec_env_requests / exec_env_bindings、python_env 工具、白名单自动批准、其余走审批卡、pip 垫片、按会话挂载。 +- P3:管理区「Python 环境」页,以及回收、重建基础层、上传 wheel 的管理接口。 +- 测试(SELF,本机):execenv、tools、store、app、server、runmgr、config、cmd/agent-system 通过。含 sandbox 参数、离线解析、真实 bwrap、两个会话各一层,以及 housestyle.build 产出的 docx 通过结构自检。权威源仍是 CI,本次未推送。 + +## 非目标 + +不重启正在运行的 8788。不修改方案文件。不把项目角色加入审批人。 diff --git a/modules/backend b/modules/backend index 24bbb7b7..b85a1e1c 160000 --- a/modules/backend +++ b/modules/backend @@ -1 +1 @@ -Subproject commit 24bbb7b777d860195ae79e51a60454b9e1ffd6ae +Subproject commit b85a1e1ca357073c8614be61b844d3558385430a diff --git a/modules/documents b/modules/documents index 5f411499..945db355 160000 --- a/modules/documents +++ b/modules/documents @@ -1 +1 @@ -Subproject commit 5f411499c51903cb62fad6f3e83ef41fe434ccab +Subproject commit 945db355fcae01873767b23a0315fb1b6f6a62a3 diff --git a/modules/frontend b/modules/frontend index 04269eed..e33d17e1 160000 --- a/modules/frontend +++ b/modules/frontend @@ -1 +1 @@ -Subproject commit 04269eed25aaeaa5560ed62c96b6e1353017995f +Subproject commit e33d17e1a66774925d774558b2f502b25a324bb3 diff --git a/scripts/svc.sh b/scripts/svc.sh index 60932c87..4383af44 100755 --- a/scripts/svc.sh +++ b/scripts/svc.sh @@ -3948,6 +3948,29 @@ agent_static_preflight() { return 0 } +# agent_exec_env_prepare:多个实例共用 runtime/envs。产物认识 env 子命令时先 ensure。 +# 下载失败只警告。current 基础层存在时,经环境变量把根和依赖层交给 serve, +# 不改写已经持久化的 exec=。 +agent_exec_env_prepare() { + local probe root id deps + probe="$("$ENV_BIN" env 2>&1 || true)" + case "$probe" in + *ensure*) ;; + *) return 0 ;; + esac + root="$RUNTIME/envs" + if ! "$ENV_BIN" env ensure --root "$root"; then + c_warn "[$ENV_NAME] Python 环境根未就绪($root)。启动继续,基础层导入不可用,直到 env ensure 成功。" + fi + [ -L "$root/current" ] || return 0 + id="$(basename "$(readlink "$root/current")")" + deps="$root/layers/$id/site-packages" + [ -d "$deps" ] || return 0 + guard_env+=("AGENT_SYSTEM_EXEC_ENV_ROOT=$root") + guard_env+=("AGENT_SYSTEM_EXEC_DEPS_DIR=$deps") + c_info "[$ENV_NAME] Python 环境:$root (基础层 $id)" +} + agent_do_start() { mkdir -p "$ENV_DATA" "$ENV_DIR" check_port_free || return 1 @@ -4043,6 +4066,7 @@ agent_do_start() { guard_env+=("AGENT_SYSTEM_INSTANCE_ID=$AGENT_SYSTEM_INSTANCE_ID") guard_env+=("AGENT_SYSTEM_DBREF=${AGENT_SYSTEM_DBREF:-sqlite}") fi + agent_exec_env_prepare # 9>&-:显式关闭锁 fd——服务进程绝不能继承 .start.lock(长驻持有会令后续 # 生命周期操作在锁上自锁死等;2026-10-11 自恢复任务实测发现)。 svc_write_serve_env From f88cc7fb37b724fc53d0fe66ec3d36cb54397478 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 15 Oct 2026 14:01:33 +0000 Subject: [PATCH 2/5] Sync layered-env gitlinks with current component mains Why: Backend, frontend, and documents each gained one commit on main after this branch was cut. The feature commits have to contain those mains so the pull requests can merge. Evidence: git merge origin/main in each submodule completed with the ort strategy and no conflicts. Impact: Gitlinks move to the merge commits. The layered environment changes themselves are unchanged. Refs: .task/feature-layered-python-env.md Co-authored-by: Cursor --- modules/backend | 2 +- modules/documents | 2 +- modules/frontend | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/backend b/modules/backend index b85a1e1c..9a54845d 160000 --- a/modules/backend +++ b/modules/backend @@ -1 +1 @@ -Subproject commit b85a1e1ca357073c8614be61b844d3558385430a +Subproject commit 9a54845d408f4a43220ca4345813a5bcc9dee5f1 diff --git a/modules/documents b/modules/documents index 945db355..73bbb4ce 160000 --- a/modules/documents +++ b/modules/documents @@ -1 +1 @@ -Subproject commit 945db355fcae01873767b23a0315fb1b6f6a62a3 +Subproject commit 73bbb4cea686eb84826d5066bb4c44bf883c9365 diff --git a/modules/frontend b/modules/frontend index e33d17e1..781cde66 160000 --- a/modules/frontend +++ b/modules/frontend @@ -1 +1 @@ -Subproject commit e33d17e1a66774925d774558b2f502b25a324bb3 +Subproject commit 781cde66675e6d9293004f19543500aa8e24bdb8 From f4cba944af6580840af93809305c6f5cbe194af8 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 15 Oct 2026 14:04:09 +0000 Subject: [PATCH 3/5] Point the backend gitlink at the storage migration fix Why: The combination build has to include the exec env tables in the SQLite-to-Postgres copy list, or backend CI and the Dev suite both reject the candidate. Evidence: Backend ab12fea follows the storage-migrate test that CI run 3343 failed. Impact: Only the backend gitlink moves. Refs: Agent-System-Backend pull 206 Co-authored-by: Cursor --- modules/backend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/backend b/modules/backend index 9a54845d..ab12fea4 160000 --- a/modules/backend +++ b/modules/backend @@ -1 +1 @@ -Subproject commit 9a54845d408f4a43220ca4345813a5bcc9dee5f1 +Subproject commit ab12fea4745cf22fb7648c1c25b18433ac8a3650 From bd18e118364c036a27c4c6e61a7e1ce0969ba6e5 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 15 Oct 2026 14:08:55 +0000 Subject: [PATCH 4/5] Allow the exec env package in the architecture baseline Why: app, server, and tools now call the layered Python environment. The dependency ratchet rejects those edges until they are recorded. Evidence: CI job 5179 failed test-boundaries on exactly these three edges. scripts/lint-architecture.sh passes locally after the update. Impact: The allowlist grows by three edges. No other package may import execenv until it is added the same way. Refs: Agent-System-Dev pull 570 Co-authored-by: Cursor --- policy/architecture-baseline.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/policy/architecture-baseline.json b/policy/architecture-baseline.json index a0c40cec..af2a0b47 100644 --- a/policy/architecture-baseline.json +++ b/policy/architecture-baseline.json @@ -4,6 +4,7 @@ "backend/app backend/cardsvc", "backend/app backend/cmdbus", "backend/app backend/config", +"backend/app backend/execenv", "backend/app backend/genui", "backend/app backend/hostapi", "backend/app backend/ingest", @@ -64,6 +65,7 @@ "backend/runtime backend/workflow", "backend/server backend/cardsvc", "backend/server backend/cmdbus", +"backend/server backend/execenv", "backend/server backend/ingest", "backend/server backend/intentgate", "backend/server backend/plugins", @@ -82,6 +84,7 @@ "backend/squadadapter backend/quality", "backend/store backend/blobstore", "backend/surfacesvc backend/store", +"backend/tools backend/execenv", "backend/tools backend/quality", "backend/wfcompile backend/tools", "backend/wfcompile backend/workflow", From 9c7fa2730e47a9d3bafee6a9b9c08765f665702e Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 15 Oct 2026 14:14:48 +0000 Subject: [PATCH 5/5] Keep service start from downloading the Python base layer Why: env ensure downloads an interpreter and wheels. The real-combination start test allows 120 seconds, and that download made rc1 start time out. Evidence: CI job 5184 timed out in test_U3_real_agent_identity_lifecycle_sqlite on scripts/svc.sh rc1 start. Impact: Start only mounts a base layer that already exists. The first build is an explicit env ensure, run outside start. Refs: Agent-System-Dev pull 570 Co-authored-by: Cursor --- scripts/svc.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/svc.sh b/scripts/svc.sh index 4383af44..4d072cef 100755 --- a/scripts/svc.sh +++ b/scripts/svc.sh @@ -3948,9 +3948,10 @@ agent_static_preflight() { return 0 } -# agent_exec_env_prepare:多个实例共用 runtime/envs。产物认识 env 子命令时先 ensure。 -# 下载失败只警告。current 基础层存在时,经环境变量把根和依赖层交给 serve, -# 不改写已经持久化的 exec=。 +# agent_exec_env_prepare:多个实例共用 runtime/envs。启动不下载解释器或 wheel, +# 避免把 start 拖进网络安装(真实组合测试的启动上限是 120 秒)。 +# current 基础层已经存在时,经环境变量把根和依赖层交给 serve,不改写 exec=。 +# 首次建立基础层用:<二进制> env ensure --root "$RUNTIME/envs" agent_exec_env_prepare() { local probe root id deps probe="$("$ENV_BIN" env 2>&1 || true)" @@ -3959,13 +3960,13 @@ agent_exec_env_prepare() { *) return 0 ;; esac root="$RUNTIME/envs" - if ! "$ENV_BIN" env ensure --root "$root"; then - c_warn "[$ENV_NAME] Python 环境根未就绪($root)。启动继续,基础层导入不可用,直到 env ensure 成功。" + if [ ! -L "$root/current" ]; then + c_warn "[$ENV_NAME] Python 基础层未建立($root)。启动继续;需要时运行:$ENV_BIN env ensure --root $root" + return 0 fi - [ -L "$root/current" ] || return 0 id="$(basename "$(readlink "$root/current")")" deps="$root/layers/$id/site-packages" - [ -d "$deps" ] || return 0 + [ -d "$deps" ] || { c_warn "[$ENV_NAME] Python 基础层 $id 缺少 site-packages"; return 0; } guard_env+=("AGENT_SYSTEM_EXEC_ENV_ROOT=$root") guard_env+=("AGENT_SYSTEM_EXEC_DEPS_DIR=$deps") c_info "[$ENV_NAME] Python 环境:$root (基础层 $id)"