Repository navigation
Conversation
Scoping a remote source to a root starts a read of that source. Pressing Back to an entry that names another source and root before the read commits made the root-change effect prefer the in-flight request over the restored route, so the page re-read the remote source with the restored root and rewrote the URL back to it. The app commits a route's source only from a loaded source, so a route naming a different source than the loaded one came from Back/Forward. That restored source now outranks an in-flight re-scope; an in-flight source selection is still re-scoped when the route names the loaded source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Lihua <1017343802@qq.com>
|
|
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
动机
用户从本机研究 Goal 切到远端工作,再用浏览器返回先前研究范围时会遇到这个问题。 旧版在 Remote B 的 operations 范围读取尚未完成时返回本机 research,会停在 Remote B/research;此版恢复本机 research 及 portfolio 子 Goal。
实际编译页面在同一受控时序下恢复正确来源、根范围和来源选择器,旧读取不能再覆盖它。 本 PR 只修根范围与来源一起恢复的分支,不改服务端权限、SSH 建连策略或其他已存在的同根导航行为。
页面重新请求错误来源,URL 和同名 Goal 被旧请求覆盖,用户需要再次选择来源并找回位置。 我独立执行了编译后的真实页面与两个隔离状态后端;普通完整场景在两版都能通过,进一步控制未完成读取才明确区分出缺陷与修复。作者报告的旧复跑次数未当作本次证据。
改动思路
已有根范围 effect 负责路由仲裁,已有 fence 负责迟到读取;在该处修复优先级即可闭合真实返回路径。 本 PR 交付来源与根一起恢复,不增加持久状态或第二个导航/权限 owner。
变更前已接受的依据是 docs/development/design.md,固定修订 843be494266774b63b3de61d0adf5dd7f4f877a2。本评审将其中未编号的两条原文分别标为 NAV-HISTORY(reload/Back/Forward 保留选择)和 NAV-SOURCE(选择绑定 Goal 与来源,同名 Goal 不继承另一来源选择);这两个标签仅便于引用。当前完整读取、错误恢复和受控返回分别覆盖它们。
保留原来的显式来源选择和请求隔离更合适:无条件偏好 route 会忽略正在进行的用户选择,另起来源状态或导航框架也没有收益。现有 TypeScript owner 足以处理这个有界修复。
具体改动
完整 diff 只有 apps/presentation/dashboard/src/views/dashboard-page.tsx,+7/-2;没有 CSS、页面文案、存储格式、命令或权限变更。新值完全由当前 route 与 DataSource 派生,无手动同步声明或持久状态。默认变化已经在本 PR 明确说明:只在根范围变化且 route 来源与已加载来源不同的情况下,让恢复路由先于未完成 rescope。
关键代码讲解
DashboardPage根 effect,第3680行:先取非空 route URL,判断其是否与已加载来源不同;满足时读恢复来源。否则沿用 requested、route、loaded 及默认来源的旧回退。这使历史返回不再重新读取 B 的同名 research,同时保留普通显式切换。loadFromUrl,第3497行:请求开始时捕获 root 并使用现有 generation/selection fence。目录和子 Goal 的响应只在该 root 和请求仍当前时提交。此次没有放松这些检查;受控挂起 B、返回 A、再释放 B 通过真实读取证明旧响应不会反盖。commitLoadedStatus,第3448行:仍由原 owner 一起更新 payload、source 与路由,并在完成当前请求后清理 requested URL;不新增第二个状态提交点。它与上面的源选择和 fence 共同组成完整用户路径。
验证结果:
- PASS:fresh
npm run build:chat;原goal-hierarchypackaged 完整场景 head13.67s、基线产品树13.75s。后者未自然失败,因此没有把一次绿测称为间歇问题已消失。 - PASS(可判别反例):同一浏览器时序脚本仅挂起 B 的 operations 根读取,然后
history.go(-4)、释放读取。不可变 base 的产品树最终仍为 B/research,portfolio 等待失败;精确 head12.57s完成全部断言,URL、root、来源选择器和 portfolio 均回 A。本例真实 backend 相同;基线所在分支只改另一 smoke,产品文件与843be494266774b63b3de61d0adf5dd7f4f877a2相同。 - PASS:原场景的403子Goal、畸形/空/缺失root、刷新恢复及390px键盘检查;独立 packaged
status-source-switch、smoke:status-projection-contract、smoke:status-sources。原 source readback 不变,0 mutation、0 Turns/actions。 - PASS:standard premerge 4直接+2选中,零失败、跳过或人工hold;严格 CQR
cqr_6030cfbb45553bf2091a与当前scope一致。检查器只验证记录结构,以上结论来自实际执行。
对主干的风险
主要风险是把普通显式选源误判成历史恢复,以及迟到响应覆盖当前根。原 source-switch 与 generation/root 隔离覆盖前者和后者;受控反例覆盖本次新优先级。范围不涉及 server authority、schema、调度或配额,也没有可选功能的关闭态宣称。源 URL 仍采用原有身份规范化,未外推所有alias变体。
实际路径是 source-built packaged 页面加真实隔离目录/状态 owner;SSH catalog/ensure 为合成 transport,控制 barrier 只是完成时序。没有核验本机正式安装或真实 SSH 服务,也没有把浏览路径恢复外推为模型长程净收益。已读作者评论中的历史CI说明;依当前评审配置未查询、轮询或等待CI。本次局部资格不证明当前main组合、全部browser catalog或其他同根导航缺陷已经解决。
我的整体评价
APPROVE。所选返回缺陷有独立 base 反例和精确 head 正向结果,现有 owner 的改动直接且可回退;未发现当前范围的阻断问题。已有根范围 effect 负责路由仲裁,已有 fence 负责迟到读取;在该处修复优先级即可闭合真实返回路径。 本 PR 交付来源与根一起恢复,不增加持久状态或第二个导航/权限 owner。
视觉审阅不适用:完整单文件diff没有DOM/CSS、可见文案或构图改动;这里只判断功能恢复。未验证范围包括正式安装App、真实SSH及独立用户理解/全站视觉质量;不宣称视觉改善。无需新增用户配置、确认或准备轮次。审批是此 head 的源码与有界路径结论;合并仍须当前原生readiness和维护者权限。
English verdict: APPROVE — head d4c07d7; controlled in-flight history restoration fails on the immutable baseline and passes here. Packaged navigation, source isolation, local validation and exact-scope quality checks pass; installed/real-SSH and broader integration remain outside this review.
Goal And Delivered Outcome
chat-bundle-browserjob of Python Tests (one of the jobschecksverifies) failed onmainafter test(workspace): repair the remaining dashboard-browser lane failures #7508 madedashboard-browsergreen: run 40585213327 on322591fb9,chat-bundle-browser (2)atgoal-hierarchy.mjs:241.goal-hierarchychecks that one Back restores a source and its root scope together. The scenario selects Remote B, scopes it tooperations, then goes back four entries to source A scoped toresearch. In the failing runs the route briefly reads source A/research, then the page re-reads Remote B with rootresearchand rewrites the URL back to Remote B. The user is stranded on the wrong source, which is the exact case the scenario's comment describes.requestedStatusUrlis Remote B until that read commits. If Back lands before the commit, the root-change effect indashboard-page.tsxchoserequestedStatusUrl ?? route, so the in-flight re-scope beat the restored source. fix(ci): stabilize required dashboard-browser goal-hierarchy shard #6890 /d8c62a0bfmade the route outrank the loaded source, but not an in-flight read of it.statusUrlinto the route only incommitLoadedStatus, always for the source it just loaded. So when a source is loaded and the route names a different one, the route came from Back/Forward, and that restored source now wins. When the route still names the loaded source, an in-flight user source selection is re-scoped as before, and the loaded source is still the fallback.researchsubtree instead of re-reading Remote B. Locally,goal-hierarchyfailed 8/8 packaged runs and 1/2 development runs onmain843be4942. With this commit it passes 4/4 packaged and 3/3 development.main). [Bug]: the required chat-bundle-browser lane is red on main — the read-only source badge repeats the visible Goal title #7378's original failure was fixed by fix(workspace): stop the read-only source badge from repeating the Goal title #7380. Basemain.Author Declaration
Implemented against
goal-hierarchycontract ("A history entry restores the source and the root scope together. The restored route must drive the read") and the existing in-flight-selection rule in the same effect.apps/presentation/dashboard/src/views/dashboard-page.tsx(root-change effect)LOOPX_PERSONAL_WORKSPACE_SCENARIO=goal-hierarchypackaged and developmentrouteRestoresSourceis false while the route names the loaded source)smoke:status-source-switch-browser,smoke:status-source-switch-packagedgoal-hierarchyearlier sectionsScope And Continuation
data/status-request-fence.tsas a pure helper with its own unit test. The only nearby contract smoke (smoke:status-projection-contract) isn't run in CI, so a helper test there would add wiring without CI coverage. The browser scenario that runs in both required lanes covers this rule, so I deferred the move.chat-bundle-browserfailures seen on recent PR runs. Each failed in a different scenario, they're tracked under CI: chat-bundle-browser and dashboard-browser shards time out on main #7389, and none reproduced as this one did.Validation
d4c07d79b(onmain843be4942).regression_paritypassedgoal-hierarchyfails at line 241 in 8/8 packaged runs and 1/2 development runs. Head: 4/4 packaged, 3/3 development.real_entrypointpassednpm run smoke:status-source-switch-browserandsmoke:status-source-switch-packaged(in-flight source selection and source switching).unitpassednpm run smoke:status-sources(status source catalog).real_entrypointpassedgoal-hierarchy. The other two also fail on the unmodified base locally and pass on hosted runners:composer-session-admission:200(fails on base 2/2 locally) andresearch-worker-readback(ECONNRESETfrom the disposable backend).staticpassedtsc --noEmiton the dashboard;scripts/generate_semantic_inventory.py --changed-from HEADreports no new vocabulary carriers.real_entrypointrunningdashboard-browser (1/2/3)andchat-bundle-browser (1/2/3)on this PR are the decisive checks.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
goal-hierarchysource/root restore contract.Shared-authority RFC fixture impact
N/A
Boundary Checklist
Signed-off-bytrailer.apps/**behavior, so it needs maintainer review and explicit merge authorization.🤖 Generated with Claude Code