292 lines
21 KiB
Markdown
292 lines
21 KiB
Markdown
# 项目文件治理计划
|
||
|
||
## 当前会话任务:多 AgentBus 用户渠道与插件串行队列
|
||
|
||
- **状态:** 实施中;用户已确认整体方案。
|
||
- **用户目标:** 支持多个 AgentBus 来源/用户渠道,每个渠道可独立配置 AgentBus key,并保证插件同一时间只执行一个任务。
|
||
- **当前安全边界:** 仅做源码、契约和数据库设计梳理;未创建迁移、未改运行配置、未部署、未向 AgentBus 或 ERP 发送数据。
|
||
|
||
### 本轮阶段
|
||
|
||
- [x] 1. 读取项目记忆、检查工作区状态并按业务登记表定位通用业务契约
|
||
- [x] 2. 核对 AgentBus 认证/来源、用户模型、任务状态和插件执行链
|
||
- [x] 3. 确认渠道身份与插件队列的产品边界
|
||
- [ ] 4. 设计并实现渠道密钥、入站归属和可恢复的单插件执行槽
|
||
- [ ] 5. 同步操作台/API/文档/测试/发布边界并完成全量验证
|
||
|
||
### 当前待确认决策
|
||
|
||
| 决策 | 推荐 | 主权衡 |
|
||
|---|---|---|
|
||
| 插件串行范围 | **已确认:**同一组织/同一 ERP 浏览器会话全局一次只允许一个任务;其他用户任务保留在服务端队列,按创建时间依次领取 | 吞吐较低但不会跨用户并发写同一 ERP 会话;按用户并行会提高吞吐却无法保证当前单插件约束 |
|
||
| AgentBus key 的连接边界 | **已确认:**每个外部用户渠道对应独立 AgentBus listener/连接,独立保存 key | 多连接与重连管理更复杂,但 key 和用户边界清晰 |
|
||
| 渠道用户身份 | **已确认:**独立外部渠道身份,不创建后台登录账号;管理员统一管理 | 暂不提供渠道用户独立登录和权限视图,避免扩大现有管理员鉴权模型 |
|
||
| 最终回执可靠性 | **已确认:**入站路由和最终回执状态持久化,队列等待和进程重启不丢回执 | 增加 outbox/投递状态和重连补发逻辑,但避免用户收到假超时或因进程重启丢回执 |
|
||
|
||
### 已收敛的实施方案
|
||
|
||
1. 新增 `user_channels`(外部渠道身份、显示名、独立加密 AgentBus key、连接配置、启用/连接状态);管理员通过后台 API/页面创建、启用、禁用和轮换 key,列表不回显完整 key。
|
||
2. 控制面启动时为每个启用渠道建立独立 AgentBus listener;任务写入 `channel_id`,幂等键和会话路由按渠道隔离;Agent/Skill operation Schema 不变。
|
||
3. 新增持久化 AgentBus 入站/回执 outbox,保存 `channel_id + inbound_frame_id` 的幂等路由;先发一次受理通知,任务进入终态后发最终回执,断线/重启/排队超时后由对应渠道重连补发。
|
||
4. 插件执行 claim 在组织级事务锁下按创建时间 FIFO;存在 `queued/accepted/running` 或结果不确定的 ERP attempt 时不再创建第二个 execution,只返回排队信息。解析仍可并行,ERP 插件执行保持单槽。
|
||
5. 操作台与扩展增加排队状态/单任务防护;补充迁移、渠道 CRUD、listener、多渠道幂等/回执、FIFO claim、并发 claim 和不确定结果阻断测试,并执行项目规定的完整验证命令。
|
||
|
||
### 默认假设与排除
|
||
|
||
- 现有组织级自动化开关继续对所有 AgentBus 渠道生效,不新增渠道级自动化策略。
|
||
- WebSocket URL、client type、重连/超时等通用参数继续使用服务端环境配置;渠道独立保存 key,并允许独立 bot address 覆盖,未提供时沿用兼容默认值。
|
||
- 禁用渠道停止接收新入站帧,但已进入任务队列或待发送 outbox 的回执保留;重新启用后继续处理。删除采用禁用/归档语义,不做物理删除。
|
||
- 不实现微信等具体渠道协议,不进入 ERP,不部署、不重启生产服务,也不读取或写出任何真实 key。
|
||
|
||
### 实施记录
|
||
|
||
- [x] 用户确认开始实施
|
||
- [ ] 数据库迁移与渠道/回执服务
|
||
- [ ] 多 listener 与 durable outbox
|
||
- [ ] FIFO 插件 claim 与前端/扩展单任务防护
|
||
- [ ] 测试、文档、发布边界与完整验证
|
||
|
||
|
||
## 当前会话任务:AgentBus onboarding 更新后重新对接
|
||
|
||
- **状态:** 已完成;运行进程已按当前受保护配置重新建立 AgentBus session 并通过健康检查。
|
||
- **用户请求:** 按 `/Users/inmanx/Downloads/agentbus-bot-onboarding-bot-2076193998368161793-listener.md` 重新对接 AgentBus listener。
|
||
- **安全边界:** 仅使用文档中的连接参数;token 不写入仓库、不输出、不进入日志;不执行外部业务发送或 ERP 写入。
|
||
|
||
### 本轮阶段
|
||
|
||
- [x] 1. 读取项目记忆、检查工作区状态并审阅 onboarding 连接事实
|
||
- [x] 2. 核对当前 AgentBus listener 的握手实现与运行状态
|
||
- [x] 3. 让运行进程使用 onboarding 参数重新建立 session 并验证 ready
|
||
- [x] 4. 更新本轮发现、进度并报告可验证结果
|
||
|
||
### 本轮结论
|
||
|
||
- onboarding 中的 token 与当前受保护运行配置一致,未修改 `.env`、源码或发布物。
|
||
- listener 已重新启动并收到 `session.ready`;当前 `/health/ready` 显示 `connected=true`、`session_ready=true`,地址为 `bot:2076193998368161793:listener`。
|
||
- 已通过 onboarding 的 Invoke API 发送一条明确标记为“仅测试、不执行 ERP”的探测消息;接口返回 `202 accepted`,listener 收到并受理,随后发出受理进度和最终 `task.result`。
|
||
- 探测文本不是有效业务指令,解析服务最终返回非标准 JSON,控制面按失败契约回传错误摘要;这证明 AgentBus 收发链路正常,但不代表业务解析服务可处理任意测试文本。
|
||
- 当前进程日志中未发现新的 `channel:wechat` 入站帧;之前用户消息未进入当前 listener 的证据仍在上游渠道投递侧,而非 AgentBus WebSocket 握手。
|
||
- 用户再次发送后连续观察 20 秒,当前健康 listener 仍未收到新的微信渠道帧;当前 `/health/ready` 保持 connected/session_ready,进程未发生自动重启。
|
||
- 本轮未写入 ERP、未改变业务任务数据;探测只产生了一条非业务测试任务。
|
||
|
||
### 文件探测结论
|
||
|
||
- 已通过 Invoke API 发送 59 字节的临时 `agentbus-file-test.txt`,接口返回 `202 accepted`。
|
||
- listener 实际收到的入站 payload 包含 `attachments`;但当前 `processInboundTask` 只将 `payload.text` 交给任务服务,未把入站附件持久化或带入最终回执。
|
||
- 因此本轮验证了 AgentBus 可以承载附件字段,但尚未验证真正的渠道文件回传;当前项目的出站附件仍只来自 `confirmation_export` 执行结果中的受控附件元数据。
|
||
|
||
### 发信探测结论
|
||
|
||
- 已通过 Invoke API 发送纯文本探测;接口返回 `202 accepted`,listener 收到并受理,随后发出受理进度和最终失败回执,最终结果也收到 AgentBus `accepted`。
|
||
- 失败仅因为探测文本不是可执行业务指令,未进入 ERP;AgentBus 发信、收信和回件链路正常。
|
||
|
||
## 当前会话任务:生产 PostgreSQL / OSS 对接
|
||
|
||
- **状态:** 已完成本轮对接与验证;未执行服务部署、重启或真实 ERP 写入。
|
||
- **用户确认:** 使用干净生产 Schema,不迁移/删除旧测试数据;OSS 公共可读、仅后端可写/删;直接返回公共 URL;暂不启用自动清理。
|
||
- **远程落点:** PostgreSQL `lwlt_agent` 数据库内新建 `liansyn_prod` Schema;旧 `public` Schema 保持不变。
|
||
- **已完成:** OSS V4 provider、随机执行 UUID 对象路径、任务附件元数据、事务失败回滚清理、生产环境模板和 retention 开关。
|
||
- **已完成:** 完整仓库门槛、部署前检查、本轮证据与活动文档收口。
|
||
|
||
### 本轮阶段
|
||
|
||
- [x] 1. 探测 PostgreSQL / OSS 实际权限和 Bucket 状态
|
||
- [x] 2. 接入 OSS provider、独立数据库 Schema 和生产配置
|
||
- [x] 3. 执行远程 Schema 迁移并验证上传/公共读取/删除
|
||
- [x] 4. 完成本地测试、构建、仓库卫生和发布边界收口
|
||
|
||
## 当前会话任务:AgentBus 用户回复契约重构
|
||
|
||
- **状态:** 已完成;已确认用户端只保留受理通知和最终返回通知。
|
||
- **用户确认:** 失败时优先返回 ERP 业务反馈,没有 ERP 反馈才返回简短错误摘要;成功时按业务 action 与客户模板返回业务回执;解析完成/进入自动化 ERP 执行不对用户发送。
|
||
- **本轮重点:** 按现有五类业务能力更新成功回执契约,正式接入酒店安排中英文客户模板,并保持 AgentBus 不泄露技术细节。
|
||
|
||
### 本轮阶段
|
||
|
||
- [x] 1. 核对业务注册表、Schema、mapping 与当前 AgentBus/平台实现
|
||
- [x] 2. 形成各业务成功/失败/文件回执矩阵与酒店模板契约
|
||
- [x] 3. 实现控制面、平台/插件消息路由及回归夹具
|
||
- [x] 4. 完成仓库门槛、类型检查、控制面/遗留测试与构建验证
|
||
|
||
### 本轮决策
|
||
|
||
| 决策 | 结论 |
|
||
|---|---|
|
||
| 用户侧消息层级 | 仅发送受理通知和最终返回通知;解析完成、进入自动化执行为内部状态 |
|
||
| 失败回执 | 有明确 ERP 业务反馈时返回 ERP 反馈;否则返回简短错误摘要 |
|
||
| 成功回执 | 按 action 定义业务字段,按客户模板决定文本格式;不把通用技术消息直接作为用户回执 |
|
||
| 酒店安排成功格式 | 支持客户给定的英文/中文双格式,包含团号、入住/退房、晚数、房型/房数 |
|
||
|
||
### 本轮收敛
|
||
|
||
- `arrangement_hotel` 新增成功且字段完整时使用客户双语模板;酒店变更/清除无法套模板时返回酒店业务字段,不输出空占位符。
|
||
- 酒店双语模板的两段日期都使用同一份实际执行日期;客户名称仅在执行上下文提供时追加,不硬编码示例中的客户名。
|
||
- 文件回执只向 AgentBus 暴露文件名、类型、大小和受控下载地址;外部渠道的二进制直传仍需独立的渠道适配与鉴权转发。
|
||
- 真实 ERP 写入、部署、重启和外部发送未执行。
|
||
|
||
### 最终验证
|
||
|
||
- `node --run check:repo`:9/9。
|
||
- `node --run check`:通过。
|
||
- `node --run test:control-plane`:46/46。
|
||
- `node --run test:legacy`:201/201。
|
||
- `node --run build`:通过。
|
||
- `node --run test`:通过;`git diff --check`:通过。
|
||
|
||
### 本轮错误记录
|
||
|
||
| 错误 | 次数 | 处理 |
|
||
|---|---:|---|
|
||
| 当前 shell 没有 `npm` 命令,首次 `npm run check` 未执行 | 1 | 改用 workspace bundled Node/npm 路径后重跑;未修改源码 |
|
||
| 旧控制面/AgentBus 测试仍断言解析进度和旧成功文本 | 1 | 已确认是本轮契约预期差异,更新断言并补充酒店/业务回执测试 |
|
||
| 新增测试直接访问宽类型 `task.success_receipt` 导致 TypeScript 类型错误 | 1 | 在测试中增加最小结构断言类型;源码未回退 |
|
||
|
||
## 当前会话任务:后台附件详情视觉收口
|
||
|
||
- **状态:** 已完成源码调整、静态契约检查、控制面/遗留回归和构建验证。
|
||
- **用户确认:** 后台附件区域移除简要操作信息;有文件时只保留文件名和下载按钮,其他业务审核信息保持不变。
|
||
- **执行结果:** `confirmation_export` 不再渲染 action、目标日期、业务选择和操作明细;附件卡片隐藏文件类型/大小,仅保留文件名与鉴权下载按钮;详情面板之间不再显示无意义的横向分割线。
|
||
- **验证结果:** `check:repo` 9/9、`check`、控制面 41/41、legacy 201/201、`build` 和 `git diff --check` 通过。
|
||
|
||
## 已完成基线:团队文件后台附件交付
|
||
|
||
- **状态:** 已完成实现、控制面/遗留契约回归、DOCX 同步、版本化制品和仓库门槛;真实部署与 OSS 接入仍待单独授权。
|
||
- **用户确认:** 导出团队文件的原始字节要保存到平台后台,页面提供鉴权下载;真实上线后附件存 OSS,当前先用加密数据库存储并保留对象存储替换接口。
|
||
- **目标:** 修复“ERP 文件 HTTP 200 但后台没有文件”的假完成路径,使导出只有在附件落库成功后才可标记完成。
|
||
- **根因:** 旧 `exportConfirmationSources` 只返回来源元数据并固定 `downloaded=false`,控制面没有附件表、保存事务或下载路由。
|
||
- **执行结果:** 插件携带 base64 原始字节与 SHA-256;控制面校验大小/哈希、加密写入 `task_artifacts`、返回鉴权下载地址;保存失败显式阻断,禁止把来源读取当作交付完成。
|
||
- **验证边界:** 已完成只读源码、契约、迁移、包/源码一致性和全页 DOCX QA;未执行真实 ERP 写入、服务部署、重启或 OSS 外部写入。
|
||
|
||
## 目标
|
||
|
||
建立并落实全仓库文件治理:每类内容只有固定位置和单一权威源,保留 Planning with Files 三个项目记忆文件,分离当前源码、生成物、运行输出、验证证据与历史归档,并通过自动检查阻止后续会话再次散落或复制文件。
|
||
|
||
## 当前阶段
|
||
|
||
阶段 10:后台附件详情视觉收口
|
||
|
||
## 阶段
|
||
|
||
### 阶段 1:全仓库发现与分类
|
||
|
||
- [x] 确认用户目标和治理边界
|
||
- [x] 确认 `task_plan.md`、`findings.md`、`progress.md` 是正式项目记忆
|
||
- [x] 审计全部活动目录、根文件、引用、构建消费者及版本管理状态
|
||
- [x] 识别当前源码、生成物、运行输出、历史资料、敏感配置与无效残留
|
||
- **状态:** 已完成
|
||
|
||
### 阶段 2:制定唯一目录规范
|
||
|
||
- [x] 定义根目录允许项和各目录职责
|
||
- [x] 定义 Planning with Files 文件压缩与历史轮转规则
|
||
- [x] 定义 `dist/`、`archive/`、`reports/`、`quarantine/` 的边界
|
||
- [x] 将规则固化到项目级 `AGENTS.md` 与当前入口文档
|
||
- **状态:** 已完成
|
||
|
||
### 阶段 3:安全迁移与压缩
|
||
|
||
- [x] 保留已有未提交业务改动,不覆盖用户工作
|
||
- [x] 压缩当前规划记忆并将详细历史移入日期归档
|
||
- [x] 迁移过期文档、重复交付副本和无引用历史产物
|
||
- [x] 同步所有受影响链接、说明和制品清单
|
||
- **状态:** 已完成
|
||
|
||
### 阶段 4:自动治理
|
||
|
||
- [x] 新增仓库卫生检查
|
||
- [x] 检查禁止的根目录散落、重复制品、版本漂移、源码/包不一致和断链
|
||
- [x] 接入适当的本地验证入口
|
||
- **状态:** 已完成
|
||
|
||
### 阶段 5:验证与交付
|
||
|
||
- [x] 运行链接、Skill、Schema、构建、测试和制品完整性验证
|
||
- [x] 复核活动目录只含当前上下文
|
||
- [x] 更新规划文件并交付最终目录说明
|
||
- **状态:** 已完成
|
||
|
||
### 阶段 6:桌面历史产物收口
|
||
|
||
- [x] 按 SHA-256 区分桌面历史目录与项目 `dist/`、`archive/releases/` 的重复和唯一文件
|
||
- [x] 确认桌面历史目录没有正在打开的文件
|
||
- [x] 将 10 个仅存桌面的历史制品补录到日期化项目归档并登记哈希
|
||
- [x] 复核剩余桌面有效文件均已有项目副本
|
||
- [x] 将整个桌面历史目录可恢复地移入废纸篓
|
||
- [x] 更新归档索引、Planning 文件并完成适用验证
|
||
- **状态:** 已完成;全仓库卫生门槛仅被当前 Word 会话生成的实时锁文件暂时阻断
|
||
|
||
### 阶段 9:团队文件后台附件交付
|
||
|
||
- [x] 定位导出流程中“读取成功但未持久化文件”的根因
|
||
- [x] 增加加密数据库附件存储、任务归属校验和鉴权下载路由
|
||
- [x] 让插件上传原始字节并以大小/SHA-256 校验作为完成门槛
|
||
- [x] 同步操作台、Schema、mapping、业务模板、回归夹具和版本化插件制品
|
||
- [x] 完成控制面、遗留契约、仓库卫生、构建及 DOCX 全页渲染检查
|
||
- **状态:** 已完成当时的数据库附件实现;本轮已补齐 OSS provider 和远程基础设施验证,真实部署与真实 ERP/生产业务复测仍留待后续授权
|
||
|
||
### 阶段 10:后台附件详情视觉收口
|
||
|
||
- [x] 移除导出团队文件详情中的冗余 operation 审核摘要
|
||
- [x] 附件卡片只保留文件名和下载按钮,保留等待/链接不可用状态
|
||
- [x] 移除重要消息、审核、附件和结果面板之间的无意义横向分割线,保留卡片与日志边框
|
||
- [x] 保持其他业务审核信息、附件鉴权下载接口和任务生命周期日志不变
|
||
- **状态:** 已完成;未修改业务数据或下载接口
|
||
|
||
## 已确认决策
|
||
|
||
| 决策 | 理由 |
|
||
|---|---|
|
||
| 全仓库审计,不局限于已点名文件 | 用户要求解决跨会话长期遗留问题 |
|
||
| Planning with Files 三文件保留在项目根目录 | 它们是用户指定的正式项目管理机制 |
|
||
| 规划文件过大时做语义压缩和历史轮转,不直接删除 | 保持新会话上下文精炼,同时保留可追溯性 |
|
||
| 暂不改名 `agent设计规范/` | 目录名称本身不是重复根因,避免无收益的大规模引用迁移 |
|
||
| 先审计引用和构建消费者,再移动或归档 | 防止误伤启动、测试、发布或当前业务事实 |
|
||
| 根目录固定保留 README、AGENTS、Planning 三文件及构建配置 | 兼顾项目入口、机器约束和跨会话恢复 |
|
||
| TypeScript 构建输出迁到忽略的 `.build/` | `dist/` 只承载版本化交付物,生成代码不再混入发布目录或活动搜索 |
|
||
| `dist/` 移除无版本插件别名和松散 Prompt/示例副本 | 它们无运行/测试消费者,且已经发生模板漂移 |
|
||
| 历史 README/发布门槛先冻结原文再精简活动版本 | 保留可追溯性,同时避免旧版本流水污染当前上下文 |
|
||
| DOCX 从 Markdown 确定性重建并做全 15 页视觉 QA | 修复现有多处内容漂移和中文字体缺失,减少以后手工漏同步 |
|
||
|
||
## 审计结论
|
||
|
||
1. 当前活动目录均有明确源码、测试、部署、发布或安全隔离职责;未发现空目录或无归属根文件。
|
||
2. TypeScript 编译结果是可重建生成物;版本化插件、五个 Skill 和 DOCX 是当前交付物,由发布清单定义。
|
||
3. 活动文档只链接当前契约或日期化不可变证据;历史快照不再承担当前入口职责。
|
||
4. Planning 三文件只保留当前决策、事实和进度,详细时间线已冻结到日期归档。
|
||
|
||
## 错误记录
|
||
|
||
| 错误 | 次数 | 处理 |
|
||
|---|---:|---|
|
||
| 首次合并补丁假定 `progress.md` 标题为“进度记录” | 1 | 读取实际标题“项目进度”,改为按真实锚点分别应用补丁;首次补丁整体失败,未产生部分修改 |
|
||
| `fc-list` / `fc-match` 不在当前 PATH,无法直接枚举中文字体 | 1 | 定位 workspace dependencies 内 bundled `fc-scan` 与 fontconfig,再用 DOCX 实际渲染验证 |
|
||
| 单个补丁同时删除并新增同一路径的 README 被拒绝 | 1 | 拆成新增规则/修改配置、删除旧 README、新增新 README 三个原子补丁;失败补丁未产生部分修改 |
|
||
| 新增 DOCX 构建器的首个补丁使用了不存在的 `tools/README.md` 锚点 | 1 | 读取真实表格结构后重新应用;失败补丁未产生部分修改 |
|
||
| bundled Python 没有 `fontTools` | 1 | 改用 macOS `mdls` 和 bundled `fc-scan` 只读识别字体 |
|
||
| 默认 LibreOffice 字体配置将 DOCX 中文渲染为方框 | 3 | 使用 workspace dependencies 的 Poppler fontconfig,并将构建字体固定为 `Arial Unicode MS`;最终 15 页全部清晰 |
|
||
| 首轮仓库卫生检查发现 macOS 重建根 `.DS_Store` | 1 | 再次可恢复地移入废纸篓并保留自动阻断规则,复跑通过 |
|
||
| 归档索引检查发现两处仍链接旧维护规范 | 1 | 改为链接根 `AGENTS.md`,复跑归档索引验证 |
|
||
| 一次 `rg` 命令中的反引号导致 zsh 引号不闭合 | 1 | 改用单引号正则重新执行;未修改任何文件 |
|
||
| `pnpm run test` 内部硬编码调用缺失的 `npm` | 1 | 将聚合测试改为 Node 22 原生 `node --run`,兼容 npm/pnpm 入口后重新执行 |
|
||
| 最终 JSON 检查误用 `jq -e empty`,因无输出提前退出 | 1 | 改为 `jq empty` 后完整重跑 JSON、JS、归档、差异和目录检查 |
|
||
| 清理新生成的根 `.DS_Store` 时假定旧废纸篓治理目录仍存在 | 1 | 只读检查确认该旧目录已不存在,改用废纸篓根下新的唯一目标名;首次命令在移动前退出,无文件变化 |
|
||
| 首次直接调用 bundled `node --run check:repo` 时,脚本内子进程找不到 `node` | 1 | 为验证命令显式把 bundled Node 目录加入 `PATH` 后重跑;首次失败未修改文件 |
|
||
| 本轮 `check:repo` 首次复跑发现 `dist/.DS_Store` 与已知 Word 实时锁文件 | 1 | `.DS_Store` 可恢复移入废纸篓;Word 锁文件因当前 DOCX 仍打开而保留,关闭 Word 后再完成卫生门槛 |
|
||
|
||
## 阶段 6 实时边界
|
||
|
||
- `/Users/inmanx/Desktop/LTJT-历史版本归档` 共 68 个文件:56 个有效文件已有项目内同哈希副本,10 个历史制品仅存桌面,另有 `.DS_Store` 和 Word 锁文件两个残留。
|
||
- 10 个补录制品已通过 `SHA256SUMS` 全量校验;补录后再次扫描桌面目录,结果为 `matched=56`、`unmatched=0`、`residue=2`。
|
||
- 桌面历史目录经 `lsof` 复核无打开文件后,已整体移入 `/Users/inmanx/.Trash/LTJT-历史版本归档-20260816`;原桌面路径已不存在,废纸篓副本可恢复。
|
||
- 项目当前 DOCX 正由 Microsoft Word 打开,`dist/~$联泰AI指令表-0.5.118.docx` 是实时锁文件,本轮不得移动、读取或删除。
|
||
- 适用验证:10 个补录文件哈希全通过;`node --run check`、`test:control-plane`(37/37)、`build`、`git diff --check` 通过;`check:repo` 为 8/9、`test:legacy` 为 197/198,两个失败均是同一个 Word 实时锁文件导致 `dist/` 多出一项。
|
||
|
||
## 安全边界
|
||
|
||
- 不使用 `git reset --hard`、`git clean` 或批量回退。
|
||
- 不覆盖现有未提交业务改动。
|
||
- 不读取或输出 `.env` 中的秘密值。
|
||
- 不进入 ERP,不修改业务数据,不部署或发布。
|
||
- 所有归档移动保持可恢复,并在移动前完成精确引用审计。
|