比较提交

...
8 次代码提交
作者 SHA1 备注 提交日期
wangsli和Claude Sonnet 5 22c6cb7890 补充5d8cdf12部署验收记录到本任务实施清单 [09-11-reimbursement-payment-handoffs]
ci-minimal / check-minimal (push) Canceled after 0s
ci-e2e / e2e (push) Canceled after 0s
从孤儿 worktree(artifacts/isolated-worktrees/20260910-reimbursement-payment-integration)
合并回填与前一笔 09-04 相同的 2026-09-11 执行记录(候选 5d8cdf12 部署、公网
部分验收、测试账号隔离盘点、提交推送回执),补齐本任务自己的 implement.md——
该事件同时归属两个任务,此前只有 09-04 一侧记录,本任务侧完全空白。

无产品代码改动。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:55:56 +08:00
wangsli和Claude Sonnet 5 5068e08b39 回填财务/yj所属主体生产修正执行记录 [09-08-reimbursement-payment-closeout]
从孤儿 worktree(artifacts/isolated-worktrees/20260910-reimbursement-payment-integration)
合并回填一次真实生产数据库写入、此前从未提交的完整执行记录:

- 2026-09-11 用户明确批准仅对财务 wangzhiling 与 yj 两人做 legal_entity_id
  回填(原值须为 NULL,目标须为唯一启用未归档主体),不涉及银行明文/角色/
  经理等其他字段。
- 10:50 READ ONLY 预检确认两人在职、角色/经理未变、目标主体唯一;10:51
  READ WRITE Serializable 事务原子更新恰好两行;10:52 独立连接只读回读
  确认一致,另有独立 SSH 只读复核。执行脚本先过 13 项合成正反例自测。
- 同批次的业务就绪只读核验:确认财务/yj/管理员当时仍缺所属主体,不能
  由此推出"财务不能替别人付款"等错误结论;两者是不同资格维度。

无新增产品代码改动;本次回填是对已实际发生的生产写入补齐审计记录,
使任务文档与真实数据库状态一致。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:55:49 +08:00
wangsli和Claude Sonnet 5 7abb410be5 回填5d8cdf12部署与验收账号隔离裁决记录 [09-04-reimbursement-state-gap-finance-view]
从孤儿 worktree(artifacts/isolated-worktrees/20260910-reimbursement-payment-integration)
合并回填 2026-09-11 从未提交的真实执行记录:

- 候选 5d8cdf12 的生产预检、发布与公网部分验收(员工 smoke 双端登录、
  零明细选票入口、合成草稿创建与清理)全过程记录。
- 验收测试账号只读盘点:财务 smoke 已归档、CEO smoke 凭据 0 条匹配、
  一个经理 smoke 需改密;更关键的是角色任务/通知无测试隔离——付款复核
  按当前事实投影会指向非 smoke 的真人 CEO,通知总开关和企微绑定均已
  开启,存在真实外发风险。
- 提出 A(推荐,隔离环境验收+保留公网员工侧验收)/B(先设计完整合成
  隔离方案再做生产公网全链)两条路径,待用户选择,未擅自降级验收口径。

未同步更新 task.json 的 commit/notes 字段——origin/main 该字段已推进到
2026-09-12 财务本人报销 CEO 审批的更新内容,回填旧字段会造成状态倒退。

无产品代码改动、无账号/角色/生产写入。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:55:39 +08:00
wangsli和Claude Sonnet 5 c81ed9ca69 回填公网验收与恢复诊断中发现的测试规则 [08-23-isolated-backup-restore-drill]
从孤儿 worktree(20260909-invoice-first、20260910-reimbursement-payment-integration)
合并回填两条实测中发现、从未提交的通用测试规则:

- reimbursement-invoice-ocr.md:公网合成验收流程(provider 检查→锁定 SHA256→
  上传);Fastify 对无 body 的 DELETE 请求发送 application/json 会报
  FST_ERR_CTP_EMPTY_JSON_BODY 的坑;批量分类后编辑需等视图更新,
  getByLabel 对已有内容的嵌套 textarea 可能定位失配。
- deployment-trialrun.md:buildSha 公网字段固定截断为 12 位、探针不得按
  完整 40 位比较;readiness fixture 必须覆盖错误/过短/空/超长四种值并在
  目标主机做无权限探测;附件引用校验失败前必须先保留已完成的 DB/解包
  结果,不能让后续失败掩盖已核实的部分。

均为测试脚本经验教训,无产品代码改动。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:55:28 +08:00
wangsli和Claude Sonnet 5 dea0303485 回填10-05到期例外的73文件分流台账 [09-05-error-explainability-payment-readiness]
从孤儿 worktree(artifacts/isolated-worktrees/20260909-ops-preparation)合并
回填 2026-09-09 从未提交的到期豁免分流工作:

- 对 591 条错误原因码豁免基线(scripts/qa/error-reason-legacy-baseline.json,
  全部 2026-10-05 到期)做完整 AST inventory 核对:673 条基线、695 次调用、
  73 文件,逐条 observedCount 与基线一致、0 漂移。
- 73 文件按 A(16 文件/优先迁移)/B(25 文件/待确认业务影响)/C(32 文件/
  逐模块审查延期理由)三档分流,逐文件列出指纹与调用数,均未裁决。
- 首批 4 个具体调用已设计好迁移方案(AP 台账开关/查询校验、todo 开关、
  portal 开关的 reasonCode 与中文文案),尚未落码。
- 明确 09-11/09-18/09-25/09-30/10-02 的分阶段裁决节奏;10-05 00:00 UTC
  (北京时间 08:00)即为门禁到期时点。

无产品代码改动、无原因码源码/注册表变更;仅补齐分流台账文档,为处理
10-05 到期风险提供已有基础,避免从零重新盘点 73 个文件。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:49:07 +08:00
wangsli和Claude Sonnet 5 070ea085c0 回填付款交接待办验收环境现状盘点 [09-11-reimbursement-payment-handoffs]
从孤儿 worktree(artifacts/isolated-worktrees/20260910-reimbursement-payment-integration)
合并回填候选 5d8cdf12 实际部署验证结果,以及 2026-09-11 只读盘点发现:
财务 smoke 账号已归档、CEO smoke 凭据 0 条匹配、经理 smoke 需改密;更关键
的是角色任务/通知缺少测试隔离,付款复核当前事实投影会指向非 smoke 的真人
CEO。commit 字段同步更新为已实际部署的 5d8cdf12。

已在 notes 末尾注明:以上账号/角色现状是 2026-09-11 的只读盘点快照,回填
时(2026-09-25)未重新核验,使用前需重新只读确认。

无产品代码改动、无账号/角色/生产操作;仅补齐任务文档记录。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:45:30 +08:00
wangsli和Claude Sonnet 5 e57ed0533b 回填e5685f1公网合成验收审计记录 [08-29-reimbursement-expense-policy-invoice-guard]
从孤儿 worktree(artifacts/isolated-worktrees/20260909-invoice-first)合并
回填 2026-09-09 部署 e5685f1 后从未提交的公网验收记录:

- 部署执行计划与 deploy-existing.sh 中途 exit=255 异常的只读排查(构建/
  迁移/健康检查实际均已完成,255 原因未定位但不代表发布未发生)。
- 公网止于草稿的合成验收:真实腾讯 OCR 队列、选票、分类编辑、跨端持久化
  全链路通过;清理工具认证问题(缺 x-device-fingerprint)排查与修正。
- 2026-09-10 最终 PASS:SCOPED_CLEANUP_PASS,测试数据精确清理确认。

无产品代码改动、无生产操作;仅补齐审计记录,使任务文档反映已发生的部署
与验收历史。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:45:30 +08:00
wangsli和Claude Sonnet 5 5be9f44445 回填隔离备份恢复演练执行记录 [08-23-isolated-backup-restore-drill]
从孤儿 worktree(artifacts/isolated-worktrees/20260909-ops-preparation、
20260910-reimbursement-payment-integration)合并回填两轮从未提交的真实
执行记录:

- 2026-09-09 ARM 管理员会话完成首次隔离数据库恢复,回执 DB_RESTORE_PASS,
  66 项迁移精确匹配、12 类关键表可读。
- 2026-09-11 第二次配对恢复,AC1/AC3/AC6 勾选完成;对发票池一条历史缺失
  附件做 SHA-256 比对、来源元数据核对、生产/ARM 归档/周检查点全量搜索,
  均未命中,按用户决定非破坏性标记、暂不追查(AC4 仍未过)。

