9.0 KiB
9.0 KiB
会话回落失败定性
Goal
在与 2026-08-07 历史记录一致的本地 Playwright runner 下,稳定复现并定性 8 条“完整导航或二次返回后落到登录页”的失败,给出可审计结论:测试 fixture/session mock 问题、真实会话行为问题、二者混合,或证据仍不足而保持 PAUSED。任务价值是消除唯一尚不明确且可能影响真实用户登录态的 Residual,不以让 8 条测试变绿作为终点。
Confirmed Facts
- 父任务 Residual Register(
.trellis/tasks/archive/2026-08/08-05-product-interaction-consistency/prd.md:76-81)记录:r103-cross-page-ui-consistency.spec.ts7 条、global-search.spec.ts1 条失败,统一症状为多次完整导航或二次返回后落到登录页;现有证据不能排除真实会话续期行为。 - 历史同 runner 命令为
cd client && npx playwright test tests/e2e/procurement-flow.spec.ts tests/e2e/assets-flow.spec.ts tests/e2e/r103-cross-page-ui-consistency.spec.ts tests/e2e/pc-detail-mobile-visual-wave3.spec.ts tests/e2e/global-search.spec.ts --workers=1 --reporter=list;其中目标两份 spec 当时分别为4 passed / 7 failed与3 passed / 1 failed。 - 两份目标 spec 都拦截
/api/auth/login、/api/auth/refresh与/api/me,因此它们自身不能直接证明真实后端 refresh rotation 正常或异常。 AuthContext在完整页面重建时先检查可读的has_session=1;无 session hint 时不会请求 refresh,而是按未认证状态完成 bootstrap。真实后端登录和 refresh 会同时写 refresh cookie 与has_sessioncookie。- 现有前端规约还记录另一条真实会话风险:本地 Vite proxy 若把浏览器 Host 从
127.0.0.1:5173改写成后端 Host,refresh 的 Origin/Referer 校验会返回AUTH_005,完整刷新后丢失会话。因此诊断必须同时取证 cookie/hint、refresh 请求与 runner origin/host,不能只看最终 URL。 - 仓库已有独立证据面:
login-portal-ux.spec.ts覆盖带 session hint 的 bootstrap refresh 重试;auth.login.test.js覆盖后端 refresh rotation;它们可作为对照,但不能单独替代目标 runner 的复现。
Scope
- 两份目标 Playwright spec 的原样复现、逐条失败账本和安全诊断 ledger。
- mock session fixture、真实前端 bootstrap、真实本地后端 session 三个证据面的对照实验。
- 基于明确判据输出 FIXTURE、PRODUCT、MIXED 或 INCONCLUSIVE/PAUSED 分类。
- 分类为 FIXTURE 后可选的最小 test-only 修复;任何认证产品改动、生产连接或部署均不在本任务范围。
Requirements
R1 同 runner 稳定复现
- 先用历史命令的同一目标 spec、
--workers=1 --reporter=list复现;不得先改 fixture、断言、认证实现、Vite proxy 或 runner 配置。 - 至少执行一次两份目标 spec 的原样组合;若结果不稳定,再对失败标题逐一、重复执行以区分顺序依赖、完整导航依赖和偶发 runner 状态。
- 记录测试名、阶段、最终 pathname、cookie 名称/是否存在、是否发出 login/refresh/me 请求、响应状态与安全错误码。不得记录 cookie/token 值、密码、完整账号或原始认证 payload。
R2 证据隔离与分类实验
- 建立三个彼此独立的证据面:
- mock fixture 面:目标 spec 的 login 响应后浏览器是否真的持有
has_session,完整导航时是否触发 mock refresh/me; - 真实前端 bootstrap 面:显式存在 session hint 时 AuthContext 是否按设计请求 refresh 并保持路由;
- 真实后端 session 面:本地真实登录产生的 cookies、同源 refresh rotation 和完整导航是否成立,且 Vite proxy host/origin 符合规约。
- mock fixture 面:目标 spec 的 login 响应后浏览器是否真的持有
- 对照实验只允许使用 synthetic fixture 或经 target gate 确认为回环/本地回归库的账号与会话;禁止连接生产或复用生产凭据。
- 为证明因果,可做最小的 test-side 控制变量(例如显式安装 session hint、记录安全 request ledger);在分类完成前不得修改产品认证代码。临时探针如不形成稳定回归价值,应在结论前移除。
R3 分类判据
- FIXTURE:原样失败可复现;证据显示 mock 登录未建立 AuthContext 完整导航所需的浏览器 session contract,最小 fixture-only 控制变量消除同一失败;独立真实 bootstrap/backend 对照通过。
- PRODUCT:使用真实本地 session contract、正确同源 runner 与无 mock 的 refresh/me 路径仍可复现相同会话回落,或真实认证对照出现同一根因。立即停止本任务内修复,登记独立认证缺陷任务;后续实现必须只读 reviewer。
- MIXED:fixture 合同确有缺口,同时真实 session 对照也失败。分别登记测试债与认证缺陷,不在本任务合并修复。
- INCONCLUSIVE / PAUSED:无法稳定复现、关键证据面不可用或 target gate 不通过。不得把未复现解释为 PASS,也不得猜测根因。
R4 修复边界
- 任务终点是分类结论和证据链,不是测试全绿。
- 若结论为 FIXTURE,可在分类检查点之后选择同任务内提交最小 test-only 修复,但它不是完成 AC 的必要条件;不得改变产品认证实现、弱化会话语义或扩大 mock 的默认放行。
- 若结论为 PRODUCT 或 MIXED,必须在任何认证代码修改前停止并请求创建独立任务与实施批准。
- 不得以删除断言作为默认修法。 不得删除目标用例、移除完整导航、跳过 refresh/session 检查、增加 retry 掩盖失败,或把登录页当作可接受结果。
Acceptance Criteria
- AC1:在历史同 runner 参数下记录两份目标 spec 的原样结果,并能把 8 条历史失败逐条映射为当前 PASS/FAIL/未复现,不用套件总数代替逐条证据。
- AC2:至少一个可复现失败拥有脱敏 request/cookie/navigation ledger,能回答 session hint 是否存在、refresh/me 是否发出、在哪一步进入
/login。 - AC3:完成 mock fixture、真实前端 bootstrap、真实本地后端 session 三个证据面的对照;任何未执行项均有明确阻塞原因,不以另一层 PASS 顶替。
- AC4:按 R3 输出且仅输出一个最终分类:FIXTURE、PRODUCT、MIXED 或 INCONCLUSIVE/PAUSED,并列出支持证据和反证。— 唯一分类
FIXTURE。 - AC5:若为 PRODUCT/MIXED,认证产品代码保持未修改并停在独立任务批准前;若为 FIXTURE 且同任务修复,diff 仅限 test fixture/harness,先有分类检查点,且不得删除或弱化断言。
- AC6:原样保留并落实“不得以删除断言作为默认修法”;目标测试数量、关键完整导航与会话语义无静默减少。
- AC7:所有自动化、typecheck(若 test code 有改动)、task/process/governance/sensitive 与
git diff --check按范围通过;结果明确为本地诊断,未连接生产、未部署。
Out of Scope
- 未完成分类前修复
AuthContext、refresh rotation、cookie、Vite proxy 或后端认证路由。 - 生产登录、生产 session 查询、生产配置、部署、公网 smoke 或真实用户账号操作。
- 合同 UI 验收、员工负向验收、管理员手册附件承诺,以及其他 Playwright 失败。
- 为追求套件全绿而重写 8 条业务断言或扩大通用 mock 成功面。
Risks and Deferred Items
- 当前源码证据更偏向 fixture/session hint 缺口,但这只是待验证假设,不是结论。
- 真实本地 session 对照会创建/轮换本地测试会话;执行前必须 fail-closed 确认回环主机和本地回归库,结束后按既有测试清理合同处理。
- 若最终需要认证产品修复,风险等级上升为生产登录态缺陷,必须新建独立任务、补真实数据库/浏览器回归并启动只读 reviewer。
- 管理员手册的合同附件承诺应在首条真实合同出现前单独修订,不并入本任务。
Test Plan
- 原样复现:
cd client && npx playwright test tests/e2e/r103-cross-page-ui-consistency.spec.ts tests/e2e/global-search.spec.ts --workers=1 --reporter=list - 必要时按历史失败标题
--grep单跑并--repeat-each验证稳定性;不以 retry 作为通过证据。 - 前端对照:聚焦
login-portal-ux.spec.ts中 bootstrap refresh 用例及新增/临时安全 ledger。 - 后端对照:
cd server && npm test -- tests/unit/routes/auth.login.test.js;若需真实本地 session,先运行本地 target gate,再执行最小浏览器/API witness。 - 若修改测试:
cd client && npm run typecheck,再运行两份目标 spec 与相关 auth 对照。 python3 ./.trellis/scripts/task.py validate 08-10-session-fallback-failure-classificationnode scripts/qa/check-process-contract.mjs --baseline --jsonnode scripts/qa/check-trellis-governance.mjs --jsonnode scripts/qa/check-sensitive-content.mjsgit diff --check
Open Questions
- 无。分类目标、四种停止状态、生产边界和修复分叉均已明确;技术未知由本任务实验回答。