Skip to content

fix(research): keep child clocks visible when parent status fails - #8354

Merged
loopx-agent merged 1 commit into
mainfrom
codex/product-engineer-20261108-062840
Nov 8, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/product-engineer-20261108-062840

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

When a research parent Goal is slow or unavailable, its child cards currently lose their clocks even when each child can still be read. Keep those independent clocks available so users can choose which child research to inspect.

The parent status notice and retry remain visible. Its own research history stays gated; each child timing request continues to validate that child's Goal and source namespace.

Author Declaration

  • Written by: model_agent — OpenAI GPT-6 / Codex.
  • Specification and revision: no written specification; the bounded bug fix described in this PR is the basis. Repository frontend delivery and source-isolation rules at base 4a4fe1495b89eac3af9bd1f956183748c2944909 apply.
Criterion Disposition Owner / evidence
Child clocks remain usable during parent loading or denial implemented GoalResearchWorkbench uses the existing independently validated child reads; packaged browser regression
Parent evidence remains gated; denied child has no borrowed clock implemented Existing history guard retained; negative browser checks and native source tests
Refresh, keyboard navigation and narrow viewport remain usable implemented Existing progressive-loading browser smoke extended

Scope And Continuation

Complete for this availability bug. This does not fix slow parent status generation or qualify running/resumed execution clocks. Those remain part of the existing research-workspace work. No new backend, provider, state vocabulary, setting, or execution path is introduced. The redundant parent-derived timing flag is removed from the local navigation component.

Validation

  • Tested revision: 836d2a6ac2f6832bb2cd60b424b1326fca325a2d.
  • Run state: finished.
  • Input classes: synthetic, authorized_private_read_only.
Check kind Result Evidence / limitation
static passed Chat TypeScript check, production bundle build and source verification
regression_parity passed New child-clock assertion times out on the base implementation; passes with this change
real_entrypoint passed node examples/workspace-progressive-loading-browser-smoke.mjs: packaged loading, denial, refresh, keyboard and 390 px checks; no render errors
integration passed pytest tests/test_chat_explore_results.py tests/presentation/test_linked_goal_sources.py -q: 22 passed
real_backend passed Packaged frontend with the existing native LoopX backend, through a GET-only preview proxy: all 13 real child timing states resolve while a parent failure is confined to the proxy. Native data and screenshots remain private; this is not installed-delivery proof
static passed Risk-based premerge gate, bilingual RFC check, diff hygiene and public/private scan

Premerge reports one inherited advisory failure in control-plane-maintainability-ratchet-smoke.py, outside the changed files; the gate passes with zero blocking failures. CI waiting is disabled under the maintainer's existing delivery direction. Review and merge readiness still apply.

Frontend / Visual Evidence

Synthetic fixtures, packaged production frontend. Before uses base 4a4fe149; after uses the unchanged source bytes in reviewed head 836d2a6a. Private backend captures are excluded.

Before: the parent is loading and both child cards omit timing.

Before: child clocks hidden by parent loading

After, desktop: one child's dated records resolve; the denied child says time unavailable. Parent loading remains explicit.

After: independent child clocks on desktop

After, 390 px: the parent's denial and retry coexist with the readable child's clock.

After: denied parent and readable child on a narrow screen

The user question is which child research is available and when its records were captured. Existing hierarchy and cards carry that information; no extra explanatory UI or new controls were added. Dates remain recorded-history spans, not experiment runtime. Existing unrelated unavailable-service notices in the synthetic fixture remain visible.

Type of Change

  • Bug fix
  • Test update
  • Personal Workspace frontend

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机 / Motivation

未发现阻塞性问题。在父研究 Goal 中选择子 Goal、判断哪些研究可读的使用者。父 Goal 卡在加载或被拒绝时,旧页面把可读子 Goal 的时间一起隐藏;修复后按子 Goal 各自的读取结果显示时间或不可读状态。已验证父级失败时子级记录时间仍可读,点击 ANN 和 Codec 能进入各自研究内容。本 PR 不修复父级状态生成延迟,也不宣称记录跨度等于实验执行时长。父级慢读取根因、正在运行及恢复回合的时间来源,以及更完整的 case 分析仍未在此 PR 完成。

