验证(08-08-production-authenticated-readiness): 完成员工权限负向验收

这个提交包含在:
2026-08-11 09:58:04 +08:00
父节点 ca8a1af554
当前提交 001be8ddd9
共修改 2 个文件,包含 18 行新增和 12 行删除
@@ -1,6 +1,6 @@
# 生产登录态只读验收:执行计划与证据
> 当前状态:IN PROGRESS / EMPLOYEE LOGIN READY。生产只读基线与扩展账号诊断已完成;管理员认证已由独立任务 `08-09-production-admin-break-glass-reset` 恢复,员工认证已由独立任务 `08-10-production-employee-smoke-break-glass-reset` 恢复并写入仓库外 secret。合同 UI 仍因生产零合同等待事件触发补验。
> 当前状态:IN PROGRESS / AUTH ROLES PASS / CONTRACT UI PAUSED。管理员与员工认证均已通过,员工合同管理权限负向已在生产登录态验证;合同 UI 仍因生产零合同等待事件触发补验。
## 1. 规划确认
@@ -72,16 +72,18 @@
- [x] 员工凭据来源已切换:来自 `08-10-production-employee-smoke-break-glass-reset` 的受控 break-glass 恢复和首次强制改密,不是本任务最初诊断为失效的原始 secret;最终 secret 已就绪且值不进入任务证据。
- [x] 08-10 最终交接证明目标仍唯一、`rolesExact=true`,`*`、`project.manage`、`project.view_all`、`system.settings` 四项权限全 false;该结论只解除凭据阻塞,不替代本任务的生产登录态负向验收。
- [x] admin 只执行一次登录、零 retry,HTTP 200 并进入 `/portal`;写后只读复核为 failureCount=0、locked=false、近 15 分钟 login success=1、login failure=0。
- [ ] READY:employee 最终凭据已由 08-10 合法恢复,负向前提仍成立;本任务下一步按单 worker、零 retry执行一次登录和合同权限负向,不扩大权限、不切换管理员身份。
- [x] employee 使用 08-10 恢复后的最终凭据登录一次、零 retry,HTTP 200 并进入 `/portal`;没有用原始失效 secret 试探登录。
- [x] admin attempts=1;未发生第二次登录。浏览器在合同台账阶段 fail-closed 后关闭,未到达正常 logout;active sessions 从恢复后的 1 变为 2,新增会话留待自然过期,本任务未获直接数据库撤销授权。
- [ ] READY:employee 尚未在本任务登录,attempts=0;目标唯一性与凭据阻塞均已解除,等待执行本任务既有负向验收步骤。
- [x] 已记录 admin attempts=1、employee attempts=0;没有第二次尝试,管理员失败计数仍为 0 且未锁定。
- [x] employee attempts=1、login POST=1,浏览器 context 已清理;没有第二次尝试或主动 logout 写入,新会话留待自然过期且浏览器 token 已不可用。
- [x] 已记录 admin attempts=1、employee attempts=1;两个角色均没有第二次尝试。
### Phase D:登录态只读验收
- [ ] PARTIAL:admin 登录成功;浏览器进入合同台账阶段后因无可用合同样本停止,未进入详情。生产数据库只读计数确认合同总数为 0,active/expired/draft/archived/terminated 均为 0。
- [ ] PAUSED:无 active/expired 样本,无法进入终止面板;未填写原因、未打开确认层、terminate POST=0、全部合同 mutation request=0。
- [ ] PAUSED:员工会话未建立,未执行权限负向路径;未扩大权限或删除断言。
- [x] 员工负向 PASS:登录后可只读到达合同列表与“合同”标题,管理入口“新增合同”不存在;直达 `/contracts-registry/new` 被前端权限门重定向到 `/403` 并显示“无权限访问”。
- [x] 员工负向网络证据:合同 GET=2、合同 mutation=0、全部非认证 mutation=0;未进入详情、未发送创建/编辑/归档/续约/终止/导出请求,未切换管理员身份。
- [x] 证据边界:本轮直接验证的是 UI 隐藏、前端路由拒绝和零业务写入;“已登录但无合同管理权限的用户调用服务端写端点会返回 403”未在生产直接触发,因为现行批准合同禁止发送业务 mutation。该结论由匿名鉴权负向 3/3、已发布候选中五个合同写端点均经 `canManageContractRegistry` 守卫的源码复核,以及运行 SHA 与候选一致三层证据支撑,不记为生产实测。
- [ ] PAUSED:archived 样本数为 0,无法验证字段锁定;未创建数据。
- [ ] PAUSED:terminated 样本数为 0,无法验证“已终止”标签与终止事实区;未制造样本。
@@ -91,11 +93,15 @@
- [x] 四次窗口证据均为 OPEN/0,未发现同期真实用户关闭窗口。
- [x] 凭据恢复后的管理员验收 PRE/POST 再次均为 `terminatedRows=0`、`rollbackWindow=OPEN`、`basis=terminated_status_count`;本任务累计六次快照均 OPEN/0。
- [x] 本轮浏览器 admin login=1/200;terminate POST=0、合同 mutation=0。runner 的状态词基线曾写成“已到期”而产品映射为“已过期”,但生产合同总数为 0,状态循环未执行,该观察不是本轮停止原因;依零 retry 合同未重跑。
- [x] 汇总:admin attempts=1、employee attempts=0;terminate POST=0、合同 mutation=0;未执行账号修复、权限、合同或 schema 写入。成功登录按产品合同创建 1 个新 session 并写登录审计,浏览器未到达 logout。
- [x] 管理员阶段当时汇总:admin attempts=1、employee attempts=0;terminate POST=0、合同 mutation=0;未执行账号修复、权限、合同或 schema 写入。成功登录按产品合同创建 1 个新 session 并写登录审计,浏览器未到达 logout;后续 employee 结果见本轮员工负向记录。
- [x] 扩展诊断只读 reviewer 首轮 `PASS_WITH_FINDINGS` 要求收窄员工密码与 UI PAUSED 措辞,修订后最终复查为 `PASS`;浏览器验收收口复核另发现旧汇总把成功登录副作用误写成“写入 0”,修正为 admin attempts=1、session 1→2 与登录审计后,最终复核为 `PASS`。reviewer 未修改文件、代码或生产状态。
- [x] 已按实际证据更新 PRD AC;管理员认证记为通过,员工与无样本 UI 分支保持 `PARTIAL/PAUSED`,未把缺失样本勾成通过。
- [x] 管理员阶段已按当时证据更新 PRD AC:管理员认证通过,员工与无样本 UI 分支保持 `PARTIAL/PAUSED`;后续员工凭据恢复与负向 PASS 已另行追加,合同无样本分支继续 `PAUSED`。
- [x] 已按 `trellis-update-spec` 将零 retry runner 的细粒度阶段、状态词源码基线、无样本独立分类和登录副作用对账写入现有 `.trellis/spec/hyb-oa/deployment-trialrun.md`,未新建规约文件。
- [x] 已为合同 UI `PAUSED` 写死事件触发条件:生产出现首条 `contract_registry` 记录后启动只读补验,不按日期等待、不制造样本,也不把记录出现视为终止授权。仓库事实源显示合同台账原已纳入首批真实使用且历史存在测试数据,因此当前零合同只记为待负责人确认的运营事实,不擅自归因为“模块尚未启用”。
- [x] 员工负向 PRE/POST 均通过已发布候选的生产 identity、13/13 聚合体检与 migration pending=none,并分别得到 `rollbackWindow=OPEN`、`terminatedRows=0`、`basis=terminated_status_count`;本任务有效窗口快照累计十一轮均 OPEN/0。
- [x] 会话残留决策已保留:08-10 交接时记录的 `activeSessions=1` 未另行撤销,选择让其自然过期,因为撤销需要新的生产认证写入批准且浏览器 token 已销毁;本轮员工负向登录又按产品合同创建一次会话,context/token 同样已销毁,未为追求计数归零追加 logout 或数据库写入。
- [x] 当前分支含未推送 task 证据,首次 PRE 在 13/13 后被 provenance 拒绝;detached 候选又因无 upstream 被拒绝。两次均未进入窗口查询。最终 PRE/POST 均从临时、跟踪 `origin/main` 的 clean worktree 执行,remoteVerified 且未使用 unpublished override;临时 worktree/branch 已移除。
- [x] 员工负向只读 reviewer 交叉核对已发布候选:新增路由与新增按钮均要求三项管理权限、详情 mutation 继续受同一权限集合限制、服务端五个合同写端点均由 `canManageContractRegistry` 守卫;结合生产 403 与 mutation=0,结论 PASS。首版 reviewer 因错误要求权限数组源码顺序一致而自我失败,修正为分别匹配实际等价集合后通过;未修改代码或生产状态。
## 4. 预期证据表
@@ -119,4 +125,4 @@
## 6. 当前结论
生产只读基线与账号诊断已执行,独立任务 `08-09-production-admin-break-glass-reset` 已恢复管理员认证。管理员本轮唯一一次登录返回 200,失败计数仍为 0 且未锁定;但生产合同总数为 0,无法验证详情、终止入口、归档锁定或已终止标签,未制造样本。仓库事实源不能证明零合同属于预期未启用,后续由负责人确认其运营含义;一旦生产出现首条记录,即触发只读补验。员工负向目标已通过资格诊断从 5 个候选收敛为唯一 1 个,并确认是专用 OA-only smoke 账号而非真人员工,但缺少已确认有效凭据,负向权限仍未验证。smoke 分类后的最终 POST 仍为 OPEN/0,本任务累计九次窗口快照全部 OPEN/0,terminate POST 和合同 mutation 均为 0。当前结论为管理员认证通过、合同 UI 因无数据 `PAUSED`、员工负向因凭据缺失 `PAUSED`;仍不得告知用户可以测试合同终止功能。
生产只读基线与账号诊断已执行,独立任务 `08-09-production-admin-break-glass-reset` 与 `08-10-production-employee-smoke-break-glass-reset` 分别恢复管理员和专用 employee smoke 的认证。管理员与员工本轮均只登录一次、HTTP 200、零 retry;员工登录态下合同列表可读但新增入口不可见,直达新增路由为 403,合同及全部非认证 mutation 均为 0,负向权限验证 PASS。生产合同总数仍为 0,无法验证详情、终止入口初始禁用、归档锁定或已终止标签,未制造样本;一旦出现首条记录即触发只读补验。员工负向 PRE/POST 后,本任务累计十一次有效窗口快照全部 OPEN/0。当前结论为两类认证与员工负向通过、合同 UI 因无数据 `PAUSED`;仍不得告知用户可以测试合同终止功能。
@@ -77,12 +77,12 @@
- [x] AC1:生产运行/公网 SHA 对应已部署产品候选 `0224ad8`(短标识 `0224ad83d7f8`);65 条 migration 仍全部 applied、pending=none,未触发部署或 schema 写入。
- [x] AC2:任何登录前已对管理员、员工完成同一 `BEGIN READ ONLY` 查询合同;查询设计覆盖 `matchedBy`、active/archived/locked、失败计数和期望角色是否就绪。两个 identifier 实际均 `matchedBy=none`,故账号属性记为 `N/A` 而非生产事实,不含账号或凭据明文。
- [x] AC3:两个仓库外 identifier 均不匹配 email/phone/employee_no。只读角色候选与远端内存密码 hash 比对进一步证明:唯一活跃管理员可解析为 email、未锁定、失败计数为 0,但原管理员密码不匹配;员工有 5 个活跃非管理员候选,原员工验收密码对这些候选的匹配数为 0。后续只读资格诊断将员工目标收敛为唯一 1 个:其登录 identifier 已就绪、未锁定、失败计数为 0、无需首次改密、可进入只读合同工作区且不具备合同管理权限;运行容器内既有 smoke 命名判据将其分类为专用 OA-only smoke 账号,未依赖私有 allowlist。本次没有注入或比较密码。登录尝试保持 0,未输出 identifier/hash/角色明细。
- [ ] AC4 — PARTIAL:管理员凭据已由独立 `08-09-production-admin-break-glass-reset` 合法恢复,本轮唯一一次登录 HTTP 200,失败计数为 0 且未锁定;员工凭据已由独立 `08-10-production-employee-smoke-break-glass-reset` 合法恢复,交接时目标唯一、`rolesExact=true`、四项管理权限全 false,但本任务员工登录尚未执行、attempts=0。浏览器未重试管理员登录。
- [x] AC4:管理员凭据已由独立 `08-09-production-admin-break-glass-reset` 合法恢复,本轮唯一一次登录 HTTP 200,失败计数为 0 且未锁定;员工凭据已由独立 `08-10-production-employee-smoke-break-glass-reset` 合法恢复,交接时目标唯一、`rolesExact=true`、四项管理权限全 false,本轮唯一一次登录同为 HTTP 200。两个角色均零 retry,未试探原始失效凭据。
- [ ] AC5 — PAUSED:管理员认证通过,但生产合同总数为 0,无法进入详情或终止面板;终止端点 `POST` 计数为 0、全部合同 mutation 计数为 0,确认层未打开,未制造合同。
- [ ] AC6 — READY:员工负向目标已通过只读资格诊断唯一确定,并确认是专用 OA-only smoke 账号而非真人员工;最终凭据已由 08-10 break-glass 合法恢复,角色精确与四项权限前提未变。本任务仍需执行一次生产登录态负向;archived/terminated 样本数均为 0,无法执行对应 UI 检查,且不得扩大权限、修改断言或制造数据。
- [x] AC7:初始、登录前停止后、扩展账号诊断后、邮件能力诊断后、管理员验收 PRE/POST、员工资格诊断 PRE/POST 及 smoke 分类后的最终 POST 共九次窗口证据均为 `terminatedRows=0`、`rollbackWindow=OPEN`、`basis=terminated_status_count`;窗口未变化,本任务真实合同终止写入计数为 0。
- [x] AC6:员工负向目标已通过只读资格诊断唯一确定,并确认是专用 OA-only smoke 账号而非真人员工;最终凭据来自 08-10 break-glass,角色精确与四项权限前提未变。生产登录后合同列表可读、管理入口“新增合同”不可见,直达新增路由进入 403;合同读取请求 2、合同 mutation 与全部非认证 mutation 均为 0。archived/terminated 样本仍为 0,相应可选 UI 检查保持 `PAUSED`,未扩大权限、修改断言或制造数据。
- [x] AC7:初始、登录前停止后、扩展账号诊断后、邮件能力诊断后、管理员验收 PRE/POST、员工资格诊断 PRE/POST、smoke 分类最终 POST 以及员工负向 PRE/POST 共十一次有效窗口证据均为 `terminatedRows=0`、`rollbackWindow=OPEN`、`basis=terminated_status_count`;窗口未变化,本任务真实合同终止写入计数为 0。
- [x] AC8:邮件能力与 break-glass 建议审查、浏览器验收收口审查的 findings 均已按证据边界修订,最终只读复查为 `PASS`;task validate、process contract、governance、sensitive scan、docs registry audit 与 diff check 已复跑,docs audit 仅保留既有 22 个未注册文件 warning。
- [x] AC9:结论明确为产品已部署、生产基线健康,但登录态验收仍 `PAUSED`;当前不得告知用户可以测试。
- [x] AC9:结论明确为产品已部署、生产基线健康,管理员认证与员工登录态权限负向均通过;合同 UI 因生产零记录仍 `PAUSED`,当前不得告知用户可以测试合同终止功能。
## Out of Scope