# 会话回落失败定性:诊断设计 ## 1. 问题模型 表面症状是业务页面断言超时,实际决策点在认证 bootstrap: ```text mock login 成功 -> 内存 access token 允许首次 SPA 跳转 -> 完整 page.goto / reload 重建 AuthProvider -> 有 has_session hint ? 否 -> 不请求 refresh -> 未认证 ready -> /login 是 -> POST /api/auth/refresh -> GET /api/me -> 保持目标路由 ``` 另一个独立真实路径是 Vite proxy 的 Host/Origin 一致性:即使 cookie 齐全,proxy 错误改写 Host 也可能让后端 refresh 返回 `AUTH_005`。因此最终 URL 不能区分“无 hint”“mock refresh 失败”“真实 refresh 被拒绝”。 ## 2. 诊断观测合同 每个可复现 witness 只记录以下安全字段: - `testTitle`、`step`、`pathname`; - cookie 名称与布尔存在性,不记录值; - `login|refresh|me` 的调用计数、HTTP status、安全错误码; - browser origin、proxy target 类别(loopback/非 loopback),不记录凭据或连接串; - runner 参数、worker 数、是否原样/控制变量。 证据写入当前 task `research/` 或 `implement.md`,不复制 trace 中的 cookie、header、payload。原始 trace 仅留在本地临时测试输出,敏感检查前不得提交。 ## 3. 实验顺序 ### A. 原样基线 1. 用两份目标 spec、单 worker、无 retry 运行一次。 2. 逐条对账历史 8 条;若同类失败存在,选择最短 global-search 二次 portal 用例作为主 witness,再以一个 R103 完整导航用例交叉验证。 3. 若结果漂移,使用相同 runner 对目标标题重复执行;不更改代码来制造复现。 ### B. Mock fixture 因果实验 1. 在 login 后、第一次完整导航前取 `context.cookies()` 的名称/布尔值。 2. 记录完整导航后是否调用 refresh 和 me。 3. 控制组显式安装与真实前端合同一致的 session hint,但保持业务 API mock、断言和导航不变。 4. 若缺 hint -> 无 refresh -> `/login`,而只增加 hint 后 refresh/me -> 原路由,则形成 fixture 因果链。 ### C. 真实前端与后端对照 1. 运行已有 session-hint bootstrap refresh Playwright 用例,验证 AuthContext 的受控路径。 2. 运行后端 refresh rotation focused tests,验证服务端基本合同。 3. 若前两项不足以排除集成问题,在 loopback/local-regression target gate 后,以真实本地 login cookie 做一次同源完整导航 witness;检查 Vite browser origin、request Host/Origin 与 refresh 状态。 ## 4. 决策树 ```text 原样失败可复现? 否 -> 重复/逐条仍不能复现 -> INCONCLUSIVE / PAUSED 是 -> fixture-only hint 控制是否消除? 否 -> 检查 refresh/me ledger 与真实 session 对照 是 -> 真实 session 对照通过? 是 -> FIXTURE 否 -> MIXED 真实同源 session 仍回落? 是 -> PRODUCT(或与 fixture 缺口并存时 MIXED) ``` 分类必须显式写出反证。例如 FIXTURE 结论同时说明:真实 session 对照未复现、后端 rotation 测试通过、runner 无 Host rewrite;不能只写“加 cookie 后绿了”。 ## 5. 修改与停止边界 - Phase A/B 可添加最小 test-side ledger 或控制变量,不修改 `client/src/auth/**`、`client/src/api/http.ts`、Vite proxy 或 `server/src/routes/auth.js`。 - 分类为 FIXTURE 后,如修法显然局部且不弱化断言,可在同任务追加 test-only 修复;先把分类证据写入任务,再改测试。 - 分类为 PRODUCT/MIXED 时停止。后续任务必须覆盖认证代码、真实 PostgreSQL/session race、浏览器完整导航,并在实现后启动只读 reviewer。 - 任何测试通过若来自删除 `page.goto`、删除登录态断言、增加 retry 或把 `/login` 视为正常,均为无效结果。 ## 6. Rollback 本任务的诊断探针和 fixture 控制均是本地测试侧改动。若未形成稳定证据,恢复探针但保留任务记录。任务不触碰生产、schema 或业务数据;真实本地会话 witness 仅在 target gate 后运行并按测试合同清理。