From e2d6f203614221e496ec9804fa57131eae4dbf22 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Sun, 6 Sep 2026 10:49:22 +0000 Subject: [PATCH] docs(tasks): accept e2f4b55c (BUG-542/551-556); session title guard fix brief (BUG-557) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu --- ...SS-api-not-configured-mislabel-20260904.md | 13 ++++ ...S-composer-live-input-and-stop-20260906.md | 14 +++++ ...consultation-context-and-cache-20260906.md | 18 ++++++ ...S-session-list-title-and-order-20260906.md | 17 +++++ ...ttings-dialog-and-billing-pane-20260906.md | 15 +++++ docs/tasks/README.md | 11 ++-- .../TASK-session-title-guard-fix-20260906.md | 63 +++++++++++++++++++ 7 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 docs/tasks/TASK-session-title-guard-fix-20260906.md diff --git a/docs/tasks/PROGRESS-api-not-configured-mislabel-20260904.md b/docs/tasks/PROGRESS-api-not-configured-mislabel-20260904.md index 62b98613..1ce6202f 100644 --- a/docs/tasks/PROGRESS-api-not-configured-mislabel-20260904.md +++ b/docs/tasks/PROGRESS-api-not-configured-mislabel-20260904.md @@ -44,3 +44,16 @@ Node 22 mock 契约:子进程 `mock.module(..., { namedExports })`(BUG-514 ## 遗留 未做浏览器真人走查。部署窗口的短暂 503 仍会出现,只是说法不再误导成环境变量丢失。未跑全量 `npm run lint` / `npm test`(任务书验收是 tsc + lint 0 error + 本单测试;改动文件 eslint 已 0 error)。 + +## 验收(Claude,2026-09-06,对照 `TASK-api-not-configured-mislabel-20260904.md`) + +共用门禁(`origin/staging` @ `e2f4b55c`,含五单全部提交):`tsc --noEmit` 0 错;`npm run lint` 0 error / 79 warning(全部既有);`npx tsx --test tests/*.test.ts` 2770 项 / pass 2729 / fail 29 / skipped 12——29 条失败全为环境缺口(25 条 Docker / rsync / pyyaml 缺失的库测与部署套件;2 条 `--experimental-test-module-mocks` 子进程在本机 Node 20 下解析不到 `@/` 别名,CI 为 Node 22;2 条 `beam-avatar` / `chat-composer-queue` 渲染用例因验收工作树里一个多余的 `node_modules/node_modules` 软链造成双份 React,删链后单独重跑通过);默认 `npm run build`(Turbopack)退出 0、`/` 为 `○ Static`、产物无 `/membership` 页;首屏 JS gzip-9(预渲染 `index.html` 引用脚本去重求和,与 09-02 口径一致)`d2a209d3` 519,437 B → `e2f4b55c` 522,617 B,**+3,180 B / +0.61%**,五单合计在 ±2% 内。执行方进度里「`next build --webpack` 停在 `dossierResponse` 导出类型」一事:`dc6598d7` 已去掉该 `export`,本次默认构建不再出现。 + +| 项 | 结论 | 依据 | +| --- | --- | --- | +| 5.1 共享 helper,只在 `isSupabaseConfigurationError` 时说「服务尚未配置」 | 通过 | `lib/api/service-unavailable.ts::jsonForSupabaseSetupFailure`;其余异常 503 `service_unavailable` + `console.error(routeName, errorName)`,不打印 message | +| 5.2 16 处路由替换、无遗漏 | 通过 | `grep -rn "服务尚未配置" frontend/src` 只命中 helper | +| 5.3 测试 `tests/api-service-unavailable-20260904.test.ts` | 环境缺口 | 4 条中 2 条走 `--experimental-test-module-mocks` 子进程,本机 Node 20 解析不到 `@/`(与既有 `report export` 用例同一模式);CI Node 22 应绿,以门禁结果为准 | +| 5.4 BUG-542 记录、CHANGELOG | 通过 | `docs/BUG_HISTORY.md` BUG-542 | + +**结论:通过**(2 条测试留 CI 复核)。修复 SHA `5483649b`。 diff --git a/docs/tasks/PROGRESS-composer-live-input-and-stop-20260906.md b/docs/tasks/PROGRESS-composer-live-input-and-stop-20260906.md index 7287089f..23d49f55 100644 --- a/docs/tasks/PROGRESS-composer-live-input-and-stop-20260906.md +++ b/docs/tasks/PROGRESS-composer-live-input-and-stop-20260906.md @@ -37,3 +37,17 @@ | `tests/class-name-definition-contract.test.ts` | 3/3 | | `page.tsx` | 2040 行 | | `npm run build -- --webpack` | 编译通过;随后在既有 `dossierResponse` 路由导出类型上失败,与本次无关 | + +## 验收(Claude,2026-09-06,对照 `TASK-composer-live-input-and-stop-20260906.md`) + +共用门禁(`origin/staging` @ `e2f4b55c`,含五单全部提交):`tsc --noEmit` 0 错;`npm run lint` 0 error / 79 warning(全部既有);`npx tsx --test tests/*.test.ts` 2770 项 / pass 2729 / fail 29 / skipped 12——29 条失败全为环境缺口(25 条 Docker / rsync / pyyaml 缺失的库测与部署套件;2 条 `--experimental-test-module-mocks` 子进程在本机 Node 20 下解析不到 `@/` 别名,CI 为 Node 22;2 条 `beam-avatar` / `chat-composer-queue` 渲染用例因验收工作树里一个多余的 `node_modules/node_modules` 软链造成双份 React,删链后单独重跑通过);默认 `npm run build`(Turbopack)退出 0、`/` 为 `○ Static`、产物无 `/membership` 页;首屏 JS gzip-9(预渲染 `index.html` 引用脚本去重求和,与 09-02 口径一致)`d2a209d3` 519,437 B → `e2f4b55c` 522,617 B,**+3,180 B / +0.61%**,五单合计在 ±2% 内。执行方进度里「`next build --webpack` 停在 `dossierResponse` 导出类型」一事:`dc6598d7` 已去掉该 `export`,本次默认构建不再出现。 + +| 项 | 结论 | 依据 | +| --- | --- | --- | +| 5.1 输入框不再随生成禁用;生成中回车进排队卡,结束后自动发出 / 失败放回 | 通过 | `lib/queued-draft.ts::queuedDraftSettleAction`(completed / succeeded → 发送,其余 → 放回);`page.tsx` `inputDisabled` 只剩结构性条件,`submitBlocked` 含 `Boolean(queuedDraft)`;`useConsultationRun` 开跑时 `setReplyOutcome(null)`,结算 effect 不会用上一轮结果误发 | +| 5.2 校正面停止改中性态、选择题 / 采用等待中停止有效 | 通过 | `stopped: true` 气泡、`isAbortError`、choice / adopt fetch 挂 `runAbort` 的 `AbortController`,`rectification-agentic-entry` 新增 abort 用例 | +| 5.3 `page.tsx` 不增行 | 通过 | 2041 → 2040(本单)→ 1976(BUG-554 后) | +| 5.4 测试 / DESIGN / VOICE / BUG-551、552 | 通过 | `chat-composer-queue.test.ts` 4 条本机通过(删双份 React 软链后) | +| 备注(不阻塞) | — | `useConsultationRun` 现在内部含 `useQueuedMessage` + `useEffect`,偏离 AGENTS §6「参数式 hook 内部 0 个 React hook」;任务书 §5 允许「或按仓库既定模式」,本次不追;下次改该 hook 时留意 | + +**结论:通过**。修复 SHA `055b7adc`。真实环境走查见 `docs/testing/composer-live-input-and-stop-20260906.md`。 diff --git a/docs/tasks/PROGRESS-consultation-context-and-cache-20260906.md b/docs/tasks/PROGRESS-consultation-context-and-cache-20260906.md index 94d3412e..a1168a23 100644 --- a/docs/tasks/PROGRESS-consultation-context-and-cache-20260906.md +++ b/docs/tasks/PROGRESS-consultation-context-and-cache-20260906.md @@ -59,3 +59,21 @@ - 溢出重试只包住 `agent.stream()` 抛错;流开始之后供应商才报超窗时不会第二次缩窗(咨询公共事件不能发 `attempt.reset`)。 - 摘要失败只 `console.warn("session context summary failed", error)`,不打印摘要正文。 - `costMicrousd` 仍按全价输入单价。 + +## 验收(Claude,2026-09-06,对照 `TASK-consultation-context-and-cache-20260906.md`) + +共用门禁见 `PROGRESS-session-list-title-and-order-20260906.md` 验收段(`e2f4b55c`:tsc 0 错、lint 0 error、2770 项测试 29 条环境失败、`next build` `/` Static、首屏 gzip +0.61%)。 + +| 项 | 结论 | 依据 | +| --- | --- | --- | +| 5.1 迁移 `20260906010000_chat_session_context_summary.sql`(`context_summary jsonb null` + 列级 grant) | 通过(`test:db` 环境缺口) | 本机无 Docker;执行方 `BLOCKED.md` 已记 Docker 地址池耗尽;**部署前必须先跑 Migrate Staging Database** | +| 5.1 历史 = 摘要之后 append-only 尾巴;单条 12,000 + 省略标记;按 `context_window` 预算 `clamp((cw−60k)×1.5, 4k, 40k)` 从最旧丢整条;null → 128k | 通过 | `consultation-session-history.ts::consultationHistoryWindow / historyBudgetChars / clipConsultationHistoryText`;`model-catalog.ts` 现读 `v.context_window` | +| 5.1 检查点摘要:尾巴 >16,000 字才触发、最后一对不进摘要、`complete_consultation_response` 成功后异步、不扣点、ref 计时器 15 s、默认模型、正则清洗、乐观并发 | 通过 | `session-context-summary.ts`;`checkpointConsultationContext` 的 update 带 `context_summary->>updatedAt = seen` / `is null` 守卫;`messages` 数组只追加不删(RPC 全部核过),`throughMessageIndex` 稳定 | +| 5.1 摘要放最后一条用户消息、时间行之后、问题之前 | 通过 | `consultationUserTurnContent`;三条路径(agentic / general / legacy)同一函数 | +| 5.1 溢出识别 + 同请求一次降级重试 | 通过(有边界) | `isContextOverflowError` 覆盖 OpenAI / Anthropic 文案与 400;`streamWithOverflowRetry` 只包 `agent.stream()` 抛错,流开始后的供应商报错不再缩窗——执行方已在「收尾限制」写明,接受 | +| 5.2 后台缓存可见 | 通过 | `api/admin/usage/aggregate` 按 `actual_model_id` × 7/30 天给 `runsWithCache / hitRate / readTokens / writeTokens / noCacheTokens / cacheShare`;列表 `cacheReadTokens` | +| 5.3 Anthropic 最后一条历史加第二断点 | 通过 | `agent-generation-settings.ts::cachedHistoryMessage` 仅 anthropic 生效 | +| 5.4 Full-spectrum + Event judgment skeleton 进系统块、工具结果只剩领域段 | 通过 | `skill-binding.ts` ``(+6,446 B);`consultation-methodology.ts::sharedConsultationMethodMarkdown`;9 段节选未回退 | +| 5.5 BUG-555 / 556、CHANGELOG、testing 清单 | 通过 | — | + +**结论:通过**(`test:db` 为环境缺口)。修复 SHA `bf8ad0d1`。部署顺序:先 Migrate Staging Database(本迁移 + `bab07187` 的 `5010000_personal_report_longform_appendices.sql`),再 deploy,再核 `/api/health`。 diff --git a/docs/tasks/PROGRESS-session-list-title-and-order-20260906.md b/docs/tasks/PROGRESS-session-list-title-and-order-20260906.md index ba0d44d2..b47ceb97 100644 --- a/docs/tasks/PROGRESS-session-list-title-and-order-20260906.md +++ b/docs/tasks/PROGRESS-session-list-title-and-order-20260906.md @@ -50,3 +50,20 @@ | `page.tsx` | 2035 行(上限 2041) | | `npm run build -- --webpack` | webpack 编译通过;类型检查仍停在既有 `dossierResponse` 路由导出(`api/rectification/cases/[caseId]`),与本单无关。本单曾误把 `metadataUpdateValues` 从 sessions `[id]` 路由再导出,已撤回。 | | 全量 `npm test`(含 `database-*`) | 本机 Docker 库测多项 300s 超时 / 权限负例 ERROR,与本单无关;未当作本单回归。 | + +## 验收(Claude,2026-09-06,对照 `TASK-session-list-title-and-order-20260906.md`) + +共用门禁(`origin/staging` @ `e2f4b55c`,含五单全部提交):`tsc --noEmit` 0 错;`npm run lint` 0 error / 79 warning(全部既有);`npx tsx --test tests/*.test.ts` 2770 项 / pass 2729 / fail 29 / skipped 12——29 条失败全为环境缺口(25 条 Docker / rsync / pyyaml 缺失的库测与部署套件;2 条 `--experimental-test-module-mocks` 子进程在本机 Node 20 下解析不到 `@/` 别名,CI 为 Node 22;2 条 `beam-avatar` / `chat-composer-queue` 渲染用例因验收工作树里一个多余的 `node_modules/node_modules` 软链造成双份 React,删链后单独重跑通过);默认 `npm run build`(Turbopack)退出 0、`/` 为 `○ Static`、产物无 `/membership` 页;首屏 JS gzip-9(预渲染 `index.html` 引用脚本去重求和,与 09-02 口径一致)`d2a209d3` 519,437 B → `e2f4b55c` 522,617 B,**+3,180 B / +0.61%**,五单合计在 ±2% 内。执行方进度里「`next build --webpack` 停在 `dossierResponse` 导出类型」一事:`dc6598d7` 已去掉该 `export`,本次默认构建不再出现。 + +| 项 | 结论 | 依据 | +| --- | --- | --- | +| 5.1 起名 Agent:ref 计时器 8 s、30 token、清洗 6–14 汉字 / 拒换行 / 拒生日形态 | 通过 | `lib/session-title-agent.ts`、`lib/session-title.ts::sanitizeSessionTitle` | +| 5.1 只在首轮、非校正、非日期式标题时起名;与主回答并行、`session.title` 流事件 | 通过 | `shouldGenerateSessionTitle`;`use-consultation-run.ts` `streamedTitle ?? reply.title` | +| 5.1 **服务端守卫写库** | **未通过(P1)** | `api/consult/route.ts` L693 的 `expectedTitle` 取自 RPC 之前的 select;L531 `append_consultation_question` 已把空 / 「新对话」标题改写成 `left(question,14)‖'…'`(迁移 `20260901010000` L84–90);L710 `.eq("title", expectedTitle)` 因此对新会话恒匹配 0 行且无报错——服务端从不落库模型标题,只靠客户端结算时 PATCH。用户中途刷新 / 换设备时 `status` 路由回读的是问题截断标题。无测试覆盖此守卫。修复单 `TASK-session-title-guard-fix-20260906.md`(BUG-557) | +| 5.2 侧栏去「资料名 · 」前缀、他人资料小字副标题 | 通过 | `home-profile.ts::sessionSidebarTitle` / `sessionSidebarSubtitle` | +| 5.3 排序:置顶 + `updatedAt` 倒序;元数据 PATCH 不再推进 `updated_at`;客户端改名不再 `timestamp()` | 通过 | `session-metadata-update.ts` 只展开 patch 字段;`use-session-management.ts` 无 `updatedAt: timestamp()` | +| 5.4 今天 / 昨天 / 7 天 / 30 天 / 更早分组,收藏不分组 | 通过 | `lib/session-groups.ts::groupSessionsByRecency` | +| 5.5 游标分页 40 条、置顶首页全量、`archived=1`、滚到底静默续取 | 通过 | `api/sessions/route.ts`(`limit+1` 探测 `nextCursor`)、`app-sidebar.tsx` `IntersectionObserver`,无 spinner / 「加载更多」文案 | +| 5.6 BUG-553、CHANGELOG、testing 清单 | 通过 | — | + +**结论:未通过(1 项 P1,其余通过)**。修复 SHA `a1956deb`;P1 修复单 `TASK-session-title-guard-fix-20260906.md`。 diff --git a/docs/tasks/PROGRESS-settings-dialog-and-billing-pane-20260906.md b/docs/tasks/PROGRESS-settings-dialog-and-billing-pane-20260906.md index 76350d1e..f67ef741 100644 --- a/docs/tasks/PROGRESS-settings-dialog-and-billing-pane-20260906.md +++ b/docs/tasks/PROGRESS-settings-dialog-and-billing-pane-20260906.md @@ -72,3 +72,18 @@ Next.js 16 typed routes 不允许 `route.ts` 额外 export。`dossierResponse` 分支相对当前 `origin/staging` 落后 2 个提交(BUG-555/556)。未在脏树上合并,避免和本单的 `CHANGELOG` / `BUG_HISTORY` 撞车。 浏览器走查见 `docs/testing/settings-dialog-and-billing-pane-20260906.md`。本机未起登录会话,真实四分区切换留给 staging 验收。 + +## 验收(Claude,2026-09-06,对照 `TASK-settings-dialog-and-billing-pane-20260906.md`) + +共用门禁见 `PROGRESS-session-list-title-and-order-20260906.md` 验收段(`e2f4b55c`:tsc 0 错、lint 0 error、2770 项测试 29 条环境失败、`next build` `/` Static、首屏 gzip +0.61%)。 + +| 项 | 结论 | 依据 | +| --- | --- | --- | +| 5.1 弹窗壳固定尺寸 + 四分区 | 通过 | `.settings-modal { width: min(100vw − 32px, 880px); height: min(84dvh, 640px) }`;`chart-library-modal` / `profile-modal` 已无;导航 个人资料 → 星盘资料 → 账户与点数 → 通用设置 | +| 5.2 个人资料搬出 `page.tsx`,无「管理星盘资料」 | 通过 | `profile-panel.tsx`;`page.tsx` 2035 → 1976 行(净减 59 ≥ 40) | +| 5.3 星盘资料列表 → 详情 | 通过 | `chart-library-panel.tsx` 内部视图 `list / self / other / add`,默认列表,无无条件 `)`。 +4. 守卫更新要 `.select("id")` 回读影响行数,0 行时 `console.warn("session title guard missed")`,不再静默。 + +## 4. 硬红线 + +- 不改 RPC、不改迁移、不改客户端 `use-consultation-run.ts`。 +- 不得把守卫放宽成无条件写入。 +- 不得为测试重写路由结构;用现有 `application-billing-contract.test.ts` 的源码合同方式或 mock Supabase 链的方式二选一。 + +## 5. 任务分解 + +### 5.1 守卫取 RPC 后标题 +- `route.ts`:`appendedQuestion` 成功后 `const { data: titleRow } = await supabase.from("chat_sessions").select("title").eq("id", sessionId).eq("user_id", userId).maybeSingle()`;`shouldGenerateSessionTitle` 仍用 RPC 前标题;守卫 `.eq("title", titleRow?.title ?? expectedTitle)`;更新后 `.select("id")`,长度 0 → `console.warn`。 +- 验收:测试——模拟 RPC 前标题「新对话」、RPC 后标题「问题前 14 字…」、模型标题「X」:断言 update 链的 `eq("title", …)` 收到的是 RPC 后标题;模拟用户中途把标题改成「我的标题」(回读值与守卫值不等)→ 更新 0 行且 `console.warn` 被调用一次、返回的流事件仍是 `session.title`。 + +### 5.2 记录 +- `docs/BUG_HISTORY.md` BUG-557(关联 BUG-553;说明为何 a1956deb 的测试没拦住:无守卫命中断言);`CHANGELOG.md` 一条;`docs/tasks/PROGRESS-session-title-guard-fix-20260906.md`;`docs/testing/session-list-title-and-order-20260906.md` 补一条「首轮生成中刷新页面,回来后标题仍是模型标题」。 + +## 6. 让步顺序 + +5.1 不可拆;5.2 不可省。 + +## 7. 开工前置命令 + +```bash +git fetch origin --prune +git worktree add -b codex/session-title-guard-fix-20260906 .worktrees/session-title-guard-fix-20260906 origin/staging +cd .worktrees/session-title-guard-fix-20260906/frontend +ln -s /workspace/Jyotisha/frontend/node_modules node_modules # 注意:不要在已有 node_modules 的目录里再建,会产生 node_modules/node_modules 双份 React +npx tsx --test tests/session-title-agent.test.ts tests/application-billing-contract.test.ts 2>&1 | grep -E "^# (tests|pass|fail)|^not ok" +``` + +收尾同一条命令 fail=0,再 `tsc --noEmit`、`npm run lint`。