21 KiB
21 KiB
项目文件治理计划
当前会话任务:多 AgentBus 用户渠道与插件串行队列
- 状态: 实施中;用户已确认整体方案。
- 用户目标: 支持多个 AgentBus 来源/用户渠道,每个渠道可独立配置 AgentBus key,并保证插件同一时间只执行一个任务。
- 当前安全边界: 仅做源码、契约和数据库设计梳理;未创建迁移、未改运行配置、未部署、未向 AgentBus 或 ERP 发送数据。
本轮阶段
- 1. 读取项目记忆、检查工作区状态并按业务登记表定位通用业务契约
- 2. 核对 AgentBus 认证/来源、用户模型、任务状态和插件执行链
- 3. 确认渠道身份与插件队列的产品边界
- 4. 设计并实现渠道密钥、入站归属和可恢复的单插件执行槽
- 5. 同步操作台/API/文档/测试/发布边界并完成全量验证
当前待确认决策
| 决策 | 推荐 | 主权衡 |
|---|---|---|
| 插件串行范围 | **已确认:**同一组织/同一 ERP 浏览器会话全局一次只允许一个任务;其他用户任务保留在服务端队列,按创建时间依次领取 | 吞吐较低但不会跨用户并发写同一 ERP 会话;按用户并行会提高吞吐却无法保证当前单插件约束 |
| AgentBus key 的连接边界 | **已确认:**每个外部用户渠道对应独立 AgentBus listener/连接,独立保存 key | 多连接与重连管理更复杂,但 key 和用户边界清晰 |
| 渠道用户身份 | **已确认:**独立外部渠道身份,不创建后台登录账号;管理员统一管理 | 暂不提供渠道用户独立登录和权限视图,避免扩大现有管理员鉴权模型 |
| 最终回执可靠性 | **已确认:**入站路由和最终回执状态持久化,队列等待和进程重启不丢回执 | 增加 outbox/投递状态和重连补发逻辑,但避免用户收到假超时或因进程重启丢回执 |
已收敛的实施方案
- 新增
user_channels(外部渠道身份、显示名、独立加密 AgentBus key、连接配置、启用/连接状态);管理员通过后台 API/页面创建、启用、禁用和轮换 key,列表不回显完整 key。 - 控制面启动时为每个启用渠道建立独立 AgentBus listener;任务写入
channel_id,幂等键和会话路由按渠道隔离;Agent/Skill operation Schema 不变。 - 新增持久化 AgentBus 入站/回执 outbox,保存
channel_id + inbound_frame_id的幂等路由;先发一次受理通知,任务进入终态后发最终回执,断线/重启/排队超时后由对应渠道重连补发。 - 插件执行 claim 在组织级事务锁下按创建时间 FIFO;存在
queued/accepted/running或结果不确定的 ERP attempt 时不再创建第二个 execution,只返回排队信息。解析仍可并行,ERP 插件执行保持单槽。 - 操作台与扩展增加排队状态/单任务防护;补充迁移、渠道 CRUD、listener、多渠道幂等/回执、FIFO claim、并发 claim 和不确定结果阻断测试,并执行项目规定的完整验证命令。
默认假设与排除
- 现有组织级自动化开关继续对所有 AgentBus 渠道生效,不新增渠道级自动化策略。
- WebSocket URL、client type、重连/超时等通用参数继续使用服务端环境配置;渠道独立保存 key,并允许独立 bot address 覆盖,未提供时沿用兼容默认值。
- 禁用渠道停止接收新入站帧,但已进入任务队列或待发送 outbox 的回执保留;重新启用后继续处理。删除采用禁用/归档语义,不做物理删除。
- 不实现微信等具体渠道协议,不进入 ERP,不部署、不重启生产服务,也不读取或写出任何真实 key。
实施记录
- 用户确认开始实施
- 数据库迁移与渠道/回执服务
- 多 listener 与 durable outbox
- FIFO 插件 claim 与前端/扩展单任务防护
- 测试、文档、发布边界与完整验证
当前会话任务:AgentBus onboarding 更新后重新对接
- 状态: 已完成;运行进程已按当前受保护配置重新建立 AgentBus session 并通过健康检查。
- 用户请求: 按
/Users/inmanx/Downloads/agentbus-bot-onboarding-bot-2076193998368161793-listener.md重新对接 AgentBus listener。 - 安全边界: 仅使用文档中的连接参数;token 不写入仓库、不输出、不进入日志;不执行外部业务发送或 ERP 写入。
本轮阶段
- 1. 读取项目记忆、检查工作区状态并审阅 onboarding 连接事实
- 2. 核对当前 AgentBus listener 的握手实现与运行状态
- 3. 让运行进程使用 onboarding 参数重新建立 session 并验证 ready
- 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 收到并受理,随后发出受理进度和最终失败回执,最终结果也收到 AgentBusaccepted。 - 失败仅因为探测文本不是可执行业务指令,未进入 ERP;AgentBus 发信、收信和回件链路正常。
当前会话任务:生产 PostgreSQL / OSS 对接
- 状态: 已完成本轮对接与验证;未执行服务部署、重启或真实 ERP 写入。
- 用户确认: 使用干净生产 Schema,不迁移/删除旧测试数据;OSS 公共可读、仅后端可写/删;直接返回公共 URL;暂不启用自动清理。
- 远程落点: PostgreSQL
lwlt_agent数据库内新建liansyn_prodSchema;旧publicSchema 保持不变。 - 已完成: OSS V4 provider、随机执行 UUID 对象路径、任务附件元数据、事务失败回滚清理、生产环境模板和 retention 开关。
- 已完成: 完整仓库门槛、部署前检查、本轮证据与活动文档收口。
本轮阶段
- 1. 探测 PostgreSQL / OSS 实际权限和 Bucket 状态
- 2. 接入 OSS provider、独立数据库 Schema 和生产配置
- 3. 执行远程 Schema 迁移并验证上传/公共读取/删除
- 4. 完成本地测试、构建、仓库卫生和发布边界收口
当前会话任务:AgentBus 用户回复契约重构
- 状态: 已完成;已确认用户端只保留受理通知和最终返回通知。
- 用户确认: 失败时优先返回 ERP 业务反馈,没有 ERP 反馈才返回简短错误摘要;成功时按业务 action 与客户模板返回业务回执;解析完成/进入自动化 ERP 执行不对用户发送。
- 本轮重点: 按现有五类业务能力更新成功回执契约,正式接入酒店安排中英文客户模板,并保持 AgentBus 不泄露技术细节。
本轮阶段
- 1. 核对业务注册表、Schema、mapping 与当前 AgentBus/平台实现
- 2. 形成各业务成功/失败/文件回执矩阵与酒店模板契约
- 3. 实现控制面、平台/插件消息路由及回归夹具
- 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:repo9/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:全仓库发现与分类
- 确认用户目标和治理边界
- 确认
task_plan.md、findings.md、progress.md是正式项目记忆 - 审计全部活动目录、根文件、引用、构建消费者及版本管理状态
- 识别当前源码、生成物、运行输出、历史资料、敏感配置与无效残留
- 状态: 已完成
阶段 2:制定唯一目录规范
- 定义根目录允许项和各目录职责
- 定义 Planning with Files 文件压缩与历史轮转规则
- 定义
dist/、archive/、reports/、quarantine/的边界 - 将规则固化到项目级
AGENTS.md与当前入口文档 - 状态: 已完成
阶段 3:安全迁移与压缩
- 保留已有未提交业务改动,不覆盖用户工作
- 压缩当前规划记忆并将详细历史移入日期归档
- 迁移过期文档、重复交付副本和无引用历史产物
- 同步所有受影响链接、说明和制品清单
- 状态: 已完成
阶段 4:自动治理
- 新增仓库卫生检查
- 检查禁止的根目录散落、重复制品、版本漂移、源码/包不一致和断链
- 接入适当的本地验证入口
- 状态: 已完成
阶段 5:验证与交付
- 运行链接、Skill、Schema、构建、测试和制品完整性验证
- 复核活动目录只含当前上下文
- 更新规划文件并交付最终目录说明
- 状态: 已完成
阶段 6:桌面历史产物收口
- 按 SHA-256 区分桌面历史目录与项目
dist/、archive/releases/的重复和唯一文件 - 确认桌面历史目录没有正在打开的文件
- 将 10 个仅存桌面的历史制品补录到日期化项目归档并登记哈希
- 复核剩余桌面有效文件均已有项目副本
- 将整个桌面历史目录可恢复地移入废纸篓
- 更新归档索引、Planning 文件并完成适用验证
- 状态: 已完成;全仓库卫生门槛仅被当前 Word 会话生成的实时锁文件暂时阻断
阶段 9:团队文件后台附件交付
- 定位导出流程中“读取成功但未持久化文件”的根因
- 增加加密数据库附件存储、任务归属校验和鉴权下载路由
- 让插件上传原始字节并以大小/SHA-256 校验作为完成门槛
- 同步操作台、Schema、mapping、业务模板、回归夹具和版本化插件制品
- 完成控制面、遗留契约、仓库卫生、构建及 DOCX 全页渲染检查
- 状态: 已完成当时的数据库附件实现;本轮已补齐 OSS provider 和远程基础设施验证,真实部署与真实 ERP/生产业务复测仍留待后续授权
阶段 10:后台附件详情视觉收口
- 移除导出团队文件详情中的冗余 operation 审核摘要
- 附件卡片只保留文件名和下载按钮,保留等待/链接不可用状态
- 移除重要消息、审核、附件和结果面板之间的无意义横向分割线,保留卡片与日志边框
- 保持其他业务审核信息、附件鉴权下载接口和任务生命周期日志不变
- 状态: 已完成;未修改业务数据或下载接口
已确认决策
| 决策 | 理由 |
|---|---|
| 全仓库审计,不局限于已点名文件 | 用户要求解决跨会话长期遗留问题 |
| Planning with Files 三文件保留在项目根目录 | 它们是用户指定的正式项目管理机制 |
| 规划文件过大时做语义压缩和历史轮转,不直接删除 | 保持新会话上下文精炼,同时保留可追溯性 |
暂不改名 agent设计规范/ |
目录名称本身不是重复根因,避免无收益的大规模引用迁移 |
| 先审计引用和构建消费者,再移动或归档 | 防止误伤启动、测试、发布或当前业务事实 |
| 根目录固定保留 README、AGENTS、Planning 三文件及构建配置 | 兼顾项目入口、机器约束和跨会话恢复 |
TypeScript 构建输出迁到忽略的 .build/ |
dist/ 只承载版本化交付物,生成代码不再混入发布目录或活动搜索 |
dist/ 移除无版本插件别名和松散 Prompt/示例副本 |
它们无运行/测试消费者,且已经发生模板漂移 |
| 历史 README/发布门槛先冻结原文再精简活动版本 | 保留可追溯性,同时避免旧版本流水污染当前上下文 |
| DOCX 从 Markdown 确定性重建并做全 15 页视觉 QA | 修复现有多处内容漂移和中文字体缺失,减少以后手工漏同步 |
审计结论
- 当前活动目录均有明确源码、测试、部署、发布或安全隔离职责;未发现空目录或无归属根文件。
- TypeScript 编译结果是可重建生成物;版本化插件、五个 Skill 和 DOCX 是当前交付物,由发布清单定义。
- 活动文档只链接当前契约或日期化不可变证据;历史快照不再承担当前入口职责。
- 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,不修改业务数据,不部署或发布。
- 所有归档移动保持可恢复,并在移动前完成精确引用审计。