Skip to content

fix(workflows): bound dashboard history hydration - #319

Open
testikun wants to merge 2 commits into
openpi-dev:mainfrom
testikun:codex/issue-178-dashboard-hydration-bound
Open

fix(workflows): bound dashboard history hydration#319
testikun wants to merge 2 commits into
openpi-dev:mainfrom
testikun:codex/issue-178-dashboard-hydration-bound

Conversation

@testikun

Copy link
Copy Markdown
Contributor

Summary

Relates to #178 by fixing the dashboard's unbounded persisted-run materialization.

  • Build the /workflows list from normalized workflow.json metadata without reading result.json or transcripts.json.
  • Enforce independent dashboard count and UTF-8 byte bounds for non-pinned history while keeping disk artifacts canonical.
  • Hydrate result/transcript artifacts only when opening a run, and rehydrate once when a live run settles while its detail view is open.
  • Surface omitted-run counts in the TUI and preserve full-ID/suffix lookup and ambiguity across omitted history.
  • Keep referenced history eligible without allowing session-wide references to bypass the projection bound.

Validation

  • npx --yes bun@1.3.14 run check
  • npx --yes node@24 scripts/run-tests.mjs — 1083 passed, 1 skipped
  • npx --yes node@24 --test tests/extensions/workflows/dashboard.test.ts tests/extensions/workflows/target-resolution.test.ts — 33 passed
  • TUI smoke verified omitted-history status and lazy transcript detail rendering.

The change does not alter workflow artifact formats, execution, delivery, resume/replay, or the settled session-memory retention policy.

Keep dashboard list projections metadata-only and bounded by count and UTF-8 bytes. Hydrate result and transcript artifacts only when a run is opened, preserve explicit target lookup across omitted history, and surface omitted runs without changing canonical artifacts.
@github-actions github-actions Bot added the area:workflows Workflow engine, capability, skills, or tests label Aug 31, 2026
@testikun

Copy link
Copy Markdown
Contributor Author

TUI smoke

验证 Dashboard 修复后的实际界面:列表显示省略数量,打开详情后才加载完整 transcript。

OpenPI Dashboard TUI smoke

@tt-a1i tt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

复审 exact head b2dc49ee74643aa4842216dc4b04b9f697a061af。目标是让 /workflows 列表只保留有界元数据,打开详情再加载磁盘正文,减少历史规模带来的内存/读取开销。方向和价值成立,但当前有两个可复现回归,需要修改后再合并。

Standards

1 项:enterEntry 对 live entry 调用会修改输入的 stale recovery,违背 AGENTS 中 canonical execution facts 与 operator-facing UI 分离的边界。仅查看 UI 不应改变真实任务状态。

Spec

2 项:

  • P1:打开正在运行的 run,原始 active Map 对象及 agent 都从 running 变成 uncertain,并被写入 finishedAt/error。这违反 PR 的“不改变 execution/delivery”承诺。
  • P2:从列表打开的 run 完成后被32条历史限额省略,current 仍标记 live,不进入一次性 artifact hydration,无法看到 canonical transcript。这违反“live run settles while its detail view is open 时 rehydrate once”的承诺。

详见行内评论。最小修复可局限在 live/history 分支与当前详情的 pin/refresh,无需新增存储或生命周期框架;不要求本 PR 一并完成 #178 的全部 retention 工作。

验证

隔离 checkout、Node 24:bun run check 通过;bun run test:Node 1083 passed / 1 skipped,Vitest 30 passed;git diff --check 通过。另用实际 WorkflowDashboard class 完成两条独立复现:live 对象被原地改写;33条记录 mock FS 中 current 被省略、artifactReads=0、current.live=true。现有绿测未覆盖这两个交叉场景。本轮不是安装后真实 Pi/TUI 或模型验收。

Comment thread extensions/workflows/dashboard.ts Outdated
}) ?? entry.details);
this.current = {
...entry,
details: recoverStaleWorkflowDetails(details),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] 不要对 live entry 做 stale recovery

当从 active Map 打开正在运行的 Workflow 时,上方 entry.live ? entry.details 直接拿到 canonical runtime 对象。recoverStaleWorkflowDetails 会原地将 run/agents 的 running 改为 uncertain,并写入 finishedAt、error 等字段。实际 class 复现:仅打开详情后,active Map 中 run.status 和 agent.state 都已为 uncertain。这不是只改变渲染结果。请只对已失去 owner 的历史记录/副本做恢复,live 分支直接使用真实状态,并增加打开 live 详情前后 canonical 状态不变的回归。

@@ -837,18 +982,45 @@ export class WorkflowDashboard {
const refreshed = this.entries.find(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] 当前打开的详情不能依赖有界列表才能完成 hydration

refresh 的 projection 只 pin initialRunId。通过普通列表打开较早的 live run 后,它完成并落出32条历史限额时,这里找不到 refreshed,后面的 live→settled hydration 完全跳过。33条记录复现结果:omittedRuns=1、targetListed=false、current.live=true、artifactReads=0,磁盘上已有 transcript 但当前详情读不到。请在详情打开期间 pin current.runId(或独立刷新当前详情),并覆盖完成时被列表省略的回归;无需让所有历史引用突破限额。

@tt-a1i

tt-a1i commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

审查结论:Changes Requested,exact head b2dc49e。价值是降低 /workflows 历史加载开销;已确认 P1 查看 live 详情会改写真实运行态,以及 P2 当前详情被历史限额省略后不加载完成 transcript。建议仅修 live/history 分支和当前详情 pin/refresh。check、完整测试(Node 1083 passed/1 skipped,Vitest 30)通过,但两个独立复现暴露了测试遗漏。详见正式 review:#319 (review) 。本轮未改代码或合并。

@tt-a1i tt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

复审 exact head 93ab72ca8ca8e64d1554111f43a31de69fc2bd8a。目标是降低 /workflows 历史加载成本:列表只读 metadata,详情按需 hydrate,并把 operator projection 限制为 32 条 / 2 MiB。作者这次已经修复上轮两项回归:打开 live 详情不再改 canonical state,省略的 live run 完成后也能 pin 并 hydrate。

仍有 1 项运行时资源边界问题:最终列表有界,但每次刷新仍同步枚举并解析全部 workflow.json;存在 live run 或 notice 时,这个过程每 120 ms 执行一次。独立 exact-head 基准(最小 metadata)显示 warm refresh:100 条约 2.7 ms、1,000 条约 136–166 ms、5,000 条约 706–780 ms,已经超过刷新周期并会持续占用 TUI 线程;5,000 条首次读取约 7.1 s。

最小修复不需要新存储框架:把“全量持久历史扫描”移出 spinner tick,刷新周期只处理 active/current pin 的变化;持久 metadata projection 可在打开、显式刷新或可证明的增量事件上重建。

验证:bun run check 通过;dashboard/target-resolution 35/35 通过;GitHub CI 全绿。绿测覆盖了最终投影边界,但没有覆盖扫描工作量边界。

else addBounded(entry);
};

const runIds = new Set([

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] 这里仍会同步列出所有持久 run,并在下面逐个读取/解析 workflow.jsonrefreshTimer() 又在存在 live/notice 时每 120 ms 调用整个 projection。结果数组虽然只保留 32 条/2 MiB,扫描和 I/O 本身仍随历史线性增长。exact-head 基准在 1,000 条时 warm refresh 已约 136–166 ms,5,000 条约 706–780 ms,Dashboard 会在长历史下持续卡住。请把全量持久扫描移出 spinner tick,周期刷新只处理 active/current detail,或使用现有生命周期事件做有界增量更新。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:workflows Workflow engine, capability, skills, or tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants