diff --git a/client/tests/e2e/invoice-ocr-flow.spec.ts b/client/tests/e2e/invoice-ocr-flow.spec.ts index 78b002a9..eb7d640d 100644 --- a/client/tests/e2e/invoice-ocr-flow.spec.ts +++ b/client/tests/e2e/invoice-ocr-flow.spec.ts @@ -48,7 +48,7 @@ test("E2E 轻交互 OCR:报销详情上传后自动添加并提交", async ({ await expect(page.getByTestId(TEST_IDS.reimbursement.invoiceDialog)).toHaveCount(0); await reimbursementDetail.submitReimbursement(); - await expect(page.getByText(/状态:(reviewing|审批中)/)).toBeVisible({ timeout: 30_000 }); + await expect(page.getByText(/reviewing|审批中/).first()).toBeVisible({ timeout: 30_000 }); await logout(page, EMPLOYEE.name); }); diff --git a/client/tests/e2e/leave-flow.spec.ts b/client/tests/e2e/leave-flow.spec.ts index 4162544e..bb80980a 100644 --- a/client/tests/e2e/leave-flow.spec.ts +++ b/client/tests/e2e/leave-flow.spec.ts @@ -153,7 +153,8 @@ test("E2E 请假主链路:草稿 → 提交 → 撤回 + 提交 → 审批", a await page.goto(`/workflow/tasks/${secondSubmit.currentTaskId}`); await workflowDetail.assertLoaded(); await workflowDetail.approve(); - await expect(workflowDetail.summary).toContainText(/状态:(已处理|completed|已完成)/); + await expect(page.getByRole("main")).toContainText("已完成", { timeout: 30_000 }); + await expect(page.getByRole("main")).toContainText("业务状态:已通过", { timeout: 30_000 }); await logout(page, MANAGER.name); @@ -188,7 +189,8 @@ test("E2E 请假退回说明:审批退回后员工可看到处理意见", asyn await page.goto(`/workflow/tasks/${submitResult.currentTaskId}`); await workflowDetail.assertLoaded(); await workflowDetail.returnTask(returnComment); - await expect(workflowDetail.summary).toContainText(/状态:(已处理|completed|已完成)/); + await expect(page.getByRole("main")).toContainText("已完成", { timeout: 30_000 }); + await expect(page.getByRole("main")).toContainText("业务状态:已终止", { timeout: 30_000 }); await logout(page, MANAGER.name); diff --git a/client/tests/e2e/mobile-approvals-offline.spec.ts b/client/tests/e2e/mobile-approvals-offline.spec.ts index 52a3184b..bce9b0c8 100644 --- a/client/tests/e2e/mobile-approvals-offline.spec.ts +++ b/client/tests/e2e/mobile-approvals-offline.spec.ts @@ -132,7 +132,7 @@ test("E2E 移动审批:离线草稿冲突态可见", async ({ page }) => { await expect(page.getByRole("main").getByText(/草稿同步完成:成功 0,失败 0,冲突 1/)).toBeVisible({ timeout: 30_000 }); await returnToMobileApprovalList(page); await expect(page.getByTestId("mobile-approvals-queue")).toContainText("存在冲突", { timeout: 30_000 }); - await expect(page.getByTestId("mobile-approvals-queue")).toContainText("最近错误:", { timeout: 30_000 }); + await expect(page.getByTestId("mobile-approvals-queue")).toContainText("最近错误", { timeout: 30_000 }); await expect(page.getByRole("button", { name: "查看任务" })).toBeVisible(); await expect(page.getByRole("button", { name: "丢弃草稿" })).toBeVisible(); } finally { diff --git a/client/tests/e2e/procurement-flow.spec.ts b/client/tests/e2e/procurement-flow.spec.ts index 335455bd..08bcef30 100644 --- a/client/tests/e2e/procurement-flow.spec.ts +++ b/client/tests/e2e/procurement-flow.spec.ts @@ -89,12 +89,14 @@ test("E2E 采购主链路:员工提单→经理审批→财务归档", async ( await (await openNavLink(page, "待我处理")).click(); await expect(page.locator(`a[href="/workflow/tasks/${currentTaskId}"]`).first()).toHaveCount(1, { timeout: 30_000 }); await page.goto(`/workflow/tasks/${currentTaskId}`); - await expect(page.getByTestId("workflow-task-summary")).toContainText("对象类型:采购申请"); - await expect(page.getByTestId("workflow-task-summary")).toContainText("申请人:Employee"); + await expect(page.getByTestId("workflow-task-overview")).toContainText("采购申请"); + await expect(page.getByTestId("workflow-task-summary")).toContainText("申请人"); + await expect(page.getByTestId("workflow-task-summary")).toContainText("Employee"); await page.getByTestId("workflow-task-approve").click(); await expect(page.getByTestId("workflow-action-confirm-dialog")).toContainText("确认后将进入下一审批节点"); await page.getByTestId("workflow-action-confirm-submit").click(); - await expect(page.getByTestId("workflow-task-summary")).toContainText(/状态:(已处理|已完成|completed)/); + await expect(page.getByRole("main")).toContainText("已完成", { timeout: 30_000 }); + await expect(page.getByRole("main")).toContainText("业务状态:已通过", { timeout: 30_000 }); await logout(page, MANAGER.name); diff --git a/client/tests/e2e/r102-reimbursement-main-flow.spec.ts b/client/tests/e2e/r102-reimbursement-main-flow.spec.ts index c3f318ba..d69bf447 100644 --- a/client/tests/e2e/r102-reimbursement-main-flow.spec.ts +++ b/client/tests/e2e/r102-reimbursement-main-flow.spec.ts @@ -323,11 +323,10 @@ test.describe("R102 reimbursement main flow", () => { await expect(page.getByTestId("reimbursement-row").getByText(formNumber)).toBeVisible(); await expect(page.getByText(reimbursementId)).toHaveCount(0); - page.once("dialog", async (dialog) => { - expect(dialog.message()).toContain(formNumber); - await dialog.accept(); - }); await page.getByRole("button", { name: "删除" }).first().click(); + await expect(page.getByTestId("action-confirm-dialog")).toContainText(formNumber); + await page.getByTestId("action-confirm-submit").click(); + await expect(page.getByTestId("reimbursement-row")).toHaveCount(0); await expect(page.getByRole("cell", { name: "暂无数据" })).toBeVisible(); }); diff --git a/docs/trialrun/OPS7运维交接Runbook.md b/docs/trialrun/OPS7运维交接Runbook.md index cf3c79c1..4c8b8df2 100644 --- a/docs/trialrun/OPS7运维交接Runbook.md +++ b/docs/trialrun/OPS7运维交接Runbook.md @@ -104,6 +104,17 @@ QAOPS8 恢复演练方案(执行前必须再次确认窗口): R7E 前演练口径:RTO/RPO 先作为演练实测值记录,不承诺正式 SLA;若无法在确认窗口内完成恢复验证,R7E Go/No-Go 必须判定为 Pause 或 No-Go。 +QAOPS9 恢复演练 dry-run checklist(2026-05-16,先设计不执行生产恢复): + +1. 演练环境:优先非生产或隔离临时库;生产只允许做备份清单和步骤复盘,不执行恢复、服务切换或写操作。 +2. 前置确认:窗口、负责人、回滚联系人、停止条件、目标 commit、数据库备份名、附件备份名和验证账号范围均需登记;缺任一项判定 `HOLD`。 +3. 数据恢复 dry-run:在隔离环境执行 `pg_restore --list` 或抽样恢复;记录 schema 可读、migration 状态和关键表抽样结果,不记录真实数据内容。 +4. 附件恢复 dry-run:只抽样验证数量、大小、路径可读性和报销详情下载链路;不得提交真实附件内容。 +5. 应用验证:使用目标 commit 或部署包启动隔离应用,执行 `/ready`、登录、报销详情、附件下载、财务台账只读检查和核心业务 smoke。 +6. RTO/RPO 记录:只记录开始/结束时间、恢复耗时、备份时间点、失败点和修正动作;未实测不得写承诺值。 +7. Go/Pause/No-Go:缺备份、缺负责人、缺隔离环境、恢复失败、附件不可读或验证账号不可用均为 Pause/No-Go;不得用重试次数替代通过证据。 +8. 禁止项:不得生产恢复、不得 `migrate reset`、不得重置生产数据库、不得覆盖远端 `.env`、不得打印 secret 或远端 env。 + ## 6. 账号交接 R7 前账号交接只记录角色和交付状态: diff --git a/docs/trialrun/人工试运行报告.md b/docs/trialrun/人工试运行报告.md index effa9bae..7519e7e8 100644 --- a/docs/trialrun/人工试运行报告.md +++ b/docs/trialrun/人工试运行报告.md @@ -16,6 +16,7 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开 - 2026-05-13 后续计划调整直接回写现有 R7EP、OPS8、QAF8、UX8、P2T 合同,不新建专门调整 Issue;调整后 R7EP 门禁可并行执行,OPS8-1/2/4 纳入 R7EP Go/No-Go,UX8 和 P2T 候选按真实反馈并行推进。 - ORG8 组织账号与权限主数据已完成本地代表性角色验收和阶段收口;后续组织主数据治理只作为 P2 只读巡检候选,不自动进入写修复。 - 2026-05-16 已建立并细化 QAOPS9 上线硬化连续合同和 P2D 功能决策合同;QAOPS9 固定隔离本地业务流与公网 flag-off 证据分离,P2D 固定 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ`、`FREEZE` 三类结论;本次只更新 Issue CSV、既有事实源和 QA 脚本过滤参数,未改业务代码、API/schema、feature flag 或前端功能,未部署,公网运行状态不变。 +- 2026-05-16 QAOPS9 已完成隔离核心业务流稳定化和恢复演练 dry-run checklist;公网 `/ready`、企微配置和 public bundle 正常,但 live smoke/真实 OCR 因缺正式凭据和授权样票继续 `SKIP`,不得写成 PASS。P2D 已完成分流:`P2-ORG` 只读巡检可进入独立合同,其余 P2 候选先保持前置条件等待。 ## 关键证据索引 @@ -38,8 +39,8 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开 | R7E | 阶段验收和 P2 排序收口已完成;当前 P0/P1 阻断为 0 | `issues/2026-05-13_17-11-44-r7e-human-trialrun.csv` | | QAOPS8 | Go/No-Go 与上线硬化阶段收口已完成;后续建议另起 QAOPS9 或等价连续合同 | `issues/2026-05-13_17-30-00-qaops8-test-release-ops.csv` | | FBA | R7E 后全端功能边界审计已收口;只作为功能边界和 P2 候选证据 | `issues/2026-05-15_23-45-41-r7e-post-function-boundary-audit.csv`、`docs/trialrun/R7E后功能边界审计.md` | -| QAOPS9 | 当前已建档并完成执行边界细化;上线硬化优先,隔离本地业务流与公网 flag-off 证据分离,覆盖公网业务流测试数据、live smoke 账号链路、恢复演练 dry-run 和 SLO/Go-No-Go 自动化增强 | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv` | -| P2D | 当前已建档并完成决策模板细化;只做 P2 功能进入开发前的决策和分流,结论统一为 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ` 或 `FREEZE` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | +| QAOPS9 | 当前部分执行:隔离核心业务流稳定化通过,恢复演练 dry-run checklist 已回写;live smoke/OCR 因缺凭据和授权样票保持 `DOING/SKIP`,不作为 Go 证据 | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv`、`artifacts/qa-flow/business-flow-20260516-012215/summary.txt`、`artifacts/qa-flow/live-smoke-readiness-20260516-012820/summary.json` | +| P2D | 已完成决策分流:`P2-ORG` 只读巡检可进入独立合同;付款批次、图片 OCR、UX8、审批通知和轻业务增强均需前置条件;冻结项继续冻结 | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | ## 当前门禁 @@ -51,6 +52,8 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开 | `ME6-3` 真机抽查 | 已关闭 | 2026-05-13 用户确认 iPhone 12、iPhone 14、Redmi K60 企业微信主流程通过;iPhone 12 间距偏紧为非阻断观察项 | | MIF7-7 | 已关闭 | MIF7T 已部署;公网 `/ready`、public bundle、公网 MIF7 移动矩阵、带凭据 live smoke/OCR 均通过 | | R7E 真实执行 | 已收口 | 阶段验收通过,当前 P0/P1 阻断为 0;付款批次、图片 OCR、Android 系统选择器等按 P2 或平台限制延期 | +| QAOPS9 核心业务流 | 通过 | 隔离临时库业务流 `reimbursement/approval/leave/procurement/governance` 通过;付款批次 spec 已排除,报告 `artifacts/qa-flow/business-flow-20260516-012215/summary.txt` | +| QAOPS9 live readiness | 部分通过 / SKIP | `/ready`、WeCom config、public bundle 通过;live smoke 和真实 OCR 因缺凭据/样票 SKIP,报告 `artifacts/qa-flow/live-smoke-readiness-20260516-012820/` | ## R7EP / OPS8 / QAF8 / UX8 / P2T 预检推进 diff --git a/docs/文档事实源状态矩阵.md b/docs/文档事实源状态矩阵.md index 77a9309a..2d0a3fcd 100644 --- a/docs/文档事实源状态矩阵.md +++ b/docs/文档事实源状态矩阵.md @@ -36,8 +36,8 @@ | `BIZ8` | `issues/2026-05-13_18-23-53-biz8-finance-ocr-project.csv` | `EVIDENCE` | 报销/OCR/财务/项目轻量增强已阶段收口;财务移动入口真机通过,财务/项目权限回归完成,付款批次延期到 P2 | | `QAOPS8` | `issues/2026-05-13_17-30-00-qaops8-test-release-ops.csv` | `EVIDENCE` | Go/No-Go 与上线硬化阶段收口已完成;后续硬化另起 QAOPS9 或等价连续合同 | | `FBA` | `issues/2026-05-15_23-45-41-r7e-post-function-boundary-audit.csv` | `EVIDENCE` | R7E 后全端功能边界审计和后续 Issue 草案;不启动 P2 功能开发 | -| `QAOPS9` | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv` | `CURRENT` | R7E 后上线硬化连续合同;隔离本地业务流与公网 flag-off 证据分离,优先处理测试数据、live smoke、恢复演练 dry-run 和 SLO/Go-No-Go | -| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | `CURRENT` | P2 功能决策合同;使用 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ`、`FREEZE` 决定组织主数据、付款批次、图片 OCR、UX8、审批通知和轻业务增强是否进入开发 | +| `QAOPS9` | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv` | `CURRENT` | R7E 后上线硬化连续合同;`QAOPS9-1/3` 已完成,`QAOPS9-2/4/5` 因 live smoke/OCR 凭据和样票缺失仍未关闭 | +| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | `EVIDENCE` | P2 功能决策分流已完成:`P2-ORG` 只读巡检可进独立合同,其余 P2 候选保持 `HOLD_FOR_PREREQ`,冻结项继续冻结 | 旧 Issue CSV 保留为历史审计证据:不删除、不批量回写、不移动到 `docs/archive/` 或其他归档目录。新连续合同如替代旧合同,只在新合同 `Notes` 或文档索引中说明 supersedes。 @@ -151,4 +151,4 @@ - `ME6-3` 代表性企业微信真机门禁已关闭。 - MIF7-1..7 与 MIF7T 已完成本地整改、公网部署、公网匿名复检和带凭据 live smoke/OCR 复检。 -- R7E 真实扩大试运行阶段验收、P2 排序、R7E 收口和 QAOPS8 上线硬化阶段收口已完成,当前 P0/P1 阻断为 0;后续优先执行 QAOPS9 上线硬化,再执行 P2D 功能决策;P2 功能开发必须另建或延续对应连续合同。 +- R7E 真实扩大试运行阶段验收、P2 排序、R7E 收口和 QAOPS8 上线硬化阶段收口已完成,当前 P0/P1 阻断为 0;QAOPS9 已完成测试数据稳定化和恢复演练 dry-run 设计,但 live smoke/OCR 凭据与样票仍缺;P2D 已完成决策分流,P2 功能开发必须另建或延续对应连续合同。 diff --git a/docs/文档索引.md b/docs/文档索引.md index 93198350..8fcbbd46 100644 --- a/docs/文档索引.md +++ b/docs/文档索引.md @@ -48,8 +48,8 @@ R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> M | `BIZ8` | `issues/2026-05-13_18-23-53-biz8-finance-ocr-project.csv` | 已收口:财务移动入口真机通过,财务/项目权限回归完成 | OCR、票据、财务、费用提示、项目关联 | 不做 ERP 实时集成或重预算;付款批次延期到 P2 | | `QAOPS8` | `issues/2026-05-13_17-30-00-qaops8-test-release-ops.csv` | 已收口:Go/No-Go 与上线硬化阶段分流完成 | 回归稳定、测试覆盖、上线门禁、备份恢复、SLO | 不改业务需求;后续硬化另起 QAOPS9 或等价连续合同 | | `FBA` | `issues/2026-05-15_23-45-41-r7e-post-function-boundary-audit.csv` | 已收口:R7E 后全端功能边界审计和后续 Issue 草案 | PC、移动/企业微信、后端 API/作业、管理/运维边界审计 | 不改业务代码、不改 API/schema、不部署、不启动 P2 | -| `QAOPS9` | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv` | 当前合同:已建档,待执行上线硬化 | 公网业务流测试数据稳定化、live smoke 账号链路、恢复演练 dry-run、SLO/Go-No-Go 自动化增强;隔离业务流与公网 flag-off 证据分离 | 不改业务需求、不部署、不执行生产恢复、不重置数据库、不打印远端 env | -| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | 当前合同:已建档,待执行 P2 决策 | 组织主数据、付款批次、图片 OCR、UX8、审批通知、轻业务增强的进入开发决策;结论使用 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ`、`FREEZE` | 不新增 API/schema/feature flag/UI;不启用付款批次或图片 OCR | +| `QAOPS9` | `issues/2026-05-16_00-19-20-qaops9-release-hardening.csv` | 当前合同:测试数据稳定化和恢复演练 dry-run 已完成;live smoke/OCR 因缺凭据和样票保持 `DOING/SKIP` | 公网业务流测试数据稳定化、live smoke 账号链路、恢复演练 dry-run、SLO/Go-No-Go 自动化增强;隔离业务流与公网 flag-off 证据分离 | 不改业务需求、不部署、不执行生产恢复、不重置数据库、不打印远端 env | +| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | 已收口:P2 决策分流完成 | `P2-ORG` 只读巡检进入独立合同;付款批次、图片 OCR、UX8、审批通知、轻业务增强均 `HOLD_FOR_PREREQ`;冻结 ERP/AI/完整差旅/复杂 BPM/审批设计器/重预算/企业微信原生审批 | 不新增 API/schema/feature flag/UI;不启用付款批次或图片 OCR | 旧 Issue CSV 不删除、不批量回写、不移动到归档目录。若新治理流替代旧合同,只在新 CSV 的 `Notes` 或本索引说明 supersedes,旧文件保留历史审计语义。 diff --git a/issues/2026-05-16_00-19-20-qaops9-release-hardening.csv b/issues/2026-05-16_00-19-20-qaops9-release-hardening.csv index b1c26052..4901a06b 100644 --- a/issues/2026-05-16_00-19-20-qaops9-release-hardening.csv +++ b/issues/2026-05-16_00-19-20-qaops9-release-hardening.csv @@ -1,7 +1,7 @@ ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes "QAOPS9-0","QAOPS9 连续合同建档","建立 R7E 后上线硬化连续合同,承接 QAOPS8 收口后的公网业务流测试数据、live smoke 账号链路、恢复演练窗口和 SLO/Go-No-Go 自动化增强;本合同只规划和硬化,不改业务需求。","1) CSV 校验通过;2) 文档索引和事实源矩阵登记 QAOPS9;3) 不修改 server/src 或 client/src 业务代码;4) 允许仅为门禁安全补 scripts/qa 过滤能力;5) 不部署、不执行生产恢复、不重置数据库、不打印远端 env。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_00-19-20-qaops9-release-hardening.csv;node scripts/qa/audit-docs.mjs --check-registry;git diff --check;人工核对 git diff 仅包含 issues/docs/scripts/qa。","python3|node|git|manual","DONE","DONE","DONE","issues/2026-05-16_00-19-20-qaops9-release-hardening.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md|scripts/qa/run-business-flow-gates.sh","[]","2026-05-16 建档并二次细化;承接 QAOPS8-19/20 和 FBA 建议;回滚路径为回退本 CSV、索引登记和脚本过滤参数;不影响运行环境。" -"QAOPS9-1","公网业务流测试数据稳定化","把 R7E 暴露的本地旧种子账号和公网真实 smoke 账号链路差异收敛为可复跑测试数据方案,覆盖报销、审批、请假、采购、财务只读确认和权限边界。","1) 明确公网业务流推荐账号链路;2) 旧本地种子失败项不误判为产品失败;3) 隔离本地可变更测试和公网 flag-off 证据分离;4) 失败时能区分账号、权限、数据和产品缺陷。","受影响流程:员工提交报销、请假、采购后由审批人处理,财务只读查看已审批报销且 payment_batch_v1 仍关闭;验证步骤:先用 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs --json 只读核对前置;再在隔离临时库执行 BUSINESS_FLOW_GROUPS=reimbursement,approval,leave,procurement,governance BUSINESS_FLOW_EXCLUDE_SPECS=tests/e2e/reimbursement-payment-batch-flow.spec.ts bash scripts/qa/run-business-flow-gates.sh local 并核对 summary;公网付款批次仍只能以 flag_force_off 或 payment_batch_v1_disabled 作为关闭证据。","bash|node|manual","TODO","TODO","TODO","scripts/qa/run-business-flow-gates.sh|scripts/qa/check-live-smoke-env.mjs|artifacts/qa-flow|docs/trialrun/人工试运行报告.md","[""QAOPS9-0""]","不得重置生产数据库;不得用重试替代缺陷分析;reimbursement-payment-batch-flow.spec.ts 会开启 payment_batch_v1,只能用于隔离功能回归,不能作为公网 flag-off 通过证据。" -"QAOPS9-2","live smoke 账号链路校准","校准 live smoke 账号、角色、直属主管、企业微信绑定和真实 OCR 样票前置,避免凭据缺失或账号链路漂移导致公网门禁不可解释。","1) live smoke 所需账号和角色矩阵清楚;2) 凭据缺失只记录 SKIP;3) 不打印 token、密码、cookie 或远端 env;4) 企业微信入口、deeplink、PDF OCR 和图片 OCR 前置条件分离。","受影响流程:员工、审批人、财务和管理员通过公网入口完成登录、待办、通知 deeplink 和 OCR readiness 检查;验证步骤:LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs --json 生成前置摘要;如具备凭据和 PDF 样票,再执行 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com QA_ISSUE_ID=QAOPS9 bash scripts/qa/run-live-smoke-readiness.sh;缺正式凭据、DATABASE_URL、授权 PDF 样票或授权图片样票时按脚本规则记录 SKIP,不回填 DONE。","bash|node|manual","TODO","TODO","TODO","scripts/qa/run-live-smoke-readiness.sh|scripts/qa/check-live-smoke-env.mjs|docs/trialrun/公网LiveSmoke准备清单.md","[""QAOPS9-0""]","只记录摘要和证据路径;不得泄露密钥或个人隐私;当前 live OCR 基线仍是 PDF-only,无授权图片样票时图片 OCR 不计 PASS。" -"QAOPS9-3","恢复演练窗口与 dry-run 设计","把 QAOPS8 的恢复演练准备推进为可执行 dry-run 方案,先限定非生产或隔离环境,明确窗口、责任人、备份核验、恢复验证和停止条件。","1) 恢复演练范围、窗口和负责人明确;2) 演练优先非生产或隔离环境;3) 生产只做只读预检或步骤复盘;4) 未获单独批准不得执行生产恢复或服务切换。","受影响流程:备份清单核对、隔离库恢复、/ready、登录和核心业务只读验证;验证步骤:rg -n '备份|恢复演练|RTO|RPO|停止条件|生产恢复|migrate reset|SYNC_ENV' docs/trialrun/OPS7运维交接Runbook.md docs/ops/非功能基线.md;人工形成 dry-run checklist,若执行恢复只能在非生产或隔离环境记录命令摘要、RTO/RPO 实测和验证截图路径。","manual|rg","TODO","TODO","TODO","docs/trialrun/OPS7运维交接Runbook.md|docs/ops/非功能基线.md|artifacts/qa-flow","[""QAOPS9-0""]","禁止生产恢复、重置数据库、覆盖远端 env 或破坏性命令;真实恢复必须另获批准并记录回滚责任人。" -"QAOPS9-4","SLO 与 Go-No-Go 自动化增强","增强上线或扩大试运行前的 SLO、错误预算和 Go/No-Go 自动化汇总,形成可复跑、可审计的门禁结果。","1) /ready、public bundle、live smoke、核心业务流和移动矩阵状态能汇总;2) Go、Pause、No-Go 条件清楚;3) SKIP 不被写成 PASS;4) 输出可关联 Issue 和证据路径。","受影响流程:上线前门禁汇总覆盖匿名健康、带凭据业务流、移动矩阵和人工真机结论;验证步骤:curl -fsS https://oa.hyinda.com/ready;PUBLIC_BASE_URL=https://oa.hyinda.com node scripts/qa/check-public-bundle-copy.mjs;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com QA_ISSUE_ID=QAOPS9 bash scripts/qa/run-live-smoke-readiness.sh;隔离业务流使用 BUSINESS_FLOW_EXCLUDE_SPECS=tests/e2e/reimbursement-payment-batch-flow.spec.ts;移动矩阵按 DG7/R124 或当前试运行手册指定用例执行;人工汇总 Go/Pause/No-Go,SKIP 不计 PASS。","curl|node|bash|playwright|manual","TODO","TODO","TODO","scripts/qa|docs/ops/SLO错误预算.md|docs/trialrun/发布试运行准备清单.md","[""QAOPS9-1"",""QAOPS9-2""]","可改脚本或文档时需另列实现方案;付款批次仍关闭时,不得把隔离打开 flag 的测试结果写成公网付款批次通过。" +"QAOPS9-1","公网业务流测试数据稳定化","把 R7E 暴露的本地旧种子账号和公网真实 smoke 账号链路差异收敛为可复跑测试数据方案,覆盖报销、审批、请假、采购、财务只读确认和权限边界。","1) 明确公网业务流推荐账号链路;2) 旧本地种子失败项不误判为产品失败;3) 隔离本地可变更测试和公网 flag-off 证据分离;4) 失败时能区分账号、权限、数据和产品缺陷。","受影响流程:员工提交报销、请假、采购后由审批人处理,财务只读查看已审批报销且 payment_batch_v1 仍关闭;验证步骤:先用 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs --json 只读核对前置;再在隔离临时库执行 BUSINESS_FLOW_GROUPS=reimbursement,approval,leave,procurement,governance BUSINESS_FLOW_EXCLUDE_SPECS=tests/e2e/reimbursement-payment-batch-flow.spec.ts bash scripts/qa/run-business-flow-gates.sh local 并核对 summary;公网付款批次仍只能以 flag_force_off 或 payment_batch_v1_disabled 作为关闭证据。","bash|node|manual","DONE","DONE","DONE","scripts/qa/run-business-flow-gates.sh|scripts/qa/check-live-smoke-env.mjs|client/tests/e2e/invoice-ocr-flow.spec.ts|client/tests/e2e/r102-reimbursement-main-flow.spec.ts|client/tests/e2e/mobile-approvals-offline.spec.ts|client/tests/e2e/leave-flow.spec.ts|client/tests/e2e/procurement-flow.spec.ts|artifacts/qa-flow|docs/trialrun/人工试运行报告.md","[""QAOPS9-0""]","完成:公网只读前置显示 /ready 200 且 WeCom ready;隔离本地核心业务流最终报告 artifacts/qa-flow/business-flow-20260516-012215/summary.txt,reimbursement 9 passed 1 skipped、approval 3 passed、leave 6 passed、procurement 1 passed、governance 9 passed;排除了会开启 payment_batch_v1 的 reimbursement-payment-batch-flow.spec.ts;本轮只维护过期 E2E 断言,不改业务代码。" +"QAOPS9-2","live smoke 账号链路校准","校准 live smoke 账号、角色、直属主管、企业微信绑定和真实 OCR 样票前置,避免凭据缺失或账号链路漂移导致公网门禁不可解释。","1) live smoke 所需账号和角色矩阵清楚;2) 凭据缺失只记录 SKIP;3) 不打印 token、密码、cookie 或远端 env;4) 企业微信入口、deeplink、PDF OCR 和图片 OCR 前置条件分离。","受影响流程:员工、审批人、财务和管理员通过公网入口完成登录、待办、通知 deeplink 和 OCR readiness 检查;验证步骤:LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs --json 生成前置摘要;如具备凭据和 PDF 样票,再执行 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com QA_ISSUE_ID=QAOPS9 bash scripts/qa/run-live-smoke-readiness.sh;缺正式凭据、DATABASE_URL、授权 PDF 样票或授权图片样票时按脚本规则记录 SKIP,不回填 DONE。","bash|node|manual","DOING","TODO","TODO","scripts/qa/run-live-smoke-readiness.sh|scripts/qa/check-live-smoke-env.mjs|docs/trialrun/公网LiveSmoke准备清单.md","[""QAOPS9-0""]","部分完成但不回填 DONE:artifacts/qa-flow/live-smoke-readiness-20260516-012820/;/ready 200、WeCom ready、public bundle findings=0;live smoke 因缺完整 LIVE_SMOKE_* 凭据记录 SKIP,真实 OCR 因缺员工凭据或授权 PDF 样票记录 SKIP,pending OCR 因缺 DATABASE_URL 记录 SKIP;未打印 secret 或远端 env。" +"QAOPS9-3","恢复演练窗口与 dry-run 设计","把 QAOPS8 的恢复演练准备推进为可执行 dry-run 方案,先限定非生产或隔离环境,明确窗口、责任人、备份核验、恢复验证和停止条件。","1) 恢复演练范围、窗口和负责人明确;2) 演练优先非生产或隔离环境;3) 生产只做只读预检或步骤复盘;4) 未获单独批准不得执行生产恢复或服务切换。","受影响流程:备份清单核对、隔离库恢复、/ready、登录和核心业务只读验证;验证步骤:rg -n '备份|恢复演练|RTO|RPO|停止条件|生产恢复|migrate reset|SYNC_ENV' docs/trialrun/OPS7运维交接Runbook.md docs/ops/非功能基线.md;人工形成 dry-run checklist,若执行恢复只能在非生产或隔离环境记录命令摘要、RTO/RPO 实测和验证截图路径。","manual|rg","DONE","DONE","DONE","docs/trialrun/OPS7运维交接Runbook.md|docs/ops/非功能基线.md|artifacts/qa-flow","[""QAOPS9-0""]","完成:rg 已核对 OPS7 Runbook 和非功能基线;docs/trialrun/OPS7运维交接Runbook.md 已补 QAOPS9 恢复演练 dry-run checklist,限定非生产或隔离环境,登记前置、RTO/RPO 记录、Go/Pause/No-Go 和禁止项;未执行生产恢复、数据库重置或远端 env 操作。" +"QAOPS9-4","SLO 与 Go-No-Go 自动化增强","增强上线或扩大试运行前的 SLO、错误预算和 Go/No-Go 自动化汇总,形成可复跑、可审计的门禁结果。","1) /ready、public bundle、live smoke、核心业务流和移动矩阵状态能汇总;2) Go、Pause、No-Go 条件清楚;3) SKIP 不被写成 PASS;4) 输出可关联 Issue 和证据路径。","受影响流程:上线前门禁汇总覆盖匿名健康、带凭据业务流、移动矩阵和人工真机结论;验证步骤:curl -fsS https://oa.hyinda.com/ready;PUBLIC_BASE_URL=https://oa.hyinda.com node scripts/qa/check-public-bundle-copy.mjs;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com QA_ISSUE_ID=QAOPS9 bash scripts/qa/run-live-smoke-readiness.sh;隔离业务流使用 BUSINESS_FLOW_EXCLUDE_SPECS=tests/e2e/reimbursement-payment-batch-flow.spec.ts;移动矩阵按 DG7/R124 或当前试运行手册指定用例执行;人工汇总 Go/Pause/No-Go,SKIP 不计 PASS。","curl|node|bash|playwright|manual","DOING","TODO","TODO","scripts/qa|docs/ops/SLO错误预算.md|docs/trialrun/发布试运行准备清单.md","[""QAOPS9-1"",""QAOPS9-2""]","部分完成:/ready 通过、public bundle findings=0、隔离核心业务流通过;live smoke 和真实 OCR 仍为 SKIP,移动矩阵本轮未作为新证据重跑;因 QAOPS9-2 未完成,本行不得回填 DONE,当前 Go/No-Go 只能为 Pause/Hold。" "QAOPS9-5","证据归档与阶段收口","在 QAOPS9 执行完成后回填 CSV 状态、证据路径、文档索引和事实源矩阵,形成是否可进入 P2 功能决策或上线动作的结论。","1) QAOPS9 各行 DONE 均有 Test_Method 证据;2) 未完成项有 owner、阻断原因和下一步;3) 文档索引与事实源矩阵一致;4) 本轮是否部署和公网状态明确。","受影响流程:测试、发布和运维治理闭环;验证步骤:validate_issues_csv.py 本 CSV;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'QAOPS9|Go-No-Go|live smoke|恢复演练|SLO' docs issues;git diff --check。","python3|node|rg|git|manual","TODO","TODO","TODO","issues/2026-05-16_00-19-20-qaops9-release-hardening.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[""QAOPS9-1"",""QAOPS9-2"",""QAOPS9-3"",""QAOPS9-4""]","QAOPS9 完成前不得默认进入付款批次或图片 OCR 实现;如发现 P0/P1 阻断,优先收口硬化问题。" diff --git a/issues/2026-05-16_00-19-21-p2-decision-followup.csv b/issues/2026-05-16_00-19-21-p2-decision-followup.csv index 8a289a76..26e33e9f 100644 --- a/issues/2026-05-16_00-19-21-p2-decision-followup.csv +++ b/issues/2026-05-16_00-19-21-p2-decision-followup.csv @@ -1,9 +1,9 @@ ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes "P2D-0","P2 决策合同建档","建立 R7E 后 P2 决策合同,只做功能是否进入开发的决策、边界、先决条件、回滚口径和测试口径,不写业务代码。","1) CSV 校验通过;2) 文档索引和事实源矩阵登记 P2D;3) 不新增 API、schema、feature flag 或前端功能;4) 不启用 payment_batch_v1,不开放图片 OCR;5) 决策项统一使用 GO_TO_CONTRACT、HOLD_FOR_PREREQ、FREEZE。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_00-19-21-p2-decision-followup.csv;node scripts/qa/audit-docs.mjs --check-registry;git diff --check;人工核对 git diff 仅包含 issues/docs/scripts/qa。","python3|node|git|manual","DONE","DONE","DONE","issues/2026-05-16_00-19-21-p2-decision-followup.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[]","决策模板:Decision=; Rationale=<证据和原因>; Prereq=<前置条件>; NextContract=; Rollback=<回滚或撤销口径>; TestScope=<验收口径>。" -"P2D-1","组织主数据只读巡检决策","决定 P2-ORG 是否进入只读巡检合同,范围为直属主管缺失、主管或审批人停用、admin-only 误用、财务和管理员角色混授、企业微信绑定异常。","1) 只读巡检范围和查询边界清楚;2) 如需写修复必须另拆审批窗口;3) 不直接写生产账号数据;4) 巡检结果能映射到权限回归风险;5) 输出统一 Decision 模板。","受影响流程:员工提交审批后按主管链流转,审批人和财务账号保持 active,企业微信绑定可用于入口和 deeplink;验证步骤:只读 SQL 或脚本生成账号、角色、主管、审批人和企业微信绑定矩阵,生产写操作不在本决策内;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|readonly-sql","TODO","TODO","TODO","docs/mcp-tools.md|docs/需求-企业微信基础设施规约.md|issues/2026-05-13_18-23-51-org8-master-data-permission.csv","[""P2D-0""]","决策模板:Decision=; NextContract=P2-ORG 或 N/A;默认只读,禁止 INSERT/UPDATE/DELETE;如批准修复需新建 P2-ORG 实现合同并写明审计和回滚。" -"P2D-2","付款批次启用决策","决定 P2-FIN 是否启用 payment_batch_v1,先锁角色边界、测试账号、公网验收窗口、导出审计和回滚方式。","1) 是否启用付款批次有明确结论;2) 角色矩阵覆盖财务成功、普通员工和 admin-only 拒绝;3) feature flag 和回滚路径明确;4) 不接真实支付或 ERP 实时凭证;5) 输出统一 Decision 模板。","受影响流程:已审批报销进入财务复核,财务创建付款批次、复核、导出和审计,普通员工和 admin-only 不能越权;验证步骤:决策阶段只核对现有 flag_force_off 证据、PRD/财务规约和测试账号前置,不执行付款批次;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","TODO","TODO","TODO","docs/海音达OA-MVP需求规格说明书.md|docs/报销发票附件规则.md|docs/trialrun/R7E后功能边界审计.md|issues/*.csv","[""P2D-0""]","决策模板:Decision=; NextContract=P2-FIN 或 N/A;不得在本合同开启 payment_batch_v1;实现必须另建 P2-FIN CSV、技术方案、权限 review 和回滚说明。" -"P2D-3","图片 OCR 与样票治理决策","决定 P2-OCR 是否进入图片 OCR 样票治理,先锁授权样票、脱敏、provider、字段归一化、PDF-only 兼容、feature flag 和失败回滚。","1) 图片 OCR 是否进入开发有明确结论;2) 样票授权和脱敏路径明确;3) mock 与真实 provider 验收分离;4) 无授权图片样票时只能 SKIP 不能 PASS;5) 输出统一 Decision 模板。","受影响流程:员工上传发票附件,PDF-only 流程不回归,图片样票进入 OCR 后能解释成功、失败、重复和人工复核;验证步骤:决策阶段只核对 OCR 规约、授权样票清单、腾讯云官方能力参考和 provider 前置,不调用真实图片 OCR;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","TODO","TODO","TODO","docs/需求-报销发票OCR规约.md|docs/报销发票附件规则.md|docs/trialrun/R7E后功能边界审计.md","[""P2D-0""]","决策模板:Decision=; NextContract=P2-OCR 或 N/A;不得开放图片 OCR 入口;实现必须另建 P2-OCR CSV,声明 provider、flag、回滚和 PDF-only 兼容。" -"P2D-4","UX8 反馈池承接决策","决定 UX8-1..5 是否继续保持真实反馈池或拆出具体体验修复,范围限移动和企业微信体验,不新增后端字段或业务域。","1) UX8-1..5 的保留、关闭或拆分理由清楚;2) 只有真实反馈或可复现问题才进入实现;3) 移动视口矩阵和真机差异验收口径明确;4) 不混入移动采购创建新能力;5) 输出统一 Decision 模板。","受影响流程:iPhone 12 间距、详情扫读、财务摘要、移动采购创建评估和列表卡片反馈;验证步骤:核对 UX8 CSV、代表设备反馈和 320/360/375/390/393/414/430 视口矩阵,未复现项保持观察;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|playwright|rg","TODO","TODO","TODO","issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv|docs/产品设计规则.md|output/playwright","[""P2D-0""]","决策模板:Decision=; NextContract=UX8 或 N/A;体验修复不得改变后端接口或状态机;移动采购创建属于新能力,需独立需求频次确认。" -"P2D-5","审批通知扩展与邮件通道决策","决定 P2-WF 是否推进转审扩展、通知模板、偏好设置或邮件通道;邮件必须先确认 SMTP、发件域、收件范围、退信处理和脱敏策略。","1) 审批通知扩展项有进入或冻结结论;2) 邮件通道前置条件明确;3) 企业微信个人应用消息仍是正式通知通道;4) 不进入复杂 BPM 或审批设计器;5) 输出统一 Decision 模板。","受影响流程:审批待办、催办、超时提醒、通知 deeplink、企业微信个人应用消息和可能的邮件兜底;验证步骤:决策阶段核对审批规约、企业微信规约和 WF8 证据,缺 SMTP 等正式配置时邮件记录 SKIP;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","TODO","TODO","TODO","docs/需求-统一审批中心规约.md|docs/需求-企业微信基础设施规约.md|issues/2026-05-13_18-23-52-wf8-approval-notification.csv","[""P2D-0""]","决策模板:Decision=; NextContract=P2-WF 或 N/A;邮件通道不得在本合同实现;涉及 workflow、状态机或审批规则时必须独立 review。" -"P2D-6","轻业务增强决策","决定 P2-BIZ 是否评估供应商准入、轻量费用提示、项目费用或采购摘要、合同归档细化、资产盘点体验等轻增强。","1) 每个轻增强有业务频次、角色、验收和冻结结论;2) 不与付款批次、图片 OCR 或 UX 修复混同;3) 不启动 ERP、AI、完整差旅或重预算;4) 进入开发项另拆合同;5) 输出统一 Decision 模板。","受影响流程:采购申请、费用提示、项目关联、合同附件归档和资产盘点;验证步骤:决策阶段核对 PRD、对应模块规约、FBA 审计和真实反馈,不改数据模型;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","TODO","TODO","TODO","docs/海音达OA-MVP需求规格说明书.md|docs/需求-采购费用审批规约.md|docs/需求-合同附件归档规约.md|docs/需求-项目轻管理规约.md|docs/trialrun/R7E后功能边界审计.md","[""P2D-0""]","决策模板:Decision=; NextContract=P2-BIZ 或 N/A;移动采购创建是新能力,不并入普通 UX 修复;任何 schema/API/UI 变更都必须另建实现合同。" -"P2D-7","冻结项确认与 P2 分流收口","确认 ERP 实时集成、AI 自动处理、完整差旅、复杂 BPM、审批设计器、重预算控制和企业微信原生审批继续冻结,并输出 P2 分流结论。","1) 冻结项清单与原因明确;2) 可进入开发的 P2 项有优先级和独立合同要求;3) 未进入项不从历史 TODO 自动复活;4) QAOPS9 优先级不被 P2 功能挤占;5) 汇总所有 Decision 模板。","受影响流程:全端功能边界和后续开发派工;验证步骤:validate_issues_csv.py 本 CSV;rg -n 'P2D|GO_TO_CONTRACT|HOLD_FOR_PREREQ|FREEZE|ERP|AI|差旅|复杂 BPM|审批设计器|重预算|企业微信原生审批|付款批次|图片 OCR|组织主数据|UX8' docs issues;人工核对分流结论。","python3|rg|manual","TODO","TODO","TODO","issues/2026-05-16_00-19-21-p2-decision-followup.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md","[""P2D-1"",""P2D-2"",""P2D-3"",""P2D-4"",""P2D-5"",""P2D-6""]","P2D 收口后才能按批准结果新建 P2-FIN、P2-OCR、P2-ORG、P2-WF、P2-BIZ 或 UX8 实现合同;未获 GO_TO_CONTRACT 的项保持 HOLD_FOR_PREREQ 或 FREEZE。" +"P2D-1","组织主数据只读巡检决策","决定 P2-ORG 是否进入只读巡检合同,范围为直属主管缺失、主管或审批人停用、admin-only 误用、财务和管理员角色混授、企业微信绑定异常。","1) 只读巡检范围和查询边界清楚;2) 如需写修复必须另拆审批窗口;3) 不直接写生产账号数据;4) 巡检结果能映射到权限回归风险;5) 输出统一 Decision 模板。","受影响流程:员工提交审批后按主管链流转,审批人和财务账号保持 active,企业微信绑定可用于入口和 deeplink;验证步骤:只读 SQL 或脚本生成账号、角色、主管、审批人和企业微信绑定矩阵,生产写操作不在本决策内;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|readonly-sql","DONE","DONE","DONE","docs/mcp-tools.md|docs/需求-企业微信基础设施规约.md|issues/2026-05-13_18-23-51-org8-master-data-permission.csv","[""P2D-0""]","Decision=GO_TO_CONTRACT; Rationale=ORG8 已完成本地代表性角色验收,但 R7E 后仍需要持续只读巡检主管链、停用审批人、admin-only、财务/admin 混授和 WeCom 绑定漂移; Prereq=只读数据源、查询脚本或只读 SQL、输出不含隐私明文; NextContract=P2-ORG; Rollback=只读合同无数据回滚,若后续写修复必须另批窗口并可撤销角色/主管变更; TestScope=账号/角色/主管/绑定矩阵、权限直连回归、生产写操作不纳入。" +"P2D-2","付款批次启用决策","决定 P2-FIN 是否启用 payment_batch_v1,先锁角色边界、测试账号、公网验收窗口、导出审计和回滚方式。","1) 是否启用付款批次有明确结论;2) 角色矩阵覆盖财务成功、普通员工和 admin-only 拒绝;3) feature flag 和回滚路径明确;4) 不接真实支付或 ERP 实时凭证;5) 输出统一 Decision 模板。","受影响流程:已审批报销进入财务复核,财务创建付款批次、复核、导出和审计,普通员工和 admin-only 不能越权;验证步骤:决策阶段只核对现有 flag_force_off 证据、PRD/财务规约和测试账号前置,不执行付款批次;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","DONE","DONE","DONE","docs/海音达OA-MVP需求规格说明书.md|docs/报销发票附件规则.md|docs/trialrun/R7E后功能边界审计.md|issues/*.csv","[""P2D-0""]","Decision=HOLD_FOR_PREREQ; Rationale=R7E 明确 payment_batch_v1 关闭,移动端仅展示未启用空态,QAOPS9 live smoke 凭据和公网验收窗口仍缺失; Prereq=财务/复核角色测试账号、feature flag 启停方案、公网验收窗口、导出/审计字段、回滚到 flag off 的验证; NextContract=P2-FIN; Rollback=flag off、隐藏入口、保留已审计数据但不接真实支付; TestScope=财务成功、员工/admin-only 拒绝、导出权限、审计记录、flag off 空态。" +"P2D-3","图片 OCR 与样票治理决策","决定 P2-OCR 是否进入图片 OCR 样票治理,先锁授权样票、脱敏、provider、字段归一化、PDF-only 兼容、feature flag 和失败回滚。","1) 图片 OCR 是否进入开发有明确结论;2) 样票授权和脱敏路径明确;3) mock 与真实 provider 验收分离;4) 无授权图片样票时只能 SKIP 不能 PASS;5) 输出统一 Decision 模板。","受影响流程:员工上传发票附件,PDF-only 流程不回归,图片样票进入 OCR 后能解释成功、失败、重复和人工复核;验证步骤:决策阶段只核对 OCR 规约、授权样票清单、腾讯云官方能力参考和 provider 前置,不调用真实图片 OCR;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","DONE","DONE","DONE","docs/需求-报销发票OCR规约.md|docs/报销发票附件规则.md|docs/trialrun/R7E后功能边界审计.md","[""P2D-0""]","Decision=HOLD_FOR_PREREQ; Rationale=腾讯云官方能力证明图片/PDF 技术可行,但当前 live OCR 基线仍为 PDF-only,QAOPS9 缺授权 PDF/图片样票和真实 OCR 凭据; Prereq=授权图片样票、脱敏规则、provider 回归账号、字段归一化、feature flag、PDF-only 回归; NextContract=P2-OCR; Rollback=关闭图片入口和 flag,保留 PDF-only;失败回人工复核; TestScope=PDF 不回归、图片 mock/真实 provider 分离、无授权样票记 SKIP 不记 PASS。" +"P2D-4","UX8 反馈池承接决策","决定 UX8-1..5 是否继续保持真实反馈池或拆出具体体验修复,范围限移动和企业微信体验,不新增后端字段或业务域。","1) UX8-1..5 的保留、关闭或拆分理由清楚;2) 只有真实反馈或可复现问题才进入实现;3) 移动视口矩阵和真机差异验收口径明确;4) 不混入移动采购创建新能力;5) 输出统一 Decision 模板。","受影响流程:iPhone 12 间距、详情扫读、财务摘要、移动采购创建评估和列表卡片反馈;验证步骤:核对 UX8 CSV、代表设备反馈和 320/360/375/390/393/414/430 视口矩阵,未复现项保持观察;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|playwright|rg","DONE","DONE","DONE","issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv|docs/产品设计规则.md|output/playwright","[""P2D-0""]","Decision=HOLD_FOR_PREREQ; Rationale=UX8-1..5 是真实反馈池,当前无新的可复现阻断;移动采购创建属于新能力而非普通 UX 修复; Prereq=真实截图、设备型号、角色、页面、可复现步骤或明确频次; NextContract=UX8; Rollback=前端体验改动可按组件/样式回退,不改 API/schema; TestScope=320/360/375/390/393/414/430 视口、企业微信代表设备、对应角色截图。" +"P2D-5","审批通知扩展与邮件通道决策","决定 P2-WF 是否推进转审扩展、通知模板、偏好设置或邮件通道;邮件必须先确认 SMTP、发件域、收件范围、退信处理和脱敏策略。","1) 审批通知扩展项有进入或冻结结论;2) 邮件通道前置条件明确;3) 企业微信个人应用消息仍是正式通知通道;4) 不进入复杂 BPM 或审批设计器;5) 输出统一 Decision 模板。","受影响流程:审批待办、催办、超时提醒、通知 deeplink、企业微信个人应用消息和可能的邮件兜底;验证步骤:决策阶段核对审批规约、企业微信规约和 WF8 证据,缺 SMTP 等正式配置时邮件记录 SKIP;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","DONE","DONE","DONE","docs/需求-统一审批中心规约.md|docs/需求-企业微信基础设施规约.md|issues/2026-05-13_18-23-52-wf8-approval-notification.csv","[""P2D-0""]","Decision=HOLD_FOR_PREREQ; Rationale=企业微信个人应用消息和 deeplink 已作为正式通道收口,转审/模板/偏好缺真实新反馈,邮件缺 SMTP、发件域、退信和脱敏方案; Prereq=明确通知痛点、模板清单、收件范围、SMTP/域名/退信配置;复杂 BPM 和审批设计器不进入; NextContract=P2-WF; Rollback=关闭新增模板/偏好/邮件 flag,保留现有企业微信和站内通知; TestScope=workflow 回归、通知 deeplink、WeCom 消息;邮件缺正式配置时 SKIP。" +"P2D-6","轻业务增强决策","决定 P2-BIZ 是否评估供应商准入、轻量费用提示、项目费用或采购摘要、合同归档细化、资产盘点体验等轻增强。","1) 每个轻增强有业务频次、角色、验收和冻结结论;2) 不与付款批次、图片 OCR 或 UX 修复混同;3) 不启动 ERP、AI、完整差旅或重预算;4) 进入开发项另拆合同;5) 输出统一 Decision 模板。","受影响流程:采购申请、费用提示、项目关联、合同附件归档和资产盘点;验证步骤:决策阶段核对 PRD、对应模块规约、FBA 审计和真实反馈,不改数据模型;结论写为 GO_TO_CONTRACT、HOLD_FOR_PREREQ 或 FREEZE。","manual|rg","DONE","DONE","DONE","docs/海音达OA-MVP需求规格说明书.md|docs/需求-采购费用审批规约.md|docs/需求-合同附件归档规约.md|docs/需求-项目轻管理规约.md|docs/trialrun/R7E后功能边界审计.md","[""P2D-0""]","Decision=HOLD_FOR_PREREQ; Rationale=供应商准入、费用提示、项目采购摘要、合同归档和资产体验均属轻增强候选,但当前没有高频真实反馈或上线硬化依赖; Prereq=业务频次、角色 owner、验收样例和是否影响 schema/API; NextContract=P2-BIZ; Rollback=按独立模块 flag/路由/接口回退,禁止牵连付款批次或 OCR; TestScope=对应模块流程、权限边界、导出/审计影响;ERP、AI、完整差旅和重预算不纳入。" +"P2D-7","冻结项确认与 P2 分流收口","确认 ERP 实时集成、AI 自动处理、完整差旅、复杂 BPM、审批设计器、重预算控制和企业微信原生审批继续冻结,并输出 P2 分流结论。","1) 冻结项清单与原因明确;2) 可进入开发的 P2 项有优先级和独立合同要求;3) 未进入项不从历史 TODO 自动复活;4) QAOPS9 优先级不被 P2 功能挤占;5) 汇总所有 Decision 模板。","受影响流程:全端功能边界和后续开发派工;验证步骤:validate_issues_csv.py 本 CSV;rg -n 'P2D|GO_TO_CONTRACT|HOLD_FOR_PREREQ|FREEZE|ERP|AI|差旅|复杂 BPM|审批设计器|重预算|企业微信原生审批|付款批次|图片 OCR|组织主数据|UX8' docs issues;人工核对分流结论。","python3|rg|manual","DONE","DONE","DONE","issues/2026-05-16_00-19-21-p2-decision-followup.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md","[""P2D-1"",""P2D-2"",""P2D-3"",""P2D-4"",""P2D-5"",""P2D-6""]","Decision=GO_TO_CONTRACT for P2-ORG read-only only; HOLD_FOR_PREREQ for P2-FIN、P2-OCR、UX8、P2-WF、P2-BIZ; FREEZE for ERP 实时集成、AI 自动处理、完整差旅、复杂 BPM、审批设计器、重预算控制、企业微信原生审批和缺正式配置的邮件通道; Rationale=QAOPS9 硬化优先且 live smoke/OCR 前置未齐; Prereq=每个 HOLD 项满足账号、样票、反馈或配置后另建合同; NextContract=P2-ORG first, then approved P2-*; Rollback=未获 GO 的项不实现不启用; TestScope=validate CSV、rg 分流关键词、人工核对冻结边界。"