docs(web-shell): add global turn navigation Phase 2 design - #11020
Conversation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Thanks for the PR — this is a re-run at Template looks good ✓ — every required heading is present, all three Risk & Scope bullets are filled in, and the Chinese translation is complete rather than abridged. Problem: not a bug report, and it doesn't need to be — this is the design doc AGENTS.md asks for before non-trivial work. I re-checked the gap independently at today's Direction: aligned. Size: not applicable. Two markdown files, +676/−5 — zero production, test, or generated lines, and no core paths, so the Stage 0 two-tier gate never engages. Approach: the scope feels right and the central call survived hard pushing — keep the SDK store flat and add a provider-owned page ledger instead of a cross-package store rewrite. My own instinct would still be a page-table store, but the doc's version is cheaper and it now states the reuse boundary honestly instead of overclaiming: it names that The prior pass deferred at 3/5 on three items — the 413 error row, the two-outcome vs three-outcome admission mismatch, and the phase-boundary contradiction with the parent design. All three are now resolved; I verified each against the code in Stage 2 rather than accepting the round summaries. The parent-design fix went the right way too: #10750's own checklist puts the whole data layer in Phase 2 and leaves Phase 3 rail-only, so moving those four items up aligns the parent with the issue that authorises it. One note for whoever picks this up next, not a request: this PR has now been through five review rounds, so per AGENTS.md only correctness-level findings should land here from this point — the remaining nits I list in Stage 2 belong in the first Phase 2 implementation PR, not in another round on this one. Risk: no elevated risk signals. Stage 1e matched nothing — both changed paths are under Moving on to code review. 🔍 中文说明感谢贡献 —— 这是在 模板完整 ✓ —— 所有必需小节都在,Risk & Scope 三条都填了,中文翻译是完整的而不是节略版。 问题: 这不是 bug 报告,也不需要是 —— 这正是 AGENTS.md 要求在做非平凡工作前先写的设计文档。我没有只采信 PR 描述,而是在今天的 方向: 对齐。 规模: 不适用。两个 markdown 文件,+676/−5 —— 没有生产代码、测试或生成代码行数,也不触及核心路径,所以 Stage 0 的两级 gate 根本不会启动。 方案: 范围合理,而且最关键的那个判断经受住了用力推敲 —— 保持 SDK store 扁平、在其之上加一个 provider 持有的页台账,而不是跨包重写 store。我自己的直觉仍然会是做页表 store,但文档这个版本更省,并且它现在诚实地写明了复用边界,而不是过度声称:它点名 上一轮 triage 以 3/5 延期,理由是三条 —— 413 错误行、两结果与三结果 admission 不一致、以及与父设计的阶段边界矛盾。三条现在都已解决;我是在 Stage 2 里逐条对着代码核实的,没有采信各轮的处置摘要。父设计那一处的修法方向也是对的:#10750 自己的清单就把完整数据层放在 Phase 2、Phase 3 只留导航条 UI,所以把这四项上移是让父设计与授权它的 issue 对齐。 给接下来接手的人一个提示,不是要求:这个 PR 已经过了五轮 review,所以按 AGENTS.md,此后只应收 correctness 级的发现 —— 我在 Stage 2 列出的剩余小项应该进 Phase 2 的首个实现 PR,而不是在本 PR 上再开一轮。 风险: 无升级风险信号。Stage 1e 没有命中任何一项 —— 两个改动路径都在 进入代码审查 🔍 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
Code reviewRe-run at The point of this pass was the three items that held the last one at 3/5. All three are genuinely fixed, not reworded — I checked each against the code rather than against the round summaries. 1. The 413 row is now correct, and the matrix no longer inherits the error. The table describes 2. Anchored admission now mirrors the real three-outcome contract. 3. The phase-boundary contradiction is resolved on both sides, and in the right direction. The parent design moves the turn-index store, tail refresh, provisional reconciliation and canonical locator map up into Phase 2 as item 4, renumbers Phase 3 to the rail UI, and adds a dated re-alignment note that points at this document as the detailed design; this doc carries a matching note. I checked which document should have moved rather than assuming: #10750's own Phase 2 checklist has eight items covering the complete data layer, and its Phase 3 is rail rendering, selection UX, keyboard/a11y and browser E2E only. So the parent was the one out of line with the issue that authorises it, and the edit aligns it. Coverage is 1:1 — each of the eight checklist items maps onto a Goal, including the "never merge non-contiguous ranges" invariant (the ledger's non-overlap/exact-cover invariant plus the gap model) and the capability/ceiling fallback. Beyond those three, I spot-checked the claims added in the later rounds, since nothing before this pass had reviewed them. They hold:
On citation discipline, one observation worth recording because it changes how the rest of this doc should be read: the round-1 drift complaints are structurally fixed, not just patched. The doc pins Three non-blocking nits, all of which belong in the first implementation PR rather than another round here:
TestingThis is an unattended run, so no PR-derived code was built or executed; the evidence below is the PR's own CI on the reviewed commit, read through the API. Real-scenario tmux testing is N/A — a markdown-only diff has no runtime surface to drive. There is also no behavioural claim for a sandboxed lane to settle, which the verification lane independently reached on its own ( Both Not verified: the ~239 B/turn wire figure in the performance model, which the doc attributes to Phase 1 maintainer measurement on #10751 (300 turns, a
中文说明代码审查在 本轮的重点是上次把结论压在 3/5 的那三条。三条都是真正修好了,不是改了措辞 —— 我是对着代码核实的,没有采信各轮的处置摘要。 1. 413 那一行现在是对的,错误矩阵也不再继承这个错误。 表格把 2. 锚定 admission 现在与真实的三结果契约一致。 3. 阶段边界矛盾在两侧都解决了,而且方向是对的。 父设计把 turn 索引存储、tail 刷新、临时条目对账与规范 locator map 上移为 Phase 2 第 4 项,把 Phase 3 重编号为导航条 UI,并加了一条带日期的重对齐说明指向本文档作为详细设计;本文档也带了对应的说明。我核实了应该改哪一份,而不是默认:#10750 自己的 Phase 2 清单有八项、覆盖完整数据层,而它的 Phase 3 只有导航条渲染、选择 UX、键盘/无障碍与浏览器 E2E。所以与授权 issue 不一致的是父设计,这次编辑让它对齐了。覆盖是 1:1 的 —— 八个清单项各自对应一个 Goal,包括"绝不合并非连续区间"不变量(台账的非重叠/精确覆盖不变量加空洞模型)与 capability/上限回退。 除这三条之外,我还抽查了后几轮新增的陈述,因为此前没有任何一轮审过它们。都成立:锚定组合规则( 关于引用规范,有一点值得记下来,因为它改变了这份文档其余部分该怎么读:第一轮的行号漂移抱怨是被结构性地修好了,而不只是补了一下。文档固定了 三条非阻塞小项,都应该进首个实现 PR,而不是在这里再开一轮: 测试这是一次无人值守的运行,因此没有构建或执行任何来自 PR 的代码;下面的证据是 PR 自己在被审 commit 上的 CI,通过 API 读取。真实场景 tmux 测试为 N/A —— 纯 markdown diff 没有可驱动的运行时表面。也没有任何行为性主张需要沙箱通道来判定,验证通道自己也独立得出了同样结论(本 PR 上 两个 未核实:性能模型里 ~239 B/turn 的线上数字,文档将其归于 #10751 上的 Phase 1 维护者实测(300 个 turn, — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
Confidence: 4/5 — the three things that held the last pass at 3/5 are genuinely fixed and I verified each against the code; what's left is three non-blocking nits that belong in the first implementation PR, not another round here. Stepping back, the reason this PR exists is still the right one, and it has not weakened since the first pass: Phase 1 landed a complete server contract this morning and the client cannot consume a byte of it. I re-confirmed that at today's My independent baseline was a page-table store, which is what the parent design literally said. The ledger-over-flat-store shape is cheaper and I still think it's the better call, mainly because the doc now states its reuse boundary honestly: it names that On the re-run risk — a fifth-round re-trigger is exactly where a gate rubber-stamps, and the author's disposition table is a very readable reason to. So I deliberately did not read the fixes through it. I re-derived all three from source: the 32 MiB cap and its four call sites including both turn-index routes, the 500-entry/160/240-code-point bounds behind the new footnote, the If I were maintaining this in six months I would thank whoever wrote it. The "Current client state (verified)" section is what makes the rest reviewable, and pinning the baseline commit turned the round-1 line-drift complaints from a recurring chore into a non-issue: I checked the citation that looked most wrong ( Why 4 and not 5: For the record on volume: this author has two open PRs, both design docs from today. I evaluated this one on its own evidence and the other gets its own pass. CI is settled green on this commit with nothing pending, so I'm approving pinned to 中文说明Confidence: 4/5 —— 上次把结论压在 3/5 的三条都真正修好了,我逐条对着代码核实过;剩下的是三条非阻塞小项,应该进首个实现 PR,而不是在这里再开一轮。 退一步看,这个 PR 存在的理由依然成立,而且比第一轮时没有变弱:Phase 1 今早合并了完整的服务端契约,而客户端一个字节都消费不了。这一点我在今天的 我的独立基线是页表 store —— 那正是父设计字面上的要求。"扁平 store 之上加台账"这个形态更省,我仍然认为它是更好的判断,主要原因在于文档现在诚实地写明了复用边界:它点名 关于 re-run 的风险 —— 第五轮的重新触发恰恰是 gate 最容易盖章放行的地方,而作者的处置表是一个非常好读的理由。所以我刻意没有透过它来读这些修复。我从源码重新推导了全部三条:32 MiB 上限及其四个调用点(含两个 turn-index 路由)、新脚注背后 500 条目 / 160 / 240 码点的界、 如果六个月后由我来维护,我会感谢写它的人。"Current client state (verified)" 那一节是让其余部分变得可评审的原因,而固定基线 commit 把第一轮的行号漂移抱怨从一件反复出现的杂务变成了非问题:我核实了看起来最错的那处引用( 为什么是 4 而不是 5: 关于数量的记录:这位作者有两个 open PR,都是今天的设计文档。我按本 PR 自己的证据评审,另一个会有它自己的一轮。 本 commit 上的 CI 已稳定为绿、无 pending,所以我把批准固定到 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
📄 Docs-only change — the automatic review ran at
Reviewed head: 中文说明📄 纯文档变更 —— 自动评审以 |
doudouOUC
left a comment
There was a problem hiding this comment.
Phase 2 设计文档 review
对照文档自称的核实基线 origin/main (80497a74d0) 逐条校验了 file:line 声明与协议契约。该 SHA 确实等于当前 origin/main HEAD 且是本 PR 的 merge-base,所以所有引用都可精确验证。
总体:设计方向站得住,Phase 1 契约引用绝大部分精确,#10750 的 Phase 2 清单 8/8 覆盖。以下 7 处实质问题建议合并前处理,其中前两条会直接把实现带偏。
已验证正确的承重事实(避免后续重复核查):
- 协议契约:entry/page 形状、
start需要snapshot(session.ts:5197-5203)、首调返回最新页(reader.ts:2564-2565)、targetRecordId/hasOlder(reader.ts:3528-3529)、200 字符 anchor 上限(session.ts:614)、256 MiB ceiling(reader.ts:89)、limit 200 ≤ max 500(reader.ts:82)、getTurnIndexPage(DaemonSessionClient.ts:988)、capability(capabilities.ts:144)——五个错误码及 HTTP 状态逐一对得上。 - 现状调研:web-shell 零 turn-index 引用、无页/gap 模型、adapter 确实丢弃
sourceRecordIds、测试 fixture 确实没有targetRecordId/hasOlder、500 块 + 15 s idle reload(MessageList.tsx:3921-3975行号精确)、1160 px 门槛、split pane 传hideSessionTimeline。 - 精确命中的引用:
materializeTranscriptHistory310、DaemonTranscriptHistory162、onTruncation874、createDaemonTranscriptStorestore.ts:24、reduceDaemonTranscriptEventstranscript.ts:194、DaemonTranscriptStatetypes.ts:1124、blocksourceRecordIdstypes.ts:912、transcriptBlocksToDaemonMessages378、getSessionTimelineEntries1194、SessionTimeline2537。
所有问题都不涉及代码改动,改完即可合。
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
All review findings addressed in
|
doudouOUC
left a comment
There was a problem hiding this comment.
第二轮 review(5f8f0c4 → e2388de5)
上轮 12 条已逐一对照代码复验,全部修复,且多处比我提的要求更深入。特别记一笔:413 的机制是你查对了、我上轮说错了——真实来源是路由序列化器的 32 MiB 整响应上限(WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 2 * SESSION_TRANSCRIPT_MAX_EXPANDED_PAGE_BYTES,routes/session.ts:276-277;唯一抛出点 :680;serializeWorkspaceTranscriptResponse 包了 4 个调用点,含两个 turn-index 路由 5167/5272),reader 自己从不抛。我原先引的 reader 4/16 MiB 选择预算是错的机制。
父设计的 delivery plan 同步更新得很干净(带日期与理由说明),两份文档不再互相矛盾。
本轮对全文做了开放式通读,新增 6 条。其中 N1 是唯一会在实现阶段立刻卡住的(「协议里没有这个 API」),N2 是常见路径上的语义空洞,建议这两条修完再合;N3-N6 可一并带上。
prettier --check 我对两个文件实跑过,均通过——所以 N4 那处内容损坏 CI 抓不到。
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Round-2 findings addressed in
另:上轮关于 413 机制的修正(路由序列化器 32 MiB 整响应上限, |
doudouOUC
left a comment
There was a problem hiding this comment.
第三轮 review(e2388de5 → 3c7838ca)
上轮 6 条全部已修,两处修得比我要求的更完整:TranscriptGap 现在把「older 邻居被驱逐、cursor 随之丢失」的回退也写进去了;两步 merge 把 validation 响应「永不 admit」这一条明确了,我拿算例走过——保留 0-149 / 150-349 加 fill 350-449,连续且无重叠。
我上轮有两处引用是错的,你改对了,记录在此避免后续被我的注释误导:
SESSION_TRANSCRIPT_MAX_LIMIT在审查基线80497a74d0上是:86,不是我写的:82。我那条 grep 打在了本地 worktree(HEAD 停在更早的80b5dab3e0,该文件在那里确实是 82 行)而不是基线——正是我在上轮反复强调的规矩,自己犯了。文档现在的:86正确。- 「code points」比我写的「chars」准确:
compactPreviewText(text, maxCodePoints)用Array.from(compacted)按码点切(session-transcript-reader.ts:1092-1097)。
prettier --check 对两个文件实跑过,均通过。
本轮对全文再做一遍开放式通读,新增 3 条,都不大但确定:R1 会直接产生一个错误请求(一行判断即可修),R2 是行为退化(一句 LRU 规则),R3 是措辞精度。三条带上后我认为即可合。
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Round-3 findings addressed in
|
doudouOUC
left a comment
There was a problem hiding this comment.
第四轮 review(3c7838ca → 701c0fd4)
上轮 3 条全部已修,修法都对:step 2 的跳过判断、最新页 pin(连带写清了「零重叠此后只出现在真正的大幅重写」这个推论)、resolver 扩为三项且第 3 项的 beforeRecordId + snapshot 组合合法性我核过。
prettier --check 两文件实跑通过。21 条 threads 里 16 条已因行变动 outdated,剩余 5 条我逐一核过都已在前几轮落地——GitHub 的 flag 跟的是锚定行而不是修复,不必据此判断。
本轮新增 2 条,都不触及结构决策:S1 是刷新分类少一个出口(一句话可修),S2 是文档自身的测试计划没跟上三轮的新规则。
收敛判断:四轮新发现量级 12 → 6 → 3 → 2,方案主体我认为已经稳定。这两条修完即可合,不必再开新一轮。其中 S2 建议在本 PR 内补齐——测试计划是这份设计文档的交付物之一,留到实现 PR 就失去了「先对齐契约、再对照契约评审实现」的意义。
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Round-4 findings addressed in
收敛确认:四轮新发现 12 → 6 → 3 → 2,方案主体稳定。CI 全绿。 |
doudouOUC
left a comment
There was a problem hiding this comment.
第五轮 review(701c0fd4 → 741cad15)
上轮 2 条都已修。S1 的三路比较每条都有出口,还把「validate 请求刻意不带 snapshot,所以截断不会让请求失败、只会静默误判」这个理由写进了文档;divergent 分支标题也同步为「divergent, zero overlap, or shrunk」。S2 我逐条对照了上轮列出的 6 项缺口——两步 merge 的四个子情形、newest-page pin、非重叠 clamp 与 ensurePage(ordinal)、三种 gap resolver(逐个点名)、新增的 admission sizing 一项、新增的 identity plumbing 一项——全部覆盖。
prettier --check 通过;markdown 结构也扫了一遍(行首 +/-、跨行 code span)无残留问题。
本轮只剩 1 条:T1,是刚修好那个问题在 older 路径上的对称遗漏,同样一句话可修。
收敛判断:五轮新发现 12 → 6 → 3 → 2 → 1,且本轮这条不涉及任何结构决策。方案主体(扁平 store + provider 页台账、每页 snapshot 权威、三种 gap resolver、三路刷新合并、三态尺寸失败)我已反复对照 80497a74d0 上的实际协议与客户端代码核过,一致。
结论:T1 修完即可合。 另按 AGENTS.md 的 review-round 约定(本 PR 已到第 5 轮,此后只收 correctness 级修复),Open question 5 那条 Suggestion 我单独留了一条评论作为延期记录,不建议在本 PR 处理。
| 5. Interior-page eviction commits via `store.reset` over retained pages — | ||
| measure commit cost at the 200-block page size; if visible, consider a | ||
| range-delete store method in the SDK as a follow-up. |
There was a problem hiding this comment.
延期记录(Suggestion,不建议在本 PR 处理)。
Q5 目前只覆盖 interior-page eviction 经 store.reset 提交的成本。但第二轮新增的 insert-at-ledger-position admission variant(见「The reuse boundary is honest」那段)走的是同一套 store.reset over retained pages 机制,而且它的延迟可见性更高——锚定插入是用户主动点击跳转触发的,而中间页驱逐按文档自己的说法是「rare, bounded」。所以真正需要实测 commit 成本的是插入路径,Q5 却没提它。
建议把 Q5 扩成「interior-page eviction 与锚定插入 都经 store.reset 提交——一并实测 commit 成本;若可见,再考虑在 SDK 加 range-delete / splice 方法」。
按 AGENTS.md 的约定,本 PR 已到第 5 轮 review,此后只应收 correctness / security / data-loss / regression 级别的修复。这条是 Suggestion,建议延到 Phase 2 首个实现 PR,或跟随 Q1 的窗口预算实测一起处理。在此留痕,以免被静默丢掉。
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Round-5 findings addressed in
收敛确认:五轮新发现 12 → 6 → 3 → 2 → 1,本轮唯一 correctness 项已修。CI 全绿,评审者结论为「T1 修完即可合」。 |
doudouOUC
left a comment
There was a problem hiding this comment.
第六轮 review(741cad15 → f32bcbb5)— 收尾
本轮 0 条新发现。这份文档我认为可以合了。
上轮 2 条的处置
T1 已修,且比我要求的多修了一处:
- 加上
boundary > 0前置条件,并把理由写进文档(boundary == 0表示最旧 turn 已保留、不存在更旧页,clamp 会算出 0 → 400); - 顺手把种子页公式从
max(0, totalTurns - limit)纠正为max(0, totalTurns - min(limit, totalTurns)),与session-transcript-reader.ts:2564-2565完全一致,并点明「≤ limit 个 durable turn 的会话一开始就 seed 在 ordinal 0」——这正是该 bug 的高频触发前提; ensurePage(ordinal)增加「已覆盖则 no-op」,把并发重复触发那条路径也堵住了;- 测试计划同步补了
boundary == 0no-request guard 与 ensurePage no-op 两项。
我复核了守卫后的算式:boundary > 0 时 limit = boundary - max(0, boundary - limit) 恒 ≥ 1,边界退化已消除。
Q5 按建议延期,文本未动(已 diff 确认),延期理由留在对应行级 thread 里。
prettier --check 对两个文件实跑通过。
六轮累计核查结论
新发现量级:12 → 6 → 3 → 2 → 1 → 0。
已逐条对照 80497a74d0 上的实际代码验证并确认无误的部分:
- 协议契约:五个错误码及其 HTTP 状态、32 MiB 整响应序列化上限(
2 × SESSION_TRANSCRIPT_MAX_EXPANDED_PAGE_BYTES,唯一抛出点routes/session.ts:680,两类路由共用)、start需伴随snapshot、cursor必须单发、beforeRecordId可与snapshot同发、锚定读取返回前向 cursor、200 字符 anchor 上限、256 MiB indexing ceiling、limit ≤ 500。 - 结构决策:扁平 store + provider 页台账(含「现有 admission 仅能头插、需新增按台账位置插入变体」这一诚实的复用边界)、每页 snapshot 为读取权威、三种 gap resolver 覆盖 cursor 丢失与无导航 turn 两类空洞、三路刷新合并(equal/greater/smaller 均有出口)、三态尺寸失败与现有
capacityReached/impossible语义对齐、能力门控的双声明点。 - 测试计划:现已覆盖六轮辩论出的全部规则,包括两步 merge 的四个子情形、newest-page pin、非重叠 clamp 与两个退化守卫、三种 resolver、admission sizing 三态、身份铺管双字段。
- 父设计:delivery plan 已重新对齐 #10750 清单,两份文档不再互相矛盾。
唯一遗留事项见我在 pinned-base 那一行的评论:origin/main 已前进 4 个 commit 导致部分行号引用漂移——但承重事实经当前 main 复验仍然成立,且我建议不要在本 PR 追。
| Facts about current code were verified against `origin/main` (`80497a74d0`), | ||
| which includes the merged Phase 1. |
There was a problem hiding this comment.
引用基线漂移记录 —— 承重事实已复验仍成立,建议不要在本 PR 追。
origin/main 在这几轮里已前进 4 个 commit(现为 c8595fc9d8)。其中 7f7bce3174 feat: chat transcript mr2a html export (#10076) 改动了本文档引用的 6 个文件,使约 9 处行号相对当前 main 漂移:
| 符号 | 文档 | 当前 main | 漂移 |
|---|---|---|---|
getSessionTimelineEntries |
1194 | 1084 | −110 |
SessionTimeline |
2537 | 2435 | −102 |
scheduleTranscriptReload |
3921 | 3819 | −102 |
nextOrdinal 计数器 |
2075 | 2157 | +82 |
trimTranscriptState |
1708 | 1788 | +80 |
DaemonTranscriptState |
1124 | 1168 | +44 |
extractSourceRecordIds |
1015 | 1032 | +17 |
transcriptBlocksToDaemonMessages |
378 | 380 | +2 |
createBase |
653 | 650 | −3 |
ui/types.ts 内其余引用整体后移约 +44。未受影响、引用仍精确的包括 routes/session.ts、error-response.ts、capabilities.ts、constants/sessions.ts、DaemonSessionProvider.tsx(applyTranscriptHistory 仍是 502)、DaemonSessionClient.ts:988、SESSION_TRANSCRIPT_MAX_LIMIT:86。
关键复验:那条承重事实——sourceRecordIds 与 promptId 都还没到 message 层——在当前 main 上仍然成立,两个文件各 0 匹配。所以迁移 step 3、Files affected、以及测试计划里「neither exists there today」这句依然正确。那个 +342 行的改动是 HTML 导出功能,与身份铺管无关。
建议不追:这一行已经明确把引用钉在一个声明过的 commit 上,所以没有任何一句是假的——这本身就是正确的做法。而 main 还会继续动,每 rebase 一次引用就要重刷一次,正是 AGENTS.md 提醒的「每轮 review 都在扩大 diff」的循环。按第 5 轮之后只收 correctness 级修复的约定,这条应当延后;真要处理,最好的时机是 Phase 2 首个实现 PR——那时人本来就要对着当时的 main 读代码。
在此留痕,以免后续 reviewer 把行号漂移误当成新缺陷、或误以为承重事实已失效。
|
@qwen-code /triage |
|
Sandboxed verification: This PR changes documentation/assets only — there is no code to execute, so a sandboxed verification has nothing to verify. 中文 — 判定:
|
|
@qwen-code /verify |
|
Sandboxed verification: This PR changes documentation/assets only — there is no code to execute, so a sandboxed verification has nothing to verify. 中文 — 判定:
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM — the three items from the earlier pass are fixed and verified against the code, and CI is green on this commit. Ready to ship. ✅
chiga0
left a comment
There was a problem hiding this comment.
Scope: Scan tier — two markdown files only. No code changes; no runtime behavior to exercise.
Not reviewed: DaemonSessionProvider.tsx line-number cross-references (207 KB, 5 159 lines; individual offsets too large to spot-check per-line at this tier). Line references in the document are guidance pointers rather than machine-processed anchors, so errors there carry bounded low impact.
Checked:
- Claim matches change: PR states docs-only; diff confirms two .md files only ✓
- CONTRIBUTING.md (base
80497a74): no AI-review ban ✓ - Key constants cited in the design verified against
80497a74d0:WEB_SHELL_HISTORY_PAGE_SIZE = 200atconstants/sessions.ts:22✓WEB_SHELL_TRANSCRIPT_RELOAD_BLOCKS = 500atconstants/sessions.ts:23✓WEB_SHELL_MAX_TRANSCRIPT_BLOCKS = 50_000atconstants/sessions.ts:40✓transcriptBlocksToDaemonMessagesfunction atadapters/transcriptToMessages.ts:378✓sourceRecordIds/promptIdgenuinely absent from message adapter (grep confirms zero hits) ✓session_turn_navigationcapability atcapabilities.ts:144✓
- Phase boundary realignment: items moved from Phase 3→Phase 2 in parent design exactly match what the Phase 2 doc declares; Phase 3 renumbering is consistent ✓
- Cross-check against prior reviews: author completed 6 explicit rounds fixing 20+ previously-identified issues (protocol shape, gap resolver coverage,
boundary==0guard, LRU newest-page pin, two-step merge divergent exit, verification plan completeness). CI bot approved after round 6. No external-reviewer findings remain unreconciled.
No blocking findings. No approval blockers.
Reviewed with AI assistance.
yiliang114
left a comment
There was a problem hiding this comment.
Design-doc review pass on head f32bcbb. The Phase 2 doc is well-grounded: the consumed Phase 1 contract and anchor/error-code combinations match the shipped routes (snapshot+record-anchor pairing rules, forward-only cursor continuation, 413 semantics), the decision to keep the SDK store flat and add a provider page ledger avoids fighting the append/prepend-only store, and the phase-boundary reconciliation with the parent doc is handled in the same PR. No blocking findings; all checks are green.
|
Released in v0.23.1. |
What this PR does
Adds the Phase 2 design document for session-wide turn navigation in Web Shell (#10750): the bounded client data layer that sits between the merged Phase 1 daemon/SDK protocol (#10751) and the Phase 3 virtualized rail UI.
The design covers: a client-side turn-index store that loads the newest metadata page first and pages older metadata independently of transcript content; a provider-owned page ledger that keeps the existing flat transcript store as the render source while adding immutable page boundaries, explicit gaps, and whole-page eviction; an anchored-open action that lands a random-access transcript page at a selected persisted turn without disturbing the live tail; canonical identity plumbing that carries persisted record IDs onto rendered messages and reconciles provisional live entries by exact prompt or record identity rather than by label or timestamp; and the capability-gated fallback that preserves the current loaded-message rail against older daemons and oversized transcripts.
It also records the verified current state of the Web Shell client data layer (store topology, pagination, retention, identity flow, rail derivation), the consumed Phase 1 contract with its full error-code mapping, a five-step migration path whose first three steps are behavior-preserving, the provider/store test plan, and the open questions that need measurement before defaults freeze.
Why it's needed
Phase 1 shipped the server contract (sparse turn index, signed snapshots, anchored reads), but the client cannot consume it yet: the transcript store is a single prepend-only array, eviction is a one-way trim with no gap model, and the rail derives from loaded messages only. Implementing the client data layer directly against code would mix several separable decisions — store topology, identity plumbing, eviction policy, capability fallback — into one large change. This document pins those decisions and their verification story before implementation starts, so the Phase 2 PRs can be reviewed against an agreed contract.
Reviewer Test Plan
How to verify
This is a design-only change; there is no runtime behavior to exercise. Suggested review focus:
web-shell-global-turn-navigation.md(parent design, three-phase delivery) andweb-shell-bounded-transcript-and-subagent-details.md(page-table model).Evidence (Before & After)
N/A (documentation only).
Tested on
Environment (optional)
N/A — documentation only.
Risk & Scope
Linked Issues
Part of #10750
中文说明
本 PR 做了什么
为 Web Shell 全会话 turn 导航(#10750)补充 Phase 2 设计文档:位于已合并的 Phase 1 daemon/SDK 协议(#10751)与 Phase 3 虚拟化导航条 UI 之间的有界客户端数据层。
设计内容覆盖:一个客户端 turn 索引存储——先加载最新元数据页,旧元数据独立于 transcript 内容分页;一个 provider 持有的页台账——保留现有扁平 transcript store 作为渲染源,同时加入不可变页边界、显式空洞与整页驱逐;一个锚定打开动作——在不干扰 live tail 的前提下,把随机访问的 transcript 页落地到选定的持久化 turn;规范身份管道——把持久化记录 ID 带到渲染出的消息上,并按精确 prompt 或记录身份(绝不按标签或时间戳)对账临时 live 条目;以及能力门控回退——在面对旧 daemon 与超大 transcript 时保持现有的已加载消息导航条。
文档同时记录了 Web Shell 客户端数据层经核实的现状(store 拓扑、分页、保留策略、身份流、导航条推导)、所消费的 Phase 1 契约及其完整错误码映射、前五步零行为变化的迁移路径、provider/store 测试计划,以及在默认值冻结前需要实测的开放问题。
为什么需要
Phase 1 交付了服务端契约(稀疏 turn 索引、签名快照、锚定读取),但客户端尚无法消费:transcript store 是单一只能前插的数组,驱逐是没有空洞模型的单向裁剪,导航条只能从已加载消息推导。直接对着代码实现客户端数据层,会把若干可分离的决策——store 拓扑、身份管道、驱逐策略、能力回退——混进一个大改动。本文档在实现开始前固定这些决策及其验证方案,使后续 Phase 2 的 PR 可以对照一份已对齐的契约评审。
Reviewer 测试计划
如何验证
这是纯设计变更,没有可运行的行为。建议评审重点:
web-shell-global-turn-navigation.md(父设计,三阶段交付)与web-shell-bounded-transcript-and-subagent-details.md(页表模型)。证据(Before & After)
N/A(纯文档)。
测试平台
环境(可选)
N/A——纯文档。
风险与范围
关联 Issue
#10750 的一部分