Repository navigation
fix(research): clarify unread-source errors with real benchmark recovery - #8098
Conversation
… recovery coverage Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.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
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
在个人工作区阅读研究历程、切换运行来源的用户。 切到一个尚未成功读取的来源并遇到网络错误时,旧版声称“已读记录保留”;新版明确指出此来源读取失败,用户可以直接重试。 首次失败不会暗示存在已保留的记录;同来源刷新失败仍保留已有记录,重试后能继续阅读正确来源。 本 PR 不证明 benchmark 改善、模型效果、SSH 实时可用性或已安装桌面 App 的交付。
问题在错误提示的真实性,而非缺少另一个读取系统。保留旧提示会让用户把没有读到的数据误认为仍可阅读,增加切换来源后排查数据归属的成本。这里两条文案就是完整、可回滚的修复;验证不能仅检查字符串,还要真正制造读取失败。
改动思路 / Approach
现有 GoalResearchHistory 继续拥有显示选择:只有 read.events.length 非零时,才显示“刷新失败,当前记录已保留”;零记录的失败走新的来源提示。来源 URL、分页、缓存失效、重试、下载和后台读取仍复用现有 owner。无新增模式、持久状态、权限或配置。
生产修复留在现有投影分支,真实 HTTP 与记录归属仍由原读取 owner 负责。当前 PR 的交付边界是未读来源的准确错误文案,以及围绕既有恢复链路的一条可持续回归场景。增加新的错误类型或重写缓存会扩大成本,不能改善这次已明确的错误。
| 实际触发 | 本次检查的结果 |
|---|---|
| 已有 33 条记录后刷新失败 | 保留 33 / 33,继续提示已保留;键盘重试恢复 |
| 切换到同 Goal 的另一物理来源但首次读取失败 | 显示此来源失败,不再显示旧来源的 33 条记录 |
| 恢复第二来源 | 11 / 11,下载为该来源的 11 条原记录 |
具体改动 / Changes
以接受本次改动前的 docs/development/frontend-delivery.md#task-first-delivery--从用户任务开始 和 docs/development/design.md#populated-page-review 为规格,spec_revision 为 33b15d0。映射:task-first-delivery 已实现,读取失败后可在同页恢复并读回来源;populated-page-review 已检查,使用公开 R7 on/off 的长标题、负面观察、来源详情与不完整状态。此处是按章节命名的标准映射,不另造产品验收编号。
关键代码讲解
GoalResearchHistory的文案:中文和英文各替换一个值,总计 2 加 2 删。新的主句只用于尚无记录的失败,不承诺不存在的快照。- 错误展示与重试分支:已有记录时仍走专用保留提示;详情与
refresh按钮保持可达。因此缩短主句没有删除重试操作和错误详情。 researchSourceRecoveryScenario:152 行场景复用现有公开捕获和RuntimeWorkspaceServer,只控制传输可用性。注册入口增加 2 行;该场景覆盖保留、跨源、键盘、导出与历史导航,未引入并行生产状态机。
PASS:不可变基线和 head 的后端集成都为 25 项;两边 control-plane typecheck、Chat bundle build 均通过。新增场景用仓库 Node 类型完成 strict TypeScript 检查。最初未带 Node 类型根的临时编译命令失败,改正编译环境后通过,保留该观察。
我用 Ego 操作各自构建的基线和 head,通过实际 HTTP owner 独立重现中英文首次失败、同来源保留、切换后的重试、11 条记录下载及 Back/Forward。导出保留 ID、顺序、正文、数值和覆盖状态;缺失字符串按既有投影归一为空串。最后一次实际失败/重试记录为 GET 503 后 GET 200,没有写请求。公开输入文件与对应 Git blob 相同。
对主干的风险 / Risks
未发现阻塞问题。最强反例是切换两个同 Goal、不同物理来源时把旧记录保留成新来源的完整历史;独立页面检查显示新来源标题、来源未读取状态和空历史,恢复后读到其 11 条记录。另一个方向也检查了:保留 33 条有效记录时没有被新的主句误报为全部不可读。
PASS:标准 source-checkout premerge 的必需检查及公共边界检查通过。FAIL:可维护性 ratchet 在不可变基线和 head 均以同一完整诊断失败,指向未修改的 _admitted_interaction_next_cli_actions。它是原有 advisory,不改成 PASS;独立比较了完整失败输出、输入集合和运行环境,保留该债务。
本次没有 opt-in/default-off 声明,常规读写、调度、配额与已安装指引未变。主要限制是使用既有公开捕获控制传输错误,未连接真实 SSH 或生产运行来源;仓库自带的 Playwright 启动场景没有另行执行,独立浏览器验证由 Ego 完成。首次视口证据在 PR 描述中;我另看了实际打包页面的桌面与窄屏状态。
我的整体评价 / Verdict
对这个文案缺陷,交付判断为 goal_achieved;更大的 benchmark 与安装验收仍在本 PR 边界之外。long_horizon:preserved,重试、导航、原记录下载可继续工作,没有新增循环或承诺。user_experience:improved,首次失败的描述真实且重试可达。
实际页面的 1200×888 默认/展开视图和 390×844 错误/展开视图已检查:来源、覆盖与重试有清晰层级;长标题在窄屏换行,正文与主数值可读,完整原文仍可展开。已展开的正文和来源字段可继续阅读;未验证范围是已安装 App、SSH 与 live benchmark,不能从捕获记录外推。自动 overflow 检查仅作补充,不替代视觉判断。
该修复沿用现有 vocabulary 和 owner,生产增量适中,无必要的兼容分支清理。没有把全部父目标完成作为批准条件。APPROVE 是这个精确 head 的代码结论;独立 merge readiness 和维护者合并授权仍须满足。
English verdict: APPROVE 7e5530d — no blocking finding; first-read copy and recovery verified with packaged UI, real HTTP owner and local checks. Existing advisory debt and installed/live-source limits remain.
Goal And Delivered Outcome
新运行来源的研究历史首次读取失败时,页面一条记录都没有,却仍提示“已读记录保留”。现在中英文提示明确指出当前来源无法读取;同源刷新失败仍保留有效记录及原有保留提示。
把已公开的真实 R7 context on/off 历史接入现有前端 smoke 集合,覆盖两源共享同一逻辑 Goal ID 时的失败、重试、原文下载和返回。来源隔离在基线上已经通过;这次修复的是首次失败提示,并补上真实数据的跨源恢复验证。
Author Declaration
docs/development/frontend-delivery.md#task-first-delivery--从用户任务开始anddocs/development/design.md#populated-page-review, revision33b15d037191be7273e39e1e78a01e66b316d732; the accepted request is to use real benchmark display state as a core frontend reference.GoalResearchHistoryzero-record error branch; failing-before/passing-after semantic assertionScope And Continuation
Complete within this bounded copy/recovery slice. Reuses the existing Explore/Research owner and fleet browser; no new provider, configuration, state vocabulary or effect authority. The Python fixture adapter supplies captured records and controlled availability to the actual HTTP owner; it does not qualify live SSH/CLI source access, current solver outcomes or an installed App. Broader research work remains separate.
Bounded refactoring pass: reused the existing scenario catalog/browser and preserved the reader implementation, whose source isolation already passed. No model, solver, evaluator, benchmark launch, installation or release was performed.
Validation
7e5530d2b6c2670afa15f3394d21938ebdf7f530(base33b15d037191be7273e39e1e78a01e66b316d732, targetmain).4b7afef; passes after the copy fix. Existing source reset behavior passes on both.test_runtime_workspace.py,test_goal_source.py,test_explore_history.py.research-source-recoveryfleet scenario: on 33 records → same-source failed refresh retains 33 → off first-read failure exposes no old graph → keyboard retry reads 11 → original JSON export → Back/Forward. Both languages; narrow overflow checked.runtime-source-workspace-browser-smoke.mjssynthetic lifecycle/analysis-failure checks._admitted_interaction_next_cli_actionsininteraction_contract.py. Immutable base/head runs with the same command/environment reproduce identical complete failure output. This remains a failed check.Reproduce after building Chat:
LOOPX_PERSONAL_WORKSPACE_PACKAGED=1 LOOPX_PERSONAL_WORKSPACE_SCENARIO=research-source-recovery LOOPX_PLAYWRIGHT_PACKAGE="$PWD/apps/presentation/dashboard/node_modules/playwright" node --experimental-strip-types examples/personal-workspace-browser-smoke.mjsCI and independent review remain separate from the local evidence. No merge authorization is claimed.
Frontend / Visual Evidence
Packaged UI with original public R7 records and a disposable read-only adapter. Before:
4b7afef; after: tested head above. No live/private session screenshots. Captures remain outside Git.Before / 首次失败错误声称保留记录(390px):
After / 明确当前来源未读到;保留原重试入口(390px):
Default populated first viewport / 原始 on 历史 33 条(1200px):
Expanded original negative result / 406 → 406 的有限范围负面证据(1200px):
Keyboard recovery / off 历史恢复为 11 条(390px):
Attention/craft review: the source name, unread coverage and one retry control answer the failure in place. The misleading preservation claim disappears only when no records exist. Default history and a long negative finding remain readable; no layout, color, graph semantics or source-authored outcome label changed. This is a packaged fixture qualification, not a claim of benchmark benefit or installed behavior.
Type of Change
LoopX Area