8.8 KiB
8.8 KiB
生产员工 Smoke Break-glass 重置:执行计划
当前状态:RELEASE APPROVED / PRE-COMMIT。用户已批准提交、推送/provenance、生产只读 preflight、正常候选发布和运行脚本 SHA-256 比对;尚未批准生产账号写入、登录或强制改密。
1. 规划事实与决策
- 目标是专用 OA-only smoke employee,不是真人员工;
08-08已只读证明唯一资格目标,登录 attempts=0。 - 已完整审阅
repair-oa-only-smoke-accounts.js:它不重置密码;apply 可恢复状态、清登录锁、token +1、补缺失角色并写 lifecycle event,但不删除额外角色、不撤销 session/challenge。 - 现有 helper 只作为一次 dry-run 对照,禁止 apply;若 action 非空即停止。
- 不扩展管理员脚本目标面;新增员工 smoke 专用脚本,角色/权限只断言、不写入。
- 新脚本不在生产镜像,必须经正常候选发布;禁止单文件复制、inline code 或手写 SQL。
- 生产写后重新验证
roles == ['employee']和四项管理权限全 false,未通过前禁止登录。
2. 启动门禁
- 用户完成本规划只读复核并明确批准
task.py start;该批准只覆盖本地实现与测试。 - 读取
trellis-before-dev、backend 与 hyb-oa 相关 spec,再编辑 server 脚本/测试。 - 确认工作区仅含本 task 规划及其实现改动;未混入 08-08 或其他任务改动。
3. Phase A:先实现最窄工具
- 新增
server/src/scripts/reset-employee-smoke-password.js,复用现有 smoke 判据、管理员 stdin 密码校验和应用同源 crypto/password policy,未扩展管理员目标面。 - 实现不接收/不输出 identifier 的唯一目标发现;精确角色与独立权限断言必须同时成立。
- 实现默认/
--dry-run/--preflight、--verify、--verify-password-changed和精确 apply 确认串;本地最小范围未加入非必要企微诊断。 - apply 使用 Serializable 事务,先锁 Employee、再锁其角色行并重新核对 id/token/status/smoke/role/permission;只写目标认证字段、目标 session/challenge 和专用 audit。
- 未知异常脱敏;稳定输出不含账号、identifier、id、路径、hash、payload,privacy 口径沿用现有 helper 且更窄。
4. Phase B:再补覆盖与只读 review
- 新增
server/tests/unit/scripts/reset-employee-smoke-password.test.js,23 条用例覆盖零/多目标、非 smoke、identifier/status/employment/archive/锁/must-change、额外角色、四个禁用权限、事务内 role/token 漂移、确认串、目标限定写入、verify 与最终改密 verify。 - apply 的 Employee update 键集合被精确断言;无 role/status/identifier/企微/业务写入,session/challenge where 精确限定 target id。
reset-active-admin-password.test.js6/6 PASS,管理员脚本目标面未扩大。repair-oa-only-smoke-accounts.test.js5/5 PASS,并新增完整副作用合同:只补角色、不删额外角色、不重置密码、不写 session/challenge。- node check、focused 34/34、Prisma validate、client typecheck/build/PWA 生成全部 PASS;build 仅有既有 Browserslist 数据陈旧提示。
- 用户只读 reviewer 复核 diff 后结论 PASS:确认唯一 Employee update 仅为认证字段,角色路径纯读,默认 dry-run/精确确认串 fail-closed,两个 verify 均重算精确角色与四项权限;reviewer 未修改代码。
- reviewer 额外确认事务以 Serializable 隔离级别先锁 Employee、再锁角色行,并在写入前重验目标/token/角色/权限;候选到写入之间的前提漂移会中止事务。
5. STOP A:发布审批
- 本地实现、测试和 reviewer PASS 后提交中文 commit,引用
08-10-production-employee-smoke-break-glass-reset。 - 已向用户报告精确 diff、测试、脚本完整写集/不写集与发布必要性;用户只读审查通过,当前进入发布审批门,未取得明确发布批准前不 commit/push/deploy。
- 用户已明确批准五步发布范围:commit、push/provenance、发布前只读 preflight、
deploy-existing.sh正常发布、发布后运行脚本 SHA-256 比对;批准不包含员工账号 apply、登录或强制改密。 - 获批后 push 并验证 provenance remoteVerified;再次确认候选无 migration、无意外产品改动。
6. Phase C:正常发布与运行脚本身份
- 运行生产 identity/read-only preflight:身份、65 migration、pending、运行/公网 SHA、rollback window 全部按部署合同通过。
- 仅在独立发布批准下使用
deploy-existing.sh发布候选;失败立即停止,不进入账号阶段。 - 发布后复核 ready/public SHA、匿名鉴权和 migration;比较运行镜像新脚本 SHA 与候选基线,要求
scriptShaMatch=true。 - 不执行
docker cp、SSH 单文件同步、工作区脚本覆盖或 inline 写入代码。
7. Phase D:生产只读前置
- 取得独立生产账号写入批准;确认批准包含脚本声明的完整认证副作用与一次强制改密,不包含角色或业务写入。
- rollback window PRE。
- 运行现有 helper 一次 dry-run:目标 safe、status=OK、actions=[]、passwordReset=false;记录 helperApplyCount=0。
- 运行新脚本
--preflight:targetMatches=1、exactTarget/rolesExact/identifierReady/locksClear=true,四项管理权限 false。 - 用独立
BEGIN READ ONLY查询复核相同角色/权限基线;读取 break-glass audit 写前计数。 - 可选写前企微诊断只记录稳定布尔/计数,不修改绑定。
- 准备
0700/0600旧 hash 有限恢复材料、互不相同的临时/最终密码和 apply attempt 哨兵;任何敏感值不回显。
8. Phase E:唯一账号写入
- 从 stdin 执行且仅执行一次
--apply EMPLOYEE_SMOKE_BREAK_GLASS;applyExecutionCount=1。 - 完整 PASS 后立即
--verify;若结果不确定,进入APPLY_UNCERTAIN,只允许--verify定性,禁止第二次 apply。 - verify 要求 must-change、locks、session/challenge、token/audit 和目标/角色/权限全部 PASS。
- 独立
BEGIN READ ONLY再次确认 targetMatches=1、roles == ['employee']、四项管理权限 false;审计计数较写前恰好 +1。 - 任一写后权限不变量失败,停止且不登录;不得在本任务修角色或权限。
9. Phase F:一次登录与强制改密
- 仅在 Phase E 全 PASS 后,原子更新仓库外 employee smoke secret 为正确 identifier + 临时密码,权限
0600。 - 单 browser/context、workers=1、retries=0 登录一次,必须进入
/change-password。 - 使用已准备的最终密码提交一次;到
/portal后立即停止,业务 API 实际发送数为 0。 --verify-password-changed与最终独立权限快照 PASS;最终 secret 原子更新且0600。- 写后企微诊断(若启用)证明绑定状态未变;不得做企微登录/绑定写入。
10. Phase G:清理、review 与交接
- 销毁临时 secret、浏览器状态、attempt 哨兵和旧 hash;记录
temporaryCredentialDestroyed/browserStateCleared/recoveryMaterialDestroyed=true。 - 最终生产 read-only preflight、migration 和 rollback window POST;合同/schema/权限/其他账号写入计数为 0。
- 只读 reviewer 核对运行脚本 SHA、apply 次数、审计 +1、目标限定副作用、写后精确角色/权限、零业务写入和清理证据。
- 更新本 task 稳定证据并运行 task/process/governance/sensitive/diff 门禁。
- 只向
08-08-production-authenticated-readiness交接最终员工凭据可用与负向权限前提未变;回原 task 执行员工合同权限负向。
11. 验证命令
node --check server/src/scripts/reset-employee-smoke-password.js
cd server && npm test -- tests/unit/scripts/reset-employee-smoke-password.test.js tests/unit/scripts/reset-active-admin-password.test.js tests/unit/scripts/repair-oa-only-smoke-accounts.test.js
cd server && npm run prisma:validate
cd client && npm run typecheck && npm run build
python3 ./.trellis/scripts/task.py validate 08-10-production-employee-smoke-break-glass-reset
node scripts/qa/check-process-contract.mjs --baseline --json
node scripts/qa/check-trellis-governance.mjs --json
node scripts/qa/check-sensitive-content.mjs
git diff --check
12. 当前结论
本地实现、自检与用户只读审查均已完成,结论 PASS。新脚本默认只读 preflight,只有精确确认串进入写入;角色路径只有读取、锁定与精确断言。--verify 和 --verify-password-changed 均重新输出实际 must-change、rolesExact 及四项管理权限布尔。用户已批准五步候选发布,当前进入提交前检查;账号写入、登录和强制改密仍需发布成功后的独立批准。