Files
memind/docs/regression-guards/mindspace-publish-and-chat-finish.md

5.6 KiB
Raw Permalink Blame History

MindSpace 发布与聊天 Finish 回归守卫

状态:已验证(2026-06-29)— 请勿在未更新测试/verify 的情况下删改下列行为。

本页记录两类好不容易调通的行为,以及如何用自动化手段防止后续「优化」误覆盖。

1. 公开 HTMLedit_file 必须落盘覆盖

症状

  • Agent 用 edit_file 改已有 public/*.html 后,链接仍是旧内容
  • 不是缓存,是磁盘文件未被覆盖

必须保留

位置 行为
mindspace-public-finish-sync.mjs edit_file 读取 baseline + old_str/new_str patch,再 writeFileSync 覆盖
server.mjs Finish / SSE 流式事件调用 materializePublicHtmlWritesFromSessionEvent

守卫

  • 单测:mindspace-public-finish-sync.test.mjs
  • 源码 + runtimenpm run verify:public-finish-sync-runtime

2. 聊天 Finish:禁止清空对话 / 禁止暴露内部前缀

症状

  • 流式过程正常,Finish 瞬间聊天框刷新,只剩 1 条 user 消息
  • 该消息露出 【TKMind 路由提示】static-page-publish skill 前缀等 Agent 专用文案
  • 历史记录里仍有完整对话 → 说明是 前端 Finish 同步 问题,不是 Goose 丢数据

必须保留

位置 行为
src/hooks/useTKMindChat.ts syncSessionMessagesmergeConversationSnapshot禁止盲覆盖;服务端条数不足时按 FINISH_SYNC_RETRY_DELAYS_MS 重试
server/portal-session-routes.mjs Session snapshot 缓存仅在 hint_mc hint_ua 均提供且匹配时命中
server.mjs 必须通过 attachPortalSessionRoutes 组合 Session 路由并注入 snapshot / proxy 依赖
conversation-display.mjs + src/utils/message.ts 用户消息无 displayText 时,用 deriveUserFacingText 剥掉 routing / skill / 用户身份前缀
chat-finish-sync.mjs 纯函数 merge 逻辑(被 TS 与单测共用)

守卫

  • 单测:chat-finish-sync.test.mjsconversation-display.test.mjs
  • 源码静态检查:npm run verify:chat-finish-sync
  • 文档:本文件

3. 页面需求澄清:禁止误报“未生成 public HTML”

症状

  • 用户只说「帮我生成一个页面吧」,没有给出主题或内容
  • 助手正常追问页面类型、主题或素材
  • Finish 后却显示红色错误条:「页面任务未生成 public HTML 交付物,不能标记成功」

根因与必须保留

agent-run-gateway.mjs 的页面交付守卫曾把所有页面意图都视为本轮必须交付 HTML, 没有区分“信息足够、可执行的页面任务”和“只能先澄清的泛化请求”。

  • 必须使用用户消息 metadata.displayText 判断请求本身,不能让内部 routing / skill 前缀影响判定
  • 「帮我生成一个页面吧」这类没有主题的泛化请求允许以澄清回复正常结束
  • 「帮我做一个秋夜诗 H5 页面」等已有主题的任务仍须 fail closed:没有本轮 public/*.html 就不能标记成功
  • Page Data 任务的交付守卫不受此例外影响

守卫

  • 单测:chat-skills.test.mjsagent-run-gateway.test.mjs
  • 综合验证:npm run verify:h5-session-patches

4. 页面已落盘:自动配图失败或多工作区不得吞掉链接

症状

  • 用户要求「帮我写一首诗词,做个页面吧」
  • Agent 已调用 write_filepublic/*.html 也已真实落盘
  • 自动生图失败后整个 Agent Run 仍被标记失败,前端显示红条
  • Portal 代码目录与 session 工作目录不同时,链接过滤器只检查 process.cwd()/MindSpace, 将另一个共享工作区中真实存在的链接改成「页面生成未完成」

必须保留

  • 输入区为 auto 且用户没有明确要求图片时,视觉页面配图只能是 best effort;生图失败不得拖垮已成功的 HTML 主交付
  • 用户明确要求图片,或输入区切到 required 时,仍保留位图证据 fail closed
  • 页面链接存在性检查必须同时覆盖:
    • 当前 Portal 工作目录下的 MindSpace/<userId>
    • H5_USERS_ROOT 同级的共享 MindSpace/<userId>
    • 显式 MEMIND_SHARED_PUBLISH_ROOT / GOOSED_SANDBOX_PUBLISH_ROOT
  • 不得因为 Portal 运行在临时 worktree,而误删共享 session 工作区中的有效页面链接
  • 历史消息若已被替换成「页面生成未完成」占位文案,后续读取发现同名 HTML 已存在时必须恢复为可点击链接

守卫

  • 单测:chat-intent-router.test.mjsagent-run-gateway.test.mjstkmind-proxy.test.mjs
  • 综合验证:npm run verify:h5-session-patches

发版 / CI 必跑命令

# 专项回归(单测 + 源码守卫)
npm run verify:mindspace-publish-guards

# 发版 Portal runtime 后(含 bundle 检查)
npm run verify:mindspace-publish-guards:full

scripts/release-portal-runtime-prod.shscripts/release-prod.sh 在未 --skip-tests 时会调用上述 verify。


修改这些区域时的 checklist

  • 是否仍 merge 本地与服务器消息(Finish / UpdateConversation)?
  • 是否仍过滤/剥离用户消息中的 agent-only 前缀?
  • edit_file 是否仍会 materialize 到 MindSpace/<userId>/public/
  • 是否已跑 npm run verify:mindspace-publish-guards
  • 是否更新了本页或相关单测?

相关 Cursor 规则

.cursor/rules/mindspace-publish-chat-finish-guards.mdc — Cursor 在编辑相关文件时自动提示上述约束。

其它 AI 工具(Codex / Cloud 等)

不会自动读取 .cursor/rules/。请改为阅读仓库根目录 AGENTS.md 与本目录文档;verify 与单测对所有工具同样有效。