Files
dsh-web/ACCEPTANCE.md
T

25 KiB
Raw Blame History

DESIGN.md 验收记录

2026-10-12 可信团队试运行加固(本地自动化验收)

范围:本机或仅可信账号的团队,可由管理员通过公网 HTTPS 反代访问。未修改 Nginx/Caddy,未部署面板或操作现有实例。本节仅说明当前代码的本地自动化验收,不将历史部署证据当作本次公网实测。

已修复:

  • 登录来源30次/分钟、有界1024来源桶、8个并发槽;Origin/严格JSON校验先于额度消耗;保留账号失败锁定。默认不信任XFF,仅配置的可信代理CIDR可提供来源链,非法链回退peer。非法公网URL/CIDR在创建数据目录前拒绝;URL规范化大小写与默认端口。
  • 实例文件传输改为短锁登记lease,不再持全局生命周期锁传输;同实例启停/删除/修改/升级/恢复冲突返回409。配置JSON/multipart锁外有界接收(并发4、30秒读deadline),JSON响应在解锁后发送。
  • runtime token按容器ID/StartedAt加密持久化,Host分别缓存;日志流式扫描64MiB上限、完整帧校验、逐行选最新启动token。上游401/403失效cookie,下次请求重新交换,不重放写请求。
  • 恢复快照复制失败清理本次半成品,保留有效快照;清理失败明确500及审计。目录列表10000项上限,用量和快照分批遍历。
  • 构建容量测试注入可控探测,生产2GiB阈值不变;更新模板7文档、实例范围集成脚本和一键验收入口。

实际通过:

  • bash scripts/check-trial.sh 退出0:Go全量测试、全量race、vet、build;前端32测试及生产构建;初始化3测试;集成脚本语法检查。全量race在此脚本中使用刚刚分包成功运行的Go测试缓存;API包单独完整race约54秒通过。此前一次全量并行race被工具60秒上限终止,不计通过。
  • node --test scripts/check-trial.test.mjs:11项通过(包括每阶段失败即停)。
  • TestSecurityTLSCookieJarLifecycle:真实本地TLS HTTP服务/cookiejar登录、me、refresh轮换、logout、旧会话拒绝;来源隔离、伪造头、非法配置、并发限流回归通过。不是公网证书/反代验收。
  • 慢上传/下载/配置body/错误JSON不持锁、同实例busy、失败恢复三次不耗名额回归及race通过。
  • runtime专项race覆盖9MiB raw/framed日志、逐字节分片、截断帧拒绝、面板对象重建、Host切换、启动时间变化、磁盘权限/加密/篡改、写盘失败不缓存、cookie拒绝后重交换。Docker及上游由测试HTTP服务模拟。
  • Compose用占位环境变量只读解析,公网URL及可信代理CIDR正确展开。

剩余边界与部署前检查:

  • 未重新构建/启动真实runtime镜像,未执行真实Docker生命周期、浏览器或实际公网域名验收;未调用模型、搜索或收费服务。必须在部署入口确认登录/刷新、iframe、WS/SSE和插件设置工作。
  • 必须设置实际 PANEL_PUBLIC_URL 和准确的 TRUSTED_PROXY_CIDRS;代理及后端可达范围由管理员负责。公网并不意味着支持不可信租户。
  • 旧实例首次成功连接前若启动token已轮转丢失,需维护窗口重启该实例再连接;任意上游token主动轮转不保证自动恢复。软配额、同源插件、已建立WS/SSE不即时撤销等既有边界保留。
  • 前端仍有Monaco大chunk警告。本轮未补许可证、依赖漏洞全量扫描或开源发布材料,不作开源发布就绪声明。

结论:本地代码与自动化验收通过,可进入本机/可信团队受控试运行的部署验证;不宣称实际公网部署已验收或长期生产SLA已达标。