改动思路 / Approach

父子关系负责导航,各个来源的读取权限由后端分别判定。原来的问题是前端把父级状态是否成功,当作子级时间能否读取的前置条件。保留这种依赖会继续让大父 Goal 的慢读取挡住已经可读的研究入口;增加超时或缓存也不能消除错误依赖。

复用已有子级读取及来源校验,只移除父级展示依赖;不增加缓存、超时或状态所有者。仅交付父级不可用时子级时间的独立读取与恢复,父级延迟仍留在现有任务。useChildTiming 原有三路并发、来源键与取消机制继续生效;后端拒绝的子级显示不可读,目录中的名字不会授予读取权限。父级自己的研究历史仍受原条件约束。

具体改动 / Changes

没有另行编写的独立规格;本 PR 描述的维护者需求和验收条件构成此修复的依据。评审范围为完整 head 836d2a6ac2f6832bb2cd60b424b1326fca325a2d 相对基线 4a4fe1495b89eac3af9bd1f956183748c2944909 的两个文件,也检查了未修改的读取 hook、响应 schema 和后端来源隔离验证。

关键代码讲解

  • ResearchGoalNavigation 删除由父级传下来的 showTiming 参数,直接启用已有子卡片的时间展示。请求仍逐个携带子 Goal 与来源信息,并未混合父子证据。
  • GoalResearchWorkbench 继续展示 statusNotice,并保留第 43 行对当前 Goal 历史和已保存结论的限制。移除的是跨来源的错误依赖,没有将父级拒绝改为成功。

现有渐进加载浏览器验证加入父级等待、父级 403、子级 403、完整刷新恢复及键盘导航。旧实现会在首个子级结束时间断言处超时,修改后同一数据的日期正确显示为北京时间;单独重试父级不会被误记为已刷新子级,子级恢复由原有全局刷新入口验证。后端的两个相同原 Goal、不同 namespace 用例继续拒绝错配来源,返回 409。未新增状态枚举或读取协议,也没有增加第二套时间计算。

对主干的风险 / Risks

主要风险是父级不可用时开始更多读取,或错误地把目录中的旧来源当作可读。现有三路并发限制控制了前者,后者仍由每个请求的当前来源校验和响应身份校验防守。真实只读预览在父级故障限定于代理的条件下读出了 13 个子级状态,并完成 ANN 策略与 Codec 113/113 历史的进入及返回;它证明真实后端读取路径,不能当作已经安装更新的证明。

PASS:Chat TypeScript 与生产包构建、来源校验测试 22 项、渐进加载浏览器验证、源包校验、双语 RFC 检查、公开边界扫描和 premerge gate。FAIL(非阻塞诊断):premerge 报告既有 maintainability ratchet advisory;本次未独立重跑其完整基线归因,不将其写成已经修复。远程 CI 按既有配置不读取、不轮询。没有 opt-in 或默认关闭功能的声明,非研究页面和持久数据协议均未修改。

我的整体评价 / Verdict

这是原研究工作台任务的 justified increment:可读子级不再被父级加载状态阻塞,同时保留来源拒绝与恢复路径。长程工作维度 preserved,没有新增调度或重试循环;用户体验 improved,无需新增设置、复制或确认回合。架构判断 retain,边界 proportionate,复用了已有 typed owner 并删除冗余传参。

检查了父级等待与拒绝、子级成功与不可读的整页组合,以及 13 个真实子 Goal 的重复内容;错误和重试仍在上方,时间留在各自卡片内。未将本机更新前的预览视为已安装交付;运行中与恢复回合未在本次验证。390 px 合成页面原有的服务不可用提示仍占据下部,本 PR 未改变或声称修复它。父级性能根因与真实执行时长资格仍是现有任务中的明确缺口,不由本次批准关闭。

English verdict: APPROVE — head 836d2a6; no blocking findings. Packaged failure/recovery and native source isolation pass; parent latency and installed activation remain separate.

@loopx-agent
loopx-agent merged commit efd4935 into main Nov 8, 2026
9 of 10 checks passed
@loopx-agent
loopx-agent deleted the codex/product-engineer-20261108-062840 branch November 8, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant