# 103 与本地差异报告(2026-06-26) ## 目的 这份报告用于回答三个问题: 1. `103` 当前运行代码与本地代码差异到底在哪里。 2. 哪些差异可以忽略,哪些必须回收到本地。 3. 后续如何把生产发布收口到“只能本地打包发布”。 本次对比没有直接污染本地主开发目录,而是先从 `103` 拉出只读基线副本: - `/Users/john/PycharmProjects/test/_103_baselines/Memind` - `/Users/john/PycharmProjects/test/_103_baselines/memind_adm` ## 总结结论 ### Memind `test-memind` 当前代码内容与 `103` 拉下来的只读基线已经非常接近,重点业务文件基本一致。 可见差异主要是: - 生产侧多了 `.release-manifest.txt` - 本地多了一些文档、审计脚本和历史备份文件 结论: - `Memind` 不存在明显的“线上独有核心逻辑未回收”问题 - 后续只需要继续坚持发布包流程,不应再直接改 `103` ### memind_adm `test-memindadm` 与 `103` 基线仍然存在一批结构性差异,暂时不能直接把“线上就是最新”或“本地可以无脑全量覆盖”当成事实。 这些差异集中在: - 用户详情与空间额度字段 - 订阅计划同步接口 - LLM provider 加载方式 - 启动注入与路由装配 结论: - `memind_adm` 需要一次明确的差异回收 - 但回收动作应该发生在本地代码库中 - 生产只能作为对账依据,不能继续反向当开发主线 ## 本次对比方法 ### 只读基线 从 `103` 通过 SSH 22 拉取只读副本,并排除运行态内容: - `.git` - `.env` - `node_modules` - `dist` - 日志 - pid 文件 - `.mindops` 这样做的目的是: - 保留真实源码结构 - 不把线上运行态垃圾带回本地 - 不覆盖本地主开发工作区 ### 对比范围 优先比对高价值文件: - 服务启动入口 - API 路由 - 用户与计费相关页面 - 类型定义 - 发布脚本 - 部署文档 ## Memind 对账结果 ### 生产独有 - `.release-manifest.txt` 这是正常的发布产物,不需要回收到源码仓库。 ### 本地独有 - `docs/103-reconciliation-2026-06-26.md` - `scripts/audit-103-state.sh` - `scripts/g2-lb.Caddyfile.bak-20260616-204004` - `scripts/g2-lb.Caddyfile.bak-20260619-162631` - `server.mjs.bak-20260616-195243` - `.gitignore` 这些内容里: - 文档与审计脚本应保留在本地仓库 - 备份文件需要后续择机清理 ### 重点文件比对 以下关键文件对比结果为一致: - `server.mjs` - `user-auth.mjs` - `db.mjs` - `schema.sql` - `src/App.tsx` - `src/api/client.ts` - `src/components/MindSpaceView.tsx` - `package.json` - `rsync_to_server.sh` - `scripts/release-prod.sh` - `docs/release-deploy.md` 判断: - `Memind` 当前无需做额外的线上热修回收 - 可以直接进入“只允许发布包上线”的治理阶段 ## memind_adm 对账结果 ### 生产独有 - `server/llm-provider-loader.mjs` 这说明当前线上仍保留一层 provider 加载包装逻辑,而本地已改成直接走共享实现。 这不是简单的“多一个文件”,它意味着本地与线上在启动装配方式上已经分叉。 ### 本地独有 - `PRODUCTION_RELEASE_RULES.md` - `scripts/.releaseignore-prod` - `scripts/release-prod.sh` - `server/plan-sync.mjs` 这里面: - 发布规则与发布脚本属于这次治理新增,应保留 - `server/plan-sync.mjs` 是本地新增业务能力,需要确认是否就是想带到生产的新主线 ### 双方都改了的重点文件 - `.env.example` - `docs/DEPLOY.md` - `package.json` - `scripts/rsync_to_server.sh` - `server/app.mjs` - `server/bootstrap.mjs` - `server/index.mjs` - `src/admin/pages/BillingPage.tsx` - `src/admin/pages/UserDetailPage.tsx` - `src/admin/pages/UsersPage.tsx` - `src/api/client.ts` - `src/types.ts` ### 高价值差异解读 #### 1. 用户详情与空间额度 本地版本新增了: - `GET /users/:userId` - `spaceQuotaBytes` - `spaceUsedBytes` - `spaceReservedBytes` - `spaceAvailableBytes` 同时前端用户详情页和用户列表页也接入了这些字段。 这组改动和“后台可调空间、前台可购买空间”的需求方向一致,应视为本地主线能力,而不是线上应保留的旧逻辑。 #### 2. 订阅计划同步 本地版本新增了计划同步服务与同步结果结构: - `server/plan-sync.mjs` - `PlanSyncResult` - Billing 页面同步结果展示 这组改动属于本地主线增强能力,线上基线暂未完整具备。 #### 3. LLM provider 装配方式 线上基线: - `server/bootstrap.mjs` 通过 `./llm-provider-loader.mjs` 加载 本地版本: - 直接从共享实现创建 `createLlmProviderService` 这是当前最需要审慎处理的一组差异,因为它影响服务启动边界,而不是单纯 UI 逻辑。 #### 4. 启动与监听方式 本地 `server/index.mjs` 增加了: - `createPlanSyncService` - 显式绑定 `127.0.0.1` 这类差异需要和 `103` 现有反向代理、双 Goose、启动脚本一起确认,但不需要为了本地开发去复制生产双负载拓扑。 ## 风险判断 ### 可以接受的不一致 - 生产 Goose 是双实例负载,本地不是 - 生产目录里有发布清单和运行态资产,本地没有 - 本地为了开发保留文档、审计脚本和发布脚本 这些不一致属于“环境差异”,不是“源码真相冲突”。 ### 必须收口的不一致 - `memind_adm` 启动装配路径分叉 - 用户详情与空间字段相关接口分叉 - 订阅计划同步相关接口分叉 - 生产工作树仍然允许历史上留下的手改漂移存在 这些不一致会直接影响后续版本归属,必须在本地仓库中收口。 ## 推荐收口顺序 1. 以本地 `test-memindadm` 为主线,明确保留“空间额度 + 用户详情 + 订阅同步”这组新能力。 2. 单独审查 `server/llm-provider-loader.mjs` 是否仍有线上必需逻辑。 3. 如果该文件只是在做兼容装配,则把必需逻辑回收进本地主线,再删除这层分叉。 4. 基于本地仓库走 `scripts/release-prod.sh` 做第一次正式发布。 5. 发布成功后,把 `103` 只保留为运行目标与审计对象,不再作为源码修改点。 ## 最终原则 `103` 是运行事实来源,但不是源码主线。 后续必须坚持: 1. 本地仓库合并差异 2. 本地提交生成发布包 3. 生产只接收发布包 4. 不再直接 `rsync` 5. 不再在线改源码