Free Search 模板5(部署及真实iframe验收完成)

  • 最终面板已部署:6067f9e8bd12aff649c3b8cc662c37a7a14eebec2d686b84a0d965ee599a4dc5,镜像sha256:6f397fba50a9c3469c1e5ae1ed685e6a4fe90f08ed91d947f38eca9c0b3a4932;原配置/挂载保留,旧面板停止留作回滚。正常API构建记录617457ffdd4c168c58f9cb21e7a591cc成功,模板5可用。

  • 专用新实例5dfabbdde3339c8df7bb616e1c65dce9真实iframe:Installed2、Free Search0.8.5 Running、Configure打开完整设置;前缀describe/credentials-status/mutate均200。Bing地区及缓存时长修改后保存,再恢复zh-CN/5并确认;普通DSH页面重新加载200。截图output/playwright/free-search-settings.png。未执行搜索/引擎测试/在线更新/密钥配置。

  • 实际HTTP匿名401、恶意Origin403、缺失Origin403,根路径请求拒绝;跨用户/public Host由代理自动化测试覆盖,本轮未另做实际公开域名或真实跨用户浏览器验证。全量race TEST_EXIT=0(/tmp/dsh-free-search-race.log)。

  • 上游0.8.5已确认UI限制:单改Bing地区不会置dirty,保存按钮不启用;修改缓存时长后可一起保存。未擅改上游发布包,不把此缺陷视为已修复。

  • 测试实例已经正常API删除,bind数据保留。旧63b实例仍为recipe4,容器ID/StartedAt13:01:01.657475588Z/RestartCount0保持,未安装或启用free-search。

  • 固定内置dsh-free-search0.8.5及三项普通依赖原始tarball,SHA-512校验;新profile正式依赖及bundle默认启用,旧profile不注入,mobile旧路径保留。runtime镜像dsh-web:0.2.0-rc.2-5,ID sha256:aea9e1ed8614b30457c1d60274a68175e85c1716734e4bca396205bffa885eb6。

  • 断网/非root/只读rootfs启动、两个插件inventory及listBundles、settings describe200、无重复宿主peers或绝对symlink、离线恢复和禁用状态保留、recipe4 mobile-only恢复通过。证据output/recipe5-build.log及recipe5-smoke.log。未调用搜索、引擎测试、收费服务或模型。

  • 面板精确适配8个settings路径,先登录/实例归属/Origin检查再转换loopback Host及Origin,并重新交换Host绑定cookie;客户端fetch仅重写同源精确路径。真实HTTP upstream测试涵盖公开Host、body/query、普通资源、匿名/跨用户/恶意或缺失Origin拒绝,Node测试覆盖Request/URL/string及流语义。Go全量/vet、初始化3测试和聚焦代理race通过。

  • 上游会接管等于deepseek-official的搜索及默认http抓取(包含显式同名值);其他自定义provider保留。默认Bing但自动回退可能使用已有收费API凭据,不承诺零费用。

  • 早期部署曾被权限规则拒绝,后续用户授权继续,主会话接手完成上述部署和验收;实际公网域名未单独验收。

管理员重设与用户自助修改密码验收

  • 已部署 dsh-mgr:password-complete(sha256:83189ad42e35b5a7db3ba74e27f62adcd35f4c45635be35d4f5e568b37c54c75)至127.0.0.1:40411。面板Config除Image外、HostConfig及Mounts一致,旧面板停止保留供回滚;DSH runtime ID/启动时间/重启计数未变。
  • 管理员入口:设置→用户与审计→用户列表→重设密码。普通用户及管理员自助入口:设置→账号→修改密码,必须验证当前密码。
  • 专用成员pwdqa_1791643434738真实Playwright CLI验收:管理员重设、确认不一致错误、新密码登录;成员错误当前密码保留登录、确认不一致错误、成功修改返回登录页及新密码登录均通过。没有修改既有用户密码。
  • 两次改密后旧密码及旧access/session请求401,携带原CSRF的旧refresh请求403(session已删除),新session刷新200。审计显示user.reset_password和user.change_password,不含密码。
  • Go全量race通过(/tmp/dsh-password-race-final.log,TEST_EXIT=0),vet、前端21测试及生产构建通过;既有Monaco大chunk警告仍在。
  • 证据:output/playwright/password-member-empty-form.png、password-admin-reset-empty-form.png;/tmp/dsh-password-browser-evidence.txt。测试会话已退出;因无删除用户API,专用成员保留,随机测试密码未持久化。
  • 限制:已建立的WS/SSE不会被主动即时断开,后续请求及重连拒绝旧会话。保留的旧面板是部署回滚副本,不是数据库时间点备份。

