Skip to content

fix(dashboard): load Goals with native Todos without source indexes - #5028

Merged
huangruiteng merged 2 commits into
mainfrom
codex/status-native-todo-index-0925
Sep 25, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/status-native-todo-index-0925

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Goal/source and gap: A valid Goal status response containing native Todos was rejected by the dashboard because the client required a numeric source index on every Todo. Native Todos have stable todo_id values and intentionally have no synthetic source index.
  • Observable before → after: the Goal page displayed a status parse error; the same mixed native/legacy response now loads, while a Todo with neither index nor ID remains invalid. The status contract smoke, packaged browser smoke, and an authorized private read-only status parse validate the change.
  • Issue/task and intended base: User-reported Goal loading regression; main.

Scope And Continuation

  • Completed scope and remaining work: The dashboard accepts native Todo identity throughout its shared status projection and removes an unused numeric index from the personal workspace display model. No backend Todo semantics or UI layout changed. Complete within this bug-fix scope.
  • Slice boundary / successor: Maintainer review and merge are required for the product change. A separate semantic vocabulary budget regression already present on the base branch also needs an owner fix; it is not changed or waived here.

Validation

  • Tested revision: 1491bcb290b388f88db2ce94f3dd0a0fc38189e2 against e5e1a6a9e2c85ef62b9f35b91dbeede09c6b7486.
  • Run state: finished.
  • Input classes: synthetic, authorized_private_read_only.
Check kind Result Public-safe evidence / limitation
unit passed npm run smoke:status-projection-contract: mixed native/legacy Todo rows parse; anonymous and malformed identity rows fail.
integration passed npm run smoke:workspace-progressive: packaged browser journey loads a synthetic Goal with a native Todo and preserves retry/mobile behavior.
static passed npm run build:chat, npm run build:desktop, git diff --check origin/main...HEAD, and changed-path public/private boundary scan.
real_entrypoint passed The actual status parser accepted an authorized read-only scoped Goal response and the full workspace status response after the fix. No private payload is attached.
regression_parity passed The legacy index path remains valid; native missing/null index paths now use todo_id and invalid anonymous rows remain rejected.
static failed loopx canary premerge --from-git-diff --goal-id loopx-meta: 9 of 10 selected catalog checks passed; semantic-vocabulary-drift-smoke.py reports 44 maintained Python/TypeScript twins against a budget of 43. The base branch also has 44; this diff adds no control-plane twin. Quality receipt and public boundary check passed.
  • Coverage and gaps: The status parser, packaged frontend, and real read-only status data were checked. The existing base-branch semantic budget failure prevents a fully green premerge result; no budget increase or bypass is included in this PR.

Frontend / Visual Evidence

  • UI impact: changed (valid status replaces the existing parse-error state); layout and navigation are unchanged.
  • Before: a Goal with a native Todo fell into the status-load error and Retry path.
  • After: the same synthetic status fixture reaches the existing Goal Tasks view; genuinely invalid responses still use the existing error and Retry UI.
  • States and viewports shown: synthetic packaged-browser smoke covered loading, ready, retry, and mobile states. No private screenshot is attached.
  • Source data: synthetic.
  • Attention review: this removes an erroneous full-page failure so Goal data and actions regain their place. It adds no chrome or competing status text and retains the one-step Retry control for actual failures.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

  • Direction / acceptance reference: Operator surface and IM integration; native Todo identity follows the existing control-plane contract.

Shared-authority RFC fixture impact

  • N/A: This PR changes only dashboard parsing and presentation, without changing shared Goal Authority contracts.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

@huangruiteng
huangruiteng force-pushed the codex/status-native-todo-index-0925 branch from fe23193 to f34958b Compare September 25, 2026 04:10
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/status-native-todo-index-0925 branch from f34958b to 1491bcb Compare September 25, 2026 04:16

@huangruiteng huangruiteng 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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
Reviewed exact head: 1491bcb

动机

