From 337d8200768329c7e919af7b37903db672e759b7 Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Tue, 22 Sep 2026 12:01:31 +0800 Subject: [PATCH] fix(web): recover the home screen when the bundle never runs --- CHANGELOG.md | 4 + docs/BUG_HISTORY.md | 32 +- ...ESS-home-bootstrap-reliability-20260922.md | 38 +++ .../home-bootstrap-reliability-20260922.md | 23 ++ frontend/DESIGN.md | 16 + frontend/docs/VOICE.md | 12 + frontend/src/app/layout.tsx | 3 + .../src/hooks/use-home-shell-registration.ts | 6 + frontend/src/lib/first-paint-fallback.ts | 129 ++++++++ frontend/src/lib/home-bootstrap-failure.ts | 87 +++++ .../src/lib/personal-report-generation.ts | 7 +- .../lib/rectification-agentic/user-copy.ts | 10 +- .../v9/adopt-narration.ts | 5 +- .../v9/collect-prompt.ts | 11 +- .../v9/turn-narration.ts | 5 +- frontend/src/lib/sentence-split.ts | 63 ++++ .../first-paint-fallback-contract.test.ts | 304 ++++++++++++++++++ frontend/tests/sentence-split.test.ts | 149 +++++++++ 18 files changed, 882 insertions(+), 22 deletions(-) create mode 100644 docs/tasks/PROGRESS-home-bootstrap-reliability-20260922.md create mode 100644 docs/testing/home-bootstrap-reliability-20260922.md create mode 100644 frontend/src/lib/first-paint-fallback.ts create mode 100644 frontend/src/lib/home-bootstrap-failure.ts create mode 100644 frontend/src/lib/sentence-split.ts create mode 100644 frontend/tests/first-paint-fallback-contract.test.ts create mode 100644 frontend/tests/sentence-split.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 99ec7093..9db1b906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ 普通聊天不再在切换人物后仍用登录用户本人的资料。会话锁定的是本人或当前用户名下的另一份资料;对方资料缺失、被删或不完整时会拦住发送,不会退回本人。已有消息的会话不能改绑。报告、每日星语和生时校正仍只用本人资料。Skill 版本不变。 +## 2026-09-22 — 首页脚本没跑起来时可以重新加载 + +首屏如果一直停在载入账户,大约 13 秒后换成一句说明和「重新加载」,不再只转圈。不会自动刷新。旧浏览器上本仓断句不再使用正则后行断言。Skill 版本不变。 + ## 2026-09-21 — 侧栏当前会话是一整条高亮 选中或悬停会话时,标题和右边的「⋯」共用一块底,不再拆成两个块。Skill 版本不变。 diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 021da328..d90318f4 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -12232,9 +12232,9 @@ ## BUG-936 | 首页永远停在「正在载入账户」,没有超时也没有报错 -- 状态:investigating +- 状态:兜底已补、根因待分流 - 首次发现:2026-09-17 -- 最近更新:2026-09-17 +- 最近更新:2026-09-22 - 影响面:`/` 首屏揭幕(`app/page.tsx` 的 `!hydrated || (!account && !accountError)` 门)、`AppLoadingIndicator`、`app/layout.tsx` - 用户现象:产品负责人转述,一位已有账号的用户在 iPhone Safari 打开 `https://staging.jyotisha.chat/`,永远停在「正在载入账户 / 同步个人资料与对话记录」,进不去页面。转圈动画还在动。 - 触发条件:尚未定位到具体条件。已排除接口侧。 @@ -12246,13 +12246,13 @@ 5. 线上 bundle 的语法下限是 **Safari 16.4**:`1stw4tc266s7a.js`(Next 自己的 app-router 运行时)含类静态块 `class y extends Component{static{this.contextType=...}}`;`089-80cjt8-1t.js`(本仓中文断句 `split(/(?<=[。!?;;])\s*/)`)与 `0dmsli_y64717.js`(链接识别依赖)含正则后行断言。两者在 Safari < 16.4 都是**解析期** SyntaxError,core-js 这类运行时 polyfill 救不了。 6. 该下限不是新引入:`next: 16.3.1` 从仓库首个提交 `4aa0105f`(2026-07-15)就在。所以如果这台设备以前能用,(5) 不是本次原因。 - 待定位(需要用户侧一条信息即可分流):① 设备 iOS 版本 < 16.4 → 命中 (5);② 某个 chunk 在弱网下没下全或被内容拦截器挡掉 → 无痕窗口 / 清除网站数据后恢复;③ Safari 缓存里留着坏掉的 chunk(chunk 带 `cache-control: public, max-age=31536000, immutable`)。 -- 根因:未确认,不得提前写。 -- 修复:未做。 -- 验证:未做。 -- 防复发(已可确定的一条,独立于根因):首屏不得把「出错了」的唯一出口放在可能失败的模块 bundle 里。根 layout 需要一段与 bundle 无关的内联经典脚本,在 hydrate 超时或语法不支持时把这一屏换成可读的提示与「重新加载」。见 `docs/tasks/TASK-first-paint-dead-screen-fallback-20260917.md`。 -- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路) +- 根因:未确认,不得提前写。兜底补上不等于这台 iPhone Safari 已经修好。 +- 修复:根 layout 增加一段与 bundle 无关的内联经典脚本。13 秒后,若仍有 `.app-loading` 且 `` 不是 `"1"`,把加载内容换成「这个页面没能加载完」和只在点击时刷新的「重新加载」。揭幕成功后由首页装配 hook 写 `data-hydrated="1"`,正常路径不闪这一屏。匿名标记只留类别、构建标识和耗时,不留异常原文或请求体。接口超时仍走 bundle 里原来的「连接云端服务超时」,不并进这一屏。本仓断句的后行断言另见 BUG-998,那一项不能把 Next 运行时的语法下限降到 Safari 16.4 以下。 +- 验证:`frontend/tests/first-paint-fallback-contract.test.ts` 锁定 ES5、超时大于 8000+4000、未揭幕才替换、按钮才刷新,以及 hydrate 超时 / chunk 404 / 解析失败 / 旧缓存 / 弱网 / 接口错误六类不互相冒充。未在 iPhone Safari 或断 chunk 的浏览器里走查。 +- 防复发:首屏不得把「出错了」的唯一出口放在可能失败的模块 bundle 里。不得自动刷新。见 `docs/tasks/TASK-home-bootstrap-reliability-20260922.md` 与 `docs/testing/home-bootstrap-reliability-20260922.md`。 +- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路)、BUG-998 - 复发自:无 -- 修复版本:未发布 +- 修复版本:未发布(本分支未推送,不得声称 staging 已部署) ## BUG-937 | 咨询第 0 步 `toolChoice: required` 让全部咨询整轮失败 @@ -13215,3 +13215,19 @@ - 相关记录:BUG-001、BUG-010、BUG-011、BUG-018、BUG-073、BUG-076、BUG-188 - 复发自:无 - 修复版本:本次分支提交(未推送,未部署) + +## BUG-998 | 本仓中文断句使用正则后行断言,Safari 16.4 以下在解析期失败 + +- 状态:resolved +- 首次发现:2026-09-17(写在 BUG-936 的已确认事实里,当时未单独编号;BUG-937 / BUG-938 已被咨询故障占用) +- 最近更新:2026-09-22 +- 影响面:`frontend/src/lib/sentence-split.ts`;原先后行断言在个人报告断句、校正开场句、引擎含义展示、采用旁白、采集提示、轮次旁白 +- 用户现象:无单独的用户报告。若设备 Safari 低于 16.4,含后行断言的 chunk 会在解析期抛出 SyntaxError,React 不会 hydrate。这不能解释「以前能用、这次不能用」的设备,也不能单独修好 BUG-936。 +- 触发条件:浏览器解析本仓断句 chunk,且不支持正则后行断言。 +- 根因:八处 `split` 使用后行断言来「在句末标点后切开并保留标点」。这是语法,不是运行时 polyfill 能补的。 +- 修复:共用 `splitAfterSentencePunctuation`,用手写扫描在标点后切开并保留标点。`frontend/src` 不再出现后行断言。Next 运行时里的类静态块改不了,语法下限仍是 Safari 16.4。 +- 验证:`frontend/tests/sentence-split.test.ts` 用表驱动用例和旧正则对照,确认切开结果逐字一致;源码合同扫描 `frontend/src` 无后行断言。校正与报告的既有断言未改。 +- 防复发:`frontend/src` 不得再写后行断言。测试文件可以保留旧正则作对照。 +- 相关记录:BUG-936 +- 复发自:无 +- 修复版本:未发布(本分支未推送) diff --git a/docs/tasks/PROGRESS-home-bootstrap-reliability-20260922.md b/docs/tasks/PROGRESS-home-bootstrap-reliability-20260922.md new file mode 100644 index 00000000..f95b3ca1 --- /dev/null +++ b/docs/tasks/PROGRESS-home-bootstrap-reliability-20260922.md @@ -0,0 +1,38 @@ +# PROGRESS · 首页加载失败可恢复性(2026-09-22) + +工作树:`.worktrees/home-bootstrap-reliability-20260922` +分支:`codex/home-bootstrap-reliability-20260922` +开工时 `origin/staging` = `10baeb2fa865743c428806e115ac92ca9d92fb71`。未 push。未改 `page.tsx`。 + +既有 `TASK-first-paint-dead-screen-fallback-20260917.md` 尚未合入。本分支按它的未完成项做了唯一一套内联兜底,并完成断句后行断言清理。不另写一份 first-paint 进度。 + +## T1 兜底 + +- 根 layout 在主题脚本旁增加 `firstPaintFallbackBootScript()`。生成结果是经典 `