模板4:修复插件列表不可见(取代模板3管理可用性结论)

  • 根因:仅host依赖和bundle可使插件运行,但DSH管理UI按profile dependencies判断installed,模板3未登记而被过滤。模板4固定tarball正式依赖,补缺失workspace的no-auto-peers配置,保留已有manifest/bundle禁用状态。
  • runtime dsh-web:0.2.0-rc.2-4:sha256:d967800c73888cefba67b8ea14b923c14032f96058311630a37210219877fcdd。面板已部署模板4并经正常API登记镜像。
  • 当前实例63b337c848bf23156270068ff9e5cf38已备份、升级并补mobile依赖,容器2e2d6c75946a65eb7b39a11d72e2e3d23394c3d92d6508cfe25a8fa827a450fb,配置/数据保留。备份73e27b58f421868de00b07958f88113d及此前备份保留。
  • 实际面板iframe触屏浏览器:Plugins新增Installed1,dsh-web-mobile v3.0.5,详情组件Running;真实开关关闭显示Off、再次开启恢复运行,最终保持启用。截图output/playwright/plugin-touch/recipe4-installed-detail.png。UI显示Uninstall但未执行卸载;无独立参数配置表单。
  • 初始化3测试、Go全量/race/vet通过。断网非root只读冒烟验证正式inventory、上游listBundles、无重复peers/绝对symlink,以及仅manifest/patch/lockfile恢复后离线安装并保留disabled状态。当前实例未另做disabled后容器重启测试。
  • 迁移曾因旧package.json.lock及.plugin-manager/run.json阻塞并回滚;锁PID16与新容器安装进程PID16相同。确认实例完全停止后将两份记录改名保留,停机直接升级成功。未删除配置数据;该上游纯PID锁风险未通过自动删锁规避,后续遇到需停所有profile写入者再人工核验恢复。

默认内置 dsh-web-mobile 增量验收

  • 模板修订3固定内置 [email protected],校验发布包SHA-512与宿主peer版本,不执行插件生命周期脚本。当前限定DSH rc.1/rc.2;真实镜像测试使用rc.2。
  • 新建空web profile默认加入mobile bundle;已有manifest或其他profile文件不覆盖、不强制启用。初始化拒绝符号链接目录,幂等/已有配置保留及符号链接测试均通过。
  • 发布包原始权限导致非root加载失败,已通过镜像内 chmod -R a+rX 修复。修复后 node scripts/test-mobile-image.mjs 通过:断网、非root、只读rootfs启动,manifest与实际dump-config均含mobile插件。专用冒烟容器及其tmpfs测试数据已删除。
  • 验收面板 127.0.0.1:40411 已更新至 dsh-mgr:plugin3-active(sha256:06bca1aae39accbac0721af723082e8a35a0c9cb2129e4cb942015b48fbffd85),HTTP 200。正常构建API成功登记rc.2模板3,镜像API状态available。旧面板停止保留供回滚,现有模板2实例未重启或自动加入插件。
  • 本轮通过:初始化2测试、Go全量测试/race/vet、前端19测试及生产构建(仅既有Monaco大chunk警告)。
  • 后续浏览器验收发现单纯放入node_modules仍会导入失败:DSH运行时只解析安装依赖图。已将内置包加入宿主package.json dependencies,且冒烟增加stdout/stderr激活失败检查(不输出token)。最终runtime ID:sha256:30ca773ce5d70a3a540a8f4aae149c83733102f8dfcd6a77ef9794bd992bde8e。此前只检查dump-config的成功结果不等于运行时激活成功,以下复验取代它。
  • Playwright CLI独立loopback runtime触屏复验:coarse pointer=true、maxTouchPoints=1;含dsh-web-mobile/client.js的实际模块请求200;四个data-mobile-nav标记生效。首页及tap展开目录后viewport/client/scroll/body宽度均390。截图:output/playwright/plugin-touch/rc2-3-fixed-default-390.png、rc2-3-fixed-drawer-390.png。临时runtime已删除。
  • 边界:本次插件复验未覆盖面板iframe、实体手机或模型交互;额外目录关闭tap超时,未计通过。前轮专用临时runtime token曾在工具输出回显,已删除该容器使服务不可访问,未涉及旧实例凭据。插件还包含响应压缩、会话删除入口和推理档位补全,不是纯CSS;未执行模型调用。