无产品代码改动,无生产/ARM 操作;仅补齐 Trellis 任务文档与既有证据记录,
使 in_progress 状态反映真实已发生的执行历史。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-25 19:45:18 +08:00
共修改 17 个文件,包含 698 行新增和 7 行删除
@@ -727,6 +727,12 @@ const REQUIRED_ADMIN_NAV_KEYS = ["systemSettings"];
must explicitly provide both and must not publish `unknown`.
- Deployment compares public `/ready` and the public bundle marker with the
verified commit before reporting success.
- `/health.data.buildSha` and `/ready.data.buildSha` are normalized by
`server/src/config.js` to the first 12 characters. A probe with a pinned full
commit must compare the public value to exactly those 12 characters, not the
full commit or an arbitrary-length prefix. Runtime environment and backup
manifest identities remain full-SHA checks. A public identity mismatch is
not by itself proof that production changed.
### 4. Validation & Error Matrix
@@ -759,6 +765,11 @@ const REQUIRED_ADMIN_NAV_KEYS = ["systemSettings"];
- Synthetic 40-character build: bundle contains the matching 12-character SHA
and not the full value.
- Local-stub readiness test for expected/observed SHA propagation.
- Readiness fixtures must derive the public SHA from the actual `getConfig`
contract; cover wrong, short, empty and unexpectedly full public values.
Before a privileged restore handoff, exercise the same public probe from the
target host without privileges; a stub that echoes the input full SHA cannot
substitute for this read-only check.
- Public deployment still requires separate approval and post-deploy checks.
### 7. Wrong vs Correct
@@ -1627,6 +1638,12 @@ validate_copied_batch(private/batch, source_metadata)
- Emit the fixed diagnostic fields on the failure path before runtime teardown.
Teardown remains in a trap/finally-equivalent path and must still run after
diagnostic emission; callers retain stdout, not the private raw log.
- Before an attachment-reference failure, preserve completed DB checks,
extraction/file-count results and per-source reference/mismatch counts.
Classify missing files, size/hash mismatches, unsafe paths, malformed rows,
unreadable files and external storage without outputting identifiers or paths.
Check diagnostic totals against the unchanged validator; disagreement also
fails closed. Do not skip archived, test or duplicate references to gain PASS.
- An ARM restore runner fixes `restore_execution_path=DOCKER_STDIN`. A private
Docker proxy may observe the real `pg_restore --list` and apply calls and
persist only their stage name and numeric exit code; it must not record argv,
@@ -38,6 +38,20 @@ duplicate detection or attachment behavior.
## Rules
- 公网合成验收先用明确标注测试用途、无真实交易的样票单独跑 provider 必填检查,
通过后锁定 SHA256,再上传走队列/UI;provider 成功不替代上传整链。保留失败轮次,
最终区分草稿、审批、付款证据。清理使用本轮精确对象,回读草稿为零、票据归档且
未绑定、测试会话已撤销;归档不等于物理附件/OCR/审计数据删除。
- 测试 API 无 body 的 DELETE 不发送 application/json:Fastify 会报
FST_ERR_CTP_EMPTY_JSON_BODY(400);省略该头应正常进入处理器。
登录按实际合同携带设备指纹,logout 使用对应浏览器 Cookie;无 Cookie 的 200
不是会话撤销证据。报销 precheck 虽为 POST 但不等于提交审批,测试应按实际副作用
控制白名单,不能拦截该接口后宣称正常页面请求完整通过。
- 批量分类测试先等视图完成更新并核持久化类型,再开始另一项编辑,不能仅等待
classify HTTP 响应就假定查询缓存已更新。嵌套 label 内已有内容的 textarea 可能
使 getByLabel 的精确文本定位失配;使用稳定字段标识或 label 的独立 span + textarea,
同时覆盖空值与已有值,不靠延长超时反复消耗生产登录。
- 隔离串联的 `RUN_JOB_QUEUE=1` 必须运行真实 startPgBossJobs 与上传入口 enqueue,
等对应 invoiceId 的队列任务 completed,再校验发票状态和页面,不用直接调用
worker 冒充调度。只连接脚本新建数据库;非关注周期任务不得在测试期间改其他对象。
@@ -1,5 +1,15 @@
# 隔离备份恢复演练设计
## 2026-09-11 简化执行优先
附件失败诊断不改变准入:逐表保留原校验器,额外只输出缺文件、大小/摘要、路径/编码/行格式、非普通文件、外部存储和读取失败等白名单计数,并交叉核对原校验器的总数。不排除测试、归档、留痕或重复引用。所有表核对结束再执行同一失败门禁,避免只知道首张表失败;解包和普通文件数量验证、已完成 DB 验证须在附件失败前写入回执,不被笼统 NOT_TESTED 掩盖。无任何实际路径、记录 ID、文件摘要或内容进入诊断输出。
本轮遵循 PRD 最新收敛:固定摘要的一次性脚本内嵌已发布的 DB/附件恢复脚本和附件校验器,普通账号暂存,管理员在自己的终端输入一次 sudo 密码后执行;校验的是读入内存并将被执行的同一份字节,不采用先校验再以 root 重新读取文件的两次读取方式。没有长期安装器、sudoers 修改或通用 root shell。
仅本轮随机标签的无网络 PostgreSQL 容器、专属卷和私有目录可写;最终 TCP 查询连续成功再进入 restore,避免历史初始化临时服务竞态。来源提交动态冻结迁移名和 SQL 摘要;附件仍复用既有五类引用校验,base64 换行在 SQL 中去除。实际失败输出阶段、退出码和白名单错误类别,不回传原始 stderr。清理先校验本轮标签,身份不匹配不得删除;源归档前后摘要和监控/公网健康另行只读核验。
下文八段 RTO、历史 runner 部署/授权装置保留用于追溯,不作为本轮执行前提。本轮报告总恢复耗时、RPO、阶段和清理结果;应用与其他附件模型的端到端恢复不冒充已覆盖。
## 设计结论
采用“ARM 最新正式日归档 + 本轮私有临时副本 + 无宿主端口的一次性 PostgreSQL 16 + 空附件目录”的数据恢复方案。腾讯云生产只做演练前后公网 `/ready` 读取,不执行任何远端生产写操作;开发机不接收真实备份。
@@ -143,3 +153,36 @@ Attempt 4 在 `dump_list=PASS/0` 后、实际 restore apply 前以 `restore_targ
## 证据边界
执行证据写入当前 task 的 `research/restore-drill-evidence.md`,随后只在现有 OPS7 Runbook 或人工试运行报告中补一条脱敏状态摘要;不新建 `docs/` 平行文档。不得保存主机地址、SSH 别名、完整远端路径、Secret、连接串、真实账号、表内容、附件名或原始日志。
## 2026-09-09 最小人工恢复路径
### 与旧装置的关系
本阶段直接调用已跟踪的恢复脚本,不新增执行 runner、安装器、确定性渲染、sudoers 规则或 RTO 分段平台。现有 shadow/目标名称确认是恢复脚本内置安全条件,不删除、不改参数绕过。原正式演练指标继续保留未验,本阶段不改写五次历史结果。
本地已固定脚本身份:
| 文件 | SHA-256 |
| --- | --- |
| `scripts/restore-db.sh` | `3707d81db02364c5a4917f230ddde721731c04aa66ab746bd23a7bdcd475b95d` |
| `scripts/restore-storage.sh` | `de9e9340e16383d05b9821cdc73b65a0c28fbb2784a5ecb93d70c2e456ca651b` |
| `scripts/qa/validate-offhost-shadow-restore-attachments.py` | `2c2981d0e3f522145ffa1770f5ff519b3ffdfea74267e4d8ea9e30c130f7f0c2` |
### 手工操作清单(实际执行另批)
1. 在 ARM 获准管理员会话确认权限、镜像可用性、内存与磁盘余量。读取当时最新正式批次,而非复用 09-08 的摘要;核对 manifest 身份、PG/来源版本、DB/附件配对、字节数/摘要和24小时年龄。批次有歧义、超龄或损坏停止;现阶段没有选定备份,不声称上述前置已通过。
2. 生成本轮唯一标识,登记本轮容器与临时卷/目录;容器无宿主端口、network=none、明确 shadow 库名,使用临时凭据且不回显。只读使用归档数据或通过 stdin 输入,不挂生产数据卷、不向容器注入生产数据库连接,不启动 OA/worker,也不执行 migration/seed。
3. 容器内 TCP 回环查询 current_database,名称必须匹配本轮影子库;采用已有稳定就绪合同的连续两次成功和有界等待,不能以首次 pg_isready/socket 就绪直接开始。这里只是手工操作的就绪确认,不新增等待框架。失败保留阶段与安全错误后停止。
4. 明确指定 DB_TOOL_MODE=docker、DB_CONTAINER、POSTGRES_DB/USER、临时密码、RESTORE_SCOPE=shadow、RESTORE_CONFIRM_DATABASE,调用上述版本的 restore-db.sh。参数从本轮受控会话生成,不从生产 env 复制;私有原始输出仅留受控临时位置。脚本任何非零不忽略、不自动重试,是否源备份损坏需进一步依据,不能由“恢复失败”一句话判定。
5. 确认恢复整个命令退出 0;查询来源 migration 集合、失败状态以及原任务规定的12类关键表可读与数量摘要,不输出业务行。数量不是与实时生产一致的证明;恢复成功结论限于该具体批次。不要为了核对计数新增生产表数据读取。
6. 数据库通过后可按另获准的范围继续以 restore-storage.sh 恢复配对附件到本轮空目录,复用既有附件关联校验器;检查归档路径安全、文件集合和适用引用/摘要。若只批准数据库,附件明确 NOT_TESTED,不顺手解包。
7. 清理前生成短脱敏结果:批次指纹、开始/结束、退出码、DB/附件/应用验证状态、失败阶段和安全错误类别。原始敏感日志按既有受控清理规则处理,不能先删掉唯一诊断再留下“原因未知”。
8. 按本轮登记身份精确删除临时容器、临时卷/目录和临时凭据并回查;不删正式备份、不清理旧回滚镜像、不变更监控/timer。目标不明确立即停止清理并报告,不宽泛 prune。未清理完的结果不得写成完全闭环。
### 结果字典
- DB_RESTORE_PASS / STORAGE_NOT_TESTED / APP_NOT_TESTED:本批次数据库恢复成功,附件和应用仍未验;不是原正式演练整体 PASS。
- DB_RESTORE_PASS / STORAGE_RESTORE_PASS / APP_NOT_TESTED:成对数据恢复及既定一致性检查成功,不证明应用启动、正式切换或完整恢复耗时。
- STOPPED + 实际失败阶段 + 安全错误类别:不自动认定备份损坏;不继续业务发布来掩盖失败。若备份完整性或真正恢复数据步骤报错,优先单独报告并保全恢复点,不将其降为工具债。
- CLEANUP_PENDING:保留本轮目标标识与待清对象,不声明环境已恢复原状。
@@ -26,6 +26,193 @@
摘要匹配不等于实测恢复;旧镜像不撤销留痕删除或票据释放;若未来恢复生产,备份时点后数据丢失风险仍须另批。当前只准备清单,未 SSH、未复制或恢复真实备份。
## 2026-09-11 已完成历史缺失标记:保留归档记录、暂不追查
用户:"可能是测试时候的……不在当前报销单里,影响不大的情况下,可以删除或标记就行。"选择保留原记录并在本任务/恢复缺口材料标记,不硬删、不伪造原件或改变存储路径。现有 invoice-pool PATCH 只允许 available/ocr_failed;archived 不允许编辑,因此不绕过接口状态守卫直接修改备注。此处置是任务/运维记录标记,不声称已新增系统页面标签或写入发票字段。
- [x] 限定单条只读回核:记录/路径摘要一致,仍 archived/manual,当前原件缺失、报销/明细/差旅及同路径报销/采购/回单/请假附件关联均不存在。UTC 2026-09-11 06:22 实测,只返回 1 条、7 个关联布尔值均 false,生产版本 fe025e65、运行身份不变。
- [x] 在当前 task 与 provenance/historical-missing-disposition.json 登记"已知历史附件缺失,低当前业务影响,保留归档记录、暂不追查";不再作为继续业务开发/其他验收的阻塞项。
- [x] 保留技术结论:该固定备份 DB 恢复通过、附件引用缺 1、app 未测试。标记不是恢复成功或发布例外批准,不修改恢复门禁或历史备份,不删除数据。未来关联/重要性证据变化时重新打开该缺口。
本阶段处置闭合:选择标记而非删除,不再反复恢复、扩大搜索或索取同一处置授权。标记仅在现有任务和恢复证据里,未给生产票据加 UI 标签、未修改其备注/状态,也未新增审计或业务记录;不能对外称"生产数据已打标"。回核代码语法与 5 个本地合成条件通过(无关联、已关联、文件重新存在、状态变化和投影未知);原始回执在 provenance/disposition-precheck-result.json。这里接受的是已知历史缺口的低当前业务影响,不是"已确认测试数据"或"完整恢复通过",也不替代候选独立复核和发布审批。
## 2026-09-11 单份 PDF 摘要比对完成:大小和摘要均未命中
用户对"只将此前提供的那份发票 PDF 与登记文件摘要比对,需要读取字节、不展示内容、不写回、不扩大搜索"回复"是"。复用本 task 与原证据 provenance 子目录,不新建任务。
- [x] 只读取指定本地 PDF;拒绝符号链接/非普通文件、超限及读取期间变化,原始摘要仅在内存中传给既有受控只读生产通道,不展示或写入证据。本地读取字节是本次明确授权范围,不能把整次操作称为"未读文件内容";远端没有读取发票文件。
- [x] 精确定位既有记录/路径双摘要,在有超时的 READ ONLY 事务内比较登记摘要和大小;仅返回布尔结果、范围与运行身份未变。
- [x] 4/4 合成测试验证大小/摘要四种组合、目标变化和失败回滚、非法输入不连接、SQL 投影边界;实际生产只读查询退出 0,结果未匹配。按约定停止,不扫描其他 PDF。
结果:候选文件 56436 字节,PDF 文件头有效且读取前后身份/大小/修改时间未变;目标此前登记 57786 字节,本次数据库直接比较 sizeMatches=false、sha256Matches=false、exactFileMatch=false。既有记录/路径及 archived/manual 标记核对一致,生产运行镜像/容器身份不变。文件内容及实际文件摘要均未展示,原件未上传生产,未改库、补文件、触发备份、恢复或部署。
该结果只证明候选文件与登记原件字节不一致,不证明两份 PDF 的业务内容必然不同;本轮未做票据解析或内容比较。不能以"相似文件"替换登记原件,也不删除/忽略缺失引用。此次限定比对已经结束;保留历史缺失和整体恢复 NO_GO,后续只能基于新的明确原件线索或单独批准的缺失处置方案推进,不再原样恢复或逐次扩大目录搜索。运行时候选和发布授权均未变化。
证据:provenance/single-candidate-result.json。测试命令 node --test artifacts/qa-flow/20260911-invoice-reference-readonly/provenance/compare.test.cjs(4/4);沿用已验证的有界生产读取封装,不改此前冻结脚本。新比对代码只属本地诊断材料,不进入运行时候选。
## 2026-09-11 单条来源元数据核对完成:历史 mock OCR、手工归档标记
用户回复"是,同意"。复用当前 task 与原证据目录的 provenance 子目录;只查该记录,不扩展到个人访问/登录历史、全量审计或其他票据。
- [x] 对照当前生产版本的 schema、上传与归档写入路径,确定来源字段能证明什么;988 个本地受版本控制的源码文件做静态字符串路径摘要对照,精确命中 0,不覆盖动态生成路径或未跟踪材料。
- [x] 有超时的 RepeatableRead READ ONLY 单条查询,按既有记录/规范化路径双 SHA-256 核对身份,只输出安全枚举、时间、技术元数据和身份关系布尔值;5/5 本地测试通过,含一次性真实 PostgreSQL 精确行筛选、成功/身份不符后的数据不变与清理;Python 语法检查通过。
- [x] 既有生产 SSH 通道执行成功,恰 1 条记录;SQL 定位摘要和 Node 规范化路径摘要一致,生产仍 fe025e65、镜像/容器启动身份前后不变。未读单张文件、未访问 OCR 服务、ARM 或历史数据库,未部署或写库。
- [x] 回填结果和证据边界,不自动补原件、改路径、删除或排除该条记录。
当前行实测:UTC 2026-07-27 12:07:48 创建(北京时间 20:07),12:16:37 归档(约 8 分 48 秒后);status=archived、archived_reason=manual,而不是 unused_timeout。创建/上传/归属对应同一账号,当前更新人也是该账号;不读取账号身份,不将当前 updated_by 等同于已查明的归档操作者。技术元数据为 PDF、57786 字节、日期/UUID 上传路径形态,存储摘要格式合法;ocr_provider=mock、VAT、尝试 1 次,存在请求/完成标记及结果引用,但未读取 OCR 结果内容。当前报销/明细/差旅关联仍均为空。
证据解释:这是一条 7 月的历史记录,带 mock OCR 和手工归档标记;不是自动超时归档标记,不是现在腾讯 OCR 配置的核验结果。路径形态与标准上传生成方式一致,但数据库没有可靠的"真实上传/测试来源"专门字段;mock OCR 可以处理真实 PDF,不能据此确认为测试数据。988 个源码静态路径无精确命中也不能排除动态夹具。当前及本地历史手工归档实现只更新状态/元数据,不删文件;未证明该历史提交就是当时部署版本,不据此声称已查明删除原因。
本轮已完成获准来源元数据核对,不再追加同路径恢复或扩大个人历史查询。缺失原因、原件内容、创建入口和测试身份仍未获确证,整体恢复继续 NO_GO(DB 已通过、附件引用未通过、app NOT_TESTED)。处置应保留该历史缺口:若后续寻找原件,建议先将用户此前明确提供的那一份发票 PDF 与该记录保存的文件摘要做定向比对,不扩大到整个 input 目录;这需要读取候选文件字节计算摘要,不能伪称纯元数据检查,须另批这个单文件范围。匹配只能证明候选文件与登记摘要一致,补回仍另批;不匹配则如实收口,不自动全盘搜索。补文件、改引用或经核实后的清理同样另批;不让员工代做恢复验证。
安全回执与测试汇总位于 artifacts/qa-flow/20260911-invoice-reference-readonly/provenance/production-result.json、source-and-result-summary.json、selftest-result.json。生产只返回脱敏定位摘要、时间、枚举、技术值和关系布尔值,未读取票据正文/金额/备注/银行字段、人员账号、访问日志或审计 payload。没有修改运行代码、提交或推送。
收尾 task validate、Trellis 治理、流程基线及 git diff --check 通过;本地脚本摘要与实际执行输入一致。敏感扫描仅命中合成测试的随机 credential 变量引用,主会话核为误报,保留原始 FAIL 与说明于 provenance/completion-checks.json;不修改扫描规则,不冒充独立复核。此轮没有新的规约变化,复用既有只读最小投影合同。
## 2026-09-11 历史备份目录项定位完成:限定范围内未命中
用户批准下一步限定只读查找,复用当前 task 和证据目录的 history 子目录,不改变运行候选或部署授权。
- [x] 仅从既有生产自动备份合同与 ARM 接收器合同定位正式历史备份根;不遍历全盘、inbox 或临时事务目录,不读取数据库包。
- [x] 本地合成用例验证路径规范化、目录项匹配、危险条目拒绝、读权限/损坏/变化独立报告,禁止 extractfile/extractall;设置批次数、归档大小、条目数和总耗时上限。python3 -B -I artifacts/qa-flow/20260911-invoice-reference-readonly/history/selftest.py:12/12 通过。
- [x] 完成两端获准正式历史目录项扫描。生产本地 7 份、ARM 日归档 7 份及周检查点 4 份均未匹配该路径;ARM 回执经既有 SSH 直接读取,冻结脚本摘要再次一致。ARM 日根另有 1 个非规范目录项未纳入,类型/内容未验证,不宣称全盘或所有历史备份都已检查。
- [x] 保留已扫描范围、失败/跳过原因及当前恢复仍 NO_GO 的结论;找到仅标待验证原件,补回或改引用另批。没有新增部署、备份、数据库或业务写入。
生产只读结果:正式本地保留批次 7/7 扫描完成,覆盖 UTC 2026-09-05 18:30 至 2026-09-10 18:30,路径匹配 0;非规范目录项 0,归档元数据及运行容器身份前后不变。该结果只排除这 7 份归档中的同一路径,不排除其他路径、较早备份或原始上传文件,不能推出永久丢失。没有核验单张文件内容或历史数据库身份,不把元数据稳定当作全包完整性通过。
执行前 ARM 普通身份目录访问为 PERMISSION_DENIED,sudo -n 需交互密码;管理员现已在自己的终端执行固定摘要脚本,权限前置已解决,不再要求重复输入或重新扫描。脚本最多每根 64 个批次、单归档 512 MiB、展开流 2 GiB/20000 条目、总扫描期限 120 秒并设 150 秒信号上限;只遍历目录项、不调用 extractfile/extract/extractall,不恢复或写业务数据。
ARM 实际结果 SEARCH_COMPLETE,UTC 2026-09-11 05:45 回执:日归档 7/7(备份时点 UTC 09-04 至 09-10),周检查点 4/4(最早 UTC 08-17);路径匹配 0,已扫归档元数据前后不变。11 个 ARM 目录对应 10 个不同 manifest,周/日存在重复来源,不计作 11 个独立恢复点。另 1 个非规范目录项只计数排除,未查类型或内容;未读历史数据库,不能由早期检查点无该路径推断当时已有这条记录或原件永久丢失。
本轮证据为 history/production-summary.json(远端 stdout 的脱敏汇总,非原始逐批回执)、arm-confirmed-result.json(SSH 回读实际完整安全回执)、completed-receipt.json;执行前权限受限回执、暂存及合成测试证据继续保留。SSH 回读不冒充外部独立复核,不修改此前阶段回执。限定路径搜索完成,但缺口未修复:数据库恢复 PASS、附件引用失败、应用 NOT_TESTED,整体仍 NO_GO。
下一步建议结束同路径重复扫描,围绕这一条记录确认来源与预期原件,再决定补原件、修路径或经核实后的历史缺失处置;进一步数据读取或任何修复须明确最小范围,不以"已归档、未关联"自动认定测试数据或忽略失败。不让员工代做恢复测试,不重复要求管理员运行同一命令,当前不部署、不提交推送。
## 2026-09-11 生产侧只读核对完成:源端同样缺少已归档发票文件
沿已授权生产通道完成最小字段 RepeatableRead READ ONLY 查询和应用实际存储根的 realpath/stat 检查;未打开单张发票内容,未读取金额、银行资料、人员信息或访问日志。6 个本地测试通过,其中一次性真实 PostgreSQL 验证了实际 SQL、关联投影、只读事务与记录不变;另 4 个合成归档目录项用例通过,禁止 extractfile。生产脚本退出 0,无需用户再次操作 ARM。
实测当前发票引用 42:源文件存在 41、缺少 1,无权限拒绝。缺少的引用同时不在已固定 manifest 对应的 107 个附件归档文件路径中。该记录 status=archived、archived_at 非空,创建和更新时点均早于备份;当前没有报销、明细、差旅关联,也不存在同路径的报销附件、采购附件、付款回单或请假附件引用。只保留记录/路径 SHA-256 脱敏定位,不回传原始 ID、路径或账号。
生产仍 fe025e65;容器启动时间/镜像未变,源端同一附件归档前后摘要匹配。没有生产业务写入、恢复、清理、下载真实备份或部署。该证据表明缺口在当前源端也存在,不是仅恢复副本缺文件;但本轮没有再次读取备份数据库的逐条身份,不能只凭当前数量和时间戳相同就声明已证明历史缺失原因。原件是否位于其他路径或更早备份、该记录是否来自测试以及何时/为何缺失仍未验证。
源码核对:当前 invoice-pool 手工归档路由和 invoiceArchiveJob 只更新状态/归档元数据,不删除文件;业务规约要求保留 PDF 原件。因此不把"已归档、未关联"自动视为可删或可排除条件,不改变 AC4 和整体 NO_GO。它当前没有查到报销/回单关联,不能扩大成整个系统所有业务已验收。
下一步建议围绕这一个脱敏引用查找可用原件或历史备份,并另行形成补文件/修引用或缺失处置方案。任何真实文件补回、引用修正、测试数据清理或发布例外继续另批;不再原样重跑恢复。就本轮授权而言,只读核对已经完成,数据缺口未修复,未做文件内容或历史备份搜索。
证据复用 artifacts/qa-flow/20260911-invoice-reference-readonly/:production-result.json、probe-inputs.json、selftest.log、final-receipt.json 与 evidence-manifest.json;脚本及回执均不进入运行时候选。收尾 task validate、治理、流程基线、git diff --check 通过,文档登记检查错误 0(保留既有警告)。定向敏感扫描命中本地合成测试的随机密码变量引用 1 处,主会话核为非凭据字面量的误报,保留原始 FAIL 与复核说明,不修改扫描规则,不冒充独立复核;未提交或推送。
## 2026-09-11 已授权生产引用与源文件只读核对
用户对限定只读核对回复"是"。本轮可连接当前生产,只查询发票引用定位、状态及关联标记,并用文件元数据判断源文件是否存在;不读取发票正文、金额、银行资料、完整人员信息或访问历史,不登录业务账号,不修复或删除记录。复用原 task,不新增任务。
执行顺序:核对当前生产容器及同一备份 manifest 身份;在有超时的 RepeatableRead READ ONLY 事务中取得最小引用投影;在实际应用存储根下做路径安全和 stat 检查;必要时只遍历同一附件归档的目录项,对照规范化路径摘要,不解包落盘或读取单张附件正文。缺文件、权限拒绝、路径异常必须分开;只输出数量、状态和脱敏引用标识。生产当前引用和备份时点的数据库引用不得因数量相同就冒称完全相同;历史来源因果不明时明确保留缺口。前后回读运行身份不变;不部署、不恢复生产、不清理测试数据。
## 2026-09-11 第三次诊断结果:发票池 1 条引用缺文件
已从 ARM 的 result.json 读取管理员实际执行回执,诊断不是仅由聊天转述:NO_GO / verify_attachment_references / ATTACHMENT_REFERENCE_MISMATCH。数据库再次 DB_RESTORE_PASS,68 条迁移集合和摘要匹配、异常 0,12 类关键表可读。当前同源批次年龄约 10.57 小时,manifest/包完整性通过。
- 附件解包成功,归档普通文件 107、解包普通文件 107,文件数一致。
- 发票池引用 42:41 条通过存在性、大小和 SHA-256,1 条 FILE_MISSING;该缺失条目未进行大小/摘要验证。
- 报销附件引用 5/5、付款回单引用 1/1 均通过存在性、大小和 SHA-256;采购/请假引用均为 0。
- 合计引用 48、通过 47、缺失 1、外部存储 0;诊断计数与原校验器一致,未跳过任何记录。
- 容器、卷、临时文件已清理,sourceArchiveUnchanged=true,生产前后公网健康与 ARM timer 状态未变;未部署或修改生产业务数据。
结论仅为"这份已校验备份恢复后,有 1 条发票池引用的目标路径不存在",不等于整包损坏,也不能推出原始票据永久丢失或该条一定属于测试数据。107 个归档文件是否在其他路径含有同一内容、生产源端是否仍存在目标文件、该引用是否关联真实报销均未验证。AC4 继续未通过,整个配对恢复仍 NO_GO,应用 NOT_TESTED;保留已有 DB 恢复通过证据。
接下来不原样重复恢复、不删除或排除这条记录。建议增加受控生产侧只读核对,与同一备份对照:只取发票引用定位所需元数据/关联状态和源文件存在性,区分源端缺失、备份遗漏、路径变化或历史异常;不读金额、票据正文、银行资料或个人访问历史。此生产附件/引用核对超出原"生产仅健康和备份元数据"的范围,待用户明确同意再执行;任何补文件、改引用、清理测试记录仍须另批写入。原任务继续承接,不新建 task,不声称原因已修复。
安全回执为 artifacts/qa-flow/20260911-paired-restore/arm-attempt3-result.json;此前两次结果和冻结脚本保留。当前没有遗留影子库可供继续查询,后续若需查看同批次数据库引用,须明确临时隔离读取和清理边界,不以此为由改查完整生产业务数据。
## 2026-09-11 配对恢复第二次:DB 通过,附件引用未通过
管理员回执由普通 SSH 独立读取:NO_GO / verify_attachment_references / ATTACHMENT_REFERENCE_MISMATCH。DB restore 退出 0,68 条迁移集合和 SQL 摘要一致、异常 0,12 类表可读;数据库恢复能力在当前 fe025e65 备份上已得到实证。ARM 最新同一 manifest 完整性通过、年龄约 9.97 小时、余量约 89.41 GiB;生产前后公网健康与 ARM timer 未变,源归档摘要未变,本轮容器/卷/临时数据已清理。
storage=NOT_TESTED 不是"未解包":执行到该阶段意味着 restore-storage.sh 已退出 0、归档和解包普通文件数已经一致;但回执未在最终引用门禁前写入这些结果。旧校验器只返回总数/不一致数/s3 数,本轮包装器又在写入计数前抛错,所以现有证据不能判断缺文件、大小不符、摘要不符、路径/行格式或外部存储是哪一类。不得称为备份损坏,也不得称为整个配对恢复通过;未启动 OA 应用。
接续仅补诊断,不修复或排除任何数据:按原五类影子库引用逐表运行原校验器,另计算白名单失败类别计数并与原结果交叉核对;所有表检查完再保持原失败门禁。解包/文件数、引用总数、适用大小/摘要验证与失败类别在清理之前写入脱敏结果,不输出账号、单据 ID、路径、内容或原始校验行。不读生产附件字段,不修改生产、备份或已恢复数据,不把真实备份下载到开发机。旧脚本与摘要保存在 attempt2/,真实失败回执为 arm-attempt2-result.json。原隔离资源已按约清理,若要定位现场原因须执行带诊断的同范围隔离过程,不能在没有现场数据时猜测原因或宣称已经修复。
诊断版准备完成:python3 -I selftest.py 20/20 通过,含真实 PostgreSQL 合成配对正例、迁移失败/附件缺失后的完整清理、12 种合成附件条件与原校验器逐一对照、重复引用不去重。缺失反例完整报告五类来源而非遇第一处即停止,解包成功和失败计数在清理后仍保留。本地本轮容器/卷残留 0;ARM 普通账号实测同一公网检查与两个 timer 通过。源端同一 manifest 再次完整性通过(约 10.32 小时),未触发新备份。
诊断脚本已普通账号暂存并由另一 SSH 回读摘要匹配,一次 sudo -n 尝试仍要求管理员密码,诊断版未实际恢复。待管理员执行新摘要命令后读取 attachmentChecks 的分类计数;不承诺下一次会 PASS,不将原附件引用失败降级忽略。当前候选、生产版本和备份不变,未部署;任务整体仍未完成。
## 2026-09-11 配对恢复首次执行暂停:校验器口径错误
ARM 管理员回执已由普通 SSH 读取确认:PAUSED / preconditions / PRODUCTION_CHANGED,restoreStarted=false;没有开始归档校验、复制、建容器或恢复,三个 Removed=true 表示没有本轮恢复资源需要清理,并非已经恢复后清理成功。
只读定位发现 server/src/config.js 的 normalizeBuildSha 将公网 buildSha 截成 12 位,而本轮校验器错误地直接与完整 40 位比较。当前公网 200/ok、版本前缀 fe025e65cfb5;生产容器完整版本和镜像再次核对未变,同一源端备份完整性仍通过(本次约 9.23 小时)。不能将该错误码解释为真实生产部署或备份损坏。
修订保持原任务范围:公网值严格等于已固定完整提交的前 12 位,不接受任意长度前缀;manifest/build/image 仍完整匹配。用实际 getConfig 生成测试值,补错误前缀、全长误用、过短/空值、非法期望值和失败零资源检查,并先在 ARM 普通身份实测公网检查再交付重试。旧脚本、摘要、测试和指令保存在同一证据目录 attempt1/,实际失败回执单独保留;不覆盖旧失败,不自动部署,不扩大 sudo 权限。
修订验证:python3 -I selftest.py 完整复跑 18/18 通过,本地本轮容器/卷残留 0;ARM 普通账号调用同一 production_ready 后实际通过,两个监控 timer 也通过。首次新增实际配置测试遇到本地 Node 不在执行器受限 PATH 的测试环境问题,测试改为解析当前 Node 绝对可执行位置后复跑通过,未改变远端执行器 PATH。不能再用"把输入完整 SHA 原样回显"的 stub 声称验证了生产健康接口。
修订脚本新目录暂存并由另一 SSH 回读摘要匹配;一次 sudo -n 受控执行尝试仍要求交互密码,未开始恢复。现在仅待管理员运行修订后的固定摘要命令;旧命令对应已证实错误的检查器,不再使用。新接续回执见 arm-unprivileged-precheck.json、arm-revision2-execution.json;schema、生产配置、备份和运行候选均未修改,独立候选复核仍待外部。
## 2026-09-11 接续:一次性 DB+附件配对恢复
用户"执行下一步工作"承接已推荐的 ARM 隔离配对恢复,不包含生产恢复、部署、真实业务操作或权限扩张。官方 current 已切回本 task;候选 fedcaed1 不变,独立复核仍标为待外部,不以 inline 主会话自审替代。
- [x] 刷新 ARM 既有 SSH 管理员渠道:仍需交互 sudo 密码;不改 sudoers、不申请通用 root shell、不收聊天密码。
- [x] 复用已发布的 restore-db.sh、restore-storage.sh 和附件校验器,准备固定摘要的一次性脚本;仅普通账号暂存,管理员在自己终端输入一次密码执行完整限定流程。
- [x] 先用本地合成备份验证真实 PostgreSQL 恢复、附件配对、失败关闭和本轮资源清理;本地通过不算 ARM 恢复通过。
- [ ] ARM 执行前重验最新归档及固定来源 manifest、24 小时时效、来源 build/image、现存 PG16 镜像、磁盘预算与监控;变化则暂停,不自动选择旧批次或拉镜像。
- [ ] 同一 manifest 的 DB+附件恢复至随机专属容器/卷与空目录;无宿主端口、network=none、随机临时凭据,不执行 migrate/seed、不启动 OA 或通知/OCR/银行调用。
- [ ] 对照来源提交动态核验迁移集合/摘要/异常项、12 类表及适用附件引用/大小/摘要;数据库记录只供机器校验,输出仅统计与安全错误类别。
- [ ] 无论成败,只清理本轮创建资源并回读确认;正式归档前后摘要匹配,生产只读健康、ARM 监控状态单独核验。实际结果出来后补原 task 回执,不提前声明完成。
本轮简化执行优先于下方历史 runner 的安装、sudoers、三阶段诊断和八段 RTO 装置要求;不扩建这些装置。保留数据 RPO/恢复总耗时与失败阶段,应用恢复明确 NOT_TESTED。当前备份早于今日两条所属主体修正,不能证明含备份之后变化;生产数据恢复仍需另批。脚本及本地合成证据留在联合副本 artifacts/qa-flow/20260911-paired-restore/,不纳入运行时候选。
本地 python3 -I selftest.py:15/15 通过,真实 PostgreSQL 合成 DB+附件正例、迁移摘要不符和附件缺失两类恢复后失败都完成清理;另覆盖 manifest 固定、来源身份、损坏、超龄、危险 tar/重复项、错误标签拒删、脱敏诊断和公网健康响应合同。12 类表和 68 个来源 migration 指纹用于合成验证,不冒充正式备份的行数验证。运行期间未下载真实备份、未调用 OCR/银行、未部署。
候选已提交树的 32/32 文件摘要仍与原冻结包一致,independentReview=PENDING_EXTERNAL_INLINE。源端最新备份再次完整性匹配,核验时约 8.69 小时,仍早于今日回填;ARM 两个监控 timer 的实际名称、enabled/active 已只读核对。ARM 脚本 0600、暂存目录 0700,另一 SSH 回读摘要匹配;现在仅等管理员终端密码执行,不是授权不足或恢复已失败。恢复脚本、输入摘要、本地日志与暂存回执分别见同目录 bundle-manifest.json、selftest-result.json、arm-staging.json。新增脚本只属本地受控执行材料,不改变 fedcaed1 候选,不自行提交推送这些补记。
## 2026-09-11 当前应用镜像制品已固定(不是恢复通过)
用户单独批准保存当前生产镜像并校验。本轮 fe025e65 镜像已保存为独立文件,1,119,357,440 字节,配置摘要/14 层/归档摘要通过,另一次 SSH 回读一致;文件 0600、目录 0700,独立于 Docker 存储但仍在生产同机。服务未重启,未 docker load,生产剩余约 40.04 GiB;旧镜像/备份全部保留。
同次另一窄授权仅回填财务/yj 的所属主体,已两行更新及独立连接回读。今日 02:30 的数据库备份早于该修正,不含这些后续变化;没有启动新备份。镜像回退不撤销主数据修正,配对 DB/附件和应用恢复仍待单独授权及受控管理员渠道,不用制品摘要匹配冒充恢复成功。
定位与完整回执共用联合副本 artifacts/qa-flow/20260911-authorized-preparation/,没有复制真实备份到开发机或向聊天输出银行资料。此前"当前版本独立制品未找到"是此授权执行前事实,已由本节更新;ARM 归档当前受交互凭据限制的缺口仍存在。
## 2026-09-11 限定只读刷新回执(未恢复)
本轮获准只读预检,没有恢复或镜像持久化授权。生产仍 fe025e65,候选 fedcaed1 已推送;今日 02:30:49 同版本备份的 manifest/DB/附件包大小摘要匹配,核验约 7.27 小时,PASS_INTEGRITY_ONLY。生产余量 41.09 GiB;现有登记回滚目录没有当前生产版本镜像的独立制品,3 份其他版本回执保留。
源端成功回执及最新 watchdog 时效检查正常;ARM dead-man 今日 06:30 退出 0、timer active,但本次普通账号归档路径读取被拒,sudo 非交互访问要求管理员密码。没有绕权限,今日 ARM 归档文件及目录容量未独立核验,也没有恢复、复制真实备份或清理资源。此前管理员回传的一次 DB_RESTORE_PASS 仍有效,仅不替代本次 DB+附件+应用配对验证。
证据共用联合副本 artifacts/qa-flow/20260911-readonly/。接下来先给受控隔离目标的管理员执行渠道,再按明确批准做配对恢复;只读检查不自动授权 docker save/load、服务重启或生产数据回退。不扩复杂演练器、不索要聊天明文密码。
## 2026-09-09 最小恢复阶段执行记录
- 已完成本地准备:在独立 ops-preparation worktree 修订 PRD/design,直接复用 restore-db.sh、restore-storage.sh 和已有附件关联校验器,固定三文件摘要;没有修改任何恢复脚本、安装器或 runner。
- 未访问 ARM 或生产,未选择当日备份、未核对当日容量/新鲜度、未创建容器或恢复数据。不能用历史09-08完整性结果当作本次前置。
- 实际执行待明确授权,授权对象须区分"数据库最小恢复"与"配对附件恢复";未批准附件就只出 DB 结果。代码提交/推送、正式应用恢复及生产切换均不包含在本阶段。
- 本地验收:恢复 shell 语法、task validate、Trellis governance 和 diff 检查;这些不替代真实恢复成功。原整体 AC 保持原状;下一次远端成功/失败证据仍追加 research/restore-drill-evidence.md,不创建新证据体系。
| 代码 | 发布 | 业务/恢复验收 | 等谁 |
| --- | --- | --- | --- |
| 只修订本地操作方案,无恢复脚本改动 | 不适用,本轮不发布 | 正式备份最小恢复未执行 | 等用户单独批准受控 ARM 操作,执行时再核对最新批次与容量 |
## 2026-09-09 获批数据库最小恢复:访问前置停止
用户已明确批准仅数据库的ARM隔离恢复、结果检查及本轮精确清理;附件未授权。本次不再处于"等待恢复授权",而是"管理员通道不可用"。
北京时间2026-09-09 09:22:40执行既有SSH通道的最小检查:SSH退出0、当前UID=1000、sudo -n true未通过。只证明当前非交互通用提权不可用;未采集sudo原始报错,不把它进一步断言为具体密码/策略故障。没有尝试新账号、读取密码、修改权限/sudoers、利用Docker绕过文件权限,亦未反复试探其他提权方式。
结果STOP_ADMIN_CHANNEL_UNAVAILABLE;backupRead=false、containerCreated=false、restoreStarted=false。未选择最新批次、未核对当日备份完整性/年龄,不复用昨日结果冒充已验;无本轮远端临时文件、容器或卷需要清理。该结果不是新的pg_restore失败,也不说明正式备份不可恢复。
脱敏回执保存在原主工作区artifacts/qa-flow/project-roadmap-execution-20260909/restore-minimal/access-check.json。下一步使用用户已说明可用的ARM管理员交互会话执行最小操作;密码只在用户终端输入,不要求发到聊天,不以清理或诊断为名扩权。本地规划与清单仍保留,生产部署和真实付款继续暂停。
## 2026-09-09 最小数据库恢复阶段闭合
- [x] 用户既有管理员交互会话完成最新批次完整性检查;原版恢复脚本退出 0。
- [x] 管理员回传来源 migration 66 项精确匹配、异常 0,12 类关键表可读及数量摘要;本地来源/候选 migration 目录集合一致。
- [x] 管理员回传本轮容器、卷及临时文件已精确清理;不读取或保存业务明细与临时凭据。
- [ ] 配对附件恢复、引用验证、应用恢复及原整体演练其余验收:本次未执行,不以数据库阶段成功代替。
- [ ] 独立远端复核:未执行;本阶段以管理员执行回执为证,代理本地审查不称独立复核。
证据见 research/restore-drill-evidence.md 的同日最小恢复记录。旧访问停止段为历史前置,不再是本阶段当前阻塞;没有变更 task 的整体完成状态。未提交、未推送、未部署。后续规划仍先 seed 初始化/升级分离,不在本轮扩大恢复范围或自动发布。
## 执行前门禁
- [x] 确认任务已在用户审阅最终规划摘要后由 `task.py start` 进入 `in_progress`。
@@ -1,5 +1,38 @@
# 隔离备份恢复演练
## 2026-09-09 最小验真阶段(本地准备已批准,远端执行另批)
用户批准综合规划开始本地实施。本 task 不再把安装器/固定 runner 的完善当作下一次数据库恢复验真的前置;新增受控管理员人工最小路径。只在既有授权通道操作,不能以“不用 sudoers”解释为绕过现有读取权限。未收到本次 ARM 真实备份恢复授权,本轮不连接远端。
本阶段数据库结果和配对附件结果分开:数据库退出 0、来源 migration 与关键表检查通过,才可记 DB_RESTORE_PASS;附件未执行记 STORAGE_NOT_TESTED;不启动应用,不宣称应用或完整灾备 RTO 已验证。原整体 Goal、数据库/附件 AC 和历史 NO_GO 保留;最小阶段通过不自动勾选原整体 AC。原 runner 渲染/安装及分段 RTO 不作为本次最小阶段新增工程前置,仅适用于保留的正式演练合同。
保留生产零写入/零重启、影子目标确认、无宿主端口、批次来源与24小时新鲜度、配对摘要、敏感输出限制、非零失败关闭及本轮精确清理。若本地脚本在实际最新批次上失败,保留脱敏诊断并停止;不得现场放宽条件、转用旧批次或自动重试。Attempt 3 底层原因仍未知,不追认所有失败均为工具问题。
## 2026-09-11 本轮执行口径
用户认可在当前无业务关联、影响较低的前提下删除或标记。选择非破坏性标记:复核仍为 archived/manual、原件缺失且无当前业务关联后,在现有任务/恢复缺口记录登记"已知历史附件缺失,保留记录,暂不继续追查"。当前票据接口不允许编辑 archived 记录,不为添加备注绕过状态守卫改库,不新增缺失状态或删除记录。"可能是测试数据"仍是推测,不写成已确认事实。此处置不把恢复 AC4 改为通过,不改校验器、不排除缺失项,也不自动授权部署。
该处置已完成:再次只读核对无当前报销/明细/差旅及同路径附件/回单关联,记录和源文件缺失状态未变;已在本 task 和恢复证据中标记,生产数据保持原样。按用户决定暂不追查,不阻塞其他业务开发/验收;技术恢复仍如实记录 1 条附件引用缺失,发布例外及独立复核不由该标记替代。
用户批准对此前明确提供的单份发票 PDF 读取字节计算 SHA-256,并与唯一缺失记录登记的文件摘要、大小比对。不展示文件内容或原始文件摘要,不遍历 input 目录、不读其他文件,不上传原件、不补回或改生产。只读返回匹配/不匹配;匹配不代表原件已补回、备份已更新或恢复已通过,不匹配则停止,不自动扩查。
本次单文件比对已执行:大小和 SHA-256 均不匹配,不能将它补作登记原件。已按约定停止搜索,未补文件、改库或部署;不推断 PDF 业务内容必然不同。当前仍保留单条历史附件缺失,恢复 AC4 未通过;后续需新的明确原件线索或另批缺失处置方案,不重复恢复或自动扩大搜索。
用户另行批准只读核对唯一缺失记录的创建/归档来源元数据。本轮只定位既有记录 SHA-256 与路径 SHA-256,查询该行的时间、状态、归档原因枚举、创建/上传/更新身份关系布尔值及必要技术元数据;不读取人员账号、个人访问历史、审计 payload、票据正文、金额、备注或银行字段,不改数据。结合本地已发布源码解释字段含义;没有确证不得归因为测试数据或手工删除。
此元数据核对已完成:记录创建于 2026-07-27,约 9 分钟后标记 manual 归档,PDF 技术类型,存有 mock OCR 处理记录;当前无报销/明细/差旅关联。没有读取 OCR 结果或文件内容;不因 mock 或手工归档标记认定为测试数据,也不推断是谁删除了文件。来源入口与缺失原因仍未证实,AC4 未通过;后续内容摘要比对必须单独明确读取范围,任何修复仍另批。
用户进一步批准围绕该唯一缺失引用,只读查历史备份目录项和文件元数据以寻找原件。仅在已有生产/ARM 管理渠道可读的正式备份目录内做有界搜索,按已记录的规范化路径 SHA-256 匹配;不读票据正文、不恢复数据库、不解包落盘、不补文件或改引用。找到目录项只算候选原件,内容一致性与可恢复性仍须另验;权限拒绝、覆盖范围不足和未命中必须分开,不以未找到推断永久丢失。
该限定搜索已完成:生产 7 份、ARM 日归档 7 份及周检查点 4 份均未命中;ARM 另 1 个非规范目录项未纳入,不能称为所有历史备份都已检查。管理员已执行且主会话 SSH 回读结果,不再等待该次密码或执行。缺失引用未修复,AC4 继续未通过,不扩大为永久丢失或测试数据结论。
第三次诊断已确认发票池 1 条引用缺文件。用户另行批准生产侧限定只读核对:最小引用/关联状态和源文件存在性,可对照已固定附件归档目录项;不读票据正文、金额或银行资料,不改数据或生产配置。此限定读取是下文历史"生产仅健康探测"范围的显式补充,不授权恢复生产或修复记录。
用户已同意继续做 ARM 一次性 DB+附件隔离配对恢复;不是生产恢复或发布授权。本轮复用已有 shadow 恢复脚本,以一次管理员终端操作完成前置验证、临时恢复、校验与清理,不再安装历史 runner、sudoers 入口或增加分段计时装置。按原 R1–R4 保留输入身份、时效、隔离、迁移和附件配对边界,R5 记录总耗时与安全失败阶段即可。实际配对恢复已执行:DB 通过、附件引用失败,清理完成;不以本地合成通过替代,也不原样重跑已知失败过程。
固定输入来自今日最新源端校验通过的 fe025e65 备份;若执行时 ARM 最新批次、manifest、来源 build/image 或现存 PostgreSQL 镜像变化,暂停刷新证据,不自动取旧批次或拉镜像。恢复不启动 OA 应用,app 必须标 NOT_TESTED;镜像回退和 DB/附件恢复仍是不同能力。09-09 管理员回传的最小 DB_RESTORE_PASS 已有效记录,不再沿用"从未成功恢复数据库"的旧结论。
## Goal
在不覆盖、不暂停腾讯云生产 OA 的前提下,使用 ARM 备份机上最新的完整异机批次完成一次数据库与附件的隔离影子恢复,证明“备份存在”进一步达到“最新成对数据备份可恢复”,并记录实测数据恢复 RTO、RPO 和脱敏证据。
@@ -61,12 +94,12 @@
## Acceptance Criteria
- [ ] AC1:ARM 最新正式日批次通过文件集、manifest、字节数和 SHA-256 校验,来源构建是当前构建的祖先或相同,且实测 RPO 不超过 24 小时;是否已形成当前构建同源恢复点单独记录。
- [x] AC1:ARM 最新正式日批次通过文件集、manifest、字节数和 SHA-256 校验,来源构建是当前构建的祖先或相同,且实测 RPO 不超过 24 小时;是否已形成当前构建同源恢复点单独记录。2026-09-11 第二次配对执行已证同源 fe025e65、约 9.97 小时;不代表未来批次自动通过。
- [ ] AC2:腾讯云生产在演练前后 `/ready` 均正常,生产容器、数据库、附件、配置、timer 和业务数据零写入、零重启、零切换。
- [ ] AC3:一次性 PostgreSQL 16 影子库无宿主端口,数据库恢复成功;恢复 migration 集合与 manifest 来源提交一致且无失败/未知项,来源与当前 migration 差异已明确;固定 12 类关键表均可读并形成仅含数量的脱敏摘要。
- [x] AC3:一次性 PostgreSQL 16 影子库无宿主端口,数据库恢复成功;恢复 migration 集合与 manifest 来源提交一致且无失败/未知项,来源与当前 migration 差异已明确;固定 12 类关键表均可读并形成仅含数量的脱敏摘要。2026-09-11 第二次配对执行:68 条迁移集合/摘要匹配、异常 0、12 类表通过;附件失败不抹掉此项实证。
- [ ] AC4:附件安全恢复成功,归档与解包普通文件数一致;所有纳入范围的本地附件引用均安全且存在,适用的哈希/大小核对无不一致。
- [ ] AC5:记录本轮数据恢复 RTO、RPO、同源恢复点可用滞后、开始/结束时间、失败点或 finding、Go/Pause/No-Go 结论;即使恢复未开始也保留已观测空窗,不把任何指标表述为完整应用灾备 RTO 或 SLA。
- [ ] AC6:演练结束后本轮容器、端口、网络和临时数据全部清理,ARM 正式归档与现有 dead-man/健康监控不受影响。
- [x] AC6:演练结束后本轮容器、端口、网络和临时数据全部清理,ARM 正式归档与现有 dead-man/健康监控不受影响。2026-09-11 第二次配对执行已清理,源归档摘要与 timer 未变;后续新运行须重新核验。
- [ ] AC7:任务校验、Trellis 治理、流程合同、文档审计、敏感扫描和 `git diff --check` 通过;证据不含敏感信息。
## Out of Scope
@@ -79,7 +112,7 @@
## Blocking Open Questions
- 无。构建门禁已裁决为“来源提交是当前构建祖先或相同 + 批次年龄不超过 24 小时”;实施仍需用户审阅本次修订后的最终规划摘要并再次明确批准。
- 单条历史缺失已按用户决定完成非破坏性标记,来源未证实但暂不继续追查;不再等待其处置授权或管理员密码。实际附件恢复仍未全部通过,不自动改为完整恢复成功。若未来需要修复或生产恢复/部署,仍需对应明确范围与授权。
## Test Plan
@@ -87,3 +120,10 @@
- 通过现有 shadow 恢复脚本完成 PostgreSQL 16 和附件恢复,验证来源提交的 migration 集合、与当前构建的 migration 差异、固定 12 类表及附件引用聚合。
- 复核无宿主端口、生产前后 `/ready`、ARM 监控未受影响和本轮临时对象零残留。
- 运行 task validate、Trellis governance、process contract、docs registry、敏感扫描和 `git diff --check`。
## 2026-09-09 数据库最小恢复执行授权
用户对“通过ARM既有合法管理员通道,核对当时最新正式备份,在一次性隔离PostgreSQL中执行数据库恢复、检查结果并清理本轮临时资源”明确回复“是”。本次只批准数据库,不解包附件、不启动OA、不触碰生产、不改权限或sudoers、不删除正式备份。权限不足或恢复失败停止并报告;不需再次征询同一范围的授权。
最初代理非交互管理员通道检查未通过;随后用户通过既有 root 交互会话执行获批操作。2026-09-09 管理员回传本批次 DB_RESTORE_PASS、66 项 migration 集合匹配、12 类关键表可读和本轮资源清理完成。该结果并非代理独立远端验证;附件与应用仍未验,整体任务保持未完成。详见 research/restore-drill-evidence.md 同日记录。
@@ -592,3 +592,37 @@ receiver 聚合结果:正式原子日归档共 7 个,最新归档在复核
调查器本身出现并安全关闭了两类本地缺陷:首次生产探针错误假设部署账号可 sudo,安装前即被权限拒绝;前两次 ARM 探针把 dead-man unit 写成近似但不存在的名称,均在状态读取前以合同不可读失败。每次 root 入口、sudoers candidate、普通用户暂存均为 0。最终版本从仓库 receiver 安装器机械提取并比较 unit basename,并将生产探针改为无提权只读执行;Bash/Python 语法、两种 ExecStart 解析 fixture 和敏感扫描通过。上述缺陷不改变生产、ARM、归档、timer 或告警状态,也没有伪造调查结果。
当前独立生产 finding 为:最新可用异机恢复点已超过 24 小时目标,自动备份传输链正在失败;恢复演练因此保持阻塞。该事件不再作为恢复演练的普通 finding 排队处理,建议另建 Trellis 生产事件任务承载传输/容量调查与修复,当前演练任务仅保留证据交叉引用和阻塞关系。后续优先顺序是另行批准修复生产到 ARM 的传输链并形成新的原子批次,确认自动备份/两端 dead-man 与 watchdog 恢复,再对新批次重新执行身份探针。手工补跑备份、修改网络/SSH/timer、清理 partial 或发送测试告警均不在本次只读批准内。
## 2026-09-09 最小数据库隔离恢复通过(管理员执行回传)
证据来源:用户在 ARM 既有 root 交互会话执行本会话提供的分步命令,回传脱敏 JSON;代理未获得该会话的管理员凭据,未独立登录读取恢复库或核验远端清理。代理独立完成的是本地来源提交 migration 集合提取、原恢复脚本摘要核对及普通 SSH 临时上传。以下远端结果按管理员执行回执记录,不冒充独立复核。
- 批次创建时间:2026-09-08T18:30:05+00:00,即北京时间 2026-09-09 02:30:05;完整性回执年龄 7.35 小时,不是后续任意时点的当前年龄。
- manifest SHA-256:`968426af94092cd05a672817178e46773837d893fc9bd0491a4c76d3a49a611f`;来源构建 `f223bfb72fb2baef51199702c2def84c41af7aef`。
- 数据库包和配对附件压缩包均大小与 SHA-256 匹配。附件仅校验压缩制品,未解包、未做附件引用验证。
- 镜像为既存 `postgres:16-alpine`,linux/arm64;固定镜像 ID `sha256:c05eced0bdb41ea9b95a656472a6aa4d50cad0d8a2e33d14eb1c53fd6204f2ae`。先前只检查 `postgres:16` 的 false 不能解释为所需镜像缺失。本轮未下载镜像。
- 执行前回传 archive/docker 可用空间均 89.35 GiB;恢复命令另设磁盘及可用内存下限检查。此值不是生产容量或清理后容量。
- 使用原版 `restore-db.sh`,SHA-256 `3707d81db02364c5a4917f230ddde721731c04aa66ab746bd23a7bdcd475b95d`;一次性 PG16 容器无宿主端口、network=none、独立本轮卷。连续两次 TCP 回环确认影子库后执行,恢复脚本退出码 0,未自动重试。
- 验证只读事务使用 ON_ERROR_STOP;来源 migration 集合 66 项精确匹配、异常 migration 0。名称集合 SHA-256 为 `18967953c57e88cab87453074e7e2c5a566482b60da1f67276d342b976c99d35`。本地从来源 Git 提取,非旧证据中 65 项硬编码;与本地候选 `b918530` 的目录集合一致。未执行 migrate 或 seed。
| 关键表 | 恢复后行数 |
| --- | ---: |
| departments | 5 |
| employees | 8 |
| employee_roles | 14 |
| purchase_requests | 0 |
| reimbursement_forms | 6 |
| invoice_pool | 36 |
| payment_batches | 2 |
| contract_registry | 0 |
| projects | 0 |
| purchase_attachments | 0 |
| reimbursement_attachments | 5 |
| payment_batch_receipt_attachments | 1 |
最终回执:`DB_RESTORE_PASS`,12 类关键表全部可读;`storage=NOT_TESTED`、`app=NOT_TESTED`。行数只描述该具体备份恢复后的聚合结果,不是与实时生产逐项比对或业务流程可用的证明。
清理回执:`cleanupPending=false`、`containerRemoved=true`、`volumeRemoved=true`、`temporaryFilesRemoved=true`。检查通过后精确删除本轮容器、卷、临时凭据、日志及上传脚本;命令不删除正式归档、不清理旧回滚镜像、不改权限/sudoers或生产服务。本轮未独立查询生产健康或 ARM 监控,不能据此勾选原整体演练的前后健康验收。
结论限于本批次:已实际证明数据库恢复命令及约定数据库检查通过,不能继续笼统记为“本任务当前正式备份数据库恢复能力仍无答案”。历史五次 NO_GO 保留,Attempt 3 原因仍未知;本次成功不追溯解释历史失败,也不证明所有备份都可恢复。配对附件恢复、应用恢复/业务验收、完整灾备 RTO/RPO 和独立复核均未完成,整体 task 不关闭、不归档,不自动取得发布例外或部署资格。
@@ -1,6 +1,59 @@
# 实施清单:报销费用口径与票据明细门禁
## 当前接续点:只读复核与发布候选准备
## 当前接续点:已部署,公网草稿闭环验证完成
### 2026-09-10 公网草稿最终 PASS(本节替代前次样票阻塞状态)
- 用户再次批准继续验证。未修改产品代码、权限、审批定义或生产配置,运行版本仍 e5685f1;本轮仅维护受控验收脚本和记录,无再次部署。
- 生成新版全合成 PDF:采用表格化票面布局,明确标注不可报销/支付,无真实交易/账号/票据内容。每轮独立合成票号,不修改真实样票、不绕查重。先走部署环境已有 provider 检查,再经线上 UI 上传走真实队列及腾讯;最终样本摘要与 probe manifest、生产持久化发票逐一一致。
- 最终命令:`node artifacts/qa-flow/20260909-release-e5685f1/probe-synthetic.cjs && node artifacts/qa-flow/20260909-release-e5685f1/verify-live-draft.cjs`,exit=0,证据 live-draft-result-v6.json=PASS_DRAFT_ONLY。专用 employee 真实浏览器登录1次 HTTP200,上传、OCR available、用户点击添加前零明细、一票一明细、批量分类、编辑说明、桌面刷新持久化均通过;同单转手机路径修改说明、保存刷新通过;真实 precheck POST 正常返回。submitRequests=0、blockedWrites=0,不是公网审批验收。
- 只读最终回验:6 张本阶段合成票均 archived/manual 且无单据/明细/差旅绑定,标记测试草稿0,测试时间窗口内活动会话0。最后样票的哈希、合计1.00、税额0.00、日期2026-09-10、provider=tencent 均匹配;原始合成文件及OCR审计资料按正常保留机制留存,不能宣称物理删除。证据 live-draft-final-readback.json。
- 中间失败保留而不抹掉:v2 桌面通过但拦截10次 precheck;核实该 POST 是只读预检查后放行,仅禁止提交等范围外写入。v3 分类后马上编辑的持久化断言失败,测试改为等待已分类视图并回读类型后再编辑,后续通过;这不证明所有快速点击竞态均无风险。v4/v5 手机说明定位超时;本地最小 HTML 复现 `getByLabel('说明', exact=true)` 对已有内容的 textarea 命中0,按 label 的 span + textarea 定位命中1,v6 补验通过,无产品修补。
- 清理工具根因补验:Fastify 合成 DELETE 带 application/json 却没有 body,稳定返回400/FST_ERR_CTP_EMPTY_JSON_BODY;不发送多余 Content-Type 返回200。修正后各轮均经业务API删除草稿及归档合成票,不再直接写库。登录必须带设备指纹;logout 必须使用浏览器Cookie上下文,不把无Cookie返回200写成会话已撤销;最终数据库只读计数提供撤销证据。
- 现已补上“公网真实腾讯→队列→选票→可编辑草稿”的同环境证据,不再沿用先前只能分层推断的缺口。边界仍是公网不提交、不审批、不付款;提交及三段审批沿既有隔离环境证据,不能扩成真实用户/全票种/整站全面验收。
- 主线本阶段完成;下一阶段按已有顺序进入 09-04 退回删除修复,再做 09-08 付款文件名/下载理由/进度布局,复用原任务、不叠改当前产品。部署/验收记录与新增经验尚未提交,不自动归档整个历史任务。
### 2026-09-10 公网止于草稿的实测结果
- 用户批准公网只验上传/OCR/选票/分类编辑/保存刷新,不提交审批。定位到既有仓库外 live-smoke.env(0600),仅在进程内读取 employee 凭据;此前“常规 env 无配置”不等于专用凭据不存在。生产只读前置确认唯一 active、未锁定、无需改密且角色精确 employee 的 smoke 账号,未改账号或生产配置。
- 执行 `node artifacts/qa-flow/20260909-release-e5685f1/verify-live-draft.cjs`:真实浏览器登录一次 HTTP 200,创建标记草稿,上传一份 Chromium 生成的中文 PDF,显式标注“合成测试样张、不可报销、无支付效力”。未使用用户真实票据、未改 provider 或注入 OCR 结果。上传创建成功,轮询终态 ocr_failed,结果 STOPPED/SYNTHETIC_OCR_NOT_AVAILABLE。
- 这证明登录、草稿创建、上传及识别失败终态路径;不能证明腾讯能识别该合成版式,不据此认定生产 OCR 配置坏了,也不记自动建明细/分类/编辑刷新通过。submitRequests=0;浏览器安全拦截了 6 个未列入本次写入白名单的请求,具体类型未记录,不谎称全部请求均正常。未产生审批任务或付款。
- 验收脚本自动清理未成功,后续仅清理用途的 API 登录也未通过;已核实该清理请求缺少生产要求的 x-device-fingerprint,不能记为账号密码失败,不继续重试登录。原脚本 loggedOut=true 仅表示无 Cookie logout 返回成功,不证明会话撤销,该结论撤回。
- 随后只读确认恰有本次前缀标记草稿 1 张(draft、明细0)与合成文件名票据1张(ocr_failed、未绑定)。按已获准清理范围执行专用 Serializable 事务:锁单/票后重验唯一数量、smoke精确角色、owner=submitter、标记、状态、无明细及无绑定;只删除该草稿、归档该失败合成票、撤销按该次建单/上传时间窗口唯一定位的测试会话。任一条件不符全事务拒绝。
- 最终 SCOPED_CLEANUP_PASS:草稿删除回读0、合成票归档、测试会话撤销。合成 PDF 与 OCR/审计记录按既有保留机制留存,不声称物理文件已删除。未清理其他账号、单据、发票或会话;未做真实业务写入。
- 证据在既有发布目录:live-draft-result.json 保留原失败,live-draft-cleanup.json 保留清理API失败,live-draft-cleanup-final.json 记录最终定点清理。仅测试工具与本记录变化,无产品改动、未再部署。
- 后续缺口:需要可被腾讯识别且不会占用真实报销票号的专用测试样票,或另行批准真实样票在确认无业务占用/查重风险后的受控用途;不能以随意排版的合成 PDF 冒充已验证发票样本。先修正测试器认证/会话清理与失败诊断,再安排下一次受控验证,不交给用户手工测试,不反复消耗账号登录。
### 公网合成业务验收前置(用户已授权,停在写入前)
- 用户已明确授权专用测试账号的合成报销上传/OCR/选票/分类编辑/提交审批及测试数据清理;不包含真实报销、真实付款、修改真人账号或生产审批路由。
- 本轮只读查询运行容器的账号状态及当前报销工作流,事务/连接强制 read only,仅回传测试别名、角色与状态。四个既有 smoke 候选:两个 active employee+manager(其中一个 must_change_password=true),一个 active employee,一个 archived employee+finance;启用 smoke 角色集合只有 employee、manager,没有 ceo。不得将已归档财务视为可直接登录,也不以管理员替代财务验收。
- 当前活动报销工作流 assignee_rule 为 role=ceo,不是直接经理步骤。即使测试员工有测试直接经理,也不能据此保证提交不会派给真人;目前缺少仅限本次测试的审批隔离路径。不能为了跑通而给测试账号增加 ceo(会影响全局角色路由)、修改活动工作流或擅自启用财务。
- 当前执行进程、常规本地 env 与生产容器未配置 LIVE_SMOKE 凭据键。这不证明仓库外凭据不存在,也未尝试密码、重置账号或复制生产身份。获准的此前真实样票只做过 provider 检查,不能直接占用为合成报销材料或绕过真实票据查重。
- 本次 loginAttempts=0、businessMutationCount=0、workflowSubmitCount=0,无新建单据/票据/会话需清理;没有尝试完整公网闭环,不能记 PASS。已部署健康检查结论不受此影响。
- 建议调整验收边界:公网用获准专用凭据及腾讯可识别的测试样票验到可编辑草稿,不提交进入真人待办;提交审批继续沿已通过的隔离数据库/真实认证/队列/浏览器三段审批证据。若要求公网全链独立通过,先另审仅测试数据的审批隔离方案和财务启停窗口,不在本轮临时改生产规则。
### e5685f1 已部署与后置检查补齐(2026-09-09)
- 生产实际运行 `e5685f18b233901cffc9a12c9c277cc5c642725c`。原 deploy-existing 调用最终 exit=255,日志仅回传到 build-init,不能改写为原脚本 exit=0;255 原因尚未定位,不凭退出码断言产品失败或发布完全没发生。
- 中断后只读核实已完成构建、切换与迁移,未盲目重发整次部署或回滚。运行源码摘要与候选一致;init 日志顺序为 validate_config → migrate → check_required_configuration,INIT_PASS/existing,无 seed 阶段。
- 单独补跑生产身份/迁移后置预检 PASS,pending=none;数据库只读校验费用类型列 nullable,金额/日期仍 NOT NULL,本迁移成功记录一条、当时 null 分类明细为 0。该计数会随用户操作变化,不构成以后随时切旧镜像安全的保证。
- 单独执行既有 external-deps smoke 与 runtime smoke 均 exit=0;公网 ready/home/主脚本 HTTP 200,buildSha=e5685f18b233;既有公网 bundle-copy 扫描 106 项、focused=2、buildMarker PASS、findings=0。
- 受控身份 probe/refresh 均 PASS,最终回读 backupContractBuildMatches=true。本次属于应用已部署后补齐后置检查,不把原 exit=255 回执覆盖成成功。未新增产品修复、未执行数据库恢复。
- 发布前正式备份完成于 15:33:41 UTC,属于 b87cc55,manifest/数据库/附件大小与摘要匹配;旧 b87cc55 镜像保存为独立文件,14 层摘要通过,未演练 load/恢复。刷新备份合同不等于已产出 e5685f1 新版本备份;旧备份及回滚制品保留。发布后可用空间 43.55 GiB,无追加清理。
- 公网 Chromium 打开站点后进入登录页,登录内容可见;未登录业务账号、未创建真实或合成报销。两条控制台资源错误均为 favicon.ico 404,本任务未改图标,记录为非阻断观察,不擅自扩修。首次 CLI 默认 Chrome 缺失,改用已安装 Chromium 后通过;首次 /ready 检查误读顶层 buildSha,按既有 data 包装修正检查后通过,均非产品修复。
- 证据入口仍为 `artifacts/qa-flow/20260909-release-e5685f1`:原 deployment-result.json、备份与独立制品回执、recovery-smoke.json、post-preflight-result.json、final-postcheck-result.json、public-check.json、浏览器快照。原日志受控留存,不输出原始环境或票据。
- 当前结论:已部署、发布健康及结构检查完成;不是公网带账号的报销完整业务验收。下一步由执行端取得专用测试账号及线上合成单据写入/清理的明确授权后,验证上传→识别→选票→分类编辑→提交审批,不让真实员工代测,不以此授权真实付款。退回删除、付款体验两个 task 仍未实施,整个 task 保持 in_progress。
### e5685f1 发布执行计划(2026-09-09,用户明确授权部署)
- 固定已推送候选 `e5685f18b233901cffc9a12c9c277cc5c642725c`;使用干净发布 clone,不将本记录或其他未提交内容同步生产。证据目录 `artifacts/qa-flow/20260909-release-e5685f1`。
- 只读前置已通过:运行版本 b87cc55、最低配置 39/3/1;待迁移仅 `20260909210000_reimbursement_draft_expense_type`;磁盘可用 45.52 GiB。预检 rollbackWindow=OPEN 仅是 terminated 状态统计,不是数据兼容或恢复演练结论。
- 发布前保存当前 b87cc55 独立镜像并核归档层摘要,触发既有正式备份服务,再核同运行版本的 manifest/数据库/附件完整性。失败停止,不绕权限、不清理旧制品。
- 沿 deploy-existing.sh:existing、SYNC_ENV=0,预检待迁移显式匹配,执行本次 DROP NOT NULL,不运行 seed、不重建数据库容器;随后核迁移无 pending、版本、ready、依赖/runtime smoke、公网资源及合同 refresh。
- 此次仍无完整候选门禁通过证据,附件/应用恢复未演练;分层腾讯与本地流程证据不等于公网完整报销验收。用户已授权准备并部署,不记录为完整门禁通过。
- 回退目标为 b87cc55,不是此前 f223bfb。迁移后若未生成 null 分类,旧应用兼容仍需核验;若存在 null,不自动切旧镜像、不逆迁移、不猜分类回填。失败先确定应用切换和数据库阶段,保全证据并报告;数据库恢复及可能丢失恢复点后数据不自动执行。
- 上线自动化由执行端承担;不处理真实报销、不真实付款。本次未额外授权线上合成单据写入,先做既有发布健康/smoke与只读版本/结构检查,不能以此冒称已走通公网报销全链路。
### 用户复核与提交授权(2026-09-09)
@@ -24,6 +24,38 @@
根因:共享detail-workspace-grid使用比例列,而报销壳另有max-w-7xl,付款壳无同一上限。新增局部共享detail-workspace-grid--payment类供两处使用,lg起固定320px侧栏,主列minmax(0,1fr),保持各自正文宽度和手机规则。frontend-design不可用,仅复用现有表格、边框和按钮样式,不创建新视觉体系。已关联票据采用响应式表格,窄屏按行紧凑排列;未关联票据保留原纠错控件与唯一锚点。姓名和号码允许换行,预览、移除及OCR告警按原capabilities保留。
## 2026-09-11 公网合成验收的账号与路由隔离裁决(待选择,不实施生产修改)
用户批准继续只读准备测试账号最小修复清单,不代表批准解归档、改密、创建CEO账号、调整角色/所属主体/银行卡或全局关闭通知。当前生产保持5d8cdf12。本轮直接归本任务的交付验收前置;根工作区09-07-e2e-auth-preconditions是本地mock/认证启动合同,不把同名“认证前置”误当生产账号维护授权,不新建细碎任务。
### 最新事实与最小处理清单
来源:artifacts/qa-flow/20260911-release-5d8cdf12/synthetic-isolation-readonly.json。一次READ ONLY事务、8条账号元数据;不输出姓名、邮箱、手机号或银行值,不读数据库密码哈希、不解密银行卡、不尝试登录。本地受控凭据文件只用于按真实登录规则(邮箱或手机号)定位;“凭据存在”不证明密码正确。
| 对象 | 实际状态 | 最小处理结论(尚未授权写入) |
| --- | --- | --- |
| 配置中的员工smoke | 活动、无需改密;经理为配置中的经理smoke;无主体/银行资料,通知开启且有企微绑定 | 登录无需修复;不能为了跑付款直接绑定真实公司付款资料。现有绑定不能被“smoke”名称推定为安全通知接收端 |
| 配置中的经理smoke | 活动、必须改密、无上级;通知开启、无企微绑定 | 如日后选生产测试,先批准正常改密/凭据更新,不直接清must_change_password绕过流程;密码未核验 |
| 另一经理smoke | 活动、无需改密,但无已确认可用凭据;上级为非smoke | 不是可随手替换的测试经理,不借用或改其上级关系;不自动重置密码 |
| 配置中的财务smoke | status=archived且archived_at非空,不只是“未启用” | 不直接解归档;先确认历史保留目的。隔离验收可使用新合成财务身份,不恢复生产归档账号 |
| 配置中的CEO | 登录规则精确匹配0条;生产CEO角色由非smoke持有 | 不猜人、不用真人、不把经理改成CEO;新测试CEO也不能单独解决路由隔离 |
| 管理员凭据 | 精确匹配非smoke | 排除出合成验收,不使用其通配权限顶替业务角色 |
### 账号修好仍不成立的隔离边界
- workflow role分派保留assigneeRole;notifications/index.js按角色取所有活动账号,没有按测试身份划分。当前ceo/finance均有活动非smoke接收人。仅禁用测试账号通知不能阻止这些真人的站内任务或通知。
- paymentBatches.js:resolvePaymentReviewRecipientIds按工号/id排序,优先选CEO、再经理。按当前只读事实投影将选到非smoke CEO;这不是创建真实批次的实测,也不能通过给测试CEO换排序靠前的工号来规避隔离设计。
- IM_NOTIFIER_ENABLED=true;非smoke CEO/财务的推送开关和企微绑定存在。实际渠道发送未测试,不声称已经通知过真人;当前存在外发风险,不能继续完整公网提交/组批。
- 全部4个smoke缺所属主体、加密收款账号和建行关联。银行路径读取快照会解密,不能靠假定“可以不解密”或选非bank渠道来冒充中文银行制单验收。也不能把测试账号绑定真实付款账户后称其与真实财务隔离。
### 推荐路径与验收边界(需要用户选择)
A(推荐):生产不改账号/角色/归档或通知;保留已经完成的公网员工双端门户和合成草稿验收,完整角色/审批/制单链在与5d8cdf12一致的隔离环境,用专用合成账号、银行夹具和禁外发配置执行,复用已有隔离验证装置,不另造管理系统。隔离通过不能标为完整公网链通过;如这是验收口径调整,必须明确接受,不能由执行端自动降级。优先核现有同树证据是否已满足,输入未变不无目的重跑。生产恢复副本含真实数据时,访问和脱敏另批,不默认复制。
B:坚持全部流程在生产公网做,需要先批准一项有边界的合成业务隔离方案,覆盖角色任务可见性、指定测试复核人、站内通知/外发、付款主体及银行制单隔离和清理,再谈账号修复。这是实质范围变化,不是几行数据回填;当前没有设计实现或测试证据,不承诺“补几个账号就能跑完”。
不建议:全局关通知、解归档财务测试账号、借真人CEO审批、构造工号优先抢单、给smoke加通配权限、直接修改生产审批定义。这些做法会影响真实职责或绕过被验证的业务规则。下一步先选A/B;未选择前不新增生产写入、不部署新代码。
## 2026-09-11 下一步与侧栏一致性方案(已批准本地实施)
本轮只读核对已发布候选,未查询生产。ReimbursementDetailPage 的 approved 分支无条件显示“等待财务组建付款批次”,其主动作只再检查 payment.batch.manage;同一页面 ProcessingProgress 已消费服务端按真实批次状态构造的阶段。修复必须连接这两处投影,不能只把错误文字换成另一句固定文案。
@@ -157,6 +157,53 @@ Trellis治理、process-contract baseline、原因码strict及git diff --check
未提交、未推送、未部署、未做生产写入;制单备注仍在另一独立副本。本轮不归档整个task。下一步按路径汇总本UI增量与独立备注增量的候选复核输入,经明确授权后再分别提交/推送及准备发布,不覆盖原integration任务历史。
## 2026-09-11 专用账号只读盘点与隔离决策(最新,待选择)
本轮只读核清专用账号后,确认不是单纯登录问题:财务smoke已经归档(status及archived_at均确认),CEO凭据精确匹配0条;另有一个经理smoke但其上级是非smoke,不能盲目借用。角色通知会覆盖活动真人CEO/财务,付款复核按现有优先CEO规则投影指向非smoke;通知总开关、相关真人推送开关及企微绑定存在。所有smoke缺主体和收款配置。没有登录尝试、改密/解归档/改角色、解密或业务写入。
最小修复清单与A/B验收路径已写入本任务design的最新节,脱敏回执保存于既有release目录synthetic-isolation-readonly.json。推荐生产账号保持不变,复用同候选隔离环境完成全链,将公网已测范围与隔离结果分开;这属于验收口径选择,待用户确认,不擅自降级。若坚持生产公网全链,必须先设计测试任务/通知/复核/付款数据隔离,而不是先启用账号。既有09-07本地认证夹具任务不承接未经批准的生产账号操作。
当前5d8cdf12已部署、员工公网部分验收通过、合成草稿已清理的事实不变;完整公网付款链仍未验收,任务不归档。下一步等待验收路径选择,不继续反复尝试同一组不适用账号,不让员工代测。
## 2026-09-11 新候选已部署与公网部分验收(已完成阶段)
用户已明确批准5d8cdf12发布例外、部署及有限合成验收/清理,不含真实单据、实际付款或删除回滚制品。使用独立干净main克隆,候选树精确匹配dd2e96e0,无来源override。首次因预检超过15分钟在本地停止、尚未部署;重新只读刷新后通过正式13项聚合门及迁移预检,再以existing模式完成构建/init/应用切换、部署后迁移核验、公网版本/资源检查和备份合同刷新。初始化seed未运行。部署于北京时间09-11 20:58完成,生产与公网短版本5d8cdf12b456一致,68条迁移无pending;数据库未重启。最终磁盘33.6%/39.10GiB可用,原fe025e65独立镜像制品仍在且摘要匹配,未清理镜像/备份。
公网部分验收实际通过:唯一安全普通员工smoke账号真实浏览器登录一次,PC与手机均实际请求门户且不展示财务卡;创建一张本次标识的空合成草稿,双端在零明细时可打开“我的发票”。未上传发票、未调用腾讯OCR、未提交/审批/组批/付款;合成草稿已删除,HTTP404及另一次数据库只读回读确认记录为0且删除审计保留。编号消费和审计不回滚。浏览器与上下文均关闭,无待清理业务对象。
完整付款链未验收:配置中的管理员不是smoke,未使用;经理smoke必须改密,财务smoke非活动,CEO测试凭据未匹配唯一账号,员工smoke缺主体。这是测试身份前置缺口,不推断真实员工账号故障。未尝试这些账号登录,未绕过密码或角色校验、未启用账号/重置密码/修改主体,未使用真人兜底。下一步沿既有认证前置任务只读明确专用测试身份修复清单,生产账号变更另批后再跑完整链;当前不宣布全员验收完成,不让员工代测。
回执见artifacts/qa-flow/20260911-release-5d8cdf12:deployment-receipt.json、postcheck.json、employee-acceptance.json、synthetic-role-preconditions.json、cleanup-readback.json。此前预检和交审快照保留,不把新部署状态写回冻结manifest。完整门禁、正式附件/应用恢复等例外继续保留;本轮没有触发新备份,合同已更新不等于已有新版本恢复点。状态补记留在候选之外,未新增提交/推送。
## 2026-09-11 新候选生产只读预检(发布前历史)
已按用户确认执行下一步,只读连接生产,未部署/清理/写业务数据。2026-09-11 20:36 北京时间回读:生产 fe025e65,检查期间运行身份和环境摘要一致;候选与生产 68 条迁移全部一致,无 pending/未知/异常/checksum 差异,查询使用 READ ONLY 事务。数据库、附件、回滚目录所在文件系统使用率 32.1%,可用 40.03GiB。
最新同源本地备份于北京时间 09-11 02:30:49 完成,观测时18.09小时;manifest及DB/附件包尺寸摘要匹配。当前生产独立镜像制品1,119,357,440字节、尺寸摘要匹配,仍同机;没有执行恢复或docker load。独立worker profile未创建,主server配置JOBS_ENABLED=true/OCR_PROVIDER=tencent,不据此宣称腾讯调用成功。
证据与审批材料:artifacts/qa-flow/20260911-preflight-5d8cdf12/readonly-receipt.json、release-request.md。复用已审只读探针,迁移输入来自候选Git对象,不运行旧候选入口、不覆盖旧证据。未重跑本地测试,未修改冻结候选或追加提交。
下一步必须单独批准绑定5d8cdf12的发布例外、部署及有限合成验收写入范围。完整候选门禁、正式附件/应用恢复、真实OCR/公网角色链与构建峰值未因此通过;部署时还须新鲜核验并执行正式门禁,不直接从脏工作副本部署。只操作获准合成对象、保留审计,不实际付款、不发送外部通知、不删回滚制品、不让员工代测。
## 2026-09-11 独立复核接收与预检准备(历史时点,未部署)
用户回传新候选 5d8cdf12/树 dd2e96e0 的独立只读复核:放行、无阻断。覆盖输入/拆分、双端身份 key/enabled、signal 到 fetch 及 401 重放;未审按钮/窄屏/附件定位具体内容与测试断言,未运行测试、未复现浏览器、未验证生产或服务端。接收外部结论,不扩写为全量独立验收或已证实生产泄露。
F1 已更正交接 README 的未提交/未推送过期描述,并区分当前状态与 commit-plan/manifest 历史快照;F2 复用输入未变测试、不新增计数的措辞保留。独立结论存入 postpush-cancellation-commit-preparation/independent-review.json,原冻结包及历史 NO_GO 不变。两任务元数据同步最新 commit/状态,本节及元数据是候选外未提交补记,不新增代码提交。
下一步准备绑定 5d8cdf12 的只读预检,按下方既有发布验收清单核生产版本/镜像、迁移 checksum、磁盘峰值余量、最新同源备份完整性与独立回滚制品。旧 run-precheck.mjs 固定先前 push-receipt/输出目录且要求整个工作副本干净,不能直接重跑、覆盖旧证据或清理脏文件;执行时从冻结候选提取输入,另存新回执,复用已审只读探针。权限不足停在边界,不绕权限。
本轮仅更正文档和准备预检,未连接生产;所有历史磁盘数字均不能作当前容量。此次有限范围复核不解除完整门禁、附件/应用级恢复及公网验收缺口;部署例外必须重新绑定新候选获批。原已批准的提交推送已经完成,不再重复索取;部署、真实数据及公网合成写入仍不在该授权中。
## 2026-09-11 补充修订提交推送回执(历史时点,候选外补记)
用户明确批准两笔提交并推送,仅供独立复核,暂不部署。详情修正 9e41f107(9 文件)与门户修正 5d8cdf12(10 文件,共享规约按内容拆分)已按顺序提交;最终候选 5d8cdf12b45685b2bd5d8a36a0cea376cac366f3,树 dd2e96e0506885640eb462499e230926800cd832,与 postpush-cancellation 冻结树完全一致。远端 main 和本地 origin/main 回读一致,待推送 0;7 个恢复/付款准备脏文件未纳入、未改动。
本轮只做输入摘要核对、提交和推送,未重跑未变测试,复用联合 66/66 页面、构建与真实隔离链结果及按输入核对的 135 单测。原 manifest、NO_GO 与历史证据不改写。提交准备目录 postpush-cancellation-commit-preparation 保存计划、两笔补丁、commit-receipt.json 和 push-receipt.json;本节是候选之外的未提交状态补记,不另建任务或追加第三笔提交。
独立复核仍 PENDING_INLINE,不能把本轮提交或主会话验证当作独立通过。下一步将新候选交独立只读复核;通过后刷新执行时生产预检,再按候选专属批准部署并由执行端完成公网合成验收。本轮未连接生产、未部署、未让员工代测;不沿用历史生产观测冒充当前现状。
## 2026-09-11 迟到 401 复核接续(最新,门户取消修正本地通过)
主会话只读核对 dcde0d44 的 33 源文件、3 补丁重放及历史证据后,双端合成浏览器补查甲→乙→甲:甲旧请求迟到 401 后按乙会话重试,结果进入甲缓存,甲再次登录等待新响应时显示乙待办。该包 NO_GO;独立复核仍 PENDING_INLINE,原 6/62/真实隔离通过记录不改写。回执在 postpush-identity/readonly-review.md。
@@ -124,3 +124,10 @@ POST create
- 无 migration/schema/seed/flag/routing。生产资料补录不属于部署步骤。
- 建议按“原因码/parity、首批迁移、付款 readiness/UI”形成逻辑提交;付款提交可独立回滚且无数据库补偿。
- 部署另行批准;公网只用合成 fixture 验证。不得自动创建、复核或付款 0014。
## 8. 到期清单的后续分流合同(2026-09-09)
按已有 scanner 输出的 file/operation/fingerprint/count 与源文件摘要建立逐条台账,文件表仅作索引。未知使用状况记为待复核,不推导无需维护或默认低频;未证明删除/迁移成功的记录不得核销。保留原 expiresOn 与 owner,不把新 reviewDue 当作门禁新期限;拟延期日期和批准记录必须独立且逐模块说明。
共用 validation builder 的一个指纹可能影响多个业务分支,迁移必须在调用语义层选择原因;不能批量将所有旧错误映射成一个“通用参数错误”或只更新计数。每个获批迁移分支先定位入口与旧 HTTP status/code/details,再增加精确 reasonCode/中文及失败副作用断言。当前只完成清单,不新增迁移范围或任何线上行为。
@@ -243,6 +243,142 @@ R1包及其manifest不变;本轮代码已偏离R1,必须重冻R2后交增量
- 下一项统一待办需求仅以该真实流程的三个交接观察为输入:交给财务组批、交给经理/CEO 复核、交回财务登记付款;每处记录谁交给谁、接收人通过什么现有入口或提醒知道轮到自己、是否需要口头催办。尚未发生的交接不预填结论,不记录真实银行资料。
- 独立待办仍保留:财务测试账号 403 需要单独解决并补财务身份真实验收(管理员代验不等于该角色验收);合同只读超时需单独复现归因,不计入通过;“三张单的答复”仅作为用户提醒保留,未明确具体单据和答复内容,不自行推断或代答。
- Trellis 升级另行审查:逐条核对 workflow.md 与 project-governance.md 删除或弱化的规则及理由,独立检查 hooks 行为变化;不以模型升级为整批删除保障的理由。本次仅记录后续事项,不启动新产品任务、不修改配置或真实资料、不自动提交、部署或归档。
## 13. 2026-09-09 到期豁免后续阶段:清单落地(本地阶段已批准)
用户在综合任务规划后回复“开始实施”。本阶段复用原 task,仅在独立准备 worktree 落地豁免台账和恢复准备;不修改原因码源码、线上配置、基线日期或门禁逻辑,不与 AP/付款产品 diff 混合。责任人沿用原基线 owner,不擅自重新指派;主会话负责技术分流与后续迁移,延期须用户逐模块裁决。
### 已完成和未完成
- 已通过实际 AST inventory 按 file + operation + fingerprint 对照 673 条基线、695 次调用、73 文件;每条 observedCount 与 count 一致,0 漂移。baseline SHA-256:`ddeeaadfcc8ac267b23159c5803cd6b21f282329ecbd8847a2f79551198f441f`。
- 原因码合同 PASS,20 项 self-test PASS;原 2026-10-05 日期全部保留,主链路零豁免规则不变。所有条目当前仍在源码,没有证据支持本轮直接核销;不把“没有文件漂移”当成每个错误文案已合格。
- 文件级初分:A:16 文件 / 179 指纹 / 192 次调用;B:25 文件 / 277 指纹 / 280 次调用;C:32 文件 / 217 指纹 / 223 次调用。A 是优先审查与选取迁移,B 是需确认使用/影响,C 是逐模块审查拟延期;三者都不是已批准延期。清单覆盖所有记录,但尚未逐条完成业务语义复核,不冒充 673 条都已裁决。
- 每条指纹在 `artifacts/qa-flow/project-roadmap-execution-20260909/error-disposition.json` 保留原 owner、reason、operation、count、到期日、sourceSha256,以及 lane/reviewDue/decision;proposedExpiresOn 全为空、deferralApproved 全为 false。该路径相对于原主工作区,不是这个隔离工作树内的文件。
- 已核对首批小范围候选:AP 开关关闭及台账查询参数校验、todo 开关关闭、portal 开关关闭(4 个具体 legacy 调用);它们只作迁移设计候选,不改权限及状态规则,不宣称已迁移。用户资料/审批等高频分支按同一表继续细分,不能被这 4 条代替。
- 特别限制:`paymentAccounts.js` 的唯一登记是 `function:validationError` 共享 builder,覆盖多个实际调用原因。不能因“只有 1 条”就在 builder 里硬塞同一个固定 reasonCode;需先区分各调用的业务含义。指纹数不是工作量或用户错误数。
### 日期和延期裁决
09-11 前逐模块确认本期分支名单;09-18 验证首批迁移;09-25 复审容量;09-30 前逐模块确定是否延期及各自新日期;10-02 查剩余到期项。门禁按 UTC 日期,10-05 00:00 UTC(北京时间 08:00)即判当天到期,不到午夜再处理。不能因为完成这份台账就把日期延长;每份延期需写业务影响、现有兜底、未迁移原因、负责人和新复审日期并获批,不能整包统一延期。
### 全量文件处置入口
A=优先审查/选迁移;B=业务影响复核;C=延期理由逐模块交审(并非已延期)。所有行原到期日均为 2026-10-05,裁决均未完成;下面数量是指纹条数/实际调用数。
| 文件 | 指纹 / 调用 | 分流 | 原 owner | 首次复核 |
| --- | --- | --- | --- | --- |
| `server/src/plugins/auth.js` | 1 / 1 | A | shunli | 09-11 |
| `server/src/routes/ai.js` | 1 / 1 | C | shunli | 09-11 |
| `server/src/routes/announcements.js` | 9 / 9 | C | shunli | 09-11 |
| `server/src/routes/apOperations.js` | 2 / 2 | A | shunli | 09-11 |
| `server/src/routes/approvalRules.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/routes/assetMovements.js` | 11 / 11 | C | shunli | 09-11 |
| `server/src/routes/assets.js` | 28 / 29 | C | shunli | 09-11 |
| `server/src/routes/attendance.js` | 10 / 10 | C | shunli | 09-11 |
| `server/src/routes/audit.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/auth.js` | 15 / 15 | A | shunli | 09-11 |
| `server/src/routes/budgetControlRules.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/routes/budgets.js` | 13 / 14 | B | shunli | 09-11 |
| `server/src/routes/confidentialDocRefs.js` | 4 / 4 | C | shunli | 09-11 |
| `server/src/routes/configRead.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/contractsRegistry.js` | 10 / 10 | B | shunli | 09-11 |
| `server/src/routes/cutover.js` | 4 / 4 | C | shunli | 09-11 |
| `server/src/routes/dashboard.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/delegations.js` | 17 / 17 | C | shunli | 09-11 |
| `server/src/routes/departments.js` | 14 / 14 | B | shunli | 09-11 |
| `server/src/routes/employees.js` | 25 / 31 | A | shunli | 09-11 |
| `server/src/routes/expenseStandards.js` | 11 / 11 | B | shunli | 09-11 |
| `server/src/routes/expenseTypes.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/routes/exports.js` | 9 / 9 | B | shunli | 09-11 |
| `server/src/routes/featureFlags.js` | 8 / 8 | C | shunli | 09-11 |
| `server/src/routes/feeControl.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/integrations.js` | 22 / 22 | C | shunli | 09-11 |
| `server/src/routes/inventoryChecks.js` | 11 / 14 | C | shunli | 09-11 |
| `server/src/routes/invoicePool.js` | 29 / 30 | A | shunli | 09-11 |
| `server/src/routes/invoicePool/read.js` | 7 / 7 | A | shunli | 09-11 |
| `server/src/routes/invoicePool/shared/schemas.js` | 1 / 1 | A | shunli | 09-11 |
| `server/src/routes/invoicePool/verification.js` | 7 / 7 | A | shunli | 09-11 |
| `server/src/routes/leave-types.js` | 6 / 6 | C | shunli | 09-11 |
| `server/src/routes/masterData.js` | 25 / 25 | B | shunli | 09-11 |
| `server/src/routes/masterDataHolidayCalendars.js` | 15 / 15 | B | shunli | 09-11 |
| `server/src/routes/masterDataSuppliers.js` | 11 / 11 | B | shunli | 09-11 |
| `server/src/routes/me.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/migrationRuns.js` | 5 / 5 | C | shunli | 09-11 |
| `server/src/routes/notifications.js` | 7 / 7 | A | shunli | 09-11 |
| `server/src/routes/paymentAccounts.js` | 1 / 1 | A | shunli | 09-11 |
| `server/src/routes/payroll.js` | 17 / 18 | C | shunli | 09-11 |
| `server/src/routes/performance.js` | 12 / 12 | C | shunli | 09-11 |
| `server/src/routes/portal.js` | 2 / 2 | A | shunli | 09-11 |
| `server/src/routes/presence.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/routes/projects.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/routes/purchaseRequests.js` | 50 / 52 | B | shunli | 09-11 |
| `server/src/routes/reimbursementTemplates.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/routes/riskFlags.js` | 5 / 5 | C | shunli | 09-11 |
| `server/src/routes/search.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/routes/systemWorkspace.js` | 2 / 2 | C | shunli | 09-11 |
| `server/src/routes/todos.js` | 5 / 5 | A | shunli | 09-11 |
| `server/src/routes/travelAuthorizations.js` | 5 / 5 | B | shunli | 09-11 |
| `server/src/routes/travelOrders.js` | 9 / 9 | B | shunli | 09-11 |
| `server/src/routes/travelReconciliation.js` | 12 / 12 | B | shunli | 09-11 |
| `server/src/routes/travelRequests.js` | 21 / 21 | B | shunli | 09-11 |
| `server/src/routes/travelTransactions.js` | 7 / 7 | B | shunli | 09-11 |
| `server/src/routes/users.js` | 35 / 40 | A | shunli | 09-11 |
| `server/src/routes/wecomAuth.js` | 7 / 8 | A | shunli | 09-11 |
| `server/src/routes/weeklyReports.js` | 7 / 7 | C | shunli | 09-11 |
| `server/src/routes/workflow.js` | 20 / 20 | A | shunli | 09-11 |
| `server/src/routes/workflowDefinitions.js` | 11 / 11 | B | shunli | 09-11 |
| `server/src/services/ai/suggestions.js` | 1 / 1 | C | shunli | 09-11 |
| `server/src/services/attendance.js` | 8 / 9 | C | shunli | 09-11 |
| `server/src/services/budgetPool.js` | 7 / 7 | B | shunli | 09-11 |
| `server/src/services/contractRegistryFilters.js` | 4 / 4 | B | shunli | 09-11 |
| `server/src/services/cutover.js` | 1 / 1 | C | shunli | 09-11 |
| `server/src/services/documentSequence.js` | 5 / 5 | B | shunli | 09-11 |
| `server/src/services/employeeDirectoryFilters.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/services/feeControl.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/services/presenceHistory.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/services/purchaseBudget.js` | 3 / 3 | C | shunli | 09-11 |
| `server/src/services/travelPayments.js` | 2 / 2 | B | shunli | 09-11 |
| `server/src/services/travelReconciliation.js` | 6 / 6 | B | shunli | 09-11 |
| `server/src/utils/workflow.js` | 15 / 15 | A | shunli | 09-11 |
### 四项状态
| 代码 | 发布 | 业务验收 | 等谁/下一步 |
| --- | --- | --- | --- |
| 原功能已交付;本阶段只有台账,没有新产品改动 | 本轮未发布 | 台账核对通过,不等于真人错误处理验收 | 先等待 T0 两笔收口的提交授权;分支细分不需生产访问;延期名单交用户裁决 |
## 14. 2026-09-09 首批具体分支与验证要求
用户采纳“推进最小恢复授权,同时完成错误豁免分支清单”的建议。本轮只细化清单,不将该回复扩大为ARM真实恢复、延期审批或产品发布授权。主仓已是b918530;73文件的源码摘要与原清单仍全部一致,清单没有因两笔提交失效。准备worktree仍基于58dcee0,未来实际写代码前须迁移到当时最新已提交基线,不能在旧基线上实施后覆盖已提交的CEO修订。
### 第一批四个明确调用
下面均为已有legacy调用,原到期日2026-10-05不变,reasonCode/文案为具体迁移方案,尚未修改源码或注册表。不将“功能开关关闭”改成“无权限”,不调整守卫顺序,也不自动开启开关。
| 文件 / operation | 指纹短标识 | HTTP保持 | 拟原因码 | 拟用户文案 |
| --- | --- | --- | --- | --- |
| `server/src/routes/apOperations.js` / `function:ensureFeatureEnabled` | `48951ae2ad49` | 409 | `ap_operations.feature_disabled` | 应付账款暂未开放,请联系管理员确认处理方式。 |
| `server/src/routes/apOperations.js` / `/ap-operations/reimbursement-ledger` | `4673e0a3f7e9` | 400 | `ap_operations.query_invalid` | 查询条件不符合要求,请检查筛选条件后重试。 |
| `server/src/routes/todos.js` / `function:ensureFeatureEnabled` | `309a572d3996` | 409 | `todo.feature_disabled` | 待办功能暂未开放,请联系管理员确认处理方式。 |
| `server/src/routes/portal.js` / `function:ensureFeatureEnabled` | `de0048472baa` | 409 | `portal.feature_disabled` | 工作台暂未开放,请联系管理员确认处理方式。 |
### 每个分支的结束判据
- AP关闭:两个GET以及带筛选查询均保持409和原VALID_001/featureFlag/reason,增加精确reasonCode;业务财务查询次数为0。开启时继续验证CEO/manager无权403、finance等合法身份可读,原权限矩阵不退步。
- AP查询非法:开启功能且有读取权限时无效查询保持400、保留原校验details,增加精确reasonCode,台账业务查询为0;合法查询200,无权身份不因参数非法绕过或改变原403守卫。
- todo关闭:覆盖所有消费同一guard的入口,不只GET;409、旧details和新增原因码一致,业务读写均不发生;开关开启原合法路径正常。必须补对应路由注入覆盖,本次未发现已有按todos命名的专门路由测试,不能拿portal测试代替。
- portal关闭:沿已有portal路由测试补精确原因码和业务查询零调用断言;开启后原首页查询不退步,不新增通知或待办业务行为。
- 前端三个页面已消费统一resolveErrorMessage,仍需用实际ApiError路径断言四句中文,而不只检查注册表有四个字符串;未知原因保留安全兜底,不把details或内部开关名展示给员工。
- AP现有权限测试的自定义error handler只返回code,不能用它证明details.reasonCode;需使用生产等价响应处理或另建原因码测试,保留原权限断言,不为了绿改成宽泛message匹配。
- 注册表、客户端映射、中文fixture与真实分支测试必须同步。只移除这四个精确file/operation/fingerprint记录,不按文件删除基线,不改其余expiry。若仅本批四次调用迁移完成且无其他并发变更,预期残余669条记录/691次调用;这个数是未来验收预期,不是当前成果。
### 尚待细分的部分
第一批只解决四个具体分支,不等于73文件都已形成迁移决定。员工资料、登录、审批解析、票据等优先域继续按真实业务影响细分;paymentAccounts共享validationError需先追到实际调用语义,不能套一个固定原因码完成所谓“1条迁移”。余下记录仍须在既定日期逐模块确认迁移或提出有理由延期;本轮未批准任何延期。
完整四分支记录见原主工作区artifacts/qa-flow/project-roadmap-execution-20260909/error-first-batch-branches.json;原始673条台账不覆盖,保留当前与未来验收预期的区别。
# 2026-09-16 上线后契约补强
后续日期批次方案:共享date工具新增纯isValidDateOnlyString谓词(严格YYYY-MM-DD、有限UTC日期、回读同日),保持旧parseDateOnlyString行为以免无关服务突然抛500;先接报销/付款/差旅申请/资产四路由的既有Zod日期schema,optional/nullable外层语义不变,失败沿原输入错误合同且写入前拒绝。催办复用前端displayFormat的Asia/Shanghai格式并明确“北京时间”,旧details分支也校验UTC形状/有限性,不回显任意字符串。验证单测正反边界、各域实际入口/解析器、无副作用及前端typecheck/build;采购、合同、考勤等剩余消费者继续单列,不冒称所有日期解析债务清零。不迁移或改生产历史日期,不提交/部署本轮未审代码。
@@ -1,5 +1,11 @@
# 错误可解释性与付款就绪治理
## 2026-09-09 追加阶段
用户已批准综合任务安排的本地实施。复用本 task 管理 10-05 到期豁免分流,不改变原功能验收。当前交付是 73 文件/673 指纹全量核对与分流台账(implement.md §13);未迁移原因码、未修改基线日期,不把 file 级分类冒充逐调用业务裁决。新分支迁移沿原 status/code/details 兼容与精确测试合同;须先完成既有两笔隔离提交,不能在原脏树叠第三笔产品代码。延期、提交、推送、部署各守明确授权。
## Goal
把“系统知道为什么不能继续、真人只看到参数校验失败”的缺陷从逐页补文案改成可持续的错误合同,并以付款批次为第一个完整样板:财务在点击前就知道付款资料是否齐全、缺什么、由谁补;点击后的服务端二次校验与页面提示必须来自同一份实时判断。
@@ -195,3 +195,7 @@ AP task 保留原实施写入面和已通过用户复核。提交/推送后冻
- 保留敏感文件确认、重下载警告、取消零请求与 pending 防重复点击。下载次数更新后主动作仍切换上传回单,不表示付款完成。
- 右侧操作卡与进度卡相邻;移动端保留底栏快捷动作且正文操作/进度可达。操作卡不独立 sticky,避免滚动覆盖紧随其后的进度。
- 验证:路由与 BIFF8 单测、mock 桌面/移动端真实下载、隔离 PostgreSQL/真实认证 HTTP 创建复核下载,再与退回删除做同候选验证;禁止真实网银付款和伪造回单。
# 2026-09-11 两人所属主体修正
沿既有单字段受控修正方式,固定已确认财务与 yj,预检保存两人/角色/经理/唯一主体摘要。执行时 READ WRITE Serializable 事务锁定目标行与主体,并核对已审 employees UPDATE 触发器/规则;只对原值为 NULL 的两个 id 更新 legal_entity_id,恰好两行,否则整体回滚。原值非空不得覆盖;提交结果不明先只读核验,禁止盲重试。提交后新连接 READ ONLY 验证两人的字段、身份及角色/经理未漂移。回退该字段需重新核验业务使用与单独授权,不自动补偿已提交写入。
@@ -552,6 +552,26 @@ A1本地修复与402/34验证仍成立,新增范围闸待独立内容复核。
主会话检查确认运行时只改备注拼接,不动权限、状态、审批、编号或数据迁移;本轮不是独立复核。现有银行模板没有长度上限说明,网银实际导入及长备注接受性未验证。仅本地完成,未连接生产、未导出真实制单、未提交/推送/部署。下一步将本增量纳入候选复核与提交准备;提交/推送和部署须明确授权,不能直接覆盖原integration任务记录或将原有冻结候选视为包含本改动。
## 2026-09-11 已授权两人所属主体修正(已完成,未部署)
用户明确批准仅财务 wangzhiling 与 yj 两人;按已确认登录标识核对,不扩管理员或 smoke。只把两人的 legal_entity_id 从 NULL 填为执行时唯一启用且未归档主体;两人须在职启用、角色与前次确认一致、直接经理仍为已确认 CEO。禁止读取银行明文或密码,不修改角色、经理、银行资料、单据或付款账户。
复用既有单字段修正合同,先 READ ONLY 预检并冻结两人/主体/经理/角色的摘要;事务中重核 employees 触发器和规则的已审指纹,锁定目标行与主体、条件 UPDATE 恰好两行且失败整体回滚;提交后使用新连接 READ ONLY 回读。状态不符、原值非空、唯一主体不成立或提交状态不明均停止,不自动重试或擅自补偿。执行脚本先作本地语法及合成正反例验证;本轮不提交/部署。
10:50(Asia/Shanghai)READ ONLY 预检通过:两人均在职启用、财务/员工角色集合与既有确认一致、经理仍为 CEO,两个 legal_entity_id 均 NULL,目标唯一启用主体与 CEO 已绑定主体一致。10:51 条件原子更新恰好两行,事务内复核、提交后新连接只读回读通过;10:52 又经独立 SSH 只读复核,身份摘要保持一致。未改管理员/CEO/smoke、其他字段、角色或单据,不创建付款账户。
证据:联合副本 artifacts/qa-flow/20260911-authorized-preparation/ 下 entity-precheck.json、entity-apply.json、entity-readback.json;PASS_APPLIED_AND_READBACK / PASS_READONLY_READBACK。本地 node --check 及 entity-correction-selftest.cjs 13 项合成检查通过;最初旧触发器 fixture 的相对路径定位错误仅发生在本地自测,修正后通过再开始生产字段写入。既有触发器只防员工号变更,指纹与原已审值一致;没有改员工号或绕过触发器。
主数据缺项已补,不提前宣称两人已能真实付款:银行解密、实际提交及业务审批未在本轮执行。今日备份早于本次修正,恢复影响另审;不自动触发备份、回退字段或部署。当前镜像独立制品固定见 09-04 最新回执。
## 2026-09-11 已授权业务就绪只读核验(未回填、未部署)
09-04/09-11 两笔改动已推送,候选 fedcaed1;生产仍 fe025e65。原已确认四人只读盘点排除 smoke:财务与 yj 的直接经理均为 CEO 且启用;CEO 无 AP 全量权限但保留审批/付款复核,财务不能自审,管理员通配不被当成 CEO 职责。四人的门户/付款部门 gate 均开启,39 个费用类型、3 条规则及 1 个报销活动工作流存在。
当前唯一启用主体和 1 个有效建行付款账户。CEO 的主体、收款资料存在性及主体下付款账户密文存在性齐;财务/yj/管理员的所属主体仍空,不能说他们自己的报销已经能组批。管理员还无直接经理、未关联有效建行机构;是否本人报销决定其修正范围。不要把缺主体说成“财务不能替别人付款”,两者是不同资格。
本轮不读银行明文、不解密、不实际登录/提交或做完整审批人解析,不宣称已证明真人被阻断。财务/yj 的主体回填可单独申请,只改空字段且执行前后回读;管理员是否包含另定,不改 smoke,不重复建付款账户,不顺手改银行资料。证据位于联合副本 artifacts/qa-flow/20260911-readonly/employee-readiness.json 与 gates-transfer-final.json;提交/生产/备份详情共用 09-04 最新回执。部署、真实付款和消息发送均未执行。
## 2026-09-11 业务就绪只读检查准备(未执行生产查询)
复用已确认身份和经理/主体回填回执,不再猜邮箱或索取工号。排除 smoke 账号,分别核对能登录、能提交、能审批/复核、能组批/登记,不能合并成一个笼统 ready。
@@ -132,3 +132,7 @@
## 执行边界
本次技术审查沿用既有“付款复核通过后,财务主动点击下载银行制单,再由授权银行操作人导入网银”的方式;不新增自动下载或自动付款。不重复索取本地技术审查/修复授权;各项生产写入、真实账号解密、导出、付款和发布仍分别获批。
# 2026-09-11 窄范围授权追加
仅为已确认财务 wangzhiling 与 yj 修正所属主体,原值必须为 NULL、目标必须为唯一启用未归档主体;不读单据或银行明文,不改其他字段、其他员工或账户。验收为预检身份和原值匹配、恰好两行原子更新、独立连接回读一致。该授权不包含管理员/smoke、角色变更、部署或实际付款;历史 0014 单人修正限制不扩大到其他人。
@@ -1,5 +1,52 @@
# 执行清单
## 2026-09-11 专用账号只读盘点与隔离决策(最新,待选择)
本轮只读核清专用账号后,确认不是单纯登录问题:财务smoke已经归档(status及archived_at均确认),CEO凭据精确匹配0条;另有一个经理smoke但其上级是非smoke,不能盲目借用。角色通知会覆盖活动真人CEO/财务,付款复核按现有优先CEO规则投影指向非smoke;通知总开关、相关真人推送开关及企微绑定存在。所有smoke缺主体和收款配置。没有登录尝试、改密/解归档/改角色、解密或业务写入。
最小修复清单与A/B验收路径已写入本任务design的最新节,脱敏回执保存于既有release目录synthetic-isolation-readonly.json。推荐生产账号保持不变,复用同候选隔离环境完成全链,将公网已测范围与隔离结果分开;这属于验收口径选择,待用户确认,不擅自降级。若坚持生产公网全链,必须先设计测试任务/通知/复核/付款数据隔离,而不是先启用账号。既有09-07本地认证夹具任务不承接未经批准的生产账号操作。
当前5d8cdf12已部署、员工公网部分验收通过、合成草稿已清理的事实不变;完整公网付款链仍未验收,任务不归档。下一步等待验收路径选择,不继续反复尝试同一组不适用账号,不让员工代测。
## 2026-09-11 新候选已部署与公网部分验收(已完成阶段)
用户已明确批准5d8cdf12发布例外、部署及有限合成验收/清理,不含真实单据、实际付款或删除回滚制品。使用独立干净main克隆,候选树精确匹配dd2e96e0,无来源override。首次因预检超过15分钟在本地停止、尚未部署;重新只读刷新后通过正式13项聚合门及迁移预检,再以existing模式完成构建/init/应用切换、部署后迁移核验、公网版本/资源检查和备份合同刷新。初始化seed未运行。部署于北京时间09-11 20:58完成,生产与公网短版本5d8cdf12b456一致,68条迁移无pending;数据库未重启。最终磁盘33.6%/39.10GiB可用,原fe025e65独立镜像制品仍在且摘要匹配,未清理镜像/备份。
公网部分验收实际通过:唯一安全普通员工smoke账号真实浏览器登录一次,PC与手机均实际请求门户且不展示财务卡;创建一张本次标识的空合成草稿,双端在零明细时可打开“我的发票”。未上传发票、未调用腾讯OCR、未提交/审批/组批/付款;合成草稿已删除,HTTP404及另一次数据库只读回读确认记录为0且删除审计保留。编号消费和审计不回滚。浏览器与上下文均关闭,无待清理业务对象。
完整付款链未验收:配置中的管理员不是smoke,未使用;经理smoke必须改密,财务smoke非活动,CEO测试凭据未匹配唯一账号,员工smoke缺主体。这是测试身份前置缺口,不推断真实员工账号故障。未尝试这些账号登录,未绕过密码或角色校验、未启用账号/重置密码/修改主体,未使用真人兜底。下一步沿既有认证前置任务只读明确专用测试身份修复清单,生产账号变更另批后再跑完整链;当前不宣布全员验收完成,不让员工代测。
回执见artifacts/qa-flow/20260911-release-5d8cdf12:deployment-receipt.json、postcheck.json、employee-acceptance.json、synthetic-role-preconditions.json、cleanup-readback.json。此前预检和交审快照保留,不把新部署状态写回冻结manifest。完整门禁、正式附件/应用恢复等例外继续保留;本轮没有触发新备份,合同已更新不等于已有新版本恢复点。状态补记留在候选之外,未新增提交/推送。
## 2026-09-11 新候选生产只读预检(发布前历史)
已按用户确认执行下一步,只读连接生产,未部署/清理/写业务数据。2026-09-11 20:36 北京时间回读:生产 fe025e65,检查期间运行身份和环境摘要一致;候选与生产 68 条迁移全部一致,无 pending/未知/异常/checksum 差异,查询使用 READ ONLY 事务。数据库、附件、回滚目录所在文件系统使用率 32.1%,可用 40.03GiB。
最新同源本地备份于北京时间 09-11 02:30:49 完成,观测时18.09小时;manifest及DB/附件包尺寸摘要匹配。当前生产独立镜像制品1,119,357,440字节、尺寸摘要匹配,仍同机;没有执行恢复或docker load。独立worker profile未创建,主server配置JOBS_ENABLED=true/OCR_PROVIDER=tencent,不据此宣称腾讯调用成功。
证据与审批材料:artifacts/qa-flow/20260911-preflight-5d8cdf12/readonly-receipt.json、release-request.md。复用已审只读探针,迁移输入来自候选Git对象,不运行旧候选入口、不覆盖旧证据。未重跑本地测试,未修改冻结候选或追加提交。
下一步必须单独批准绑定5d8cdf12的发布例外、部署及有限合成验收写入范围。完整候选门禁、正式附件/应用恢复、真实OCR/公网角色链与构建峰值未因此通过;部署时还须新鲜核验并执行正式门禁,不直接从脏工作副本部署。只操作获准合成对象、保留审计,不实际付款、不发送外部通知、不删回滚制品、不让员工代测。
## 2026-09-11 独立复核接收与预检准备(历史时点,未部署)
用户回传新候选 5d8cdf12/树 dd2e96e0 的独立只读复核:放行、无阻断。覆盖输入/拆分、双端身份 key/enabled、signal 到 fetch 及 401 重放;未审按钮/窄屏/附件定位具体内容与测试断言,未运行测试、未复现浏览器、未验证生产或服务端。接收外部结论,不扩写为全量独立验收或已证实生产泄露。
F1 已更正交接 README 的未提交/未推送过期描述,并区分当前状态与 commit-plan/manifest 历史快照;F2 复用输入未变测试、不新增计数的措辞保留。独立结论存入 postpush-cancellation-commit-preparation/independent-review.json,原冻结包及历史 NO_GO 不变。两任务元数据同步最新 commit/状态,本节及元数据是候选外未提交补记,不新增代码提交。
下一步准备绑定 5d8cdf12 的只读预检,按下方既有发布验收清单核生产版本/镜像、迁移 checksum、磁盘峰值余量、最新同源备份完整性与独立回滚制品。旧 run-precheck.mjs 固定先前 push-receipt/输出目录且要求整个工作副本干净,不能直接重跑、覆盖旧证据或清理脏文件;执行时从冻结候选提取输入,另存新回执,复用已审只读探针。权限不足停在边界,不绕权限。
本轮仅更正文档和准备预检,未连接生产;所有历史磁盘数字均不能作当前容量。此次有限范围复核不解除完整门禁、附件/应用级恢复及公网验收缺口;部署例外必须重新绑定新候选获批。原已批准的提交推送已经完成,不再重复索取;部署、真实数据及公网合成写入仍不在该授权中。
## 2026-09-11 补充修订提交推送回执(历史时点,候选外补记)
用户明确批准两笔提交并推送,仅供独立复核,暂不部署。详情修正 9e41f107(9 文件)与门户修正 5d8cdf12(10 文件,共享规约按内容拆分)已按顺序提交;最终候选 5d8cdf12b45685b2bd5d8a36a0cea376cac366f3,树 dd2e96e0506885640eb462499e230926800cd832,与 postpush-cancellation 冻结树完全一致。远端 main 和本地 origin/main 回读一致,待推送 0;7 个恢复/付款准备脏文件未纳入、未改动。
本轮只做输入摘要核对、提交和推送,未重跑未变测试,复用联合 66/66 页面、构建与真实隔离链结果及按输入核对的 135 单测。原 manifest、NO_GO 与历史证据不改写。提交准备目录 postpush-cancellation-commit-preparation 保存计划、两笔补丁、commit-receipt.json 和 push-receipt.json;本节是候选之外的未提交状态补记,不另建任务或追加第三笔提交。
独立复核仍 PENDING_INLINE,不能把本轮提交或主会话验证当作独立通过。下一步将新候选交独立只读复核;通过后刷新执行时生产预检,再按候选专属批准部署并由执行端完成公网合成验收。本轮未连接生产、未部署、未让员工代测;不沿用历史生产观测冒充当前现状。
## R1复核F5与R2验收补充
新增断言已随R2新构建重跑visual-portal.spec.ts,22/22、零重试,日志/tmp/followup-r2-browser.log。PC与手机财务两段href、BX/PB处理后均消失本次实际断言通过;仅合成API/认证,不宣称公网或自然交接验收。
@@ -15,12 +15,12 @@
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": "fedcaed1a13cc3b32ee47e1d72c2b5ffa5512c57",
"commit": "5d8cdf12b45685b2bd5d8a36a0cea376cac366f3",
"pr_url": null,
"subtasks": [],
"children": [],
"parent": null,
"relatedFiles": [],
"notes": "09-11复核dcde0d44发现旧请求迟到401污染旧身份缓存,双端甲→乙→甲已合成复现,原包NO_GO保留。沿原批准门户隔离范围接续取消:两页queryFn消费signal,经门户API传给HTTP,不改全局认证、角色或服务端。双端红测后最新专项10/10、联合66/66零重试、新构建/PWA及真实隔离业务链PASS,临时库/合成附件已清理;135单测按未变输入复用。新包postpush-cancellation,独立review仍PENDING_INLINE;需新输入交审、明确提交推送授权、新SHA执行时预检及另批部署/公网自动验收。本轮未提交推送、连接生产或部署,不声称全站认证缓存或真实过期会话已验证。",
"notes": "5d8cdf12已部署,公网安全员工PC/手机门户与零明细选票入口通过,唯一合成草稿清理已核。09-11最新READ ONLY盘点:财务smoke已归档、CEO凭据匹配0条、经理smoke需改密;所有smoke缺主体/收款配置。更关键的是角色任务/通知无测试隔离,付款复核按当前事实投影指向非smoke CEO,IM启用且真人CEO/财务绑定与通知开启;未真实提交或发送。不能只补账号继续生产全链。09-04 design已列最小清单及待选A/B:推荐保留公网安全验收并复用同候选隔离全链证据;若坚持生产公网全链,先批准完整合成隔离方案。口径调整未获准,不自动降级或重复跑测试。本轮无登录、解归档/改密/角色/银行解密或业务写入;未新增部署/提交,员工不代测。证据synthetic-isolation-readonly.json;任务仍in_progress,等验收路径选择。以上账号/角色现状为2026-09-11只读盘点快照,回填时(2026-09-25)未重新核验,使用前应重新只读确认。",
"meta": {}
}