旧 Dashboard 状态解析把 Markdown Todo 的 source index 当成每条 Todo 的必填身份。原生 Todo 只有稳定的 todo_id、没有 index 时,整份 Goal 状态会在解析阶段失败,连同可继续处理的 Goal 一起从工作区消失。这个 PR 要修的是可达性与真实身份,不是更改 Todo 的调度或权限;修后状态可载入,持续工作不会被一个不存在的展示坐标阻断。

改动思路

入口仍是 Dashboard 的状态拉取与 parseStatusPayload;权威输入仍是 Core 返回的 Todo 数据。todoItemSchema 允许 index 缺省或 null,但要求 index 与非空 todo_id 至少存在一个;todoIndexItemSchema 继承同一身份约束。UI 继续优先用 todo_id 做稳定 key,旧 Markdown Todo 才回退到 source index。比起给所有原生 Todo 伪造 index,这使解析边界承认已有身份,且不产生第二套持久状态。失败仍由状态请求/重试路径负责,未引入新的控制面动作。

具体改动

关键代码讲解

  • apps/presentation/dashboard/src/data/status.ts 的 todoItemSchema(约第 65–105 行)从强制 number 改为可缺省坐标,并用 refine 拒绝同时没有 index 和 todo_id 的匿名行;字符串 index 仍拒绝。
  • 同文件 todoIndexItemSchema(约第 116 行)改用 safeExtend,确保索引行继承上述 refinement,而不是绕过身份约束。
  • apps/presentation/dashboard/src/views/dashboard-page.tsx 的 personalAgentTodoFromItem 不再向展示模型传递未使用的 index;其行 key 仍先取 todo_id,旧数据保留 index 回退。
  • 状态契约 smoke 注入无 index、null index、旧式 index、匿名和类型错误五类输入;打包浏览器 smoke 把原生 Todo 注入 ready Goal,验证单个 Goal 曾失败再恢复时工作区仍可载入。我的独立复跑中,status-projection-contract、build:chat 和 workspace-progressive 均通过;一次当前 scoped status 的真实解析也通过,但那个 live Goal 当时没有原生 Todo,不能拿它冒充原生 Todo 端到端验收。

对主干的风险

本次默认解析规则确实放宽,但范围被“index 或 todo_id”约束住;未改变 claim、租约、权限、quota 或持久化语义。浏览器路径证明整页不再被混合数据击穿,却没有逐项断言原生 Todo 在视觉列表中的身份,这属于后续可增强的覆盖,不是目前发现的回归。真正的合并阻断是仓库现行必跑的 semantic-vocabulary-drift-smoke:同一 PR 基线与此 head 的 control_plane/生成器/预算实现均未变化,而独立运行仍报 44 个独立维护的 py/ts twins,预算 43。按仓库的预算决策规则,不能为了这两个 PR 偷改阈值,也不能把红色必跑验证当作通过;需要维护者在基线修复或作有证据的预算决定后重跑原检查。未查询或等待远端 CI。

语义与 CI 对齐

Todo 身份沿用已有 todo_id,没有新增共享控制面词汇;44/43 是现有绝对预算未过,并非本 PR 新增 twin。它仍是当前候选必须通过的本地检查,故我的结论是 hold,而不是以“基线也红”为理由自合并。

我的整体评价

功能方向和实现边界成立:长期工作可达性改善,用户不再因原生 Todo 缺少展示索引而丢失 Goal 视图;负例仍拒绝匿名数据。没有发现需要改动本 PR 代码的确定性缺陷,相关重构也已保持在相邻 schema/展示边界内。由于必跑预算检查在 exact head 仍失败,本次只能给出 REQUEST_CHANGES/合并暂缓;基线门槛修复并复跑通过后,可对不变 head 重新审结。此 PR 涉及 apps 行为,按仓库规则不得自合并。

English verdict: REQUEST_CHANGES

@huangruiteng
huangruiteng merged commit 4c48111 into main Sep 25, 2026
25 of 29 checks passed
@huangruiteng
huangruiteng deleted the codex/status-native-todo-index-0925 branch September 25, 2026 05:26
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