2026-10-10 移动端内嵌工作台增量验收

用户追加需求:登录默认 iframe 内嵌 DSH,设置切换容器,移动端底部导航。已实现并部署至原验收地址,镜像 dsh-mgr:mobile-renew(sha256:392c8bb64c822572005625df5d662774e1f780a1c83121caa249fafe6a16d01f)。

  • 真实浏览器390×844及320×640:外层scrollWidth等于viewport宽度;iframe底边分别780/576,与底栏顶边一致,无底栏遮挡。桌面1440×900保留侧栏。
  • 设置切换第二个真实容器、整页刷新后选择保留;停止所选实例显示启动提示而非自动切换;删除测试实例后回到可用实例。测试实例已删除,bind数据保留。
  • 设置往返iframe DOM标记保留,未重载;退出登录iframe卸载;重新登录默认iframe已验证。
  • 清除dsh_access模拟过期,真实iframe续期refresh200并回到原DSH地址,无加载错误。修复iframe导航续期及SPA X-Frame-Options冲突;使用SAMEORIGIN与frame-ancestors self保留跨源嵌入限制。
  • Go全量测试、race及vet通过;前端19测试/生产构建通过。截图:output/playwright/design-final/mobile-settings.png及page-2026-10-10T09-29-51-590Z.png、page-2026-10-10T09-34-19-112Z.png。
  • 验证为Chrome小屏视口,不代表iOS/Android真机软键盘兼容已全测。同源iframe不是安全沙箱;保留受信任团队部署边界。

以 DESIGN.md 为目标,不通过修改设计降低标准。以下最新结论覆盖后文早期进度记录。

2026-10-10 最终验收结案

结论:按用户确认的默认路径代理、软配额及功能等价替代范围,验收通过并结案。 用户在最终结构化确认中明确选择“接受功能等价替代”:标准库 Docker HTTP 客户端替代 SDK、每实例独立 bridge 替代共享 bridge、服务端保管 DSH cookie 替代下发浏览器、React+CSS 替代 shadcn(保留 Monaco)、部分模块集中于 internal/api。上述选型不再是待确认项;并未修改 DESIGN.md 来降低要求。

结案时再次确认 /healthz 返回 ok,dsh-design-check 正在运行 dsh-mgr:design-final,用户1000:1000、只读根文件系统、内存限制1073741824字节。此次结案仅更新验收文档,没有新增代码变更;沿用下列已完成测试证据。

默认路径代理、软配额方案的 M1–M7 功能已实现,真实主要流程通过;故障边界结合自动化注入测试验收,不声称所有故障均在宿主实际制造。可选 XFS/ZFS、socket-proxy、公网 TLS 未实测。

