文件
hyb-oa/.trellis/tasks/08-10-session-fallback-failure-classification/design.md
T

4.1 KiB
原始文件 Blame 文件历史

会话回落失败定性:诊断设计

1. 问题模型

表面症状是业务页面断言超时,实际决策点在认证 bootstrap:

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. 决策树

原样失败可复现?
  否 -> 重复/逐条仍不能复现 -> 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 后运行并按测试合同清理。