# 原环境执行设计与实施计划 日期:2026-10-13。用户已明确同意开放测试入口,并采用“普通接口直接触发;启停服务/占整机的测试显示影响并逐次确认”的方式。不修改原项目的脚本、配置和素材;运行本身仍按原逻辑产生输出及副作用。本轮验证不自动执行整机压测或启停现有模型。 ## 业务与执行边界 已有项目新增 native 原环境方案:在服务器原工作目录,以已登记的解释器和固定原入口运行,复用原配置文件及现有 Docker 工具。上传脚本继续在隔离容器中运行,网页不能把任意上传代码切换为宿主执行,也不能填写任意宿主命令、账号、解释器或环境变量。 每个方案明确:原入口、目录、可选参数类型/范围、环境和凭据来源、输出位置、预计影响及是否需要确认。登记可读元数据在 catalog/native-profiles.json;秘密只在宿主执行时读取并保留内存,不能进 API 响应、命令行、数据库或日志。 Native 运行使用独立的 systemd transient service,按运行编号关联,使用原账号和目录。不套用通用容器的 1 CPU/512 MiB 限制;仅限制同一控制台单任务和总时限。默认允许最长 72 小时,超过原先两小时限制的长稳测试可按需设置。工作进程/模型的实际 CPU/GPU 仍按原项目配置。 运行前预检是只读的:检查入口摘要、所需文件/工具、参数和目标服务端口(TCP 连接,不发推理请求)。预检返回计划摘要,影响确认绑定源码、参数与方案版本,变化后须重新确认。开始运行保存计划与确认记录。 菜单型入口使用 PTY,控制台仅接受数字选项/数字列表或 y/n/q,留空发送回车。不接受 shell 命令、控制键、密码或令牌;输入不写数据库,PTY 关闭回显。需要自由文本的原工具高级维护操作继续使用原维护入口,不通过此测试控制台发送。执行器只能向已启动的本项目交互式任务传入输入。 取消只针对本次 transient service 的进程组/cgroup,先给原脚本收尾时间,再强制结束残留本机进程。原脚本通过 Docker daemon 创建的容器不属于本机 cgroup,控制台不擅自清理或宣称已恢复原模型。保存运行前后容器状态差异并提示核对。worker 重启后重新关联仍存活的 native service,不重跑命令、不重置尝试次数。 数据库沿用 schema v1,在 JSON 记录增加可选 native_options 与 execution 字段。历史记录、版本、源码文件和 ID 不改写。新原环境登记是配置更新,保留旧记录和备份;恢复旧应用前须无活动 native 任务,不能让旧执行器误处理新任务。 ## 模块职责与实施顺序 - [x] 清点并登记各入口的原参数、依赖、配置、影响及缺失项;不猜测凭据/启动命令。 - [x] 先写参数、命令注入防护、来源限制、确认失效与原文件不变等测试,再实现原环境计划生成。 - [x] 实现独立 transient service、日志脱敏、取消/超时、输入通道及 worker 重关联;用本项目短样例验证,不运行整机任务。 - [x] 实现只读方案展示、原参数表单、预检与逐次影响确认、交互输入和原环境运行信息。 - [x] 集成审查、回归及真实浏览器验证,备份后更新网页/worker,核验原文件摘要和当前模型服务。 所有新手写源码文件不超过 500 行,无 Git 暂存、提交或推送。现有仓库没有提交,继续在当前已确认工作目录增量修改,不创建包含用户未提交内容的额外 Git 历史。 ## 前后端接口契约 Script 增加 `execution`:`{mode:'native'|'container', profile_id?, interpreter?, user?, cwd?, description?, impact:{level:'standard'|'resource'|'service',title,details:[],requires_confirmation}, parameters:[{key,label,type:'integer'|'number'|'select'|'text',default,min?,max?,options?:[{value,label}],required?,help?}], interactive:boolean, max_timeout_seconds:number}`。 native 项目的 config 增加 `native_options:{key:value}`。旧 args/cwd/output_paths 为方案计算值,不允许网页自由改写;网页显示只读启动目录、环境说明与输出规则。可编辑参数和 timeout_seconds,以及现有名称/说明/启用状态。PATCH 仍是 `/api/scripts/{id}`,新字段位于 `config.native_options`。 POST `/api/scripts/{id}/preflight`,JSON `{}`,含 X-XAS-Console:1。返回 `{ready:boolean,plan_token:string,mode,command_preview:string,cwd:string,user:string,checks:[{name,ok,message}],impact:{...},interactive:boolean,output_paths:[],notes:[]}`。没有副作用,不执行原脚本。原输出中的 `{run_id}` 保持占位,队列分配编号后再解析。 POST `/api/scripts/{id}/runs` 扩展 `{request_id:UUID,plan_token?:string,impact_acknowledged?:boolean}`。native 必须先预检;有影响的方案必须显式确认,计划变更返回 409/400,重新预检。普通容器脚本原调用仍可用。 Run 增加 `execution`:`{mode,profile_id?,command_preview?,cwd?,user?,impact?,impact_acknowledged?,interactive?,unit?,verification?:...}`。默认字段缺失的历史记录按 container 展示。运行仍单并发。 POST `/api/runs/{id}/input`,JSON `{text:string}`;仅 native、interactive、running 状态接受,单次 <=1024 UTF-8 字节,禁止 NUL;末尾自动换行。返回 `{accepted:true}`。无需把输入保存到历史记录。拒绝任意路径、其他任务或已结束运行。用户应只输入原菜单需要的选项,不输入密码或令牌。 日志和结果 API 沿用现有接口。native 结果包含原命令/环境引用、源码摘要、退出状态、取消/清理说明和容器状态差异。对未完成真实 GPU/长稳业务验证的项目,页面说明“启动方案已接入,未完成本轮业务验收”。