范围 最新证据
M1 镜像 rc.1/rc.2 recipe2实际构建,rc.2 smoke通过,精确版本/非root/只读/pnpm10.11.0
M2 生命周期 最终面板完整API通过;test-intent-live.mjs验证预约自动创建、两个真实运行实例、第三创建与预约409、删除释放
M3 代理 新浏览器DSH/空白会话/插件资源/SSE200;最终WS 1连接、5发送、5接收;面板替换自动重新接入网络;独立DSH页超过5分钟refresh200且PTY可操作
M4 工作区 33项真实HTTP+43项多用户断言;ZIP/Range/穿越;PTY读取上传文件;直接调用镜像内DSH read/write实现在/workspace往返(无模型调用);扩展名白名单.txt成功/.exe415
M5 配置备份 Monaco键盘编辑、保存启动、bundle/脱敏dump-config;浏览器备份创建/下载/错误密码拒绝/正确密码导入恢复
M6 升级回滚 rc.1→rc.2;manifest加入[email protected]验证依赖安装/恢复/迁移;不可达依赖触发失败,原ID/版本/停止状态恢复,数据marker保留。fixture验证安装机制,不代表任意第三方插件兼容
M7 管理安全 JWT/refresh/隔离/配额/审计;最终面板1000:1000、只读、1GiB、socket组989;管理员显式回收停止孤儿容器通过且bind目录保留

故障注入回归覆盖:构建去重/限频、磁盘不足/未知磁盘、npm精确版本、镜像缺失、重启恢复、失败释放预约、镜像引用保护、备份资源与旧包、路径/符号链接/配额并发和回滚。见internal/api/_test.go及internal/backup/_test.go;没有填满宿主磁盘或删除共享镜像。

真实验收发现并修复:dump-config顶层YAML列表误拒绝;代理日志旧token污染启动token提取。新增测试并容器复验通过。

最终镜像:

  • panel dsh-mgr:design-final:sha256:d2da2f35e00e15fc0da7afc5183c49e40be6215bd4c5d89145e48f1034617cc5
  • rc.2 recipe2:sha256:7bd09f12b4b60fa9d13358e99bae14caafc79d3a0936e70cf590fdd1af64998e
  • rc.1 recipe2:sha256:1bb553deb3cef25c4529f93526d8cd3282d218df22787be2dc5d5762defaf0c4

通过命令:go test ./... -timeout 45s;go test -race ./... -timeout 90s;go vet ./...;npm --prefix web test(12项);npm --prefix web run build。前端有Monaco大chunk警告。

证据:output/playwright/design-final/;/tmp/dsh-design-check.8ekWaC/{api-check-results.txt,isolation-results.json};/tmp/dsh-design-plugin-rollback-verified.log;/tmp/dsh-design-cross-version.log。保留专用面板及一个浏览器实例;临时实例删除但数据保留,未推送镜像、未调用付费模型。

用户确认的孤儿策略:管理员二次确认回收身份/挂载核验通过、无实例/升级引用的停止容器;不自动纳管,不触碰运行中或来源不明容器,不删数据/网络。其他架构替代见下表;不声称逐字遵循SDK、组件库或目录示意。

早期进度记录(以下由上方最新结论覆盖)

当前实现与待验收

