P2AF 收口自动化后续和默认冻结口径

这个提交包含在:
2026-05-16 22:40:45 +08:00
父节点 edabce8561
当前提交 ed608034f6
共修改 9 个文件,包含 369 行新增和 28 行删除
+12 -9
查看文件
@@ -20,9 +20,10 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
- 2026-05-16 P2D 旧口径已修正:live smoke 凭据、员工 OCR 凭据和授权 PDF 样票已具备,不再作为 P2-FIN/P2-OCR 的 HOLD 原因。P2-ORG 已完成只读巡检:当前连接数据源 high=0、medium=0、low=9,建议 `NO_WRITE_FIX_NEEDED`;低风险项为 CEO/root 无直属主管观察 1 和 active 员工无企业微信绑定 8。
- 2026-05-16 P2-FIN-DECISION 已完成付款批次启用决策准备:只读核对代码/flag/空态、角色账号、导出字段、审计事件、公网 readiness 和 flag off 回滚口径,结论为 `GO_TO_IMPLEMENT`,后续可另建 `P2-FIN-V1`;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
- 2026-05-16 P2-FIN-V1 已完成付款批次启用前本地/隔离硬化:后端 focused 回归、前端 typecheck/build、隔离付款批次闭环、权限直连审计、公网 readiness 和只读 review 均通过;本轮只修补 E2E 对当前状态胶囊和二次确认 UI 的断言,不改业务 API/schema/UI,不部署,公网 `payment_batch_v1` 继续关闭。
- 2026-05-16 P2-OCR-SAMPLE 已完成图片 OCR 样票治理和实现前置确认:当前 PDF-only 口径、`SAMPLE-IMG-*` 授权登记、脱敏证据、provider 分层和回滚设计已锁定;结论为 `HOLD_FOR_SAMPLE`,授权图片样票和真实图片 provider 回归证据形成前不进入 `P2-OCR-V1`,不开放图片 OCR。
- 2026-05-16 P2Q 已完成 P2OCRS 后续任务队列规划:后续默认按图片样票 provider 回归门槛、UX8 真实反馈池、P2-FIN-LIVE 公网启用窗口、P2-OCR-V1、P2-WF、P2-BIZ 和持续上线门禁拆独立合同推进;本轮不改业务代码、不部署。
- 2026-05-16 P2AUTO 已完成自动化优先回归:后端 focused、前端 typecheck/build、高风险确认、隔离核心业务流、隔离付款批次闭环、公网 readiness/PDF live OCR、公网移动矩阵和企业微信 UA/渲染自动化均通过;PDF 样票和 live smoke 凭据可用,图片 provider 回归仍需仓库外 manifest 或 `PLAYWRIGHT_OCR_IMAGE_*` 安全登记授权图片样票,不开放图片 OCR,不启用公网 `payment_batch_v1`,未部署。
- 2026-05-16 P2-OCR-SAMPLE 已完成图片 OCR 样票治理和实现前置确认;P2AF 纠偏后当前默认结论为 `FREEZE_BY_DEFAULT`:正式能力只维护 PDF-only OCR,图片继续作为普通附件,不开放图片 OCR。
- 2026-05-16 P2Q 已完成 P2OCRS 后续任务队列规划;P2AF 后图片 OCR 不再作为默认主线等待样票,后续默认按 UX8 真实反馈池、P2-FIN-LIVE 公网启用窗口、P2-WF、P2-BIZ 和持续上线门禁拆独立合同推进。
- 2026-05-16 P2AUTO 已完成自动化优先回归:后端 focused、前端 typecheck/build、高风险确认、隔离核心业务流、隔离付款批次闭环、公网 readiness/PDF live OCR、公网移动矩阵和企业微信 UA/渲染自动化均通过;PDF 样票和 live smoke 凭据可用,P2AF 后 provider-only 默认结论为 `FREEZE_BY_DEFAULT`,不开放图片 OCR,不启用公网 `payment_batch_v1`,未部署。
- 2026-05-16 P2AF 已完成可自动实施收口:图片 OCR 默认 `FREEZE_BY_DEFAULT`,PDF-only OCR 继续维护;新增 QA-only 回归聚合和付款批次公网关闭态只读门禁,公网 `payment_batch_v1` 继续 `flag_force_off`,本轮不做业务实现、不部署。
## 关键证据索引
@@ -50,9 +51,10 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
| P2-ORG | 已收口:组织账号主数据只读巡检完成,高/中风险为 0,低风险观察 9,不需要写修复合同 | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv`、`artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/report.json` |
| P2-FIN-DECISION | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT`;后续进入单独 `P2-FIN-V1` 合同前仍需方案批准 | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` |
| P2-FIN-V1 | 已收口:付款批次启用前本地/隔离硬化完成;隔离付款批次闭环 1 passed、权限直连审计 8 passed、公网 readiness ready | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv`、`artifacts/qa-flow/business-flow-20260516-095719/summary.txt`、`artifacts/qa-flow/business-flow-20260516-095900/summary.txt` |
| P2-OCR-SAMPLE | 已收口:图片 OCR 样票治理前置完成,结论 `HOLD_FOR_SAMPLE`;PDF live OCR 基线继续有效但不代表图片 OCR 通过 | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` |
| P2Q | 已收口:P2OCRS 后续队列和启动门槛完成;所有实现或公网启用均需另建独立合同 | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` |
| P2AUTO | 已收口:自动化优先回归和样票 provider 门禁完成;核心隔离业务流通过、付款批次隔离闭环 1 passed、公网 readiness/PDF live OCR 通过、公网移动矩阵 6 passed、企业微信渲染矩阵 8 passed;图片 provider 回归保持 `HOLD_FOR_SAMPLE` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv`、`artifacts/qa-flow/business-flow-20260516-203001/summary.txt`、`artifacts/qa-flow/business-flow-20260516-203856/summary.txt`、`artifacts/qa-flow/live-smoke-readiness-20260516-204157/` |
| P2-OCR-SAMPLE | 已收口:图片 OCR 样票治理前置完成;P2AF 后当前默认 `FREEZE_BY_DEFAULT`,PDF live OCR 基线继续有效 | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` |
| P2Q | 已收口:P2OCRS 后续队列和启动门槛完成;图片 OCR 默认冻结,所有实现或公网启用均需另建独立合同 | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` |
| P2AUTO | 已收口:自动化优先回归和样票 provider 门禁完成;核心隔离业务流通过、付款批次隔离闭环 1 passed、公网 readiness/PDF live OCR 通过、公网移动矩阵 6 passed、企业微信渲染矩阵 8 passed;provider 默认结论改为 `FREEZE_BY_DEFAULT` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv`、`artifacts/qa-flow/business-flow-20260516-203001/summary.txt`、`artifacts/qa-flow/business-flow-20260516-203856/summary.txt`、`artifacts/qa-flow/live-smoke-readiness-20260516-204157/` |
| P2AF | 已收口:可自动实施收口完成;安全回归聚合 PASS,付款批次公网关闭态只读门禁 PASS,UX8 自动矩阵通过且 UX8-1..5 保持真实反馈驱动 | `issues/2026-05-16_22-11-10-p2-automatable-followup.csv`、`artifacts/qa-flow/p2-safe-regression-20260516-222222/summary.json` |
## 当前门禁
@@ -70,9 +72,10 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
| P2-ORG 只读巡检 | 通过,含低风险观察项 | `server/src/scripts/audit-org-master-data.js` 在 READ ONLY 事务中执行;当前连接数据源 high=0、medium=0、low=9,未输出手机号、邮箱、token 或企业微信真实标识,报告 `artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/` |
| P2-FIN 决策准备 | 通过 | `LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs` 显示 publicReady/liveSmokeReady/liveOcrReady 均为 true;只读核对付款批次 flag、权限、导出、审计和回滚口径;未执行付款批次业务写入 |
| P2-FIN-V1 启用前硬化 | 通过,未部署 | 后端 focused 回归 8 tests passed;`client` typecheck/build 通过;隔离临时库 `reimbursement-payment-batch-flow` 1 passed,覆盖创建批次、复核、二次确认执行、报销 paid、票据 archived、AP 台账和 ERP outbox;权限直连审计 8 passed;公网只做 readiness,不启用 `payment_batch_v1` |
| P2-OCR-SAMPLE 样票治理 | HOLD,未部署 | 已确认当前发票 OCR 仍为 PDF-only,图片仅作为普通附件;腾讯云 `image_native` 只证明技术路径存在,正式图片 OCR 仍需授权图片样票、脱敏确认和真实图片 provider 回归;未调用真实图片 OCR |
| P2Q 后续队列 | 已收口,未部署 | 图片 OCR provider 回归等待授权图片样票;UX8 等待真实反馈;P2-FIN-LIVE 等待公网启用窗口批准;后续 P2-OCR-V1/P2-WF/P2-BIZ 均需独立合同 |
| P2AUTO 自动化优先回归 | 通过,未部署 | 后端 focused 43 tests passed;`client` typecheck/build 通过;核心隔离业务流 auth/reimbursement/approval/leave/procurement/governance PASS;付款批次隔离 flag-on 1 passed;公网 `/ready`、public bundle、live smoke 3 passed、PDF live OCR 1 passed;公网移动矩阵 6 passed;企业微信渲染矩阵 8 passed;provider-only 样票脚本输出 `HOLD_FOR_SAMPLE`,因为未通过安全 manifest/env 登记授权图片样票且本地无 Tencent provider 凭据 |
| P2-OCR-SAMPLE 样票治理 | 默认冻结,未部署 | 已确认当前发票 OCR 仍为 PDF-only,图片仅作为普通附件;腾讯云 `image_native` 只证明技术路径存在,不等同于当前产品能力;正式图片 OCR 默认 `FREEZE_BY_DEFAULT`,除非用户明确重启评估 |
| P2Q 后续队列 | 已收口,未部署 | 图片 OCR 不再作为默认主线等待样票;UX8 等待真实反馈;P2-FIN-LIVE 等待公网启用窗口批准;后续 P2-WF/P2-BIZ 均需独立合同 |
| P2AUTO 自动化优先回归 | 通过,未部署 | 后端 focused 43 tests passed;`client` typecheck/build 通过;核心隔离业务流 auth/reimbursement/approval/leave/procurement/governance PASS;付款批次隔离 flag-on 1 passed;公网 `/ready`、public bundle、live smoke 3 passed、PDF live OCR 1 passed;公网移动矩阵 6 passed;企业微信渲染矩阵 8 passed;P2AF 后 provider-only 默认结论为 `FREEZE_BY_DEFAULT` |
| P2AF 可自动实施收口 | 通过,未部署 | `run-p2-safe-regression.sh` PASS:后端 focused 43 tests passed,`client` typecheck/build 通过,核心隔离业务流 auth/reimbursement/approval/leave/procurement/governance PASS,公网 readiness/PDF live OCR 通过,付款批次公网关闭态 409 `payment_batch_v1_disabled / flag_force_off`,公网移动矩阵 6 passed,企业微信渲染矩阵 8 passed,OCR provider-only 默认 `FREEZE_BY_DEFAULT`;不启用公网 `payment_batch_v1`,不开放图片 OCR,不做业务实现 |
## R7EP / OPS8 / QAF8 / UX8 / P2T 预检推进
+6 -5
查看文件
@@ -41,9 +41,10 @@
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | `EVIDENCE` | 组织账号主数据只读巡检已完成;当前连接数据源高/中风险为 0,仅有低风险观察项,不需要写修复合同 |
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | `EVIDENCE` | 付款批次启用决策准备已完成,结论 `GO_TO_IMPLEMENT`;后续必须另建 `P2-FIN-V1` 实现合同,当前不启用 `payment_batch_v1` |
| `P2-FIN-V1` | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv` | `EVIDENCE` | 付款批次启用前本地/隔离硬化已完成;后端 focused 回归、前端构建、隔离闭环、权限审计和公网 readiness 通过,公网仍不启用 `payment_batch_v1` |
| `P2-OCR-SAMPLE` | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` | `EVIDENCE` | 图片 OCR 样票治理和实现前置确认已完成;结论 `HOLD_FOR_SAMPLE`,当前保持 PDF-only,不开放图片 OCR |
| `P2Q` | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` | `EVIDENCE` | P2OCRS 后续任务队列已锁定;后续实现均需另建独立合同,当前不部署、不改业务代码 |
| `P2AUTO` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv` | `EVIDENCE` | 自动化优先回归已收口;后端/前端/隔离业务流/公网 readiness/PDF live OCR/移动与企业微信自动化均有证据,图片 provider 回归仍需安全登记的授权图片样票和本地 provider 凭据 |
| `P2-OCR-SAMPLE` | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` | `EVIDENCE` | 图片 OCR 样票治理和实现前置确认已完成;P2AF 纠偏后当前默认 `FREEZE_BY_DEFAULT`,保持 PDF-only,不开放图片 OCR |
| `P2Q` | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` | `EVIDENCE` | P2OCRS 后续任务队列已锁定;图片 OCR 默认冻结,后续实现均需另建独立合同,当前不部署、不改业务代码 |
| `P2AUTO` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv` | `EVIDENCE` | 自动化优先回归已收口;后端/前端/隔离业务流/公网 readiness/PDF live OCR/移动与企业微信自动化均有证据,provider-only 默认决策为 `FREEZE_BY_DEFAULT` |
| `P2AF` | `issues/2026-05-16_22-11-10-p2-automatable-followup.csv` | `EVIDENCE` | 可自动实施收口已完成;纠正图片 OCR 默认冻结口径,补 QA-only 安全回归、付款批次公网关闭态只读门禁和 UX8 自动矩阵扫尾;报告 `artifacts/qa-flow/p2-safe-regression-20260516-222222/` |
旧 Issue CSV 保留为历史审计证据:不删除、不批量回写、不移动到 `docs/archive/` 或其他归档目录。新连续合同如替代旧合同,只在新合同 `Notes` 或文档索引中说明 supersedes。
@@ -51,8 +52,8 @@
| Doc_ID | Path | Category | Authority | Status | Owner | Related_Issues | Evidence | Supersedes | Last_Audited | Audit_Method | Risk | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `IDX` | `docs/文档索引.md` | 入口索引 | 最高文档入口 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1,P2-OCR-SAMPLE,P2Q,P2AUTO` | `rg` | none | 2026-05-16 | `node scripts/qa/audit-docs.mjs --check-registry` | medium | 判断当前该读什么 |
| `REG` | `docs/文档事实源状态矩阵.md` | 文档台账 | 文档分类和状态事实源 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1,P2-OCR-SAMPLE,P2Q,P2AUTO` | `audit-docs` | none | 2026-05-16 | `audit-docs --check-registry` | medium | 判断文档权威性 |
| `IDX` | `docs/文档索引.md` | 入口索引 | 最高文档入口 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1,P2-OCR-SAMPLE,P2Q,P2AUTO,P2AF` | `rg` | none | 2026-05-16 | `node scripts/qa/audit-docs.mjs --check-registry` | medium | 判断当前该读什么 |
| `REG` | `docs/文档事实源状态矩阵.md` | 文档台账 | 文档分类和状态事实源 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1,P2-OCR-SAMPLE,P2Q,P2AUTO,P2AF` | `audit-docs` | none | 2026-05-16 | `audit-docs --check-registry` | medium | 判断文档权威性 |
| `PRD-MVP` | `docs/海音达OA-MVP需求规格说明书.md` | 需求事实源 | PRD 主事实源 | `CURRENT` | product | `REQ8,P2T,GOV8` | Issue CSV | `docs/requirements-specification.md` | 2026-05-13 | `rg` | high | 定义做什么、不做什么和验收口径 |
| `PRODUCT-SCOPE` | `docs/产品口径.md` | 需求事实源 | 产品边界事实源 | `CURRENT` | product | `REQ8,P2T` | `rg` | none | 2026-05-13 | `rg` | high | 记录已拍板产品边界 |
| `DESIGN-UI` | `docs/产品设计规则.md` | 设计事实源 | PC/移动/企业微信设计事实源 | `CURRENT` | design/frontend | `MIA7,MIF7,GOV8,DG8,DG9` | Playwright/视觉审查/DG8/DG9 | none | 2026-05-13 | `rg` | high | 页面改动必须读取;DG8 后飞书为主 UI/布局参考;DG9 后按页面分层和样板选型 |
+9 -7
查看文件
@@ -20,7 +20,7 @@
## 最近事实源链
R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> MIF7/MIF7T(公网部署与带凭据公网复检已收口) -> DG8 -> DG9 -> R7E -> FBA -> QAOPS9/P2D -> P2-ORG -> P2-FIN-DECISION -> P2-FIN-V1 -> P2-OCR-SAMPLE -> P2Q -> P2AUTO。
R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> MIF7/MIF7T(公网部署与带凭据公网复检已收口) -> DG8 -> DG9 -> R7E -> FBA -> QAOPS9/P2D -> P2-ORG -> P2-FIN-DECISION -> P2-FIN-V1 -> P2-OCR-SAMPLE -> P2Q -> P2AUTO -> P2AF。
- R6、PC6、PA6、FL6、AP6、RI6、LP6 已完成并部署。
- ME6 自动化、公网视觉矩阵和 `ME6-3` 代表性企业微信真机门禁已完成。
@@ -35,9 +35,10 @@ R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> M
- P2-ORG 是 P2D 后第一个执行合同,已完成组织账号主数据只读巡检;当前连接数据源下高/中风险为 0,低风险观察项为 CEO/root 无直属主管 1 和 active 员工无企业微信绑定 8;本轮不需要写修复合同。
- P2-FIN-DECISION 已完成付款批次启用决策准备,结论为 `GO_TO_IMPLEMENT`:可进入单独 `P2-FIN-V1` 实现合同;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
- P2-FIN-V1 已完成付款批次启用前本地/隔离硬化:后端 focused 回归、前端 typecheck/build、隔离付款批次闭环、权限直连审计和公网 readiness 均通过;本轮只硬化 E2E 断言,不新增 API/schema/feature flag/UI,不部署,公网 `payment_batch_v1` 继续关闭。
- P2-OCR-SAMPLE 已完成图片 OCR 样票治理和实现前置确认:当前 PDF-only 口径、样票脱敏、provider 回归分层和回滚条件已锁定;结论为 `HOLD_FOR_SAMPLE`,需授权图片样票和真实图片 provider 回归证据后才可进入 `P2-OCR-V1`。
- P2Q 是 P2OCRS 后续任务队列合同:只锁定 `P2-OCR-IMAGE-REGRESSION`、`UX8`、`P2-FIN-LIVE`、`P2-OCR-V1`、`P2-WF`、`P2-BIZ` 和持续上线门禁的启动条件,不启动实现、不部署。
- P2AUTO 是 P2Q 后自动化优先回归合同:后端 focused、前端构建、高风险确认、隔离核心业务流、隔离付款批次闭环、公网 readiness/PDF live OCR、公网移动矩阵和企业微信 UA/渲染自动化均已完成;PDF 样票和 live smoke 凭据可用,图片样票仍需通过仓库外 manifest 或 `PLAYWRIGHT_OCR_IMAGE_*` 安全登记后才能进入真实图片 provider 回归。
- P2-OCR-SAMPLE 已完成图片 OCR 样票治理和实现前置确认;P2AF 纠偏后当前口径为图片发票 OCR `FREEZE_BY_DEFAULT`,正式能力只维护 PDF-only OCR,图片仍按普通附件处理。
- P2Q 是 P2OCRS 后续任务队列合同:只锁定 `UX8`、`P2-FIN-LIVE`、审批通知、轻业务增强和持续上线门禁等启动条件;图片 OCR 不进入默认主线,只有用户明确重启评估才另建 provider 回归或实现合同。
- P2AUTO 是 P2Q 后自动化优先回归合同:后端 focused、前端构建、高风险确认、隔离核心业务流、隔离付款批次闭环、公网 readiness/PDF live OCR、公网移动矩阵和企业微信 UA/渲染自动化均已完成;PDF 样票和 live smoke 凭据可用,图片 OCR 默认冻结。
- P2AF 是 P2AUTO 后可自动实施收口合同:纠正图片 OCR 默认冻结口径,补 QA-only provider 决策语义、安全回归聚合、付款批次公网关闭态只读门禁和 UX8 自动矩阵扫尾;不部署、不启用公网付款批次、不开放图片 OCR。
## 当前活跃治理流
@@ -59,9 +60,10 @@ R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> M
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | 已收口:组织主数据只读巡检完成 | 主管链、停用审批人、角色持有人、admin-only、财务/admin 混授、企业微信绑定漂移的脱敏只读审计 | 不写生产账号数据、不执行 P2-ORG-FIX、不改 API/schema/UI、不部署 |
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT` | 付款批次代码/flag/空态、角色账号矩阵、导出字段、审计事件、公网验收窗口和 flag off 回滚口径 | 不启用 `payment_batch_v1`、不写付款批次、不接真实支付、不写 ERP 实时凭证、不部署 |
| `P2-FIN-V1` | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv` | 已收口:付款批次启用前本地/隔离硬化完成 | 后端付款批次/AP/导出 focused 回归、前端构建、隔离闭环、权限审计、公网 readiness、flag off 回滚口径 | 不公网启用 `payment_batch_v1`、不部署、不接真实支付、不写 ERP 实时凭证 |
| `P2-OCR-SAMPLE` | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` | 已收口:图片 OCR 样票治理前置完成,结论 `HOLD_FOR_SAMPLE` | PDF-only 当前边界、`SAMPLE-IMG-*` 授权登记口径、脱敏证据规则、mock/PDF/真实图片 provider 分层、feature flag 和回滚设计 | 不开放图片 OCR、不新增入口或 feature flag、不调用真实图片 provider、不保存真实票据、不部署 |
| `P2Q` | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` | 已收口:P2OCRS 后续队列和启动门槛完成 | 图片 OCR provider 回归、UX8、付款批次公网启用、图片 OCR V1、审批通知、轻业务增强和持续上线门禁的后续合同顺序 | 不直接启动 HOLD 项、不新建综合规划文档、不改业务代码、不部署 |
| `P2AUTO` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv` | 已收口:自动化优先回归和样票 provider 门禁完成 | 凭据/样票掩码核对、后端 focused、前端构建、高风险确认、隔离业务流、隔离付款批次、公网 readiness/PDF live OCR、移动/企业微信自动化、OCR provider-only 脚本 | 不部署、不开放图片 OCR、不打开公网 `payment_batch_v1`、不自动选择未登记图片样票 |
| `P2-OCR-SAMPLE` | `issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv` | 已收口:图片 OCR 样票治理前置完成;P2AF 后当前默认 `FREEZE_BY_DEFAULT` | PDF-only 当前边界、`SAMPLE-IMG-*` 授权登记口径、脱敏证据规则、mock/PDF/真实图片 provider 分层、feature flag 和回滚设计 | 默认不支持图片发票 OCR;不新增入口或 feature flag、不调用真实图片 provider、不保存真实票据、不部署 |
| `P2Q` | `issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv` | 已收口:P2OCRS 后续队列和启动门槛完成;图片 OCR 默认冻结 | UX8、付款批次公网启用、审批通知、轻业务增强和持续上线门禁的后续合同顺序;图片 OCR 仅在用户明确重启评估时另建合同 | 不直接启动 HOLD 项、不新建综合规划文档、不改业务代码、不部署 |
| `P2AUTO` | `issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv` | 已收口:自动化优先回归和样票 provider 门禁完成;P2AF 后 provider 默认结论为 `FREEZE_BY_DEFAULT` | 凭据/样票掩码核对、后端 focused、前端构建、高风险确认、隔离业务流、隔离付款批次、公网 readiness/PDF live OCR、移动/企业微信自动化、OCR provider-only 脚本 | 不部署、不开放图片 OCR、不打开公网 `payment_batch_v1`、不自动选择未登记图片样票 |
| `P2AF` | `issues/2026-05-16_22-11-10-p2-automatable-followup.csv` | 已收口:可自动实施收口完成 | 图片 OCR 默认冻结纠偏、QA 脚本语义、安全回归聚合、付款批次公网关闭态只读门禁、UX8 自动矩阵扫尾;报告 `artifacts/qa-flow/p2-safe-regression-20260516-222222/` | 不部署、不开放图片 OCR、不启用公网 `payment_batch_v1`、不做业务实现 |
旧 Issue CSV 不删除、不批量回写、不移动到归档目录。若新治理流替代旧合同,只在新 CSV 的 `Notes` 或本索引说明 supersedes,旧文件保留历史审计语义。
@@ -1,9 +1,9 @@
ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes
"P2Q-0","P2OCRS 后续队列建档","建立 P2OCRS 后全量后续任务队列合同,只锁定启动顺序、前置条件、后续合同 slug 和冻结边界,不执行任何业务功能开发。","1) CSV 校验通过;2) 当前事实链以 P2-OCR-SAMPLE=HOLD_FOR_SAMPLE 为基线;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret 或远端 env;5) 后续实现均必须另建独立 Issue CSV。","受影响流程:P2 后续派工、图片 OCR、UX8、付款批次公网启用、审批通知、轻业务增强和上线门禁;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv;人工核对本 CSV 不含业务代码、API/schema、部署或生产操作。","python3|manual","DONE","DONE","DONE","issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv","[]","QueueScope=DONE; no runtime effect; rollback=delete this CSV and doc status updates before commit."
"P2Q-1","图片 OCR provider 回归启动门槛","锁定 P2-OCR-IMAGE-REGRESSION 的启动条件:只有出现授权图片样票、安全别名和脱敏规则确认后,才新建 provider 回归合同。","1) 未提供授权图片样票时不启动真实图片 provider 回归;2) 仓库只记录 SAMPLE-IMG-* 别名、格式、大小、状态、字段命中摘要和失败原因;3) 不开放图片 OCR;4) 不提交真实票据或敏感字段;5) 结论枚举为 GO_TO_IMPLEMENT、HOLD_FOR_SAMPLE、FREEZE。","受影响流程:图片样票授权 -> 脱敏确认 -> 真实 provider 回归 -> P2-OCR-V1 是否启动;验证步骤:人工核对 P2-OCR-SAMPLE Notes、docs/报销发票附件规则.md 和 docs/需求-报销发票OCR规约.md;rg -n 'P2OCRS|HOLD_FOR_SAMPLE|SAMPLE-IMG|图片 OCR|image_native' docs issues server/src client/tests scripts。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/报销发票附件规则.md|docs/需求-报销发票OCR规约.md","[""P2Q-0""]","NextContract=issues/<timestamp>-p2-ocr-image-provider-regression.csv; CurrentDecision=WAIT_FOR_AUTHORIZED_IMAGE_SAMPLE; no provider call until sample evidence exists."
"P2Q-0","P2OCRS 后续队列建档","建立 P2OCRS 后全量后续任务队列合同,只锁定启动顺序、前置条件、后续合同 slug 和冻结边界,不执行任何业务功能开发。","1) CSV 校验通过;2) P2AF 后当前事实链以图片 OCR=FREEZE_BY_DEFAULT 为基线;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret 或远端 env;5) 后续实现均必须另建独立 Issue CSV。","受影响流程:P2 后续派工、图片 OCR、UX8、付款批次公网启用、审批通知、轻业务增强和上线门禁;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv;人工核对本 CSV 不含业务代码、API/schema、部署或生产操作。","python3|manual","DONE","DONE","DONE","issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv","[]","QueueScope=DONE; no runtime effect; P2AF correction=current image OCR default is FREEZE_BY_DEFAULT, not a mainline sample wait."
"P2Q-1","图片 OCR provider 回归启动门槛","锁定 P2-OCR-IMAGE-REGRESSION 的启动条件:图片 OCR 默认冻结;只有用户明确重启图片 OCR 评估并提供授权图片样票、安全别名和脱敏规则确认后,才新建 provider 回归合同。","1) 默认不启动真实图片 provider 回归;2) 仓库只记录 SAMPLE-IMG-* 别名、格式、大小、状态、字段命中摘要和失败原因;3) 不开放图片 OCR;4) 不提交真实票据或敏感字段;5) 结论枚举为 GO_TO_IMPLEMENT、HOLD_FOR_SAMPLE、FREEZE_BY_DEFAULT。","受影响流程:用户明确重启图片 OCR 评估 -> 图片样票授权 -> 脱敏确认 -> 真实 provider 回归 -> P2-OCR-V1 是否启动;验证步骤:人工核对 P2-OCR-SAMPLE Notes、docs/报销发票附件规则.md 和 docs/需求-报销发票OCR规约.md;rg -n 'P2OCRS|FREEZE_BY_DEFAULT|SAMPLE-IMG|图片 OCR|image_native' docs issues server/src client/tests scripts。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/报销发票附件规则.md|docs/需求-报销发票OCR规约.md","[""P2Q-0""]","NextContract=issues/<timestamp>-p2-ocr-image-provider-regression.csv; CurrentDecision=FREEZE_BY_DEFAULT_UNLESS_USER_RESTARTS_IMAGE_OCR; no provider call until explicit evaluation approval and sample evidence exist."
"P2Q-2","UX8 真实反馈队列","确认无授权图片样票时,默认可执行队列转向 UX8 真实反馈池;继续使用既有 UX8 CSV,不新建同类 CSV。","1) UX8-1..5 只有真实截图、设备、角色、页面、复现步骤或明确频次时才实施;2) 移动采购创建仍作为新能力评估,不并入普通 UX 修复;3) 体验修复不新增后端字段、API、状态机或业务域;4) 无新反馈时只保持 TODO 和观察;5) 需要视觉验证时覆盖 320/360/375/390/393/414/430。","受影响流程:移动首页、详情扫读、财务摘要、移动采购评估、列表卡片反馈;验证步骤:人工核对 issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv;rg -n 'UX8-1|UX8-2|UX8-3|UX8-4|UX8-5|移动采购创建|真实反馈' docs issues。","manual|rg|playwright","DONE","DONE","DONE","issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv|docs/产品设计规则.md|docs/trialrun/人工试运行报告.md","[""P2Q-0""]","NextContract=existing UX8 CSV; CurrentDecision=KEEP_FEEDBACK_POOL; no UI change without reproducible feedback."
"P2Q-3","P2-FIN-LIVE 公网启用窗口门槛","锁定付款批次公网启用窗口必须独立于 P2-FIN-V1;只有用户批准公网验收窗口、财务/复核参与人、flag 启停和回滚联系人后才启动。","1) P2-FIN-LIVE 必须另建 CSV;2) 不改变 API 契约,只受控启停公网 payment_batch_v1;3) 验收覆盖财务创建、复核、执行、审计、导出和 flag off 回滚;4) 不接真实支付、不写 ERP 实时凭证;5) 不执行生产恢复或数据库重置。","受影响流程:审批通过报销 -> 公网付款批次创建 -> 复核 -> 执行标记 -> AP 导出 -> flag off 回滚;验证步骤:人工核对 P2-FIN-V1 证据和 P2-FIN-DECISION 结论;rg -n 'P2-FIN-V1|P2-FIN-DECISION|payment_batch_v1|PAYMENT_BATCH|EXPORT_AP_OPERATIONS|flag_force_off' docs issues server/src client/tests。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv|issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv|docs/trialrun/人工试运行报告.md","[""P2Q-0""]","NextContract=issues/<timestamp>-p2-fin-payment-batch-live-enable.csv; CurrentDecision=WAIT_FOR_LIVE_WINDOW_APPROVAL; public payment_batch_v1 remains off."
"P2Q-4","P2-OCR-V1 最小实现门槛","锁定图片 OCR 最小实现只能在 P2-OCR-IMAGE-REGRESSION=GO_TO_IMPLEMENT 后启动,且必须独立声明入口、MIME allowlist、provider、字段、审计、flag 和 PDF-only 兼容。","1) 未满足授权图片样票和真实图片 provider 回归前不得启动;2) 不默认开放拍照 capture、OFD、多票种或 AI 自动处理;3) PDF-only 流程必须不回归;4) 实现合同必须包含权限、审计和回滚;5) 不从本队列自动继承 API/schema/UI 变化。","受影响流程:图片发票上传 -> provider 识别 -> 字段归一化 -> 查重 -> 人工复核 -> flag off 回滚;验证步骤:人工核对 P2Q-1 结论和 P2-OCR-SAMPLE 前置;rg -n 'P2-OCR-V1|图片 OCR|PDF-only|SAMPLE-IMG|feature flag|provider|字段归一化' docs issues。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/需求-报销发票OCR规约.md|docs/报销发票附件规则.md","[""P2Q-1""]","NextContract=issues/<timestamp>-p2-ocr-image-v1.csv; CurrentDecision=BLOCKED_BY_SAMPLE_REGRESSION; no implementation now."
"P2Q-4","P2-OCR-V1 最小实现门槛","锁定图片 OCR 最小实现默认冻结;只有用户明确重启评估且 P2-OCR-IMAGE-REGRESSION=GO_TO_IMPLEMENT 后才可启动,并必须独立声明入口、MIME allowlist、provider、字段、审计、flag 和 PDF-only 兼容。","1) 默认不启动图片 OCR 实现;2) 不默认开放拍照 capture、OFD、多票种或 AI 自动处理;3) PDF-only 流程必须不回归;4) 实现合同必须包含权限、审计和回滚;5) 不从本队列自动继承 API/schema/UI 变化。","受影响流程:未来显式重启时的图片发票上传 -> provider 识别 -> 字段归一化 -> 查重 -> 人工复核 -> flag off 回滚;验证步骤:人工核对 P2Q-1 结论和 P2-OCR-SAMPLE 前置;rg -n 'P2-OCR-V1|图片 OCR|PDF-only|SAMPLE-IMG|feature flag|provider|字段归一化|FREEZE_BY_DEFAULT' docs issues。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/需求-报销发票OCR规约.md|docs/报销发票附件规则.md","[""P2Q-1""]","NextContract=issues/<timestamp>-p2-ocr-image-v1.csv; CurrentDecision=FREEZE_BY_DEFAULT; no implementation now."
"P2Q-5","P2-WF 审批通知扩展门槛","锁定审批通知扩展先走决策合同;只有明确通知痛点、模板清单、收件范围或转审扩展需求时才进入实现。","1) 企业微信个人应用消息和站内通知继续为正式通道;2) 邮件必须先确认 SMTP、发件域、退信处理、收件范围和脱敏策略;3) 缺邮件配置时只能 SKIP;4) 不进入复杂 BPM、审批设计器或企业微信原生审批;5) 实现项必须另建合同。","受影响流程:审批待办、催办、超时提醒、通知 deeplink、企业微信个人应用消息、可选邮件;验证步骤:人工核对 P2D-5、WF8 证据和审批/企业微信规约;rg -n 'P2-WF|通知模板|偏好|邮件|SMTP|企业微信个人应用消息|复杂 BPM|审批设计器' docs issues。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_00-19-21-p2-decision-followup.csv|issues/2026-05-13_18-23-52-wf8-approval-notification.csv|docs/需求-统一审批中心规约.md|docs/需求-企业微信基础设施规约.md","[""P2Q-0""]","NextContract=issues/<timestamp>-p2-wf-notification-decision.csv; CurrentDecision=HOLD_FOR_REAL_PAIN_OR_CONFIG."
"P2Q-6","P2-BIZ 轻业务增强门槛","锁定轻业务增强先走决策合同;供应商准入、费用提示继续优化、项目/采购摘要、合同归档细化、资产盘点体验必须明确频次、owner 和验收样例后才进入实现。","1) P2-BIZ 不牵连付款批次或 OCR;2) 是否影响 API/schema 必须先说明;3) ERP、AI、完整差旅、重预算继续冻结;4) 供应商、费用、项目、合同、资产候选各自有 owner 和验收样例后才能开发;5) 实现项另建合同。","受影响流程:采购、费用提示、项目摘要、合同归档、资产盘点;验证步骤:人工核对 P2D-6、BIZ8、采购/合同/项目规约和 FBA;rg -n 'P2-BIZ|供应商准入|费用提示|项目摘要|采购摘要|合同归档|资产盘点|ERP|AI|完整差旅|重预算' docs issues。","manual|rg","DONE","DONE","DONE","issues/2026-05-16_00-19-21-p2-decision-followup.csv|issues/2026-05-13_18-23-53-biz8-finance-ocr-project.csv|docs/需求-采购费用审批规约.md|docs/需求-合同附件归档规约.md|docs/需求-项目轻管理规约.md","[""P2Q-0""]","NextContract=issues/<timestamp>-p2-biz-light-enhancement-decision.csv; CurrentDecision=HOLD_FOR_FREQUENCY_OWNER_ACCEPTANCE."
"P2Q-7","持续上线门禁","锁定所有后续实现合同必须自带上线门禁,不默认新建 QAOPS10;涉及公网可测代码变更时再补 /ready、public bundle、live smoke、真实 OCR 或 SKIP、移动矩阵和 Go/No-Go。","1) 非代码决策/样票阶段不部署;2) 实现类合同必须说明是否部署;3) 公网付款批次和图片 OCR 不可混入同一上线窗口;4) 不执行生产恢复、不重置数据库、不打印远端 env;5) 恢复演练必须单独批准窗口。","受影响流程:后续 P2 实现、上线硬化、真实 OCR、公网付款批次和移动矩阵;验证步骤:人工核对 docs/试运行与自动化验证手册.md、docs/trialrun/发布试运行准备清单.md、docs/trialrun/OPS7运维交接Runbook.md;rg -n 'ready|public bundle|live smoke|真实 OCR|Go/No-Go|恢复演练|重置数据库|远端 env' docs scripts issues。","manual|rg","DONE","DONE","DONE","docs/试运行与自动化验证手册.md|docs/trialrun/发布试运行准备清单.md|docs/trialrun/OPS7运维交接Runbook.md|scripts/qa","[""P2Q-0""]","RollingGate=DONE; no QAOPS10 by default; each implementation contract carries gates."
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 P2Q-0 P2OCRS 后续队列建档 建立 P2OCRS 后全量后续任务队列合同,只锁定启动顺序、前置条件、后续合同 slug 和冻结边界,不执行任何业务功能开发。 1) CSV 校验通过;2) 当前事实链以 P2-OCR-SAMPLE=HOLD_FOR_SAMPLE 为基线;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret 或远端 env;5) 后续实现均必须另建独立 Issue CSV。 1) CSV 校验通过;2) P2AF 后当前事实链以图片 OCR=FREEZE_BY_DEFAULT 为基线;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret 或远端 env;5) 后续实现均必须另建独立 Issue CSV。 受影响流程:P2 后续派工、图片 OCR、UX8、付款批次公网启用、审批通知、轻业务增强和上线门禁;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv;人工核对本 CSV 不含业务代码、API/schema、部署或生产操作。 python3|manual DONE DONE DONE issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv [] QueueScope=DONE; no runtime effect; rollback=delete this CSV and doc status updates before commit. QueueScope=DONE; no runtime effect; P2AF correction=current image OCR default is FREEZE_BY_DEFAULT, not a mainline sample wait.
3 P2Q-1 图片 OCR provider 回归启动门槛 锁定 P2-OCR-IMAGE-REGRESSION 的启动条件:只有出现授权图片样票、安全别名和脱敏规则确认后,才新建 provider 回归合同。 锁定 P2-OCR-IMAGE-REGRESSION 的启动条件:图片 OCR 默认冻结;只有用户明确重启图片 OCR 评估并提供授权图片样票、安全别名和脱敏规则确认后,才新建 provider 回归合同。 1) 未提供授权图片样票时不启动真实图片 provider 回归;2) 仓库只记录 SAMPLE-IMG-* 别名、格式、大小、状态、字段命中摘要和失败原因;3) 不开放图片 OCR;4) 不提交真实票据或敏感字段;5) 结论枚举为 GO_TO_IMPLEMENT、HOLD_FOR_SAMPLE、FREEZE。 1) 默认不启动真实图片 provider 回归;2) 仓库只记录 SAMPLE-IMG-* 别名、格式、大小、状态、字段命中摘要和失败原因;3) 不开放图片 OCR;4) 不提交真实票据或敏感字段;5) 结论枚举为 GO_TO_IMPLEMENT、HOLD_FOR_SAMPLE、FREEZE_BY_DEFAULT。 受影响流程:图片样票授权 -> 脱敏确认 -> 真实 provider 回归 -> P2-OCR-V1 是否启动;验证步骤:人工核对 P2-OCR-SAMPLE Notes、docs/报销发票附件规则.md 和 docs/需求-报销发票OCR规约.md;rg -n 'P2OCRS|HOLD_FOR_SAMPLE|SAMPLE-IMG|图片 OCR|image_native' docs issues server/src client/tests scripts。 受影响流程:用户明确重启图片 OCR 评估 -> 图片样票授权 -> 脱敏确认 -> 真实 provider 回归 -> P2-OCR-V1 是否启动;验证步骤:人工核对 P2-OCR-SAMPLE Notes、docs/报销发票附件规则.md 和 docs/需求-报销发票OCR规约.md;rg -n 'P2OCRS|FREEZE_BY_DEFAULT|SAMPLE-IMG|图片 OCR|image_native' docs issues server/src client/tests scripts。 manual|rg DONE DONE DONE issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/报销发票附件规则.md|docs/需求-报销发票OCR规约.md ["P2Q-0"] NextContract=issues/<timestamp>-p2-ocr-image-provider-regression.csv; CurrentDecision=WAIT_FOR_AUTHORIZED_IMAGE_SAMPLE; no provider call until sample evidence exists. NextContract=issues/<timestamp>-p2-ocr-image-provider-regression.csv; CurrentDecision=FREEZE_BY_DEFAULT_UNLESS_USER_RESTARTS_IMAGE_OCR; no provider call until explicit evaluation approval and sample evidence exist.
4 P2Q-2 UX8 真实反馈队列 确认无授权图片样票时,默认可执行队列转向 UX8 真实反馈池;继续使用既有 UX8 CSV,不新建同类 CSV。 1) UX8-1..5 只有真实截图、设备、角色、页面、复现步骤或明确频次时才实施;2) 移动采购创建仍作为新能力评估,不并入普通 UX 修复;3) 体验修复不新增后端字段、API、状态机或业务域;4) 无新反馈时只保持 TODO 和观察;5) 需要视觉验证时覆盖 320/360/375/390/393/414/430。 受影响流程:移动首页、详情扫读、财务摘要、移动采购评估、列表卡片反馈;验证步骤:人工核对 issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv;rg -n 'UX8-1|UX8-2|UX8-3|UX8-4|UX8-5|移动采购创建|真实反馈' docs issues。 manual|rg|playwright DONE DONE DONE issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv|docs/产品设计规则.md|docs/trialrun/人工试运行报告.md ["P2Q-0"] NextContract=existing UX8 CSV; CurrentDecision=KEEP_FEEDBACK_POOL; no UI change without reproducible feedback.
5 P2Q-3 P2-FIN-LIVE 公网启用窗口门槛 锁定付款批次公网启用窗口必须独立于 P2-FIN-V1;只有用户批准公网验收窗口、财务/复核参与人、flag 启停和回滚联系人后才启动。 1) P2-FIN-LIVE 必须另建 CSV;2) 不改变 API 契约,只受控启停公网 payment_batch_v1;3) 验收覆盖财务创建、复核、执行、审计、导出和 flag off 回滚;4) 不接真实支付、不写 ERP 实时凭证;5) 不执行生产恢复或数据库重置。 受影响流程:审批通过报销 -> 公网付款批次创建 -> 复核 -> 执行标记 -> AP 导出 -> flag off 回滚;验证步骤:人工核对 P2-FIN-V1 证据和 P2-FIN-DECISION 结论;rg -n 'P2-FIN-V1|P2-FIN-DECISION|payment_batch_v1|PAYMENT_BATCH|EXPORT_AP_OPERATIONS|flag_force_off' docs issues server/src client/tests。 manual|rg DONE DONE DONE issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv|issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv|docs/trialrun/人工试运行报告.md ["P2Q-0"] NextContract=issues/<timestamp>-p2-fin-payment-batch-live-enable.csv; CurrentDecision=WAIT_FOR_LIVE_WINDOW_APPROVAL; public payment_batch_v1 remains off.
6 P2Q-4 P2-OCR-V1 最小实现门槛 锁定图片 OCR 最小实现只能在 P2-OCR-IMAGE-REGRESSION=GO_TO_IMPLEMENT 后启动,且必须独立声明入口、MIME allowlist、provider、字段、审计、flag 和 PDF-only 兼容。 锁定图片 OCR 最小实现默认冻结;只有用户明确重启评估且 P2-OCR-IMAGE-REGRESSION=GO_TO_IMPLEMENT 后才可启动,并必须独立声明入口、MIME allowlist、provider、字段、审计、flag 和 PDF-only 兼容。 1) 未满足授权图片样票和真实图片 provider 回归前不得启动;2) 不默认开放拍照 capture、OFD、多票种或 AI 自动处理;3) PDF-only 流程必须不回归;4) 实现合同必须包含权限、审计和回滚;5) 不从本队列自动继承 API/schema/UI 变化。 1) 默认不启动图片 OCR 实现;2) 不默认开放拍照 capture、OFD、多票种或 AI 自动处理;3) PDF-only 流程必须不回归;4) 实现合同必须包含权限、审计和回滚;5) 不从本队列自动继承 API/schema/UI 变化。 受影响流程:图片发票上传 -> provider 识别 -> 字段归一化 -> 查重 -> 人工复核 -> flag off 回滚;验证步骤:人工核对 P2Q-1 结论和 P2-OCR-SAMPLE 前置;rg -n 'P2-OCR-V1|图片 OCR|PDF-only|SAMPLE-IMG|feature flag|provider|字段归一化' docs issues。 受影响流程:未来显式重启时的图片发票上传 -> provider 识别 -> 字段归一化 -> 查重 -> 人工复核 -> flag off 回滚;验证步骤:人工核对 P2Q-1 结论和 P2-OCR-SAMPLE 前置;rg -n 'P2-OCR-V1|图片 OCR|PDF-only|SAMPLE-IMG|feature flag|provider|字段归一化|FREEZE_BY_DEFAULT' docs issues。 manual|rg DONE DONE DONE issues/2026-05-16_10-15-21-p2-ocr-image-sample-governance.csv|docs/需求-报销发票OCR规约.md|docs/报销发票附件规则.md ["P2Q-1"] NextContract=issues/<timestamp>-p2-ocr-image-v1.csv; CurrentDecision=BLOCKED_BY_SAMPLE_REGRESSION; no implementation now. NextContract=issues/<timestamp>-p2-ocr-image-v1.csv; CurrentDecision=FREEZE_BY_DEFAULT; no implementation now.
7 P2Q-5 P2-WF 审批通知扩展门槛 锁定审批通知扩展先走决策合同;只有明确通知痛点、模板清单、收件范围或转审扩展需求时才进入实现。 1) 企业微信个人应用消息和站内通知继续为正式通道;2) 邮件必须先确认 SMTP、发件域、退信处理、收件范围和脱敏策略;3) 缺邮件配置时只能 SKIP;4) 不进入复杂 BPM、审批设计器或企业微信原生审批;5) 实现项必须另建合同。 受影响流程:审批待办、催办、超时提醒、通知 deeplink、企业微信个人应用消息、可选邮件;验证步骤:人工核对 P2D-5、WF8 证据和审批/企业微信规约;rg -n 'P2-WF|通知模板|偏好|邮件|SMTP|企业微信个人应用消息|复杂 BPM|审批设计器' docs issues。 manual|rg DONE DONE DONE issues/2026-05-16_00-19-21-p2-decision-followup.csv|issues/2026-05-13_18-23-52-wf8-approval-notification.csv|docs/需求-统一审批中心规约.md|docs/需求-企业微信基础设施规约.md ["P2Q-0"] NextContract=issues/<timestamp>-p2-wf-notification-decision.csv; CurrentDecision=HOLD_FOR_REAL_PAIN_OR_CONFIG.
8 P2Q-6 P2-BIZ 轻业务增强门槛 锁定轻业务增强先走决策合同;供应商准入、费用提示继续优化、项目/采购摘要、合同归档细化、资产盘点体验必须明确频次、owner 和验收样例后才进入实现。 1) P2-BIZ 不牵连付款批次或 OCR;2) 是否影响 API/schema 必须先说明;3) ERP、AI、完整差旅、重预算继续冻结;4) 供应商、费用、项目、合同、资产候选各自有 owner 和验收样例后才能开发;5) 实现项另建合同。 受影响流程:采购、费用提示、项目摘要、合同归档、资产盘点;验证步骤:人工核对 P2D-6、BIZ8、采购/合同/项目规约和 FBA;rg -n 'P2-BIZ|供应商准入|费用提示|项目摘要|采购摘要|合同归档|资产盘点|ERP|AI|完整差旅|重预算' docs issues。 manual|rg DONE DONE DONE issues/2026-05-16_00-19-21-p2-decision-followup.csv|issues/2026-05-13_18-23-53-biz8-finance-ocr-project.csv|docs/需求-采购费用审批规约.md|docs/需求-合同附件归档规约.md|docs/需求-项目轻管理规约.md ["P2Q-0"] NextContract=issues/<timestamp>-p2-biz-light-enhancement-decision.csv; CurrentDecision=HOLD_FOR_FREQUENCY_OWNER_ACCEPTANCE.
9 P2Q-7 持续上线门禁 锁定所有后续实现合同必须自带上线门禁,不默认新建 QAOPS10;涉及公网可测代码变更时再补 /ready、public bundle、live smoke、真实 OCR 或 SKIP、移动矩阵和 Go/No-Go。 1) 非代码决策/样票阶段不部署;2) 实现类合同必须说明是否部署;3) 公网付款批次和图片 OCR 不可混入同一上线窗口;4) 不执行生产恢复、不重置数据库、不打印远端 env;5) 恢复演练必须单独批准窗口。 受影响流程:后续 P2 实现、上线硬化、真实 OCR、公网付款批次和移动矩阵;验证步骤:人工核对 docs/试运行与自动化验证手册.md、docs/trialrun/发布试运行准备清单.md、docs/trialrun/OPS7运维交接Runbook.md;rg -n 'ready|public bundle|live smoke|真实 OCR|Go/No-Go|恢复演练|重置数据库|远端 env' docs scripts issues。 manual|rg DONE DONE DONE docs/试运行与自动化验证手册.md|docs/trialrun/发布试运行准备清单.md|docs/trialrun/OPS7运维交接Runbook.md|scripts/qa ["P2Q-0"] RollingGate=DONE; no QAOPS10 by default; each implementation contract carries gates.
@@ -7,5 +7,5 @@
"P2AUTO-5","隔离业务流自动化","在隔离临时库中运行核心业务流 flag-off 门禁,并单独运行付款批次 flag-on 闭环;付款批次结果不得解释为公网启用。","1) 核心业务流通过或失败有明确用例;2) payment_batch_v1 公网保持关闭;3) 付款批次仅隔离环境 flag-on;4) 报告路径写入 Notes;5) 不执行生产数据写入。","受影响流程:登录、企业微信入口、报销、审批、请假、采购、权限治理、付款批次隔离闭环;验证步骤:BUSINESS_FLOW_GROUPS=auth,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;cd client && E2E_BASE_URL=<local-or-isolated-url> npx playwright test tests/e2e/reimbursement-payment-batch-flow.spec.ts --workers=1 --reporter=list。","bash|playwright","DONE","DONE","DONE","scripts/qa/run-business-flow-gates.sh|client/tests/e2e/reimbursement-payment-batch-flow.spec.ts|artifacts/qa-flow","[""P2AUTO-4""]","PASS: core isolated business flow auth/reimbursement/approval/leave/procurement/governance passed, report artifacts/qa-flow/business-flow-20260516-203001/summary.txt; payment batch isolated flag-on flow 1 passed, report artifacts/qa-flow/business-flow-20260516-203856/summary.txt; public payment_batch_v1 remains off."
"P2AUTO-6","公网自动化门禁","在公网只跑 /ready、public bundle、live smoke、PDF live OCR、pending OCR 扫描和 live smoke Playwright,不执行公网付款批次写入。","1) /ready 通过;2) public bundle findings=0;3) live smoke 通过;4) PDF live OCR 进入可解释终态;5) pending OCR 缺 DATABASE_URL 时只作非阻断 SKIP。","受影响流程:公网健康、登录 smoke、PDF live OCR、企业微信 config、公网资源;验证步骤:set -a && source ~/.hyb-oa/live-smoke.env && set +a;QA_ISSUE_ID=P2AUTO LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh;cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/live-smoke.spec.ts --workers=1 --reporter=list。","bash|node|playwright","DONE","DONE","DONE","scripts/qa/run-live-smoke-readiness.sh|client/tests/e2e/live-smoke.spec.ts|artifacts/qa-flow","[""P2AUTO-5""]","PASS: live readiness report artifacts/qa-flow/live-smoke-readiness-20260516-204157; /ready ok, public bundle findings=0, live smoke 3 passed, PDF live OCR 1 passed with duplicate-invoice explainable terminal state; pending OCR missing local DATABASE_URL recorded SKIP; no public payment batch writes."
"P2AUTO-7","移动与企业微信自动化门禁","执行移动矩阵、企业微信 UA、入口/绑定/deeplink 自动化;真机只保留少量真实差异确认,不阻断可自动化收口。","1) 移动矩阵通过;2) WeCom UA/入口/绑定自动化通过;3) 企业微信真机差异不被自动化替代;4) 发现移动缺陷进入 UX8;5) 不新增移动业务能力。","受影响流程:/mobile、审批、报销、企业微信入口、绑定、deeplink 和移动布局;验证步骤:cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list;cd client && npx playwright test tests/e2e/wecom-entry.spec.ts tests/e2e/wecom-first-bind.spec.ts tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list。","playwright|manual","DONE","DONE","DONE","client/tests/e2e|docs/trialrun/人工试运行报告.md","[""P2AUTO-6""]","PASS: public DG7/R124 mobile matrix 6 passed; local auth business-flow covered wecom-entry/wecom-first-bind; R6 WeCom rendering matrix 8 passed after subpixel test assertion normalization; real-device delta remains manual-only when user requests."
"P2AUTO-8","OCR provider 样票自动化缺口","新增并运行 provider-only 样票 QA 脚本;PDF 样票可回归,图片样票未在 manifest 或环境变量登记时记录 SKIP,不得写 PASS。","1) scripts/qa/check-ocr-provider-samples.mjs 存在且 node --check 通过;2) 无样票时输出 SKIP;3) 有样票时输出脱敏 JSON 摘要;4) 不输出票面、税号、手机号、二维码、完整号码或真实路径;5) 不开放图片 OCR。","受影响流程:PDF/image provider 样票 -> Tencent OCR -> 字段命中摘要 -> GO/HOLD/FREEZE 决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;OCR_PROVIDER_SAMPLE_MANIFEST=/safe/ocr-samples.json node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;无授权图片样票或 manifest 时写 SKIP。","node|manual","DONE","DONE","DONE","scripts/qa/check-ocr-provider-samples.mjs|external","[""P2AUTO-1""]","QA script added and node --check passed. Provider-only run with current safe env found PDF sample only and no image manifest/env; local Tencent provider credentials not present, so output status=SKIP decision=HOLD_FOR_SAMPLE. Do not auto-select arbitrary image candidates; image OCR remains closed."
"P2AUTO-8","OCR provider 样票自动化缺口","新增并运行 provider-only 样票 QA 脚本;PDF 样票可回归,图片 OCR 默认冻结,未显式进入图片评估时不得把缺图片样票写成主线 HOLD。","1) scripts/qa/check-ocr-provider-samples.mjs 存在且 node --check 通过;2) 默认无图片评估时输出 FREEZE_BY_DEFAULT;3) 有显式样票时输出脱敏 JSON 摘要;4) 不输出票面、税号、手机号、二维码、完整号码或真实路径;5) 不开放图片 OCR。","受影响流程:PDF provider 样票 -> Tencent OCR 可用性摘要;默认图片 OCR -> FREEZE_BY_DEFAULT;显式图片评估 -> 字段命中摘要 -> GO/HOLD 决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;OCR_IMAGE_OCR_EVALUATION=1 node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json。","node|manual","DONE","DONE","DONE","scripts/qa/check-ocr-provider-samples.mjs|external","[""P2AUTO-1""]","P2AF correction: default provider-only run with current safe env should report decision=FREEZE_BY_DEFAULT when image evaluation is not explicit. Do not auto-select arbitrary image candidates; image OCR remains closed."
"P2AUTO-9","收口回填与中文提交","汇总 P2AUTO 自动化证据,回填 CSV、人工试运行报告、索引和事实源矩阵,完成最终校验和中文 commit。","1) 已执行项按真实 Test_Method 回填;2) 未执行外部项记录 SKIP 或后续条件;3) validate、audit-docs、rg、git diff --check 通过;4) 中文 commit 引用 P2AUTO;5) 明确未部署。","流程级验证:validate_issues_csv.py 本 CSV;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'P2AUTO|PDF live OCR|图片样票|payment_batch_v1|SKIP|live smoke|企业微信' docs issues scripts;git diff --check;git status --short。","python3|node|rg|git|manual","DONE","DONE","DONE","issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[""P2AUTO-2"",""P2AUTO-3"",""P2AUTO-4"",""P2AUTO-5"",""P2AUTO-6"",""P2AUTO-7"",""P2AUTO-8""]","Closeout=PASS; validate_issues_csv passed; audit-docs errors=0 warnings=1 existing unregistered docs files=24; rg keyword sweep explainable; git diff --check passed; not deployed; no business API/schema/UI/runtime change."
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
7 P2AUTO-5 隔离业务流自动化 在隔离临时库中运行核心业务流 flag-off 门禁,并单独运行付款批次 flag-on 闭环;付款批次结果不得解释为公网启用。 1) 核心业务流通过或失败有明确用例;2) payment_batch_v1 公网保持关闭;3) 付款批次仅隔离环境 flag-on;4) 报告路径写入 Notes;5) 不执行生产数据写入。 受影响流程:登录、企业微信入口、报销、审批、请假、采购、权限治理、付款批次隔离闭环;验证步骤:BUSINESS_FLOW_GROUPS=auth,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;cd client && E2E_BASE_URL=<local-or-isolated-url> npx playwright test tests/e2e/reimbursement-payment-batch-flow.spec.ts --workers=1 --reporter=list。 bash|playwright DONE DONE DONE scripts/qa/run-business-flow-gates.sh|client/tests/e2e/reimbursement-payment-batch-flow.spec.ts|artifacts/qa-flow ["P2AUTO-4"] PASS: core isolated business flow auth/reimbursement/approval/leave/procurement/governance passed, report artifacts/qa-flow/business-flow-20260516-203001/summary.txt; payment batch isolated flag-on flow 1 passed, report artifacts/qa-flow/business-flow-20260516-203856/summary.txt; public payment_batch_v1 remains off.
8 P2AUTO-6 公网自动化门禁 在公网只跑 /ready、public bundle、live smoke、PDF live OCR、pending OCR 扫描和 live smoke Playwright,不执行公网付款批次写入。 1) /ready 通过;2) public bundle findings=0;3) live smoke 通过;4) PDF live OCR 进入可解释终态;5) pending OCR 缺 DATABASE_URL 时只作非阻断 SKIP。 受影响流程:公网健康、登录 smoke、PDF live OCR、企业微信 config、公网资源;验证步骤:set -a && source ~/.hyb-oa/live-smoke.env && set +a;QA_ISSUE_ID=P2AUTO LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh;cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/live-smoke.spec.ts --workers=1 --reporter=list。 bash|node|playwright DONE DONE DONE scripts/qa/run-live-smoke-readiness.sh|client/tests/e2e/live-smoke.spec.ts|artifacts/qa-flow ["P2AUTO-5"] PASS: live readiness report artifacts/qa-flow/live-smoke-readiness-20260516-204157; /ready ok, public bundle findings=0, live smoke 3 passed, PDF live OCR 1 passed with duplicate-invoice explainable terminal state; pending OCR missing local DATABASE_URL recorded SKIP; no public payment batch writes.
9 P2AUTO-7 移动与企业微信自动化门禁 执行移动矩阵、企业微信 UA、入口/绑定/deeplink 自动化;真机只保留少量真实差异确认,不阻断可自动化收口。 1) 移动矩阵通过;2) WeCom UA/入口/绑定自动化通过;3) 企业微信真机差异不被自动化替代;4) 发现移动缺陷进入 UX8;5) 不新增移动业务能力。 受影响流程:/mobile、审批、报销、企业微信入口、绑定、deeplink 和移动布局;验证步骤:cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list;cd client && npx playwright test tests/e2e/wecom-entry.spec.ts tests/e2e/wecom-first-bind.spec.ts tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list。 playwright|manual DONE DONE DONE client/tests/e2e|docs/trialrun/人工试运行报告.md ["P2AUTO-6"] PASS: public DG7/R124 mobile matrix 6 passed; local auth business-flow covered wecom-entry/wecom-first-bind; R6 WeCom rendering matrix 8 passed after subpixel test assertion normalization; real-device delta remains manual-only when user requests.
10 P2AUTO-8 OCR provider 样票自动化缺口 新增并运行 provider-only 样票 QA 脚本;PDF 样票可回归,图片样票未在 manifest 或环境变量登记时记录 SKIP,不得写 PASS。 新增并运行 provider-only 样票 QA 脚本;PDF 样票可回归,图片 OCR 默认冻结,未显式进入图片评估时不得把缺图片样票写成主线 HOLD。 1) scripts/qa/check-ocr-provider-samples.mjs 存在且 node --check 通过;2) 无样票时输出 SKIP;3) 有样票时输出脱敏 JSON 摘要;4) 不输出票面、税号、手机号、二维码、完整号码或真实路径;5) 不开放图片 OCR。 1) scripts/qa/check-ocr-provider-samples.mjs 存在且 node --check 通过;2) 默认无图片评估时输出 FREEZE_BY_DEFAULT;3) 有显式样票时输出脱敏 JSON 摘要;4) 不输出票面、税号、手机号、二维码、完整号码或真实路径;5) 不开放图片 OCR。 受影响流程:PDF/image provider 样票 -> Tencent OCR -> 字段命中摘要 -> GO/HOLD/FREEZE 决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;OCR_PROVIDER_SAMPLE_MANIFEST=/safe/ocr-samples.json node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;无授权图片样票或 manifest 时写 SKIP。 受影响流程:PDF provider 样票 -> Tencent OCR 可用性摘要;默认图片 OCR -> FREEZE_BY_DEFAULT;显式图片评估 -> 字段命中摘要 -> GO/HOLD 决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;OCR_IMAGE_OCR_EVALUATION=1 node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json。 node|manual DONE DONE DONE scripts/qa/check-ocr-provider-samples.mjs|external ["P2AUTO-1"] QA script added and node --check passed. Provider-only run with current safe env found PDF sample only and no image manifest/env; local Tencent provider credentials not present, so output status=SKIP decision=HOLD_FOR_SAMPLE. Do not auto-select arbitrary image candidates; image OCR remains closed. P2AF correction: default provider-only run with current safe env should report decision=FREEZE_BY_DEFAULT when image evaluation is not explicit. Do not auto-select arbitrary image candidates; image OCR remains closed.
11 P2AUTO-9 收口回填与中文提交 汇总 P2AUTO 自动化证据,回填 CSV、人工试运行报告、索引和事实源矩阵,完成最终校验和中文 commit。 1) 已执行项按真实 Test_Method 回填;2) 未执行外部项记录 SKIP 或后续条件;3) validate、audit-docs、rg、git diff --check 通过;4) 中文 commit 引用 P2AUTO;5) 明确未部署。 流程级验证:validate_issues_csv.py 本 CSV;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'P2AUTO|PDF live OCR|图片样票|payment_batch_v1|SKIP|live smoke|企业微信' docs issues scripts;git diff --check;git status --short。 python3|node|rg|git|manual DONE DONE DONE issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md ["P2AUTO-2","P2AUTO-3","P2AUTO-4","P2AUTO-5","P2AUTO-6","P2AUTO-7","P2AUTO-8"] Closeout=PASS; validate_issues_csv passed; audit-docs errors=0 warnings=1 existing unregistered docs files=24; rg keyword sweep explainable; git diff --check passed; not deployed; no business API/schema/UI/runtime change.
@@ -0,0 +1,8 @@
"ID","Title","Description","Acceptance","Test_Method","Tools","Dev_Status","Review1_Status","Regression_Status","Files","Dependencies","Notes"
"P2AF-0","P2AF 自动实施合同建档","建立 R7E 后可自动实施工作合同,只做口径纠偏、QA 脚本、自动化门禁和既有证据回填,不启动业务功能开发。","1) 本 CSV 校验通过;2) 范围限定 issues/docs/scripts/qa 和必要测试维护;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret;5) 公网 payment_batch_v1 继续关闭,图片 OCR 默认冻结。","受影响流程:后续 P2 派工、OCR PDF-only 口径、付款批次公网关闭态、自动化回归;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_22-11-10-p2-automatable-followup.csv;人工核对不改业务运行时能力。","python3|manual","DONE","DONE","DONE","issues/2026-05-16_22-11-10-p2-automatable-followup.csv","[]","CSV validated; Scope=automatable-followup; baseline=edabce8; no deployment; no runtime capability change."
"P2AF-1","OCR 口径纠偏","把图片发票 OCR 从主线等待样票纠正为 FREEZE_BY_DEFAULT;当前正式能力只维护 PDF-only OCR,图片仅普通附件,未来只有用户明确重启评估才另建合同。","1) P2Q/P2AUTO Notes 不再表达为主线等待图片样票;2) docs/文档索引.md、docs/文档事实源状态矩阵.md、docs/trialrun/人工试运行报告.md 记录 FREEZE_BY_DEFAULT;3) PDF live OCR 样票继续记录为可用;4) 不改 OCR 业务入口;5) 不新建综合规划文档。","受影响流程:PDF 发票上传 -> OCR -> 查重/重复票据可解释终态;图片附件 -> 普通附件材料;验证步骤:rg -n 'FREEZE_BY_DEFAULT|HOLD_FOR_SAMPLE|PDF-only|图片 OCR|普通附件|P2AUTO|P2Q' docs issues scripts;node scripts/qa/audit-docs.mjs --check-registry。","rg|node|manual","DONE","DONE","DONE","issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv|issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[""P2AF-0""]","DefaultDecision=FREEZE_BY_DEFAULT; P2Q/P2AUTO and existing docs corrected; audit-docs errors=0 warnings=1 existing unregistered docs."
"P2AF-2","OCR provider QA 脚本默认冻结语义","调整 scripts/qa/check-ocr-provider-samples.mjs:默认无显式图片 OCR 评估时输出 FREEZE_BY_DEFAULT;只有 OCR_IMAGE_OCR_EVALUATION=1 或显式参数开启时,图片样票缺失才输出 HOLD_FOR_SAMPLE。","1) 默认运行不把缺图片样票视为主线阻断;2) 显式图片评估模式仍支持 manifest/env 图片样票;3) 输出不包含真实路径、税号、手机号、二维码、完整号码或票面内容;4) node --check 通过;5) 不调用图片 OCR,除非显式评估且样票和凭据具备。","受影响流程:provider-only 样票脚本 -> PDF 基线摘要 -> 默认冻结/显式图片评估决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;set -a && source ~/.hyb-oa/live-smoke.env && set +a && node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;OCR_IMAGE_OCR_EVALUATION=1 node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json。","node|bash","DONE","DONE","DONE","scripts/qa/check-ocr-provider-samples.mjs","[""P2AF-1""]","node --check passed; default output decision=FREEZE_BY_DEFAULT imageEvaluation=false with PDF sample alias; explicit OCR_IMAGE_OCR_EVALUATION=1 returns HOLD_FOR_SAMPLE without image sample; no business runtime impact."
"P2AF-3","自动回归聚合脚本","新增 scripts/qa/run-p2-safe-regression.sh,串联后端 focused、前端构建、隔离核心业务流、公网 readiness、移动矩阵、企业微信 UA/渲染和 OCR 默认冻结检查,并生成 artifacts/qa-flow/p2-safe-regression-* 摘要。","1) 脚本默认不部署、不启用公网 payment_batch_v1、不开放图片 OCR;2) 支持 P2_SAFE_SKIP_LIVE=1 和 P2_SAFE_SKIP_BUILD=1;3) 失败时返回非 0 并保留摘要;4) 报告路径可追溯;5) 不打印 secret。","受影响流程:全端自动化门禁聚合;验证步骤:bash scripts/qa/run-p2-safe-regression.sh;必要时 P2_SAFE_SKIP_LIVE=1 bash scripts/qa/run-p2-safe-regression.sh 验证本地聚合;检查 artifacts/qa-flow/p2-safe-regression-*/summary.txt。","bash|npm|node|playwright","DONE","DONE","DONE","scripts/qa/run-p2-safe-regression.sh|artifacts/qa-flow","[""P2AF-2""]","bash scripts/qa/run-p2-safe-regression.sh PASS; report=artifacts/qa-flow/p2-safe-regression-20260516-222222; backend focused 43 tests passed; frontend typecheck/build passed; core isolated business flow PASS; live readiness PASS; OCR default FREEZE_BY_DEFAULT."
"P2AF-4","付款批次公网关闭态只读门禁","新增或复用 QA 脚本验证公网 payment_batch_v1 继续关闭:只允许登录和 GET/只读探测,不创建、复核、执行付款批次。","1) 公网只读检查能证明付款批次关闭态可解释;2) 不执行 POST/PATCH/DELETE 付款批次动作;3) 财务账号只读访问不泄露敏感数据;4) 普通员工/admin-only 不越权;5) 输出脱敏摘要。","受影响流程:公网财务入口/AP/payment-batches 关闭态;验证步骤:set -a && source ~/.hyb-oa/live-smoke.env && set +a;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-payment-batch-flag-off.mjs --json;确认输出只含状态、角色、HTTP 状态和错误码摘要。","node|manual","DONE","DONE","DONE","scripts/qa/check-payment-batch-flag-off.mjs|external","[""P2AF-0""]","ReadOnly=true; PASS: finance /api/payment-batches and /api/ap-operations plus employee/admin /api/payment-batches all returned 409 payment_batch_v1_disabled reason=flag_force_off; no POST/PATCH/DELETE."
"P2AF-5","UX8 自动矩阵扫尾","运行移动/企业微信自动化矩阵,记录 UX8 当前无新真实反馈时保持 TODO;若自动化发现确定性问题,只修复测试前置或明确前端体验缺陷。","1) DG7/R124 公网移动矩阵通过或失败可归因;2) R6 WeCom 渲染矩阵通过或失败可归因;3) UX8-1..5 无新反馈时不强行改 UI;4) 移动采购创建不并入本轮;5) 结果写入 Notes。","受影响流程:移动首页、移动审批/报销/通知、企业微信 UA、UX8 反馈池;验证步骤:cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list;cd client && npx playwright test tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list;人工核对 UX8 CSV 不误置 DONE。","playwright|manual","DONE","DONE","DONE","client/tests/e2e|issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv","[""P2AF-3""]","Public mobile matrix DG7/R124 6 passed; WeCom rendering matrix 8 passed across 320/360/375/390/393/414/430 plus font failure case; UX8-1..5 remain TODO pending real feedback."
"P2AF-6","P2AF 收口回填与提交","回填 P2AF、既有文档和历史连续合同 Notes,运行最终门禁并提交中文 commit。","1) P2AF 状态真实回填;2) validate、audit-docs、rg、git diff --check 通过;3) 中文 commit 引用 P2AF;4) 明确未部署;5) 无未解释工作区变更。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_22-11-10-p2-automatable-followup.csv;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'P2AF|FREEZE_BY_DEFAULT|HOLD_FOR_SAMPLE|PDF-only|图片 OCR|payment_batch_v1|P2AUTO|UX8' docs issues scripts;git diff --check;git status --short。","python3|node|rg|git","DONE","DONE","DONE","issues/2026-05-16_22-11-10-p2-automatable-followup.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[""P2AF-1"",""P2AF-2"",""P2AF-3"",""P2AF-4"",""P2AF-5""]","Closeout=PASS; validate_issues_csv passed; audit-docs errors=0 warnings=1 existing unregistered docs files=24; keyword sweep explainable; git diff --check passed before final commit; not deployed."
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 P2AF-0 P2AF 自动实施合同建档 建立 R7E 后可自动实施工作合同,只做口径纠偏、QA 脚本、自动化门禁和既有证据回填,不启动业务功能开发。 1) 本 CSV 校验通过;2) 范围限定 issues/docs/scripts/qa 和必要测试维护;3) 不新增业务 API/schema/UI/feature flag;4) 不部署、不执行生产恢复、不重置数据库、不打印 secret;5) 公网 payment_batch_v1 继续关闭,图片 OCR 默认冻结。 受影响流程:后续 P2 派工、OCR PDF-only 口径、付款批次公网关闭态、自动化回归;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_22-11-10-p2-automatable-followup.csv;人工核对不改业务运行时能力。 python3|manual DONE DONE DONE issues/2026-05-16_22-11-10-p2-automatable-followup.csv [] CSV validated; Scope=automatable-followup; baseline=edabce8; no deployment; no runtime capability change.
3 P2AF-1 OCR 口径纠偏 把图片发票 OCR 从主线等待样票纠正为 FREEZE_BY_DEFAULT;当前正式能力只维护 PDF-only OCR,图片仅普通附件,未来只有用户明确重启评估才另建合同。 1) P2Q/P2AUTO Notes 不再表达为主线等待图片样票;2) docs/文档索引.md、docs/文档事实源状态矩阵.md、docs/trialrun/人工试运行报告.md 记录 FREEZE_BY_DEFAULT;3) PDF live OCR 样票继续记录为可用;4) 不改 OCR 业务入口;5) 不新建综合规划文档。 受影响流程:PDF 发票上传 -> OCR -> 查重/重复票据可解释终态;图片附件 -> 普通附件材料;验证步骤:rg -n 'FREEZE_BY_DEFAULT|HOLD_FOR_SAMPLE|PDF-only|图片 OCR|普通附件|P2AUTO|P2Q' docs issues scripts;node scripts/qa/audit-docs.mjs --check-registry。 rg|node|manual DONE DONE DONE issues/2026-05-16_10-35-22-p2-post-p2ocrs-followup-queue.csv|issues/2026-05-16_20-09-49-p2-automated-regression-sweep.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md ["P2AF-0"] DefaultDecision=FREEZE_BY_DEFAULT; P2Q/P2AUTO and existing docs corrected; audit-docs errors=0 warnings=1 existing unregistered docs.
4 P2AF-2 OCR provider QA 脚本默认冻结语义 调整 scripts/qa/check-ocr-provider-samples.mjs:默认无显式图片 OCR 评估时输出 FREEZE_BY_DEFAULT;只有 OCR_IMAGE_OCR_EVALUATION=1 或显式参数开启时,图片样票缺失才输出 HOLD_FOR_SAMPLE。 1) 默认运行不把缺图片样票视为主线阻断;2) 显式图片评估模式仍支持 manifest/env 图片样票;3) 输出不包含真实路径、税号、手机号、二维码、完整号码或票面内容;4) node --check 通过;5) 不调用图片 OCR,除非显式评估且样票和凭据具备。 受影响流程:provider-only 样票脚本 -> PDF 基线摘要 -> 默认冻结/显式图片评估决策;验证步骤:node --check scripts/qa/check-ocr-provider-samples.mjs;set -a && source ~/.hyb-oa/live-smoke.env && set +a && node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json;OCR_IMAGE_OCR_EVALUATION=1 node scripts/qa/check-ocr-provider-samples.mjs --provider=tencent --json。 node|bash DONE DONE DONE scripts/qa/check-ocr-provider-samples.mjs ["P2AF-1"] node --check passed; default output decision=FREEZE_BY_DEFAULT imageEvaluation=false with PDF sample alias; explicit OCR_IMAGE_OCR_EVALUATION=1 returns HOLD_FOR_SAMPLE without image sample; no business runtime impact.
5 P2AF-3 自动回归聚合脚本 新增 scripts/qa/run-p2-safe-regression.sh,串联后端 focused、前端构建、隔离核心业务流、公网 readiness、移动矩阵、企业微信 UA/渲染和 OCR 默认冻结检查,并生成 artifacts/qa-flow/p2-safe-regression-* 摘要。 1) 脚本默认不部署、不启用公网 payment_batch_v1、不开放图片 OCR;2) 支持 P2_SAFE_SKIP_LIVE=1 和 P2_SAFE_SKIP_BUILD=1;3) 失败时返回非 0 并保留摘要;4) 报告路径可追溯;5) 不打印 secret。 受影响流程:全端自动化门禁聚合;验证步骤:bash scripts/qa/run-p2-safe-regression.sh;必要时 P2_SAFE_SKIP_LIVE=1 bash scripts/qa/run-p2-safe-regression.sh 验证本地聚合;检查 artifacts/qa-flow/p2-safe-regression-*/summary.txt。 bash|npm|node|playwright DONE DONE DONE scripts/qa/run-p2-safe-regression.sh|artifacts/qa-flow ["P2AF-2"] bash scripts/qa/run-p2-safe-regression.sh PASS; report=artifacts/qa-flow/p2-safe-regression-20260516-222222; backend focused 43 tests passed; frontend typecheck/build passed; core isolated business flow PASS; live readiness PASS; OCR default FREEZE_BY_DEFAULT.
6 P2AF-4 付款批次公网关闭态只读门禁 新增或复用 QA 脚本验证公网 payment_batch_v1 继续关闭:只允许登录和 GET/只读探测,不创建、复核、执行付款批次。 1) 公网只读检查能证明付款批次关闭态可解释;2) 不执行 POST/PATCH/DELETE 付款批次动作;3) 财务账号只读访问不泄露敏感数据;4) 普通员工/admin-only 不越权;5) 输出脱敏摘要。 受影响流程:公网财务入口/AP/payment-batches 关闭态;验证步骤:set -a && source ~/.hyb-oa/live-smoke.env && set +a;LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-payment-batch-flag-off.mjs --json;确认输出只含状态、角色、HTTP 状态和错误码摘要。 node|manual DONE DONE DONE scripts/qa/check-payment-batch-flag-off.mjs|external ["P2AF-0"] ReadOnly=true; PASS: finance /api/payment-batches and /api/ap-operations plus employee/admin /api/payment-batches all returned 409 payment_batch_v1_disabled reason=flag_force_off; no POST/PATCH/DELETE.
7 P2AF-5 UX8 自动矩阵扫尾 运行移动/企业微信自动化矩阵,记录 UX8 当前无新真实反馈时保持 TODO;若自动化发现确定性问题,只修复测试前置或明确前端体验缺陷。 1) DG7/R124 公网移动矩阵通过或失败可归因;2) R6 WeCom 渲染矩阵通过或失败可归因;3) UX8-1..5 无新反馈时不强行改 UI;4) 移动采购创建不并入本轮;5) 结果写入 Notes。 受影响流程:移动首页、移动审批/报销/通知、企业微信 UA、UX8 反馈池;验证步骤:cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list;cd client && npx playwright test tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list;人工核对 UX8 CSV 不误置 DONE。 playwright|manual DONE DONE DONE client/tests/e2e|issues/2026-05-13_13-17-38-ux8-trialrun-feedback-polish.csv ["P2AF-3"] Public mobile matrix DG7/R124 6 passed; WeCom rendering matrix 8 passed across 320/360/375/390/393/414/430 plus font failure case; UX8-1..5 remain TODO pending real feedback.
8 P2AF-6 P2AF 收口回填与提交 回填 P2AF、既有文档和历史连续合同 Notes,运行最终门禁并提交中文 commit。 1) P2AF 状态真实回填;2) validate、audit-docs、rg、git diff --check 通过;3) 中文 commit 引用 P2AF;4) 明确未部署;5) 无未解释工作区变更。 流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_22-11-10-p2-automatable-followup.csv;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'P2AF|FREEZE_BY_DEFAULT|HOLD_FOR_SAMPLE|PDF-only|图片 OCR|payment_batch_v1|P2AUTO|UX8' docs issues scripts;git diff --check;git status --short。 python3|node|rg|git DONE DONE DONE issues/2026-05-16_22-11-10-p2-automatable-followup.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md ["P2AF-1","P2AF-2","P2AF-3","P2AF-4","P2AF-5"] Closeout=PASS; validate_issues_csv passed; audit-docs errors=0 warnings=1 existing unregistered docs files=24; keyword sweep explainable; git diff --check passed before final commit; not deployed.
+19 -3
查看文件
@@ -26,6 +26,7 @@ function parseArgs(argv) {
json: false,
strict: false,
manifest: process.env.OCR_PROVIDER_SAMPLE_MANIFEST || "",
imageEvaluation: process.env.OCR_IMAGE_OCR_EVALUATION === "1",
};
for (const arg of argv) {
@@ -33,6 +34,8 @@ function parseArgs(argv) {
options.json = true;
} else if (arg === "--strict") {
options.strict = true;
} else if (arg === "--image-evaluation") {
options.imageEvaluation = true;
} else if (arg.startsWith("--provider=")) {
options.provider = arg.slice("--provider=".length);
} else if (arg.startsWith("--manifest=")) {
@@ -164,6 +167,16 @@ function loadEnvSamples() {
return samples;
}
function hasExplicitImageEnv() {
return [
"PLAYWRIGHT_OCR_IMAGE_FILE",
"PLAYWRIGHT_OCR_IMAGE_FILES",
"PLAYWRIGHT_OCR_IMAGE_DIR",
"LIVE_OCR_IMAGE_FILE",
"LIVE_OCR_IMAGE_DIR",
].some((key) => Boolean(process.env[key]?.trim()));
}
function dedupeSamples(samples) {
const seen = new Set();
const result = [];
@@ -274,7 +287,8 @@ async function checkSample(provider, config, sample) {
}
}
function buildDecision(results, manifestError) {
function buildDecision(results, manifestError, imageEvaluation) {
if (!imageEvaluation) return "FREEZE_BY_DEFAULT";
if (manifestError) return "HOLD_FOR_SAMPLE";
if (!results.length) return "HOLD_FOR_SAMPLE";
const imageResults = results.filter((item) => item.kind === "image");
@@ -285,7 +299,7 @@ function buildDecision(results, manifestError) {
function printHuman(summary) {
console.log(`[ocr-provider-samples] status=${summary.status} decision=${summary.decision}`);
console.log(`[ocr-provider-samples] provider=${summary.provider} samples=${summary.counts.total} pdf=${summary.counts.pdf} image=${summary.counts.image}`);
console.log(`[ocr-provider-samples] provider=${summary.provider} imageEvaluation=${summary.imageEvaluation} samples=${summary.counts.total} pdf=${summary.counts.pdf} image=${summary.counts.image}`);
if (summary.manifestError) {
console.log(`[ocr-provider-samples] manifest=${summary.manifestError}`);
}
@@ -307,12 +321,13 @@ async function main() {
const samples = dedupeSamples([...manifest.samples, ...loadEnvSamples()]);
const config = getTencentConfig();
const results = [];
const imageEvaluation = options.imageEvaluation || Boolean(options.manifest) || hasExplicitImageEnv();
for (const sample of samples) {
results.push(await checkSample(options.provider, config, sample));
}
const decision = buildDecision(results, manifest.error);
const decision = buildDecision(results, manifest.error, imageEvaluation);
const failed = results.some((item) => item.status === "HOLD");
const skipped = !results.length || results.some((item) => item.status === "SKIP");
const summary = {
@@ -320,6 +335,7 @@ async function main() {
provider: options.provider,
status: failed ? "HOLD" : skipped ? "SKIP" : "PASS",
decision,
imageEvaluation,
manifestProvided: Boolean(options.manifest),
manifestError: manifest.error,
credentialReady: hasTencentCredentials(config),
+212
查看文件
@@ -0,0 +1,212 @@
#!/usr/bin/env node
const DEFAULT_BASE_URL = "https://oa.hyinda.com";
function parseArgs(argv) {
const options = {
baseUrl: process.env.LIVE_SMOKE_BASE_URL || DEFAULT_BASE_URL,
json: false,
strict: false,
};
for (const arg of argv) {
if (arg === "--json") {
options.json = true;
} else if (arg === "--strict") {
options.strict = true;
} else if (arg.startsWith("--base-url=")) {
options.baseUrl = arg.slice("--base-url=".length);
}
}
options.baseUrl = options.baseUrl.trim().replace(/\/$/, "");
return options;
}
function getCredential(role) {
const prefixByRole = {
finance: "LIVE_SMOKE_FINANCE",
employee: "LIVE_SMOKE_EMPLOYEE",
admin: "LIVE_SMOKE_ADMIN",
};
const prefix = prefixByRole[role];
const identifier = process.env[`${prefix}_IDENTIFIER`]?.trim();
const password = process.env[`${prefix}_PASSWORD`]?.trim();
if (!identifier || !password) {
return null;
}
return { identifier, password };
}
async function fetchJson(url, init = {}) {
const response = await fetch(url, {
...init,
signal: AbortSignal.timeout(15_000),
});
const text = await response.text();
let json = null;
try {
json = text ? JSON.parse(text) : null;
} catch {
json = null;
}
return {
ok: response.ok,
status: response.status,
json,
};
}
function summarizeError(json) {
const error = json?.error ?? {};
const details = error.details ?? {};
return {
code: typeof error.code === "string" ? error.code : null,
featureFlag: typeof details.featureFlag === "string" ? details.featureFlag : null,
reason: typeof details.reason === "string" ? details.reason : null,
};
}
async function login(baseUrl, role, credential) {
const response = await fetchJson(`${baseUrl}/api/auth/login`, {
method: "POST",
headers: {
"content-type": "application/json",
"x-device-fingerprint": `p2af-flag-off-${role}`,
},
body: JSON.stringify({
identifier: credential.identifier,
password: credential.password,
}),
});
const accessToken = response.json?.data?.accessToken;
if (!response.ok || typeof accessToken !== "string" || !accessToken) {
return {
ok: false,
role,
status: response.status,
error: summarizeError(response.json),
};
}
return {
ok: true,
role,
accessToken,
};
}
async function probeEndpoint(baseUrl, role, accessToken, endpoint) {
const response = await fetchJson(`${baseUrl}${endpoint}`, {
method: "GET",
headers: {
authorization: `Bearer ${accessToken}`,
accept: "application/json",
},
});
const error = summarizeError(response.json);
const featureFlagDisabled = response.status === 409 && error.featureFlag === "payment_batch_v1_disabled";
const permissionDenied = response.status === 403 && error.code === "PERM_001";
const unexpectedOpen = response.status === 200;
const acceptable = featureFlagDisabled || (role !== "finance" && permissionDenied);
return {
role,
endpoint,
httpStatus: response.status,
status: acceptable ? "PASS" : "FAIL",
featureFlagDisabled,
permissionDenied,
unexpectedOpen,
error,
};
}
function buildRolePlan() {
return [
{ role: "finance", endpoints: ["/api/payment-batches", "/api/ap-operations"] },
{ role: "employee", endpoints: ["/api/payment-batches"] },
{ role: "admin", endpoints: ["/api/payment-batches"] },
];
}
function printHuman(summary) {
console.log(`[payment-batch-flag-off] status=${summary.status} base=${summary.baseUrl}`);
for (const missing of summary.missingCredentials) {
console.log(`[payment-batch-flag-off] ${missing.role} status=SKIP reason=missing_credentials`);
}
for (const loginFailure of summary.loginFailures) {
console.log(`[payment-batch-flag-off] ${loginFailure.role} status=FAIL loginStatus=${loginFailure.status}`);
}
for (const result of summary.results) {
const detail = result.featureFlagDisabled
? "featureFlag=payment_batch_v1_disabled"
: result.permissionDenied
? "permission=denied"
: `error=${result.error.code || "-"}`;
console.log(
`[payment-batch-flag-off] ${result.role} ${result.endpoint} status=${result.status} http=${result.httpStatus} ${detail}`,
);
}
}
async function main() {
const options = parseArgs(process.argv.slice(2));
const missingCredentials = [];
const loginFailures = [];
const results = [];
for (const item of buildRolePlan()) {
const credential = getCredential(item.role);
if (!credential) {
missingCredentials.push({ role: item.role });
continue;
}
const session = await login(options.baseUrl, item.role, credential);
if (!session.ok) {
loginFailures.push(session);
continue;
}
for (const endpoint of item.endpoints) {
results.push(await probeEndpoint(options.baseUrl, item.role, session.accessToken, endpoint));
}
}
const hasFailures = loginFailures.length > 0 || results.some((result) => result.status !== "PASS");
const status = hasFailures ? "FAIL" : missingCredentials.length ? "SKIP" : results.length ? "PASS" : "SKIP";
const summary = {
checkedAt: new Date().toISOString(),
baseUrl: options.baseUrl,
status,
expectedFeatureFlag: "payment_batch_v1",
expectedState: "off",
readOnly: true,
missingCredentials,
loginFailures: loginFailures.map((item) => ({
role: item.role,
status: item.status,
error: item.error,
})),
results,
};
if (options.json) {
console.log(JSON.stringify(summary, null, 2));
} else {
printHuman(summary);
}
if (status === "FAIL" || (options.strict && status !== "PASS")) {
process.exit(1);
}
}
main().catch((error) => {
console.error(`[payment-batch-flag-off][ERROR] ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
});
+99
查看文件
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
set -u -o pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
CLIENT_DIR="$ROOT_DIR/client"
SERVER_DIR="$ROOT_DIR/server"
PUBLIC_BASE_URL="${LIVE_SMOKE_BASE_URL:-https://oa.hyinda.com}"
REPORT_DIR="${P2_SAFE_REPORT_DIR:-$ROOT_DIR/artifacts/qa-flow/p2-safe-regression-$(date +%Y%m%d-%H%M%S)}"
SUMMARY_TXT="$REPORT_DIR/summary.txt"
STATUS=0
mkdir -p "$REPORT_DIR"
: >"$SUMMARY_TXT"
load_default_env() {
local env_file="${P2_SAFE_ENV_FILE:-$HOME/.hyb-oa/live-smoke.env}"
if [[ "${P2_SAFE_SKIP_ENV_FILE:-0}" == "1" || ! -f "$env_file" ]]; then
return 0
fi
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
PUBLIC_BASE_URL="${LIVE_SMOKE_BASE_URL:-$PUBLIC_BASE_URL}"
echo "[p2-safe] loaded masked env file" | tee -a "$SUMMARY_TXT"
}
run_step() {
local name="$1"
shift
local log_file="$REPORT_DIR/${name}.log"
echo ">>> [p2-safe] $name" | tee -a "$SUMMARY_TXT"
if "$@" > >(tee "$log_file") 2>&1; then
echo "[p2-safe][PASS] $name" | tee -a "$SUMMARY_TXT"
else
local code="$?"
echo "[p2-safe][FAIL] $name exit=$code" | tee -a "$SUMMARY_TXT"
STATUS=1
fi
}
run_shell_step() {
local name="$1"
local command="$2"
run_step "$name" bash -lc "$command"
}
write_summary_json() {
local qa_status="PASS"
if [[ "$STATUS" -ne 0 ]]; then
qa_status="FAIL"
fi
QA_REPORT_DIR="$REPORT_DIR" \
QA_ISSUE_ID="${QA_ISSUE_ID:-P2AF}" \
QA_BASE_URL="$PUBLIC_BASE_URL" \
QA_MODE="p2-safe-regression" \
QA_STATUS="$qa_status" \
QA_SUMMARY_NOTES="P2AF 安全自动回归:不部署、不启用公网 payment_batch_v1、不开放图片 OCR;图片 OCR 默认 FREEZE_BY_DEFAULT。" \
node "$ROOT_DIR/scripts/qa/write-qa-summary.mjs" >/dev/null 2>&1 || true
}
finish() {
write_summary_json
echo "[p2-safe] report=$REPORT_DIR" | tee -a "$SUMMARY_TXT"
exit "$STATUS"
}
trap finish EXIT
load_default_env
run_shell_step "backend-prisma" "cd '$SERVER_DIR' && npm run prisma:validate"
run_shell_step "backend-node-check" "cd '$SERVER_DIR' && node --check src/routes/invoicePool.js src/jobs/ocrJob.js src/services/ocr/tencent.js src/routes/paymentBatches.js src/routes/exports.js src/routes/workflow.js src/routes/wecomAuth.js"
run_shell_step "backend-focused-tests" "cd '$SERVER_DIR' && npm test -- tests/unit/services/ocr.tencent.test.js tests/unit/jobs/ocrJob.test.js tests/unit/routes/invoicePool.upload.test.js tests/unit/routes/paymentBatches.reimbursement.test.js tests/unit/routes/exports.apOperations.test.js tests/unit/routes/wecomAuth.test.js tests/unit/routes/notifications.test.js"
if [[ "${P2_SAFE_SKIP_BUILD:-0}" == "1" ]]; then
echo "[p2-safe][SKIP] frontend-build P2_SAFE_SKIP_BUILD=1" | tee -a "$SUMMARY_TXT"
else
run_shell_step "frontend-typecheck" "cd '$CLIENT_DIR' && npm run typecheck"
run_shell_step "frontend-build" "cd '$CLIENT_DIR' && npm run build"
fi
run_shell_step "business-flow-local" "BUSINESS_FLOW_GROUPS=auth,reimbursement,approval,leave,procurement,governance BUSINESS_FLOW_EXCLUDE_SPECS=tests/e2e/reimbursement-payment-batch-flow.spec.ts bash '$ROOT_DIR/scripts/qa/run-business-flow-gates.sh' local"
if [[ "${P2_SAFE_SKIP_LIVE:-0}" == "1" ]]; then
echo "[p2-safe][SKIP] live-readiness P2_SAFE_SKIP_LIVE=1" | tee -a "$SUMMARY_TXT"
echo "[p2-safe][SKIP] payment-batch-flag-off P2_SAFE_SKIP_LIVE=1" | tee -a "$SUMMARY_TXT"
echo "[p2-safe][SKIP] public-mobile-matrix P2_SAFE_SKIP_LIVE=1" | tee -a "$SUMMARY_TXT"
else
run_shell_step "live-readiness" "QA_ISSUE_ID=P2AF LIVE_SMOKE_BASE_URL='$PUBLIC_BASE_URL' bash '$ROOT_DIR/scripts/qa/run-live-smoke-readiness.sh'"
run_shell_step "payment-batch-flag-off" "LIVE_SMOKE_BASE_URL='$PUBLIC_BASE_URL' node '$ROOT_DIR/scripts/qa/check-payment-batch-flag-off.mjs' --json"
run_shell_step "public-mobile-matrix" "cd '$CLIENT_DIR' && E2E_BASE_URL='$PUBLIC_BASE_URL' npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list"
fi
run_shell_step "wecom-rendering-matrix" "cd '$CLIENT_DIR' && E2E_BASE_URL='$PUBLIC_BASE_URL' npx playwright test tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list"
run_shell_step "ocr-freeze-default" "node '$ROOT_DIR/scripts/qa/check-ocr-provider-samples.mjs' --provider=tencent --json"