# 回归清单 · 匿名演示页隐藏写入口

- 产品：CoDelphi
- 提交：[8b6a0c0](https://github.com/gzhanlei/codelphi/compare/24135a7a575d14bf930e5827d97ba1ada945b965...8b6a0c07c8ab852209ef0cc7f70da480e229a9ef)
- 生成时间：2026-11-15 03:51 UTC

## 产品发布入口
- [ ] [变化] 更新功能「产品发布入口」（行为变化）（待验证）
- [ ] [回归] EC-1 — 本次发布没有规格行为变化 打开发布对话框（影响面推荐）（证据路径命中 components/overview-publish-dialog.tsx）（待验证）
- [ ] [变化] EC-2 — 「产品发布入口」更新场景 EC-2（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：匿名演示访客查看总览页｜操作：渲染发布入口｜结果：不渲染任何发布按钮或登录链接
- [ ] [新增] EC-3 — 「产品发布入口」新增场景 EC-3（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：登录只读成员查看总览页｜操作：渲染发布入口｜结果：显示禁用的「发布产品 · 需编辑权限」按钮
- [ ] [新增] EC-5 — 「产品发布入口」新增场景 EC-5（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：匿名 demo 访客查看总览页｜操作：渲染发布入口｜结果：不渲染任何发布入口，登录引导集中在顶栏
- [ ] [变化] ER-1 — 「产品发布入口」更新场景 ER-1（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：生成发布稿接口返回错误｜操作：点击「生成发布稿」｜结果：对话框内显示错误消息，不跳转
- [ ] [新增] ER-2 — 「产品发布入口」新增场景 ER-2（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：生成发布稿草稿的接口返回错误｜操作：提交生成请求｜结果：面板显示接口错误消息，不跳转发布卡
- [ ] [变化] HP-1 — 「产品发布入口」更新场景 HP-1（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：编辑者打开产品总览页｜操作：点击「发布产品」｜结果：打开发布对话框，列出本次发布的功能及新增/更新/移除计数，默认全选
- [ ] [新增] HP-2 — 「产品发布入口」新增场景 HP-2（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：发布对话框已勾选若干功能｜操作：点击「生成发布稿」｜结果：POST release-notes 生成草稿，成功后显示「去校对并发布 →」链接
- [ ] [新增] HP-3 — 「产品发布入口」新增场景 HP-3（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：编辑者打开产品总览页｜操作：点击「发布产品」并勾选功能后生成草稿｜结果：生成发布稿草稿并跳转到发布卡校对发布

## 产品页头部与演示只读入口
- [ ] [变化] 更新功能「产品页头部与演示只读入口」（行为变化）（待验证）
- [ ] [变化] EC-1 — 「产品页头部与演示只读入口」更新场景 EC-1（行为变化；证据路径命中 components/analyze-button.tsx；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染头部操作区｜结果：不渲染分析按钮、只读提示与登录链接，页面标记 data-can-edit=false
- [ ] [新增] EC-13 — 「产品页头部与演示只读入口」新增场景 EC-13（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员打开产品页｜操作：页面渲染分析入口区域｜结果：仍渲染禁用的「发起分析 · 需编辑权限」按钮与「当前账号对该产品为只读权限。」说明。
- [ ] [新增] EC-14 — 「产品页头部与演示只读入口」新增场景 EC-14（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：登录只读成员打开产品总览页｜操作：页面渲染发布入口区域｜结果：仍渲染禁用的「发布产品 · 需编辑权限」按钮，title 提示只读权限。
- [ ] [变化] EC-2 — 「产品页头部与演示只读入口」更新场景 EC-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员打开产品页｜操作：渲染头部操作区｜结果：显示禁用的「发起分析 · 需编辑权限」按钮与只读权限说明
- [ ] [新增] EC-3 — 「产品页头部与演示只读入口」新增场景 EC-3（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员访问产品页｜操作：渲染分析入口｜结果：降为次要禁用按钮并明示只读权限原因
- [ ] [新增] EC-4 — 「产品页头部与演示只读入口」新增场景 EC-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客访问产品页｜操作：渲染分析入口｜结果：不渲染分析入口与只读提示，登录引导集中在顶栏
- [ ] [新增] EC-5 — 「产品页头部与演示只读入口」新增场景 EC-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染页面头部｜结果：data-can-edit 为 false，不渲染写入口与「登录后可分析」
- [ ] [新增] EC-6 — 「产品页头部与演示只读入口」新增场景 EC-6（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员打开产品页｜操作：渲染头部编辑控件｜结果：写操作降为禁用按钮并明示只读权限
- [ ] [新增] EC-7 — 「产品页头部与演示只读入口」新增场景 EC-7（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客查看产品页｜操作：检查页面是否含「登录后可分析」文案｜结果：页面不含该文案，写入口整体不渲染
- [ ] [新增] EC-8 — 「产品页头部与演示只读入口」新增场景 EC-8（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客查看产品页｜操作：检查移除产品控件｜结果：不渲染 data-remove-product 控件
- [ ] [变化] ER-1 — 「产品页头部与演示只读入口」更新场景 ER-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：分析请求失败｜操作：点击「立即分析」｜结果：显示错误消息，按钮恢复可用
- [ ] [新增] ER-2 — 「产品页头部与演示只读入口」新增场景 ER-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：分析因额度不足被拒绝｜操作：点击「立即分析」｜结果：显示额度不足提示与升级套餐链接
- [ ] [新增] ER-3 — 「产品页头部与演示只读入口」新增场景 ER-3（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客尝试触发写操作｜操作：服务端校验写权限｜结果：服务端拒绝写请求，demo guard 与服务端校验仍是最终边界
- [ ] [新增] ER-4 — 「产品页头部与演示只读入口」新增场景 ER-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名演示访客尝试直接发起写请求｜操作：调用写接口｜结果：服务端写权限校验拒绝，演示守卫与服务端校验仍是最终边界
- [ ] [新增] ER-5 — 「产品页头部与演示只读入口」新增场景 ER-5（行为变化；证据路径命中 components/analyze-button.tsx；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：匿名 demo 访客绕过页面直接调用写接口｜操作：发起分析或生成发布稿请求｜结果：服务端写校验仍拒绝，权限边界不因前端隐藏入口而放宽。
- [ ] [变化] HP-1 — 「产品页头部与演示只读入口」更新场景 HP-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者打开产品页｜操作：渲染头部操作区｜结果：显示可点击的「立即分析」主按钮
- [ ] [变化] HP-2 — 「产品页头部与演示只读入口」更新场景 HP-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者点击「立即分析」｜操作：请求分析接口｜结果：提示「分析已排队，稍后刷新查看」并刷新页面
- [ ] [新增] HP-3 — 「产品页头部与演示只读入口」新增场景 HP-3（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者访问产品页｜操作：渲染头部写操作入口｜结果：显示可用的分析、编辑与发布入口
- [ ] [新增] HP-4 — 「产品页头部与演示只读入口」新增场景 HP-4（行为变化）（待验证）
  情境：编辑者打开产品页｜操作：渲染头部编辑控件｜结果：渲染可用的编辑与写操作入口
- [ ] [新增] HP-5 — 「产品页头部与演示只读入口」新增场景 HP-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客打开公开演示产品页｜操作：渲染产品页头部｜结果：页面以 data-can-edit=false 渲染，不出现分析登录引导与发布入口
- [ ] [新增] HP-6 — 「产品页头部与演示只读入口」新增场景 HP-6（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者打开产品页｜操作：渲染头部操作区｜结果：渲染可用的分析等写操作按钮
- [ ] [新增] HP-7 — 「产品页头部与演示只读入口」新增场景 HP-7（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客打开产品页｜操作：页面渲染分析入口区域｜结果：不渲染分析按钮、只读提示与「登录后可分析」链接，登录引导仅出现在顶栏。

## 产品页头部与简介展示
- [ ] [变化] 更新功能「产品页头部与简介展示」（行为变化）（待验证）
- [ ] [移除] EC-10 — 「产品页头部与简介展示」移除场景 EC-10（行为变化）（待验证）
- [ ] [移除] EC-11 — 「产品页头部与简介展示」移除场景 EC-11（行为变化）（待验证）
- [ ] [移除] EC-12 — 「产品页头部与简介展示」移除场景 EC-12（行为变化）（待验证）
- [ ] [移除] EC-13 — 「产品页头部与简介展示」移除场景 EC-13（行为变化）（待验证）
- [ ] [移除] EC-14 — 「产品页头部与简介展示」移除场景 EC-14（行为变化）（待验证）
- [ ] [移除] EC-15 — 「产品页头部与简介展示」移除场景 EC-15（行为变化）（待验证）
- [ ] [移除] EC-8 — 「产品页头部与简介展示」移除场景 EC-8（行为变化）（待验证）
- [ ] [移除] EC-9 — 「产品页头部与简介展示」移除场景 EC-9（行为变化）（待验证）
- [ ] [移除] HP-10 — 「产品页头部与简介展示」移除场景 HP-10（行为变化）（待验证）
- [ ] [移除] HP-11 — 「产品页头部与简介展示」移除场景 HP-11（行为变化）（待验证）
- [ ] [移除] HP-8 — 「产品页头部与简介展示」移除场景 HP-8（行为变化）（待验证）
- [ ] [移除] HP-9 — 「产品页头部与简介展示」移除场景 HP-9（行为变化）（待验证）
- [ ] [变化] EC-1 — 「产品页头部与简介展示」更新场景 EC-1（行为变化；证据路径命中 app/globals.css）（待验证）
  情境：简介为空｜操作：渲染产品页头部｜结果：以占位样式展示空简介
- [ ] [变化] EC-2 — 「产品页头部与简介展示」更新场景 EC-2（行为变化）（待验证）
  情境：产品简介为空且访问者为编辑者｜操作：渲染产品简介行｜结果：显示「尚无产品简介」提示与 ✎ 编辑入口
- [ ] [变化] EC-3 — 「产品页头部与简介展示」更新场景 EC-3（行为变化）（待验证）
  情境：产品简介为空且访问者非编辑者｜操作：渲染产品简介行｜结果：不渲染任何占位内容
- [ ] [变化] EC-4 — 「产品页头部与简介展示」更新场景 EC-4（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客查看产品页｜操作：渲染头部｜结果：编辑控件标记为不可编辑（data-can-edit=false）
- [ ] [变化] EC-5 — 「产品页头部与简介展示」更新场景 EC-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：已登录用户访问无权限的非演示 slug｜操作：渲染产品页｜结果：保持 404
- [ ] [变化] EC-6 — 「产品页头部与简介展示」更新场景 EC-6（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：已登录但对该产品无访问权限的用户访问非演示 slug｜操作：打开产品页｜结果：返回 404，不展示产品内容
- [ ] [变化] EC-7 — 「产品页头部与简介展示」更新场景 EC-7（行为变化）（待验证）
  情境：产品简介为空｜操作：渲染产品页头部｜结果：标题回退为「产品概览」
- [ ] [新增] ER-1 — 「产品页头部与简介展示」新增场景 ER-1（行为变化）（待验证）
  情境：保存简介接口失败｜操作：点击「保存」｜结果：对话框内显示错误消息，保持打开
- [ ] [变化] HP-1 — 「产品页头部与简介展示」更新场景 HP-1（行为变化）（待验证）
  情境：编辑者查看产品页头部｜操作：点击简介旁的编辑按钮｜结果：打开「编辑产品概况」对话框，预填当前简介
- [ ] [变化] HP-2 — 「产品页头部与简介展示」更新场景 HP-2（行为变化）（待验证）
  情境：编辑对话框已修改内容｜操作：点击「保存」｜结果：调用更新接口，关闭对话框并刷新页面
- [ ] [变化] HP-3 — 「产品页头部与简介展示」更新场景 HP-3（行为变化）（待验证）
  情境：产品已有简介且访问者为编辑者｜操作：渲染产品简介行｜结果：全文展示简介并显示 ✎ 编辑入口
- [ ] [变化] HP-4 — 「产品页头部与简介展示」更新场景 HP-4（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：产品已有生成的简介｜操作：打开产品页｜结果：展示产品名与简介内容
- [ ] [变化] HP-5 — 「产品页头部与简介展示」更新场景 HP-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染产品页头部与简介｜结果：展示产品名与简介，编辑控件以 data-can-edit=false 呈现
- [ ] [变化] HP-6 — 「产品页头部与简介展示」更新场景 HP-6（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：访客打开公开演示产品页｜操作：渲染页面头部与简介｜结果：展示产品名与简介，写操作控件不渲染
- [ ] [变化] HP-7 — 「产品页头部与简介展示」更新场景 HP-7（行为变化）（待验证）
  情境：产品已有非空简介｜操作：渲染产品页头部｜结果：展示简介文本与来源标记，生成来源附证据链接

## 匿名演示态分析入口
- [ ] [变化] 更新功能「匿名演示态分析入口」（行为变化）（待验证）
- [ ] [变化] EC-1 — 「匿名演示态分析入口」更新场景 EC-1（行为变化）（待验证）
  情境：匿名演示访客查看演示外壳顶栏｜操作：渲染顶栏｜结果：显示「使用 Chandler 登录」链接作为唯一登录引导
- [ ] [变化] EC-2 — 「匿名演示态分析入口」更新场景 EC-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员打开产品页｜操作：渲染分析入口组件｜结果：显示禁用的「发起分析 · 需编辑权限」按钮与只读权限说明
- [ ] [新增] EC-3 — 「匿名演示态分析入口」新增场景 EC-3（行为变化）（待验证）
  情境：匿名演示访客在演示页触发写操作｜操作：调用 demo guard｜结果：弹出 Demo 模式只读提示对话框，写操作被拦截
- [ ] [新增] EC-4 — 「匿名演示态分析入口」新增场景 EC-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员在产品页｜操作：渲染分析入口｜结果：显示禁用按钮并说明当前账号只读
- [ ] [新增] EC-5 — 「匿名演示态分析入口」新增场景 EC-5（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客在产品页｜操作：渲染分析入口｜结果：不渲染分析入口与只读提示，登录引导集中在顶栏
- [ ] [新增] EC-8 — 「匿名演示态分析入口」新增场景 EC-8（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员查看分析入口｜操作：渲染分析按钮｜结果：显示次要按钮并明示只读权限原因
- [ ] [新增] ER-1 — 「匿名演示态分析入口」新增场景 ER-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：分析请求返回错误｜操作：提交分析｜结果：显示接口错误消息，不进入分析中状态
- [ ] [新增] ER-2 — 「匿名演示态分析入口」新增场景 ER-2（行为变化）（待验证）
  情境：分析请求被额度闸门拒绝｜操作：点击「立即分析」｜结果：展示接口返回的额度提示消息
- [ ] [变化] HP-1 — 「匿名演示态分析入口」更新场景 HP-1（行为变化；证据路径命中 components/analyze-button.tsx；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染分析入口组件｜结果：组件返回空，不输出任何按钮或提示
- [ ] [变化] HP-2 — 「匿名演示态分析入口」更新场景 HP-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者在产品页｜操作：点击「立即分析」｜结果：提交分析请求并刷新页面
- [ ] [新增] HP-4 — 「匿名演示态分析入口」新增场景 HP-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：编辑者在产品页｜操作：点击「立即分析」｜结果：调用分析接口并在完成后刷新页面

## 只读演示下的分析入口
- [ ] [变化] 更新功能「只读演示下的分析入口」（行为变化）（待验证）
- [ ] [变化] EC-1 — 「只读演示下的分析入口」更新场景 EC-1（行为变化；证据路径命中 components/analyze-button.tsx；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：登录只读成员查看分析入口｜操作：渲染组件｜结果：显示「当前账号对该产品为只读权限。」说明，不渲染主按钮
- [ ] [新增] EC-2 — 「只读演示下的分析入口」新增场景 EC-2（行为变化）（待验证）
  情境：匿名 demo 访客尝试打开场景编辑面板｜操作：点击编辑或新建场景｜结果：demo guard 拦截，不打开编辑面板
- [ ] [新增] EC-3 — 「只读演示下的分析入口」新增场景 EC-3（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：匿名演示访客在产品页｜操作：查找分析入口｜结果：页面不出现分析入口与登录引导链接
- [ ] [新增] EC-4 — 「只读演示下的分析入口」新增场景 EC-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名演示访客在产品页｜操作：查看分析入口｜结果：不渲染分析入口，登录引导集中在顶栏
- [ ] [新增] EC-5 — 「只读演示下的分析入口」新增场景 EC-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：演示产品按组织与 slug 精确解析｜操作：打开演示详情页｜结果：按 (org, slug) 精确解析产品，不使用全局 slug 兜底
- [ ] [新增] EC-6 — 「只读演示下的分析入口」新增场景 EC-6（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：演示页渲染写操作控件｜操作：渲染页面｜结果：不渲染移除产品等写控件
- [ ] [新增] EC-7 — 「只读演示下的分析入口」新增场景 EC-7（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名访客访问公开演示产品页｜操作：渲染写操作控件｜结果：不渲染移除产品等写控件，也不渲染分析登录引导
- [ ] [新增] ER-1 — 「只读演示下的分析入口」新增场景 ER-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客绕过前端提交写请求｜操作：服务端校验写权限｜结果：服务端拒绝，写能力以服务端校验为准
- [ ] [新增] ER-2 — 「只读演示下的分析入口」新增场景 ER-2（行为变化）（待验证）
  情境：匿名访客访问非 demo 产品地址｜操作：解析公开演示产品｜结果：返回 null，页面按 404 处理
- [ ] [变化] HP-1 — 「只读演示下的分析入口」更新场景 HP-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员打开产品页｜操作：渲染分析入口｜结果：显示禁用的次要按钮「发起分析 · 需编辑权限」
- [ ] [变化] HP-2 — 「只读演示下的分析入口」更新场景 HP-2（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客浏览产品规格｜操作：查看场景工作区｜结果：可浏览规格内容，不出现分析入口
- [ ] [新增] HP-3 — 「只读演示下的分析入口」新增场景 HP-3（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员在产品页｜操作：尝试触发分析｜结果：按钮禁用，不发出写请求
- [ ] [新增] HP-4 — 「只读演示下的分析入口」新增场景 HP-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员在产品页｜操作：查看分析入口｜结果：显示禁用/次要的分析按钮并说明只读权限
- [ ] [新增] HP-5 — 「只读演示下的分析入口」新增场景 HP-5（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：访客打开 canonical 组织路径的演示产品页｜操作：渲染页面｜结果：页面标记 data-can-edit=false，不出现分析入口与登录后可分析文案
- [ ] [新增] HP-6 — 「只读演示下的分析入口」新增场景 HP-6（行为变化）（待验证）
  情境：匿名访客访问公开演示产品的 canonical 地址｜操作：渲染演示产品页｜结果：以只读身份展示产品内容，data-can-edit 为 false

## 演示模式分析入口
- [ ] [变化] 更新功能「演示模式分析入口」（行为变化）（待验证）
- [ ] [变化] EC-1 — 「演示模式分析入口」更新场景 EC-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名演示访客查看产品页头部｜操作：渲染分析入口｜结果：不渲染分析按钮与只读提示
- [ ] [新增] EC-10 — 「演示模式分析入口」新增场景 EC-10（行为变化）（待验证）
  情境：登录页需要展示公开演示入口｜操作：加载公开演示产品｜结果：优先取数据库标记的 demo 产品，无则取环境变量白名单首个，都没有则不渲染入口
- [ ] [新增] EC-2 — 「演示模式分析入口」新增场景 EC-2（行为变化；证据路径命中 components/overview-publish-dialog.tsx）（待验证）
  情境：匿名演示访客查看总览页｜操作：渲染发布入口｜结果：不渲染发布按钮与登录链接
- [ ] [新增] EC-4 — 「演示模式分析入口」新增场景 EC-4（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：登录只读成员查看产品页｜操作：渲染写操作入口｜结果：显示禁用按钮与权限说明，不显示登录引导
- [ ] [新增] EC-5 — 「演示模式分析入口」新增场景 EC-5（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名访客在演示页查找登录引导｜操作：查看页面主体｜结果：主体不渲染登录引导，引导位于顶栏
- [ ] [新增] EC-6 — 「演示模式分析入口」新增场景 EC-6（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：匿名演示访客查看发布入口｜操作：渲染发布入口组件｜结果：组件输出为空字符串，不渲染发布链接
- [ ] [新增] EC-7 — 「演示模式分析入口」新增场景 EC-7（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：以 writeAccess=readonly 渲染 AnalyzeButton｜操作：渲染组件｜结果：渲染禁用按钮并写明需编辑权限
- [ ] [新增] EC-8 — 「演示模式分析入口」新增场景 EC-8（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：以 writeAccess=demo 渲染 OverviewPublishButton｜操作：渲染组件｜结果：输出为空字符串，不渲染发布入口
- [ ] [新增] EC-9 — 「演示模式分析入口」新增场景 EC-9（行为变化）（待验证）
  情境：产品未标记 demo 但在环境变量白名单中｜操作：匿名访问该产品页面｜结果：白名单兜底放行只读展示
- [ ] [新增] ER-1 — 「演示模式分析入口」新增场景 ER-1（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：绕过前端直接向写接口发请求｜操作：服务端处理写请求｜结果：由服务端写权限校验拒绝，前端隐藏不改变强制边界
- [ ] [变化] HP-1 — 「演示模式分析入口」更新场景 HP-1（行为变化）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染页面｜结果：以演示外壳渲染，侧栏标注 DEMO MODE 只读演示
- [ ] [新增] HP-2 — 「演示模式分析入口」新增场景 HP-2（行为变化）（待验证）
  情境：演示访客触发任一写操作｜操作：调用 useDemoGuard 返回的守卫｜结果：弹出「Demo 模式」对话框说明编辑不会保存
- [ ] [新增] HP-3 — 「演示模式分析入口」新增场景 HP-3（行为变化；证据路径命中 components/analyze-button.tsx）（待验证）
  情境：匿名 demo 访客打开产品页｜操作：渲染页面头部｜结果：不出现分析、发布等写入口，顶栏提供登录引导
- [ ] [新增] HP-4 — 「演示模式分析入口」新增场景 HP-4（行为变化；证据路径命中 tests/public-demo-page.test.ts）（待验证）
  情境：匿名访客进入演示产品页｜操作：浏览页面｜结果：页面正常展示只读内容，无任何写入口
- [ ] [新增] HP-5 — 「演示模式分析入口」新增场景 HP-5（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：匿名演示访客打开演示产品页｜操作：渲染分析入口组件｜结果：组件输出为空字符串，不渲染按钮或链接
- [ ] [新增] HP-6 — 「演示模式分析入口」新增场景 HP-6（行为变化；证据路径命中 tests/write-access-buttons.test.ts）（待验证）
  情境：以 writeAccess=demo 渲染 AnalyzeButton｜操作：renderToStaticMarkup 渲染组件｜结果：输出为空字符串，不渲染按钮或链接
- [ ] [新增] HP-7 — 「演示模式分析入口」新增场景 HP-7（行为变化）（待验证）
  情境：产品在数据库中标记为公开演示｜操作：匿名访问该产品页面｜结果：按 (orgSlug, slug) 精确解析并放行只读展示