设计章节 代码已接入 尚需真实证据
§1–6 sibling路径映射、每用户两实例、持久预约/取消/失败恢复、生命周期与身份对账 模板2非root全流程、刷新/重启预约恢复、并发名额
§5 精确npm版本、模板/平台身份、构建去重/限频/磁盘预检、镜像usage/missing及管理员清理 真实构建与删除、外部删镜像、空间/网络故障及重启对账
§7–8 路径反代、归属鉴权、服务端token/cookie桥接、WS/SSE 新部署的新浏览器完整流程、重启重新认证、长时续期
§9 文件管理、目录ZIP、写前配额检查/串行化、周期巡检、管理员额度更新 新UI文件流程、agent实际读写、面板各写入路径配额覆盖
§10 密码加密tar.gz v2、配置/资源目录/manifest、外部包导入、旧key包兼容、停启/健康检查/回滚 真实资源往返、原密码/错误密码、无key新包、旧key包、插件恢复失败回滚
§11 本地Monaco、YAML校验、bundle与脱敏dump-config预览、保存后启动验证 新浏览器编辑/预览/错误路径;当前仍需先停止再保存
§12 预升级密码备份、home快照、成功删旧、失败回滚及恢复原运行状态 不同DSH版本、真实插件重建/离线失败、故障矩阵与数据保留
§13–16 短JWT/refresh轮换/失败锁定、审计、资源限制、非root部署配置 模板2非root数据写入和socket访问、新浏览器及DSH独立页长JWT续期
§17–19 默认路径反代与软配额;已有回归测试及旧版集成记录 必需流程未关闭,不标记M1–M7整体完成;硬quota为可选增强

备份包含六个固定配置文件及skins、pets、agent-presets、.agent-presets资源树和manifest,不包含node_modules、会话或工作区。新密码包不依赖backup.key;保留旧密钥包时仍须保管原key。备份/恢复/升级不再统一要求用户手动停机;操作中断或回滚失败不保证自动灾难恢复。

合理替代方案(不改变验收目标)

DESIGN选型 当前实现 等价目标与边界
官方Docker SDK stdlib net/http Docker Engine client,API v1.47 仍须验证编排、构建流、错误处理和daemon兼容性,不能以未用SDK认定功能缺失
共享bridge 每实例独立bridge,面板接入 减少实例直接互通;不等于完整出站或宿主网络隔离
DSH cookie改写后下发浏览器 服务端交换/缓存cookie,反代注入并移除上游Set-Cookie 保留面板登录与实例归属鉴权;WS/SSE、重启失效与续期仍需实测
shadcn/ui 普通React组件及CSS,保留本地Monaco 不要求替换组件库,但交互、错误反馈和可用性仍须浏览器验收

代码主要按internal/api、internal/docker、internal/backup、internal/store组织,与设计目录示意不同;不宣称逐字一致。默认软配额符合§9/§18路线,XFS/ZFS硬quota依赖运维选择,不列为默认必过项。npm 0.2.0-rc.2不支持--public-url,当前使用路径代理而不传该参数。

历史证据与本轮边界

本轮已取得真实证据:

  • 非root面板 dsh-design-check(1000:1000、只读rootfs、socket附加组989)已启动;33项HTTP认证/刷新/配额/ZIP/Range检查通过,报告 /tmp/dsh-design-check.8ekWaC/api-check-results.txt。

  • 两普通用户隔离与预约43项断言通过,包括越权拒绝、两名额及取消释放;报告同目录 isolation-results.json。未把预约名额测试算作真实runtime并发测试。

  • 浏览器基础UI登录、配额、ZIP、镜像状态、版本确认与预约页面通过,证据 output/playwright/design-final/。实例相关Monaco/备份/长JWT待runtime模板2就绪。

  • 模板2实际构建进行中,详细安装日志持续有进度;尚无runtime2启动通过结论。

  • 既有记录包含旧版真实Docker文件/实例/备份恢复及同镜像替换流程;同镜像替换不能证明跨DSH版本迁移。

  • 旧浏览器证据目录output/playwright/browsercheck18091/记录插件加载、空白会话及WS/SSE,不代表模型生成、PTY或真实插件安装通过,也不能替代模板2和新增UI。

  • 上轮记录的go test -race ./... -timeout 90s、go vet ./...、前端12项测试及前后端构建通过,仅为当时检查结果;冻结后须重跑,不能据此宣称全完成。

  • 仍需关闭:模板2非root真实部署、新浏览器新增功能、插件跨版本/离线失败、长时JWT续期。主代理进行中,结论与证据待回填;本文件不将此前权限拒绝误写为当前持续阻塞。

  • 真实测试仅限已授权的本项目测试资源;工具再次拒绝时不绕过。不得隐式使用实际模型密钥或付费调用,不自动删除未知孤儿容器。

