WARCH3/WCHECK1/WEXT1 完成受控上线后续自动化

Issue: WARCH3, WCHECK1, WEXT1
这个提交包含在:
2026-05-20 13:58:40 +08:00
父节点 512a58d40e
当前提交 56b720b8ab
共修改 28 个文件,包含 2909 行新增和 72 行删除
@@ -0,0 +1,9 @@
"ID","Title","Description","Acceptance","Test_Method","Tools","Dev_Status","Review1_Status","Regression_Status","Files","Dependencies","Notes"
"WARCH3-0","归档稳定化合同与边界","建立 WARCH3 归档稳定化与自动巡检合同;承接 WROAD2 Day 0 PASS_WITH_FINDINGS,继续测试账号受控上线,不扩大真实员工,不进入 wecom_attendance_approval_mirror_v1。","1) 明确 WARCH3 只稳定每日补偿归档、趋势、finding 去重和脱敏告警;2) 巡检只允许补偿归档写 OA DB,不写企业微信、不创建模板、不提交审批单;3) Secret 来源固定 WECOM_AGENT_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;4) 缺 Secret、权限、可信 IP、可见范围或外部配置时记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;5) live smoke 凭据/pending OCR 子检查和历史 callback gap 为观察项,不阻断企微归档主链路。","受影响流程:WROAD2 Day 0 巡检 -> WARCH3 自动巡检治理 -> 后续 WCHECK1/WEXT1;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv --profile wecom --json。","python3|node","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv","[]","回滚/清理:本行仅合同;如不通过,删除本合同和后续 WARCH3 改动即可,不影响 WROAD2 既有脚本和报告。"
"WARCH3-1","每日巡检汇总与 finding 去重","新增 WARCH3 QA/ops 汇总脚本,读取 WROAD2 子报告并生成趋势、主链路状态、观察项、callback gap 解释和去重 finding。","1) 输出 artifacts/qa-flow/warch3-ops-<timestamp>/summary.json;2) 主链路关注企微 runtime、审批补偿归档写 OA、OA 离线归档读取和隐私扫描;3) live smoke 凭据/pending OCR 子检查只作为 observation;4) 重复/漏回调/状态不一致 finding 以脱敏 evidenceDigest 去重;5) 报告不泄露手机号、邮箱、token、secret、完整 userid、完整 template_id、完整 sp_no、原始 XML、密文、表单值、附件、评论或原始 payload。","受影响流程:每日巡检 -> 子报告聚合 -> 管理员看趋势和下一步建议;验证步骤:bash -n scripts/qa/run-warch3-ops-daily.sh;本地执行 WARCH3_SKIP_WROAD2=1 bash scripts/qa/run-warch3-ops-daily.sh 生成脱敏 summary.json;检查报告隐私扫描通过。","bash|node","DONE","DONE","DONE","scripts/qa/run-warch3-ops-daily.sh","[""WARCH3-0""]","回滚/清理:删除新增脚本即可;脚本默认只读,只有复用 WROAD2 时允许进程级 WECOM_ARCHIVE_WRITE=1 写 OA 留存库,不写企业微信。"
"WARCH3-2","企微脱敏巡检告警","新增 QA-only 企微巡检告警脚本,巡检失败或 finding 时向管理员 wangshunli/HYD000006 发送脱敏状态和报告路径。","1) 告警固定使用 WECOM_AGENT_SECRET 和企业微信应用消息;2) 仅发送阶段、状态、finding 数、报告路径和下一步建议;3) 默认 dry-run,不发真实消息;4) 真实发送必须带 --send 且 WARCH3_OPS_ALERT_SEND=1;5) 缺收件人绑定、Secret、权限、可见范围或 API 错误记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) 不输出手机号、邮箱、token、Secret、完整 userid、完整 template_id、完整 sp_no、表单值或原始 payload。","受影响流程:WARCH3 巡检 -> finding/失败 -> 管理员脱敏企微提醒;验证步骤:cd server && node --check src/scripts/send-wecom-ops-alert.js;cd server && npx vitest run tests/unit/scripts/send-wecom-ops-alert.test.js --reporter=verbose;公网只发送一条脱敏测试告警。","node|vitest","DONE","DONE","DONE","server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js","[""WARCH3-1""]","回滚/清理:删除告警脚本或不设置 WARCH3_OPS_ALERT_SEND 即可;真实告警为低风险应用消息,保留审计,不写企微业务数据。"
"WARCH3-3","systemd 定时器安装脚本","新增服务器 systemd service/timer 安装脚本,每天北京时间 07:30 自动触发 WARCH3/WROAD2 巡检。","1) 新增 deploy/trialrun/install-warch3-ops-timer.sh;2) service 只执行仓库脚本,不写企业微信;3) timer 使用 Asia/Shanghai 语义的 07:30;4) 安装、启用、手动触发和卸载路径明确;5) 不修改公开业务 API、Prisma schema、前端页面或 feature flag。","受影响流程:受控上线巡检 -> 服务器定时触发 -> 每日脱敏报告;验证步骤:bash -n deploy/trialrun/install-warch3-ops-timer.sh;远端 SYNC_ENV=0 部署后执行安装脚本;systemctl list-timers hyb-oa-warch3-ops.timer;systemctl start hyb-oa-warch3-ops.service。","bash|systemctl|ssh","DONE","DONE","DONE","deploy/trialrun/install-warch3-ops-timer.sh","[""WARCH3-1""]","回滚/清理:运行安装脚本 --uninstall 或 systemctl disable --now hyb-oa-warch3-ops.timer 并删除 service/timer 文件;不影响应用容器和数据库。;实际结果:安装脚本已兼容 docker compose v2 与 docker-compose v1;远端 timer 已启用,下次触发 2026-05-21 07:30 CST。"
"WARCH3-4","本地门禁与单测","执行 WARCH3 本地合同、脚本、单测、文档和最小门禁。","1) CSV 校验通过;2) process gate baseline 和 WARCH3 issue profile 通过;3) bash/node 语法通过;4) focused vitest 通过;5) 文档审计、skill 校验、git diff --check、scripts/check-minimal.sh 通过。","受影响流程:WARCH3 实施候选 -> 本地 QA -> 可部署候选;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv --profile wecom --json;bash -n scripts/qa/run-warch3-ops-daily.sh;bash -n deploy/trialrun/install-warch3-ops-timer.sh;cd server && node --check src/scripts/send-wecom-ops-alert.js;cd server && npx vitest run tests/unit/scripts/send-wecom-ops-alert.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。","python3|node|bash|vitest|git","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv|scripts/qa/run-warch3-ops-daily.sh|deploy/trialrun/install-warch3-ops-timer.sh|server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md","[""WARCH3-2"",""WARCH3-3""]","回滚/清理:门禁失败不部署、不安装 timer;修复后重跑。"
"WARCH3-5","公网部署与定时器验证","本地门禁通过后,以 SYNC_ENV=0 受控部署,安装 systemd timer,手动触发一次 service,并发送一条脱敏告警测试消息。","1) 使用 SYNC_ENV=0,不同步本地 env;2) /ready 正常;3) 远端手动触发 WARCH3 service 生成 summary.json;4) systemd timer 已启用且下次运行时间为北京时间 07:30;5) 告警仅发送脱敏状态和报告路径;6) 远端报告和告警不泄露完整外部键或敏感值。","受影响流程:部署 -> /ready -> systemd timer -> 手动 service -> 脱敏企微告警;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;ssh 远端执行 deploy/trialrun/install-warch3-ops-timer.sh;systemctl start hyb-oa-warch3-ops.service;WARCH3_OPS_ALERT_SEND=1 npm run send:wecom-ops-alert 或等效命令。","bash|ssh|curl|systemctl|npm","DONE","DONE","DONE","deploy/trialrun/deploy.sh|deploy/trialrun/install-warch3-ops-timer.sh|scripts/qa/run-warch3-ops-daily.sh","[""WARCH3-4""]","回滚/清理:如 systemd 或告警异常,先 disable timer 并保留报告;不扩大真实用户,不写企业微信业务数据。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;远端 service 手动触发成功,报告 /app/artifacts/qa-flow/warch3-ops-20260520-054841/summary.json 为 PASS_WITH_FINDINGS;告警报告 /app/artifacts/qa-flow/wecom-ops-alert-20260520T054851Z/summary.json 为 PASS_ALERT_SENT_WITH_CONFIG_GAPS,已向有效管理员 HYD000006 发送脱敏企微消息,wangshunli 仅记录为非员工号别名 gap。"
"WARCH3-6","事实源回写","更新路线图、API 目录、管理员手册、试运行报告、文档索引、事实源矩阵和项目 skill,固化 WARCH3 结果。","1) 文档明确 WARCH3 已将每日巡检升级为 systemd timer;2) 告警为脱敏企微应用消息;3) live smoke/OCR finding 属观察项;4) WARCH3 后仍需 WCHECK1 和 WEXT1 dry-run,再规划真实小范围试用;5) 不暗示完整镜像、应急或回写已完成。","受影响流程:事实源 -> 后续 WCHECK1/WEXT1/WREAL1 规划;验证步骤:node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;rg -n ""WARCH3|systemd|07:30|脱敏告警|WCHECK1|WEXT1|WREAL1|BLOCKED_BY_EXTERNAL_CONFIG"" docs .agents/skills/hyb-oa-delivery/SKILL.md。","node|python3|rg","DONE","DONE","DONE","docs/企微优先开发路线图.md|docs/企微API能力目录.md|docs/需求-企业微信基础设施规约.md|docs/管理员手册.md|docs/trialrun/人工试运行报告.md|docs/文档索引.md|docs/文档事实源状态矩阵.md|.agents/skills/hyb-oa-delivery/SKILL.md","[""WARCH3-5""]","回滚/清理:恢复本阶段文档改动即可;不修改历史 Issue 快照。"
"WARCH3-7","状态回填与中文提交","完成 WARCH3 状态回填、本地与公网证据登记和中文提交。","1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 远端报告路径、timer 状态和告警结果写入 Notes;4) git diff --check 通过;5) 中文提交完成。","受影响流程:WARCH3 实施 -> 证据回写 -> 可进入 WCHECK1/WEXT1;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WARCH3。","git|manual","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv|docs/*|scripts/qa/*|deploy/trialrun/*|server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js","[""WARCH3-6""]","提交建议:WARCH3 增加归档稳定化自动巡检。若公网因外部配置 SKIP,仍提交真实阻断事实,不伪造成 PASS。;实际结果:WARCH3 本地门禁、公网部署、timer、service、脱敏告警和事实源回写已完成;live smoke 凭据/pending OCR 与历史 callback gap 继续作为观察项。;回滚/清理:如后续公网定时巡检异常,可运行 deploy/trialrun/install-warch3-ops-timer.sh uninstall 停用 timer;报告和测试告警保留审计,不清理业务数据。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 WARCH3-0 归档稳定化合同与边界 建立 WARCH3 归档稳定化与自动巡检合同;承接 WROAD2 Day 0 PASS_WITH_FINDINGS,继续测试账号受控上线,不扩大真实员工,不进入 wecom_attendance_approval_mirror_v1。 1) 明确 WARCH3 只稳定每日补偿归档、趋势、finding 去重和脱敏告警;2) 巡检只允许补偿归档写 OA DB,不写企业微信、不创建模板、不提交审批单;3) Secret 来源固定 WECOM_AGENT_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;4) 缺 Secret、权限、可信 IP、可见范围或外部配置时记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;5) live smoke 凭据/pending OCR 子检查和历史 callback gap 为观察项,不阻断企微归档主链路。 受影响流程:WROAD2 Day 0 巡检 -> WARCH3 自动巡检治理 -> 后续 WCHECK1/WEXT1;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv --profile wecom --json。 python3|node DONE DONE DONE issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv [] 回滚/清理:本行仅合同;如不通过,删除本合同和后续 WARCH3 改动即可,不影响 WROAD2 既有脚本和报告。
3 WARCH3-1 每日巡检汇总与 finding 去重 新增 WARCH3 QA/ops 汇总脚本,读取 WROAD2 子报告并生成趋势、主链路状态、观察项、callback gap 解释和去重 finding。 1) 输出 artifacts/qa-flow/warch3-ops-<timestamp>/summary.json;2) 主链路关注企微 runtime、审批补偿归档写 OA、OA 离线归档读取和隐私扫描;3) live smoke 凭据/pending OCR 子检查只作为 observation;4) 重复/漏回调/状态不一致 finding 以脱敏 evidenceDigest 去重;5) 报告不泄露手机号、邮箱、token、secret、完整 userid、完整 template_id、完整 sp_no、原始 XML、密文、表单值、附件、评论或原始 payload。 受影响流程:每日巡检 -> 子报告聚合 -> 管理员看趋势和下一步建议;验证步骤:bash -n scripts/qa/run-warch3-ops-daily.sh;本地执行 WARCH3_SKIP_WROAD2=1 bash scripts/qa/run-warch3-ops-daily.sh 生成脱敏 summary.json;检查报告隐私扫描通过。 bash|node DONE DONE DONE scripts/qa/run-warch3-ops-daily.sh ["WARCH3-0"] 回滚/清理:删除新增脚本即可;脚本默认只读,只有复用 WROAD2 时允许进程级 WECOM_ARCHIVE_WRITE=1 写 OA 留存库,不写企业微信。
4 WARCH3-2 企微脱敏巡检告警 新增 QA-only 企微巡检告警脚本,巡检失败或 finding 时向管理员 wangshunli/HYD000006 发送脱敏状态和报告路径。 1) 告警固定使用 WECOM_AGENT_SECRET 和企业微信应用消息;2) 仅发送阶段、状态、finding 数、报告路径和下一步建议;3) 默认 dry-run,不发真实消息;4) 真实发送必须带 --send 且 WARCH3_OPS_ALERT_SEND=1;5) 缺收件人绑定、Secret、权限、可见范围或 API 错误记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) 不输出手机号、邮箱、token、Secret、完整 userid、完整 template_id、完整 sp_no、表单值或原始 payload。 受影响流程:WARCH3 巡检 -> finding/失败 -> 管理员脱敏企微提醒;验证步骤:cd server && node --check src/scripts/send-wecom-ops-alert.js;cd server && npx vitest run tests/unit/scripts/send-wecom-ops-alert.test.js --reporter=verbose;公网只发送一条脱敏测试告警。 node|vitest DONE DONE DONE server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js ["WARCH3-1"] 回滚/清理:删除告警脚本或不设置 WARCH3_OPS_ALERT_SEND 即可;真实告警为低风险应用消息,保留审计,不写企微业务数据。
5 WARCH3-3 systemd 定时器安装脚本 新增服务器 systemd service/timer 安装脚本,每天北京时间 07:30 自动触发 WARCH3/WROAD2 巡检。 1) 新增 deploy/trialrun/install-warch3-ops-timer.sh;2) service 只执行仓库脚本,不写企业微信;3) timer 使用 Asia/Shanghai 语义的 07:30;4) 安装、启用、手动触发和卸载路径明确;5) 不修改公开业务 API、Prisma schema、前端页面或 feature flag。 受影响流程:受控上线巡检 -> 服务器定时触发 -> 每日脱敏报告;验证步骤:bash -n deploy/trialrun/install-warch3-ops-timer.sh;远端 SYNC_ENV=0 部署后执行安装脚本;systemctl list-timers hyb-oa-warch3-ops.timer;systemctl start hyb-oa-warch3-ops.service。 bash|systemctl|ssh DONE DONE DONE deploy/trialrun/install-warch3-ops-timer.sh ["WARCH3-1"] 回滚/清理:运行安装脚本 --uninstall 或 systemctl disable --now hyb-oa-warch3-ops.timer 并删除 service/timer 文件;不影响应用容器和数据库。;实际结果:安装脚本已兼容 docker compose v2 与 docker-compose v1;远端 timer 已启用,下次触发 2026-05-21 07:30 CST。
6 WARCH3-4 本地门禁与单测 执行 WARCH3 本地合同、脚本、单测、文档和最小门禁。 1) CSV 校验通过;2) process gate baseline 和 WARCH3 issue profile 通过;3) bash/node 语法通过;4) focused vitest 通过;5) 文档审计、skill 校验、git diff --check、scripts/check-minimal.sh 通过。 受影响流程:WARCH3 实施候选 -> 本地 QA -> 可部署候选;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv --profile wecom --json;bash -n scripts/qa/run-warch3-ops-daily.sh;bash -n deploy/trialrun/install-warch3-ops-timer.sh;cd server && node --check src/scripts/send-wecom-ops-alert.js;cd server && npx vitest run tests/unit/scripts/send-wecom-ops-alert.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。 python3|node|bash|vitest|git DONE DONE DONE issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv|scripts/qa/run-warch3-ops-daily.sh|deploy/trialrun/install-warch3-ops-timer.sh|server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md ["WARCH3-2","WARCH3-3"] 回滚/清理:门禁失败不部署、不安装 timer;修复后重跑。
7 WARCH3-5 公网部署与定时器验证 本地门禁通过后,以 SYNC_ENV=0 受控部署,安装 systemd timer,手动触发一次 service,并发送一条脱敏告警测试消息。 1) 使用 SYNC_ENV=0,不同步本地 env;2) /ready 正常;3) 远端手动触发 WARCH3 service 生成 summary.json;4) systemd timer 已启用且下次运行时间为北京时间 07:30;5) 告警仅发送脱敏状态和报告路径;6) 远端报告和告警不泄露完整外部键或敏感值。 受影响流程:部署 -> /ready -> systemd timer -> 手动 service -> 脱敏企微告警;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;ssh 远端执行 deploy/trialrun/install-warch3-ops-timer.sh;systemctl start hyb-oa-warch3-ops.service;WARCH3_OPS_ALERT_SEND=1 npm run send:wecom-ops-alert 或等效命令。 bash|ssh|curl|systemctl|npm DONE DONE DONE deploy/trialrun/deploy.sh|deploy/trialrun/install-warch3-ops-timer.sh|scripts/qa/run-warch3-ops-daily.sh ["WARCH3-4"] 回滚/清理:如 systemd 或告警异常,先 disable timer 并保留报告;不扩大真实用户,不写企业微信业务数据。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;远端 service 手动触发成功,报告 /app/artifacts/qa-flow/warch3-ops-20260520-054841/summary.json 为 PASS_WITH_FINDINGS;告警报告 /app/artifacts/qa-flow/wecom-ops-alert-20260520T054851Z/summary.json 为 PASS_ALERT_SENT_WITH_CONFIG_GAPS,已向有效管理员 HYD000006 发送脱敏企微消息,wangshunli 仅记录为非员工号别名 gap。
8 WARCH3-6 事实源回写 更新路线图、API 目录、管理员手册、试运行报告、文档索引、事实源矩阵和项目 skill,固化 WARCH3 结果。 1) 文档明确 WARCH3 已将每日巡检升级为 systemd timer;2) 告警为脱敏企微应用消息;3) live smoke/OCR finding 属观察项;4) WARCH3 后仍需 WCHECK1 和 WEXT1 dry-run,再规划真实小范围试用;5) 不暗示完整镜像、应急或回写已完成。 受影响流程:事实源 -> 后续 WCHECK1/WEXT1/WREAL1 规划;验证步骤:node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;rg -n "WARCH3|systemd|07:30|脱敏告警|WCHECK1|WEXT1|WREAL1|BLOCKED_BY_EXTERNAL_CONFIG" docs .agents/skills/hyb-oa-delivery/SKILL.md。 node|python3|rg DONE DONE DONE docs/企微优先开发路线图.md|docs/企微API能力目录.md|docs/需求-企业微信基础设施规约.md|docs/管理员手册.md|docs/trialrun/人工试运行报告.md|docs/文档索引.md|docs/文档事实源状态矩阵.md|.agents/skills/hyb-oa-delivery/SKILL.md ["WARCH3-5"] 回滚/清理:恢复本阶段文档改动即可;不修改历史 Issue 快照。
9 WARCH3-7 状态回填与中文提交 完成 WARCH3 状态回填、本地与公网证据登记和中文提交。 1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 远端报告路径、timer 状态和告警结果写入 Notes;4) git diff --check 通过;5) 中文提交完成。 受影响流程:WARCH3 实施 -> 证据回写 -> 可进入 WCHECK1/WEXT1;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WARCH3。 git|manual DONE DONE DONE issues/2026-05-20_12-48-04-wecom-archive-stabilization-ops-v1.csv|docs/*|scripts/qa/*|deploy/trialrun/*|server/src/scripts/send-wecom-ops-alert.js|server/tests/unit/scripts/send-wecom-ops-alert.test.js ["WARCH3-6"] 提交建议:WARCH3 增加归档稳定化自动巡检。若公网因外部配置 SKIP,仍提交真实阻断事实,不伪造成 PASS。;实际结果:WARCH3 本地门禁、公网部署、timer、service、脱敏告警和事实源回写已完成;live smoke 凭据/pending OCR 与历史 callback gap 继续作为观察项。;回滚/清理:如后续公网定时巡检异常,可运行 deploy/trialrun/install-warch3-ops-timer.sh uninstall 停用 timer;报告和测试告警保留审计,不清理业务数据。
@@ -0,0 +1,9 @@
"ID","Title","Description","Acceptance","Test_Method","Tools","Dev_Status","Review1_Status","Regression_Status","Files","Dependencies","Notes"
"WCHECK1-0","打卡摘要留存合同与边界","建立 WCHECK1 打卡摘要留存合同;承接 WROAD2/WARCH3,目标是 OA 自建留存规范化打卡明细、日/月摘要和规则快照,企微不可用时仍能查看已保存历史摘要。","1) 保存范围为规范化打卡记录、日摘要、月摘要、异常摘要、规则快照摘要和原始记录 hash;2) 禁止保存完整位置、人脸、设备明文、原始 payload、token、Secret;3) Secret 来源固定 WECOM_AGENT_SECRET 或显式 WECOM_CHECKIN_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;4) 缺 Secret、权限、可信 IP、可见范围或企微 API 错误记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;5) 不写企业微信、不创建审批模板或审批单、不扩大真实员工。","受影响流程:企微打卡只读拉取 -> OA 规范化留存 -> 离线摘要读取;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv --profile wecom --json。","python3|node","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv","[]","回滚/清理:本行仅合同;如不通过,删除本合同和后续 WCHECK1 改动即可,不影响既有 WecomCheckinRecord。"
"WCHECK1-1","打卡摘要 Schema 与迁移","新增打卡日/月摘要和规则快照表,复用 WecomCheckinRecord 作为规范化明细。","1) 新增 WecomCheckinDailySummary、WecomCheckinMonthlySummary、WecomCheckinRuleSnapshot;2) 表内只保存摘要、计数、首末时间、异常计数、规则摘要、hash 和外部 userid 前缀/必要映射,不保存位置、人脸、设备明文或原始 payload;3) 有唯一键保证按员工/日期、员工/月、外部 userid/规则日幂等;4) 迁移可回滚说明明确。","受影响流程:已同步打卡明细 -> 摘要表 -> 离线读取;验证步骤:cd server && npm run prisma:validate;检查 server/prisma/migrations/*_wecom_checkin_summary_archive_v1/migration.sql;必要时受控部署执行 prisma migrate deploy。","prisma|sql","DONE","DONE","DONE","server/prisma/schema.prisma|server/prisma/migrations/*_wecom_checkin_summary_archive_v1/migration.sql","[""WCHECK1-0""]","回滚/清理:如未部署,恢复 schema 和删除迁移目录;如已部署,需单独审批后 DROP wecom_checkin_daily_summaries、wecom_checkin_monthly_summaries、wecom_checkin_rule_snapshots。"
"WCHECK1-2","打卡摘要归档服务","新增服务函数,从 WecomCheckinRecord 生成日/月摘要,并可在 live 只读模式拉取打卡规则形成规则快照。","1) 摘要生成幂等 upsert;2) 日摘要包含打卡次数、首末打卡时间、异常计数、结果摘要、source 摘要、raw_hash 聚合;3) 月摘要包含天数、异常天数、缺卡候选天数、首末覆盖日期;4) 规则快照只存规则摘要、hash、员工映射和时间窗口,不存原始 payload;5) 企微 API 阻断按 SKIP/BLOCKED_BY_EXTERNAL_CONFIG 归类。","受影响流程:打卡记录 -> 摘要生成 -> 规则快照 -> 后续离线查询;验证步骤:cd server && node --check src/services/integrations/wecomCheckinArchive.js;cd server && npx vitest run tests/unit/services/wecomCheckinArchive.test.js --reporter=verbose。","node|vitest","DONE","DONE","DONE","server/src/services/integrations/wecomCheckinArchive.js|server/tests/unit/services/wecomCheckinArchive.test.js","[""WCHECK1-1""]","回滚/清理:删除新增服务和测试即可;服务不写企业微信,写 OA 留存表用于审计。"
"WCHECK1-3","打卡摘要 QA runner","新增 QA-only runner check-wecom-checkin-summary-archive,支持 live 只读拉取、persist 写 OA 摘要和 offline 离线读取证明。","1) 默认 offline/read-only,不调用企微;2) live 模式仅调用打卡读取和规则读取,不写企业微信;3) 写 OA 摘要必须同时带 --persist-to-db 和 WECOM_CHECKIN_ARCHIVE_WRITE=1;4) 输出 artifacts/qa-flow/wecom-checkin-summary-archive-<timestamp>/summary.json;5) 报告只输出计数、日期、状态、异常摘要和脱敏 userid 前缀,不泄露完整 userid、位置、人脸、设备、token、Secret 或原始 payload。","受影响流程:企微打卡只读 -> OA 摘要留存 -> 企微 API 不可用时离线读取;验证步骤:cd server && node --check src/scripts/check-wecom-checkin-summary-archive.js;cd server && npx vitest run tests/unit/scripts/check-wecom-checkin-summary-archive.test.js tests/unit/services/wecomCheckinArchive.test.js --reporter=verbose。","node|vitest","DONE","DONE","DONE","server/src/scripts/check-wecom-checkin-summary-archive.js|server/tests/unit/scripts/check-wecom-checkin-summary-archive.test.js|server/package.json","[""WCHECK1-2""]","回滚/清理:删除 runner 和 package 脚本即可;若已写 OA 摘要,保留审计或按后续人工批准清理。"
"WCHECK1-4","本地门禁与隐私测试","执行 WCHECK1 本地合同、Prisma、语法、focused 单测、文档和最小门禁。","1) CSV 与 process gate 通过;2) Prisma validate 通过;3) node --check 通过;4) 单测覆盖空记录、幂等、规则快照脱敏、外部配置阻断、隐私不泄露;5) git diff --check 和 scripts/check-minimal.sh 通过。","受影响流程:WCHECK1 实施候选 -> 本地 QA -> 可部署候选;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv --profile wecom --json;cd server && npm run prisma:validate;cd server && node --check src/services/integrations/wecomCheckinArchive.js;cd server && node --check src/scripts/check-wecom-checkin-summary-archive.js;cd server && npx vitest run tests/unit/services/wecomCheckinArchive.test.js tests/unit/scripts/check-wecom-checkin-summary-archive.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。","python3|node|prisma|vitest|bash|git","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv|server/prisma/*|server/src/services/integrations/wecomCheckinArchive.js|server/src/scripts/check-wecom-checkin-summary-archive.js|server/tests/unit/*|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md","[""WCHECK1-3""]","回滚/清理:本地门禁失败不部署;修复后重跑。"
"WCHECK1-5","公网只读与归档验证","本地门禁通过后,以 SYNC_ENV=0 部署并远端执行 WCHECK1 runner,证明可写 OA 摘要并离线读取。","1) 使用 SYNC_ENV=0,不同步本地 env;2) /ready 正常;3) 远端 live 只读拉取打卡短窗口并在双开关下写 OA 摘要;4) 离线读取不调用企微 API、不读取企微 Secret;5) 若权限、可信 IP、可见范围或 Secret 阻断,记录真实 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) 报告隐私扫描通过。","受影响流程:部署 -> 企微打卡只读 -> OA 摘要归档 -> 离线读取;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;远端执行 WECOM_CHECKIN_ARCHIVE_WRITE=1 npm run check:wecom-checkin-summary-archive -- --live --persist-to-db --format=json;远端执行 npm run check:wecom-checkin-summary-archive -- --offline --format=json。","bash|ssh|curl|npm","DONE","DONE","DONE","deploy/trialrun/deploy.sh|server/src/scripts/check-wecom-checkin-summary-archive.js","[""WCHECK1-4""]","回滚/清理:部署异常按既有 trialrun 回滚;已写 OA 摘要保留审计,不写企业微信数据。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;live 报告 /app/artifacts/qa-flow/wecom-checkin-summary-archive-20260520T054907Z/summary.json 为 PASS_CHECKIN_ARCHIVE_READY,本窗口 0 条打卡明细、2 条规则快照写入 OA 留存;offline 报告 /app/artifacts/qa-flow/wecom-checkin-summary-archive-20260520T054926Z/summary.json 为 PASS_CHECKIN_ARCHIVE_OFFLINE_READY。"
"WCHECK1-6","事实源回写","更新路线图、API 目录、请假考勤规约、企业微信基础设施规约、管理员手册、试运行报告、文档索引、事实源矩阵和项目 skill。","1) 文档明确 WCHECK1 保存规范化明细、日/月摘要和规则快照;2) 明确不保存位置、人脸、设备明文或原始 payload;3) 明确企微不可用时 OA 只能查看已保存历史摘要,不代表继续办理;4) 后续仍需 WEXT1 dry-run 和 WREAL1 小范围真实试用。","受影响流程:事实源 -> 后续 WEXT1/WREAL1/镜像规划;验证步骤:node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;rg -n ""WCHECK1|打卡摘要|规则快照|不保存完整位置|WEXT1|WREAL1|wecom_attendance_approval_mirror_v1"" docs .agents/skills/hyb-oa-delivery/SKILL.md。","node|python3|rg","DONE","DONE","DONE","docs/企微优先开发路线图.md|docs/企微API能力目录.md|docs/需求-请假考勤修正规约.md|docs/需求-企业微信基础设施规约.md|docs/管理员手册.md|docs/trialrun/人工试运行报告.md|docs/文档索引.md|docs/文档事实源状态矩阵.md|.agents/skills/hyb-oa-delivery/SKILL.md","[""WCHECK1-5""]","回滚/清理:恢复本阶段文档改动即可。"
"WCHECK1-7","状态回填与中文提交","完成 WCHECK1 状态回填、本地与公网证据登记和中文提交。","1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 公网报告路径写入 Notes;4) git diff --check 通过;5) 中文提交完成。","受影响流程:WCHECK1 实施 -> 证据回写 -> 可进入 WEXT1/WREAL1;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WCHECK1。","git|manual","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv|server/*|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md","[""WCHECK1-6""]","提交建议:WCHECK1 增加企微打卡摘要留存。若公网因外部配置 SKIP,仍提交真实阻断事实,不伪造成 PASS。;实际结果:WCHECK1 本地门禁、公网 live 写 OA 留存、离线读取和事实源回写已完成;未写企业微信,未保存位置、人脸、设备明文或原始 payload。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 WCHECK1-0 打卡摘要留存合同与边界 建立 WCHECK1 打卡摘要留存合同;承接 WROAD2/WARCH3,目标是 OA 自建留存规范化打卡明细、日/月摘要和规则快照,企微不可用时仍能查看已保存历史摘要。 1) 保存范围为规范化打卡记录、日摘要、月摘要、异常摘要、规则快照摘要和原始记录 hash;2) 禁止保存完整位置、人脸、设备明文、原始 payload、token、Secret;3) Secret 来源固定 WECOM_AGENT_SECRET 或显式 WECOM_CHECKIN_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;4) 缺 Secret、权限、可信 IP、可见范围或企微 API 错误记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;5) 不写企业微信、不创建审批模板或审批单、不扩大真实员工。 受影响流程:企微打卡只读拉取 -> OA 规范化留存 -> 离线摘要读取;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv --profile wecom --json。 python3|node DONE DONE DONE issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv [] 回滚/清理:本行仅合同;如不通过,删除本合同和后续 WCHECK1 改动即可,不影响既有 WecomCheckinRecord。
3 WCHECK1-1 打卡摘要 Schema 与迁移 新增打卡日/月摘要和规则快照表,复用 WecomCheckinRecord 作为规范化明细。 1) 新增 WecomCheckinDailySummary、WecomCheckinMonthlySummary、WecomCheckinRuleSnapshot;2) 表内只保存摘要、计数、首末时间、异常计数、规则摘要、hash 和外部 userid 前缀/必要映射,不保存位置、人脸、设备明文或原始 payload;3) 有唯一键保证按员工/日期、员工/月、外部 userid/规则日幂等;4) 迁移可回滚说明明确。 受影响流程:已同步打卡明细 -> 摘要表 -> 离线读取;验证步骤:cd server && npm run prisma:validate;检查 server/prisma/migrations/*_wecom_checkin_summary_archive_v1/migration.sql;必要时受控部署执行 prisma migrate deploy。 prisma|sql DONE DONE DONE server/prisma/schema.prisma|server/prisma/migrations/*_wecom_checkin_summary_archive_v1/migration.sql ["WCHECK1-0"] 回滚/清理:如未部署,恢复 schema 和删除迁移目录;如已部署,需单独审批后 DROP wecom_checkin_daily_summaries、wecom_checkin_monthly_summaries、wecom_checkin_rule_snapshots。
4 WCHECK1-2 打卡摘要归档服务 新增服务函数,从 WecomCheckinRecord 生成日/月摘要,并可在 live 只读模式拉取打卡规则形成规则快照。 1) 摘要生成幂等 upsert;2) 日摘要包含打卡次数、首末打卡时间、异常计数、结果摘要、source 摘要、raw_hash 聚合;3) 月摘要包含天数、异常天数、缺卡候选天数、首末覆盖日期;4) 规则快照只存规则摘要、hash、员工映射和时间窗口,不存原始 payload;5) 企微 API 阻断按 SKIP/BLOCKED_BY_EXTERNAL_CONFIG 归类。 受影响流程:打卡记录 -> 摘要生成 -> 规则快照 -> 后续离线查询;验证步骤:cd server && node --check src/services/integrations/wecomCheckinArchive.js;cd server && npx vitest run tests/unit/services/wecomCheckinArchive.test.js --reporter=verbose。 node|vitest DONE DONE DONE server/src/services/integrations/wecomCheckinArchive.js|server/tests/unit/services/wecomCheckinArchive.test.js ["WCHECK1-1"] 回滚/清理:删除新增服务和测试即可;服务不写企业微信,写 OA 留存表用于审计。
5 WCHECK1-3 打卡摘要 QA runner 新增 QA-only runner check-wecom-checkin-summary-archive,支持 live 只读拉取、persist 写 OA 摘要和 offline 离线读取证明。 1) 默认 offline/read-only,不调用企微;2) live 模式仅调用打卡读取和规则读取,不写企业微信;3) 写 OA 摘要必须同时带 --persist-to-db 和 WECOM_CHECKIN_ARCHIVE_WRITE=1;4) 输出 artifacts/qa-flow/wecom-checkin-summary-archive-<timestamp>/summary.json;5) 报告只输出计数、日期、状态、异常摘要和脱敏 userid 前缀,不泄露完整 userid、位置、人脸、设备、token、Secret 或原始 payload。 受影响流程:企微打卡只读 -> OA 摘要留存 -> 企微 API 不可用时离线读取;验证步骤:cd server && node --check src/scripts/check-wecom-checkin-summary-archive.js;cd server && npx vitest run tests/unit/scripts/check-wecom-checkin-summary-archive.test.js tests/unit/services/wecomCheckinArchive.test.js --reporter=verbose。 node|vitest DONE DONE DONE server/src/scripts/check-wecom-checkin-summary-archive.js|server/tests/unit/scripts/check-wecom-checkin-summary-archive.test.js|server/package.json ["WCHECK1-2"] 回滚/清理:删除 runner 和 package 脚本即可;若已写 OA 摘要,保留审计或按后续人工批准清理。
6 WCHECK1-4 本地门禁与隐私测试 执行 WCHECK1 本地合同、Prisma、语法、focused 单测、文档和最小门禁。 1) CSV 与 process gate 通过;2) Prisma validate 通过;3) node --check 通过;4) 单测覆盖空记录、幂等、规则快照脱敏、外部配置阻断、隐私不泄露;5) git diff --check 和 scripts/check-minimal.sh 通过。 受影响流程:WCHECK1 实施候选 -> 本地 QA -> 可部署候选;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv --profile wecom --json;cd server && npm run prisma:validate;cd server && node --check src/services/integrations/wecomCheckinArchive.js;cd server && node --check src/scripts/check-wecom-checkin-summary-archive.js;cd server && npx vitest run tests/unit/services/wecomCheckinArchive.test.js tests/unit/scripts/check-wecom-checkin-summary-archive.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。 python3|node|prisma|vitest|bash|git DONE DONE DONE issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv|server/prisma/*|server/src/services/integrations/wecomCheckinArchive.js|server/src/scripts/check-wecom-checkin-summary-archive.js|server/tests/unit/*|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md ["WCHECK1-3"] 回滚/清理:本地门禁失败不部署;修复后重跑。
7 WCHECK1-5 公网只读与归档验证 本地门禁通过后,以 SYNC_ENV=0 部署并远端执行 WCHECK1 runner,证明可写 OA 摘要并离线读取。 1) 使用 SYNC_ENV=0,不同步本地 env;2) /ready 正常;3) 远端 live 只读拉取打卡短窗口并在双开关下写 OA 摘要;4) 离线读取不调用企微 API、不读取企微 Secret;5) 若权限、可信 IP、可见范围或 Secret 阻断,记录真实 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) 报告隐私扫描通过。 受影响流程:部署 -> 企微打卡只读 -> OA 摘要归档 -> 离线读取;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;远端执行 WECOM_CHECKIN_ARCHIVE_WRITE=1 npm run check:wecom-checkin-summary-archive -- --live --persist-to-db --format=json;远端执行 npm run check:wecom-checkin-summary-archive -- --offline --format=json。 bash|ssh|curl|npm DONE DONE DONE deploy/trialrun/deploy.sh|server/src/scripts/check-wecom-checkin-summary-archive.js ["WCHECK1-4"] 回滚/清理:部署异常按既有 trialrun 回滚;已写 OA 摘要保留审计,不写企业微信数据。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;live 报告 /app/artifacts/qa-flow/wecom-checkin-summary-archive-20260520T054907Z/summary.json 为 PASS_CHECKIN_ARCHIVE_READY,本窗口 0 条打卡明细、2 条规则快照写入 OA 留存;offline 报告 /app/artifacts/qa-flow/wecom-checkin-summary-archive-20260520T054926Z/summary.json 为 PASS_CHECKIN_ARCHIVE_OFFLINE_READY。
8 WCHECK1-6 事实源回写 更新路线图、API 目录、请假考勤规约、企业微信基础设施规约、管理员手册、试运行报告、文档索引、事实源矩阵和项目 skill。 1) 文档明确 WCHECK1 保存规范化明细、日/月摘要和规则快照;2) 明确不保存位置、人脸、设备明文或原始 payload;3) 明确企微不可用时 OA 只能查看已保存历史摘要,不代表继续办理;4) 后续仍需 WEXT1 dry-run 和 WREAL1 小范围真实试用。 受影响流程:事实源 -> 后续 WEXT1/WREAL1/镜像规划;验证步骤:node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;rg -n "WCHECK1|打卡摘要|规则快照|不保存完整位置|WEXT1|WREAL1|wecom_attendance_approval_mirror_v1" docs .agents/skills/hyb-oa-delivery/SKILL.md。 node|python3|rg DONE DONE DONE docs/企微优先开发路线图.md|docs/企微API能力目录.md|docs/需求-请假考勤修正规约.md|docs/需求-企业微信基础设施规约.md|docs/管理员手册.md|docs/trialrun/人工试运行报告.md|docs/文档索引.md|docs/文档事实源状态矩阵.md|.agents/skills/hyb-oa-delivery/SKILL.md ["WCHECK1-5"] 回滚/清理:恢复本阶段文档改动即可。
9 WCHECK1-7 状态回填与中文提交 完成 WCHECK1 状态回填、本地与公网证据登记和中文提交。 1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 公网报告路径写入 Notes;4) git diff --check 通过;5) 中文提交完成。 受影响流程:WCHECK1 实施 -> 证据回写 -> 可进入 WEXT1/WREAL1;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WCHECK1。 git|manual DONE DONE DONE issues/2026-05-20_12-48-04-wecom-checkin-summary-archive-v1.csv|server/*|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md ["WCHECK1-6"] 提交建议:WCHECK1 增加企微打卡摘要留存。若公网因外部配置 SKIP,仍提交真实阻断事实,不伪造成 PASS。;实际结果:WCHECK1 本地门禁、公网 live 写 OA 留存、离线读取和事实源回写已完成;未写企业微信,未保存位置、人脸、设备明文或原始 payload。
@@ -0,0 +1,7 @@
"ID","Title","Description","Acceptance","Test_Method","Tools","Dev_Status","Review1_Status","Regression_Status","Files","Dependencies","Notes"
"WEXT1-0","外出加班 dry-run 合同与边界","建立 WEXT1 外出/加班低风险 POC dry-run 合同;承接 WROAD2/WARCH3/WCHECK1,当前只证明 payload 可构建、非自审和脱敏报告,不 live 创建模板或审批单。","1) 范围仅 outing 外出、overtime 加班;2) 默认 dry-run,不写企业微信、不创建模板、不提交审批单;3) 申请人/审批人固定 SMOKE002 -> SMOKE101,禁止自审;4) Secret 来源固定 WECOM_AGENT_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;5) 缺用户、绑定、权限、可信 IP、可见范围或配置时记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) live 创建必须另起问答和新合同。","受影响流程:外出/加班 POC 准备 -> dry-run payload -> 后续是否 live 创建由人工决定;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv --profile wecom --json。","python3|node","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv","[]","回滚/清理:本行仅合同;dry-run 不创建企微记录,无需企微清理。"
"WEXT1-1","扩展审批样件 runner 目标","扩展现有 check-wecom-approval-fixtures runner,支持 --target=outing、--target=overtime 或 --targets=outing,overtime 的 dry-run payload 构建。","1) 默认仍为 leave/missed_punch,避免破坏 WAPC2F/WAPC2FLIVE;2) WEXT1 使用 --target=outing --target=overtime,且不传 --live、--create-templates 或 --submit-test-approvals;3) 外出/加班模板使用低风险 Text/Date/Textarea 等最小通用控件;4) live 写入路径对 outing/overtime 继续受 --live --create-templates --submit-test-approvals + WECOM_APPROVAL_FIXTURE_WRITE=1 双开关保护,但本轮不执行 live。","受影响流程:样件 runner -> 外出/加班 payload dry-run -> 后续 live 问答;验证步骤:cd server && node --check src/scripts/check-wecom-approval-fixtures.js;cd server && npx vitest run tests/unit/scripts/check-wecom-approval-fixtures.test.js --reporter=verbose。","node|vitest","DONE","DONE","DONE","server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js","[""WEXT1-0""]","回滚/清理:恢复 runner 和测试即可;本轮不写企微,无企微记录清理。"
"WEXT1-2","外出加班 dry-run 本地验证","执行 WEXT1 本地 dry-run,确认非自审、Secret 固定、payload 摘要和脱敏报告。","1) actor precheck 通过或真实 NEEDS_CONFIG;2) payload summary 包含 outing/overtime 且不含完整 userid、template_id、sp_no、表单值或原始 payload;3) live 缺双开关时不写;4) 不调用企微写接口;5) 结论为 PASS_FIXTURE_DRY_RUN_READY 或真实 PARTIAL/SKIP。","受影响流程:SMOKE002 -> SMOKE101 预检 -> 外出/加班 payload -> dry-run 报告;验证步骤:cd server && npm run check:wecom-approval-fixtures -- --format=json --target=outing --target=overtime;检查 artifacts/qa-flow/wecom-approval-fixtures-*/summary.json。","npm|node","DONE","DONE","DONE","server/src/scripts/check-wecom-approval-fixtures.js","[""WEXT1-1""]","回滚/清理:dry-run 只写本地 artifacts,保留审计或后续清理;不写企微。"
"WEXT1-3","本地门禁与文档回写","执行 WEXT1 合同、流程、runner 单测、文档和最小门禁,并更新路线事实源。","1) CSV 与 process gate 通过;2) runner 语法和 focused vitest 通过;3) 文档明确外出/加班只完成 dry-run,live 创建前必须再次问答批准;4) git diff --check 和 scripts/check-minimal.sh 通过。","受影响流程:WEXT1 dry-run 实施候选 -> 本地 QA -> 后续 live 决策;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv --profile wecom --json;cd server && node --check src/scripts/check-wecom-approval-fixtures.js;cd server && npx vitest run tests/unit/scripts/check-wecom-approval-fixtures.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。","python3|node|vitest|bash|git","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv|server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md","[""WEXT1-2""]","回滚/清理:本地门禁失败不部署;修复后重跑。"
"WEXT1-4","公网 dry-run 验证","以 SYNC_ENV=0 部署后,在远端执行外出/加班 dry-run,不设置 WECOM_APPROVAL_FIXTURE_WRITE=1。","1) /ready 正常;2) 远端 dry-run 结论 PASS_FIXTURE_DRY_RUN_READY 或真实 PARTIAL/SKIP;3) 不创建模板、不提交审批单、不写企业微信;4) 报告不泄露完整外部键或敏感值;5) live 创建留到下一轮问答。","受影响流程:部署 -> 远端 WEXT1 dry-run -> 后续人工决定是否 live;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;远端执行 npm run check:wecom-approval-fixtures -- --format=json --target=outing --target=overtime。","bash|ssh|curl|npm","DONE","DONE","DONE","deploy/trialrun/deploy.sh|server/src/scripts/check-wecom-approval-fixtures.js","[""WEXT1-3""]","回滚/清理:远端 dry-run 只生成报告,不写企微;如部署异常按既有 trialrun 回滚。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;远端 dry-run 报告 /app/artifacts/qa-flow/wecom-approval-fixtures-20260520T054940Z/summary.json 为 PASS_FIXTURE_DRY_RUN_READY;未设置 WECOM_APPROVAL_FIXTURE_WRITE,未创建模板或审批单。"
"WEXT1-5","状态回填与中文提交","完成 WEXT1 状态回填、本地与公网证据登记和中文提交。","1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 公网 dry-run 报告路径写入 Notes;4) git diff --check 通过;5) 中文提交完成;6) 最终用问答方式询问是否批准单次 live 创建 OA-POC 外出/加班测试样件。","受影响流程:WEXT1 dry-run -> 证据回写 -> 人工 live 决策;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WEXT1。","git|manual","DONE","DONE","DONE","issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv|server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md","[""WEXT1-4""]","提交建议:WEXT1 增加外出加班样件 dry-run。后续 live 创建必须另起 Issue CSV,并由用户明确批准。;实际结果:WEXT1 本地门禁、公网 dry-run 和事实源回写已完成;live 创建外出/加班样件仍需下一轮问答和独立 Issue CSV。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 WEXT1-0 外出加班 dry-run 合同与边界 建立 WEXT1 外出/加班低风险 POC dry-run 合同;承接 WROAD2/WARCH3/WCHECK1,当前只证明 payload 可构建、非自审和脱敏报告,不 live 创建模板或审批单。 1) 范围仅 outing 外出、overtime 加班;2) 默认 dry-run,不写企业微信、不创建模板、不提交审批单;3) 申请人/审批人固定 SMOKE002 -> SMOKE101,禁止自审;4) Secret 来源固定 WECOM_AGENT_SECRET,不尝试其他 Secret、无 fallback、不允许运行时猜 Secret;5) 缺用户、绑定、权限、可信 IP、可见范围或配置时记录 NEEDS_CONFIG 或 SKIP/BLOCKED_BY_EXTERNAL_CONFIG;6) live 创建必须另起问答和新合同。 受影响流程:外出/加班 POC 准备 -> dry-run payload -> 后续是否 live 创建由人工决定;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv --profile wecom --json。 python3|node DONE DONE DONE issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv [] 回滚/清理:本行仅合同;dry-run 不创建企微记录,无需企微清理。
3 WEXT1-1 扩展审批样件 runner 目标 扩展现有 check-wecom-approval-fixtures runner,支持 --target=outing、--target=overtime 或 --targets=outing,overtime 的 dry-run payload 构建。 1) 默认仍为 leave/missed_punch,避免破坏 WAPC2F/WAPC2FLIVE;2) WEXT1 使用 --target=outing --target=overtime,且不传 --live、--create-templates 或 --submit-test-approvals;3) 外出/加班模板使用低风险 Text/Date/Textarea 等最小通用控件;4) live 写入路径对 outing/overtime 继续受 --live --create-templates --submit-test-approvals + WECOM_APPROVAL_FIXTURE_WRITE=1 双开关保护,但本轮不执行 live。 受影响流程:样件 runner -> 外出/加班 payload dry-run -> 后续 live 问答;验证步骤:cd server && node --check src/scripts/check-wecom-approval-fixtures.js;cd server && npx vitest run tests/unit/scripts/check-wecom-approval-fixtures.test.js --reporter=verbose。 node|vitest DONE DONE DONE server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js ["WEXT1-0"] 回滚/清理:恢复 runner 和测试即可;本轮不写企微,无企微记录清理。
4 WEXT1-2 外出加班 dry-run 本地验证 执行 WEXT1 本地 dry-run,确认非自审、Secret 固定、payload 摘要和脱敏报告。 1) actor precheck 通过或真实 NEEDS_CONFIG;2) payload summary 包含 outing/overtime 且不含完整 userid、template_id、sp_no、表单值或原始 payload;3) live 缺双开关时不写;4) 不调用企微写接口;5) 结论为 PASS_FIXTURE_DRY_RUN_READY 或真实 PARTIAL/SKIP。 受影响流程:SMOKE002 -> SMOKE101 预检 -> 外出/加班 payload -> dry-run 报告;验证步骤:cd server && npm run check:wecom-approval-fixtures -- --format=json --target=outing --target=overtime;检查 artifacts/qa-flow/wecom-approval-fixtures-*/summary.json。 npm|node DONE DONE DONE server/src/scripts/check-wecom-approval-fixtures.js ["WEXT1-1"] 回滚/清理:dry-run 只写本地 artifacts,保留审计或后续清理;不写企微。
5 WEXT1-3 本地门禁与文档回写 执行 WEXT1 合同、流程、runner 单测、文档和最小门禁,并更新路线事实源。 1) CSV 与 process gate 通过;2) runner 语法和 focused vitest 通过;3) 文档明确外出/加班只完成 dry-run,live 创建前必须再次问答批准;4) git diff --check 和 scripts/check-minimal.sh 通过。 受影响流程:WEXT1 dry-run 实施候选 -> 本地 QA -> 后续 live 决策;验证步骤:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv;node scripts/qa/check-process-contract.mjs --baseline --json;node scripts/qa/check-process-contract.mjs --issue issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv --profile wecom --json;cd server && node --check src/scripts/check-wecom-approval-fixtures.js;cd server && npx vitest run tests/unit/scripts/check-wecom-approval-fixtures.test.js --reporter=verbose;node scripts/qa/audit-docs.mjs --check-registry;python3 /home/shunli/.codex/skills/.system/skill-creator/scripts/quick_validate.py .agents/skills/hyb-oa-delivery;git diff --check;bash scripts/check-minimal.sh。 python3|node|vitest|bash|git DONE DONE DONE issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv|server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md ["WEXT1-2"] 回滚/清理:本地门禁失败不部署;修复后重跑。
6 WEXT1-4 公网 dry-run 验证 以 SYNC_ENV=0 部署后,在远端执行外出/加班 dry-run,不设置 WECOM_APPROVAL_FIXTURE_WRITE=1。 1) /ready 正常;2) 远端 dry-run 结论 PASS_FIXTURE_DRY_RUN_READY 或真实 PARTIAL/SKIP;3) 不创建模板、不提交审批单、不写企业微信;4) 报告不泄露完整外部键或敏感值;5) live 创建留到下一轮问答。 受影响流程:部署 -> 远端 WEXT1 dry-run -> 后续人工决定是否 live;验证步骤:SYNC_ENV=0 bash deploy/trialrun/deploy.sh;curl -fsS https://oa.hyinda.com/ready;远端执行 npm run check:wecom-approval-fixtures -- --format=json --target=outing --target=overtime。 bash|ssh|curl|npm DONE DONE DONE deploy/trialrun/deploy.sh|server/src/scripts/check-wecom-approval-fixtures.js ["WEXT1-3"] 回滚/清理:远端 dry-run 只生成报告,不写企微;如部署异常按既有 trialrun 回滚。;实际结果:SYNC_ENV=0 部署通过,/ready 正常;远端 dry-run 报告 /app/artifacts/qa-flow/wecom-approval-fixtures-20260520T054940Z/summary.json 为 PASS_FIXTURE_DRY_RUN_READY;未设置 WECOM_APPROVAL_FIXTURE_WRITE,未创建模板或审批单。
7 WEXT1-5 状态回填与中文提交 完成 WEXT1 状态回填、本地与公网证据登记和中文提交。 1) Test_Method 全部真实通过或真实 SKIP;2) Issue 状态回填;3) 公网 dry-run 报告路径写入 Notes;4) git diff --check 通过;5) 中文提交完成;6) 最终用问答方式询问是否批准单次 live 创建 OA-POC 外出/加班测试样件。 受影响流程:WEXT1 dry-run -> 证据回写 -> 人工 live 决策;验证步骤:git status --short;git diff --check;git log -1 --oneline;确认提交信息包含 WEXT1。 git|manual DONE DONE DONE issues/2026-05-20_12-48-04-wecom-outing-overtime-fixture-dryrun-v1.csv|server/src/scripts/check-wecom-approval-fixtures.js|server/tests/unit/scripts/check-wecom-approval-fixtures.test.js|docs/*|.agents/skills/hyb-oa-delivery/SKILL.md ["WEXT1-4"] 提交建议:WEXT1 增加外出加班样件 dry-run。后续 live 创建必须另起 Issue CSV,并由用户明确批准。;实际结果:WEXT1 本地门禁、公网 dry-run 和事实源回写已完成;live 创建外出/加班样件仍需下一轮问答和独立 Issue CSV。