# 项目文件治理计划 ## 当前任务:名单覆盖确认后始终覆写(进行中) - **目标:** `passenger_list_import` 一旦收到 `full_replace + confirmed=true`,不再根据 ERP 当前游客值判定“无变化”;附件中所有指定序号都执行原生覆写和父表单保存,明确成功即完成。 - **安全边界:** 未确认的 `first_import` 仍不得改写已占用且不同的行;继续保留附件、唯一对象、结构、游客与领队写前投影及 ERP 明确成功响应门禁;不处理历史任务、不访问 ERP、不重载扩展或重启服务。 ### 阶段 - [ ] 先补失败回归,固定已确认覆盖对同值行也必须进入 changed/write 集合。 - [ ] 修改合并计划、版本和业务契约,移除已确认覆盖的 `passenger_import_no_changes` 阻断。 - [ ] 重建版本化 ZIP/清单并运行规定全量门禁。 - [ ] 收敛规划文件;不触碰运行态或历史任务。 ## 当前任务:8786 加载名单成功终结规则(已完成) - **目标:** 按用户授权优雅重启本机 8786 控制面,使 `0.5.154` 的名单明确成功响应终结规则和平台提示进入服务运行态。 - **安全边界:** 不查询、回查、重试或修改历史任务;不派发插件、不访问 ERP、不重载 Chrome 扩展、不部署或外发。 ### 完成结论 - 重启前唯一监听为 PID `13663`、标准 `pnpm run dev` 进程组 `13643`,live/ready 正常;已向该精确进程组发送 TERM 并确认端口完全释放。 - 新标准入口进程组 `29571` 已启动,服务 PID `29588` 成为 `127.0.0.1:8786` 唯一监听;live/ready、数据库、Schema、迁移 `014_task_input_attachments` 与 4/4 AgentBus 渠道均正常。 - 当前服务已提供最低扩展版本 `0.5.154` 和 `app.js?v=20260828-roster-server-success-1`。未调用任何任务接口或 ERP;Chrome 扩展仍需另行明确授权重载。 ### 错误记录 - 确认新监听已就绪前发起的第二个防御性标准入口 PID `29637` 因端口已由进程组 `29571` 占用而自行退出;最终复核只有一个 8786 监听,无重复服务残留。 ## 当前任务:名单明确提交成功即完成(已完成) - **目标:** 仅 `passenger_list_import` 按用户确认的业务规则,以 ERP 父表单明确成功响应作为完成证据;不再执行或要求写后逐行名单回查。 - **范围:** Chrome 名单保存结果、控制面成功回执、平台提示、mapping/release gate/风险登记、回归、扩展版本化 ZIP 与发布清单。 - **安全边界:** 继续保留附件/Program-only、目标唯一解析、覆盖确认、游客及领队完整写前投影、原生保存和明确成功响应校验;不放宽其他生命周期 action,不修改或回查历史任务,不自动重试 ERP 写入。 ### 阶段 - [x] 只读核对新任务:`0.5.153` 自动复核已运行,ERP 明确响应成功且领队哈希匹配,但异步页面逐行回查再次产生假阴性;历史任务未处理。 - [x] 先补失败回归,固定名单成功响应终结规则及其他 action 仍需回查。 - [x] 实现名单写后不逐行回查、成功提示和控制面回执语义。 - [x] 同步扩展版本、文档、ZIP/清单并运行规定全量门禁。 - [x] 收敛规划文件;不触碰历史任务或 ERP。 ### 错误记录 - 首次归档命令误在扩展子目录执行,两个相对路径归档步骤未生效;ZIP 构建成功。随后用完整绝对路径重新执行归档并核对旧包 SHA-256 未变,没有覆盖或丢失制品。 ### 完成结论 - `passenger_list_import` 在附件/Program-only、唯一对象、覆盖确认、游客行与领队联系人完整写前投影全部通过后,只调用一次父表单原生保存;ERP 明确返回成功即生成 `passenger_list_explicit_server_success` 完成凭据,不执行写后逐行回查。 - 后台已删除新名单任务的自动 hydrated 对账入口;控制面只对名单 action 接受该专用凭据,其他 lifecycle action 仍要求真实 fresh requery。 - 当前扩展为 `0.5.154`,ZIP SHA-256 为 `0e568940046ed8863123501c15ec292c0c3d79dd246799aebb9dba3842dfaa35`;旧 `0.5.153` ZIP 与发布清单已日期化归档。 - 门禁通过:仓库治理 9/9、TypeScript、控制面 125/125、legacy 245/245、build、JS/JSON/ZIP 与 `git diff --check`。本轮未修改/回查/重试历史任务,未访问 ERP 写路径,未重载扩展、重启或部署。 ## 当前任务:8786 加载名单回查修复(已完成) - **目标:** 按用户授权优雅重启本机 8786 控制面,使当前 TypeScript、平台提示和最低扩展版本 `0.5.153` 进入服务运行态。 - **安全边界:** 不重试、回查、确认或修改任何历史任务;不派发插件、不访问 ERP、不重载 Chrome 扩展、不部署或外发。 ### 阶段 - [x] 确认旧服务唯一监听 PID、进程组、工作目录和标准 `pnpm run dev` 启动入口;重启前 live/ready 正常。 - [x] 优雅停止旧进程组并按原入口启动当前源码。 - [x] 验证 8786 单一监听、live/ready、当前静态资源与最低扩展版本。 - [x] 记录完成状态;不触碰历史任务。 ### 完成结论 - 已向旧 `pnpm run dev` 进程组 `97618` 发送 TERM;旧监听 PID `97636` 退出,标准入口重新启动为进程组 `13643`,服务 PID `13663` 成为 `127.0.0.1:8786` 唯一监听。 - `/health/live`、`/health/ready` 均通过;数据库、Schema、迁移 `014_task_input_attachments` 及 4/4 AgentBus 渠道 connected/session ready。 - 运行服务已提供 `app.js?v=20260828-roster-hydrated-requery-1`、最低扩展版本 `0.5.153` 和“待管理员核验,请勿重复提交”提示。 - 未调用历史任务 API、未回查或重试任务、未派发插件或访问 ERP。Chrome 扩展仍未重载;旧扩展会被平台最低版本门禁阻止执行,直至用户另行明确授权重载。 ## 当前任务:名单写后回查假阴性与用户提示(已完成) - **目标:** 已取得 ERP 明确保存响应时,名单业务自动使用新鲜、完整加载的 ERP 页面做一次只读复核;复核匹配则直接完成,确实无法确认时明确提示用户禁止重复提交并等待管理员回查,不再显示笼统的“处理中/结果不确定”。 - **范围:** Chrome 名单 fresh requery、只读 reconciliation、平台/AgentBus 用户提示、回归、mapping、风险登记、发布说明、扩展版本化 ZIP 与发布清单。 - **安全边界:** 不放宽名单字段全等、目标身份、领队联系人或 ERP 明确响应门禁;自动补充步骤只能 GET/打开页面并读取,不得再次 POST 保存。未获授权不重试或修改现有任务,不重载扩展、不重启服务、不部署。 ### 阶段 - [x] 只读核对报告任务:ERP 当前 25 行完整投影与任务期望全等,领队联系人脱敏哈希全等;现有 `write_after_requery_mismatch` 为回查假阴性。 - [x] 先补失败回归:16/31 只作写前基线;raw GET 不匹配后只能进行一次新鲜 hydrated route 只读复核;不得再次保存。 - [x] 实现严格自动只读复核及面向用户的禁止重复提交提示。 - [x] 同步扩展版本、平台最低版本、mapping、release gate、风险登记、ZIP/清单。 - [x] 运行定向测试和规定全量门禁并收敛规划文件。 ### 当前决策 - 不能把 raw HTML 中的游客槽位数量当成 ERP 最终名单正确性的唯一事实;ERP 页面依赖原生脚本完成游客行 hydration。 - 写后快速 GET 仍可作为第一层证据,但失败不能立刻外显为不确定;只有服务端明确成功时,系统才允许自动打开同一精确对象的新鲜页面做一次只读复核。 - 新鲜页面仍须逐字段、逐目标序号、领队联系人和对象身份全等。复核不通过时保持 reconciliation,不声称成功,同时明确“禁止重复提交”。 ### 完成结论 - 报告任务在 ERP 的 25 个非空游客行与 canonical 投影逐字段全等,领队联系人也全等;旧结果来自两个回查缺陷:把初始 31 个编辑空位当成保存后下限,以及用未运行 ERP 脚本的 raw HTML 比较英文名。 - `0.5.153` 保留首次 no-store GET 快查;仅当名单取得明确成功响应、唯一 blocker 为 `write_after_requery_mismatch` 时,自动关闭陈旧精确编辑窗并打开一次同一对象的新鲜页面,对 hydrated DOM 做严格只读核验。该路径只调用 `verifyLifecycleOperation`,不调用原生保存或发出第二个 POST。 - 自动复核匹配后任务直接完成并说明“没有重复保存”;仍不匹配时平台、控制面和 AgentBus 统一提示“请勿重复提交同一任务,等待管理员只读核验”,不再用笼统提示引导用户猜测。 - 发布基线为扩展 `0.5.153`,ZIP SHA-256 为 `a52082e57cdd62e50e58e77bae83f1c7c4b6982213296ab649f9870853604d44`;`0.5.152` ZIP 与清单已日期化归档。 - 验证通过:名单 lifecycle 53/53、控制面 124/124、legacy 245/245、仓库治理 9/9、TypeScript、build、ZIP 完整性、包/源码一致性和 diff 检查。 - 未重试或修改报告任务,未重载 Chrome 扩展、重启/部署服务、写入 ERP 或外发。`0.5.153` 自动复核进入运行态仍需用户另行授权。 ### 错误记录 - AgentBus 定向测试首次把 `--import tsx` 放在测试文件之后,Node 将其当作模块路径;改为 `node --import tsx --test ...` 后通过。 - 首轮 lifecycle 和完整控制面各发现两类旧发布断言:页内脚本仍期望 `0.5.152`,页面测试仍期望上一缓存键;同步到 `0.5.153` 和当前缓存键后完整重跑通过。 ## 当前任务:Excel 领队行投影到 ERP 联系人(已完成) - **目标:** 名单 Excel 第一行仅作团信息、第二行固定为 14 列表头;当且仅当某数据行备注去空格后严格等于`领队`时,把该行姓名和电话作为结构化领队信息,并在名单父表单保存时写入 ERP `联系人/领队人`与`电话`。 - **范围:** 工作簿规范化、Program 解析态、双 Schema、Chrome operation gate/lifecycle adapter、fresh requery、业务契约、版本化制品与回归。 - **安全边界:** 同一附件最多一行领队;领队行姓名或电话为空时失败关闭。无领队标记时保持 ERP 既有联系人字段;标记行仍作为普通游客导入。未获授权不重载扩展、不重启/部署、不重试任务、不写真实 ERP。 ### 阶段 - [x] 只读核验真实模板结构:单工作表、第二行完整表头、25 条数据、恰好一行严格`领队`且姓名电话齐全;未输出个人信息。 - [x] 先补工作簿、Program、Schema、插件门禁与回查的失败回归。 - [x] 实现结构化 `passenger_list.leader_contact`,写前投影到 `jj_lianxiren/jj_dianhua`,失败时恢复父表单与游客行快照。 - [x] 同步业务登记、Skill、运营模板、mapping、版本化 ZIP/Skill/DOCX 和发布清单。 - [x] 运行定向测试与规定全量门禁,渲染检查 DOCX 全部页面并收敛规划文件。 ### 当前决策 - 备注只接受去空格后严格等于`领队`,避免`领队备注`等普通文字误触发联系人覆盖。 - `leader_contact` 放在 `passenger_list` 内,不复用顶层可选定位字段 `data.leader`;后者仍只用于查找/候选校验。 - 保存后除游客行完整投影外,还必须 fresh GET 核对联系人姓名与电话;回执只记录匹配状态和哈希,不回显个人信息。 ### 完成结论 - 工作簿只认第二行精确 14 列表头;第一行不导入。Program parser 仅对唯一严格`领队`行生成 `passenger_list.leader_contact`,并由 Schema、平台和插件三层独立核对该结构与 canonical TSV 完全一致。 - 插件在名单原生解析前快照四个联系人/接送字段,完成游客合并与恢复后只把领队姓名、电话投影到 `jj_lianxiren/jj_dianhua`;无领队标记时保留原值,任何控件缺失、写前漂移或保存后不一致均失败关闭并恢复快照。 - 发布基线收敛为扩展 `0.5.152`、五 Skill `0.5.124`、运营 DOCX `0.5.122`、Program parser `v1.0.5`、名单工作簿规范化器 `v1.1.0`、生命周期契约 `v2.9`。旧制品已进入 `archive/releases/2026-08-28/`。 - 定向回归通过;规定门禁最终为仓库治理 9/9、控制面 124/124、legacy 244/244、TypeScript 和 build 全绿。DOCX 12 页逐页检查,五个 Skill 通过官方校验,ZIP/Skill 包与源码逐文件一致。 - 11:52 运行暴露旧控制面 `v1.0.0` 与新版插件门禁错配;用户随后授权重启,8786 已加载当前源码并恢复 ready。未自动重试任务、部署或访问/写入真实 ERP;浏览器精确版本未另行读取。 ### 错误记录 - 首次规定门禁因子脚本 PATH 中没有 `node` 未进入测试;补入 workspace bundled Node 后重跑。 - 仓库治理首次发现运营模板版本断言仍为 `0.5.121`,同步到 `0.5.122` 后通过。 - legacy 首次发现 lifecycle Skill 混入插件 fresh requery 执行细节;将该细节保留在 mapping/适配器文档,Skill 收敛为纯解析契约并重打包后通过。 - lifecycle Skill 首次复验使用了错误相对路径;随后改用绝对源目录,官方校验通过。 ## 当前任务:名单覆盖行英文名写前纠正(已完成) - **目标:** 修复名单经确认覆盖已占用行后,ERP 原生 `DaoRuDones` 未可靠刷新英文名控件并触发写前投影不一致的问题。 - **范围:** Chrome 名单适配器、回归、版本化 ZIP、mapping、风险登记、release gate 和运行证据;不改变 Excel/Program 解析、覆盖确认或保存后回查契约。 - **安全边界:** 只对合并计划判定为 changed 的序号回写规范化 `NAME → pinyinxm`;完整写前投影仍须全等。未重载扩展、重启服务、部署、重试真实任务或写 ERP。 ### 阶段 - [x] 核对两次用户运行时间线与源工作簿,确认手工附件上传、25 行规范化和 Program 解析正常;失败发生在父表单保存前。 - [x] 先补失败回归,再实施只影响 changed sequences 的英文名纠正。 - [x] 发布链同步至扩展 `0.5.151`,归档 `0.5.150` 并重建版本化 ZIP/清单。 - [x] 收敛证据与文档并运行规定全量门禁。 ### 完成结论 - 第一次运行按设计因第 1、2 行已占用而要求覆盖确认;第二次确认后仅这两行报 `english_name` 投影不一致。两次均明确 `no_erp_write=true`。 - 源工作簿对应行没有特殊格式;失败范围支持原生解析覆盖旧行时遗留 `pinyinxm` 的判断。瞬时控件已恢复,因此该根因按强证据推断记录,不冒充保存成功证据。 - `0.5.151` 在 `DaoRuDones` 后只纠正确实变化行的英文名,未变更行仍恢复快照;电话保护、完整字段投影、明确响应和 fresh requery 均未放宽。 - 验证全绿:lifecycle 52/52、仓库治理 9/9、控制面 121/121、legacy 244/244、TypeScript、build、ZIP 完整性与包/源码一致性。 - 当前 ZIP SHA-256:`51529ca531f1767b4938292c1f8a637f510efa5df5d28d386711854c5f56495f`。 ### 错误记录 - 初次运行定向回归时 shell 无系统 Node;改用 workspace bundled Node。 - 首次打 ZIP 时目标相对路径多一层,未生成半成品;改用正确路径后通过完整性校验。 - 首轮全量发现两个旧扩展版本断言、一个旧页面缓存键断言及一个 Word 162 字节锁文件;同步/精确清理后全量复跑通过。 ## 相邻待处理项 - AgentBus OSS 附件曾因本机 DNS 返回私网/保留地址而被 SSRF 门禁拒绝;与本次平台手工附件成功及 ERP 英文名写前阻断是独立问题。本轮未修改下载安全策略,后续若继续应采用受控公有 DNS/主机白名单回退,不能全局放宽私网阻断。 - 运行日志已经出现 `0.5.152` 源码中的领队门禁,但未额外执行浏览器版本握手;真实 ERP 保存复测仍需用户另行明确授权。 ## 最近有效里程碑 - 两类名单业务已固定为 Program-only:文字先识别业务,任务等待单个 `.xls/.xlsx`,附件到齐后才解析;独立团 16 行、散拼子单 31 行只是初始合并基线,5000 行是技术上限。 - 当前生产模板单一源为 `agent设计规范/templates/business-input-templates.md`;运营 DOCX `0.5.122` 已按桌面示例精简并补充名单领队填写说明,完成全页渲染检查。 - 历史任务支持单条/当前页批量删除;AgentBus 渠道支持组织隔离删除;独立团人数程序解析已区分成人、占床儿童、不占床儿童和领队。 ## 历史与持续边界 - 本次压缩前完整计划见 [2026-08-28 快照](archive/project-history/2026-08-28/task_plan-pre-compression-roster-name-overwrite.md);更早历史见 `archive/project-history/`,均只供追溯。 - 当前发布版本、文件名和 SHA-256 只以 [发布清单](dist/release-manifest.json) 为准。 - 真实 ERP 写入、任务 mutation、扩展重载、服务重启、部署和外部发送仍需用户另行明确授权。