默认工作区 /workspace(模板 6,已由下述模板 7 数据根方案取代)

  • 当前用户实例已通过 DSH 界面添加并选择 /workspace,刷新后仍保留;原 normal 工作区和历史会话未移动。
  • 空实例初始化通过 DSH workspaceRegistry 注册准确的 /workspace,重复启动复用默认 ID;有历史工作区或会话时不强制迁移。
  • 真实断网非 root 容器首次初始化、插件加载、备份恢复及旧模板兼容验证通过,详见 /tmp/dsh-recipe6-test.log。
  • 面板已部署 dsh-mgr:workspace6;正常构建 API 记录 e9a368bbb66e51e6c8f2439a8e94698a 成功,recipe_rev=6,镜像 sha256:38e04308da602da22e8df49d54166da1835922d50a3fa485711b7c5f6479d287。
  • 面板部署保留配置和挂载,旧面板停止留作回滚;现有 DSH 实例未重启,构建前后实例记录一致。

模板 7:完整 DSH_HOME 改为 /workspace

管理交互优化验收

  • 配额静态展示与模态编辑、常用预设、未改变禁提交;密码明确按钮、原生模态、显示隐藏、即时UTF-8校验、取消清空及焦点恢复。账号创建规则对齐,移动用户卡片和退出分区。

  • 前端26测试、生产构建通过。Playwright真实测试账号 uxqa_1791711946466:配额10→20→10 GiB;管理员重设→登录→自助修改→退出→新密码登录均通过;取消清空、焦点恢复、确认不一致禁提交、320/390px对话框不越界通过。

  • 测试账号最终重新随机化密码、撤销会话,账号保留;未修改真实账号配额或密码。

  • 正式面板 dsh-mgr:ux-polish 已部署,挂载集合核验相同(Docker返回顺序不同),DSH容器953ed34d034f未重启。正式入口重新加载后配额/密码对话框检查通过。

  • 截图:output/playwright/ux-before-settings.png、ux-before-admin.png、ux-deployed-settings.png、ux-deployed-quota.png、ux-mobile-quota.png、ux-mobile-password-320.png。浏览器密码管理器用户名提示尚存;不声称全面无bug或完整无障碍合规。

  • 依用户澄清,实例 home 直接挂载 /workspace,四个 HOME 环境变量同步;/data/dsh-home 为兼容软链接。旧共享目录保留为 /shared,不合并、不覆盖历史文件。

  • 面板文件接口以 instance 参数校验归属、跟随所选实例;旧共享文件保留显式入口。账号总配额不变,恢复期间禁止写入,实例文件请求与升级互斥。

  • 当前实例 63b337c848bf23156270068ff9e5cf38 正常升级成功,容器 953ed34d034faed9e0f8c7373964dd0156450b1d65c2965c73a539a83a226934,运行镜像 sha256:bd541770aaaf5a846ecb898ec80863c8a356524eb7f4b8053b0eb646d6e10fad。

  • 构建 6c3589998c431acc809b5307c30e8e1e 成功,真实离线 smoke 验证环境变量、旧路径链接及同文件读写。升级中修复宿主路径转换和 pnpm 非交互日志边界;早期失败自动回滚,快照和备份保留。

  • 最终验证:DSH 代理 GET 200;实例文件 API 可见 profiles/storages,storages/normal 可见四项历史报告/笔记;旧共享接口可访问。未调用模型或搜索。

  • 前端 23 测试/build 通过,后端全量及 vet 曾通过,race 通过。最终定向 Workspace/Upgrade/Orphan 测试通过;最后一次全量受 Docker 磁盘不足 2 GiB 策略影响,3 个构建测试失败,不记为全绿。浏览器交互验证被权限拒绝,未绕过;HTTP 验证不替代浏览器验收。