Skip to content

fix(dashboard): surface host activity delivery windows - #6465

Merged
huangruiteng merged 3 commits into
loopx-project:mainfrom
ikunikun1145:codex/heartbeat-delivery-window-dashboard
Oct 15, 2026
Merged

huangruiteng merged 3 commits into
loopx-project:mainfrom
ikunikun1145:codex/heartbeat-delivery-window-dashboard

Conversation

@ikunikun1145

Copy link
Copy Markdown
Contributor

Goal and delivered outcome

  • Outcome basis: Dashboard readback slice for #3927; this PR is related to, and does not close, that issue.
  • Goal/source and gap: The status API already attaches a cadence-based delivery_window to each bound host thread. The Dashboard schema was stripping it, so users could not see stale or missing host activity.
  • Observable before to after: Before, the Goal row showed its normal activity state only. After, it retains the per-thread window through parsing and view-model projection, shows a visible stale or missing badge, and keeps host, Agent, and age in the activity detail.
  • Issue/task and intended base: Related to [Bug]: Codex App automation integration cannot detect missing scheduled prompt delivery #3927; base loopx-project/loopx:main at 3c681f1.

Author declaration

  • Written by: model agent — Codex (GPT-6).

Implemented against

Criterion Disposition Symbol / path Test or command
Preserve existing per-thread window state and age through Dashboard status parsing and projection implemented status.ts; dashboard-page.tsx npm run smoke:status-projection-contract
Make stale and missing host activity visible without changing execution state or claiming prompt receipt implemented goal-activity.ts; goal-sidebar.tsx; goal-activity-view.tsx npm run smoke:goal-activity; synthetic browser screenshots below
Verify that a scheduled task body was delivered and an Agent started out of scope #3927 host integration This PR presents only the existing activity-window evidence.
  • Self-check: Compared the Dashboard projection to the existing backend payload; checked stale, missing, fresh, and no-expectation behavior. No scheduler or host-receipt semantics were changed.

Scope and continuation

Validation

  • Tested revision: e8997a0
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
unit passed npm run smoke:goal-activity — stale/missing selection, fresh retention, and unknown/no-expectation suppression.
integration passed npm run smoke:status-projection-contract — stale state and age survive the status decoder.
static passed npm run build:desktop — TypeScript check and production Vite build passed; Vite reported its existing large-chunk advisory.
manual passed Synthetic Goal row rendered with stale and missing badges; before/after screenshots are attached.
static passed loopx canary premerge --from-git-diff --git-diff-base upstream/main — 8 selected checks passed, no warnings or failures.
integration failed npm run smoke:demo-readiness stopped in the macOS LaunchAgent install smoke; that path is outside this diff.
manual failed The broader home-browser flow reached its unrelated status-only attribution assertion and failed because the expected attribution text was absent. The focused stale/missing browser renders passed.
  • Coverage and gaps: Parsing, view-model projection, Goal-row visibility, and production compilation are covered. Live Codex App prompt delivery, Agent start, and the full LaunchAgent path were not verified.

Frontend / Visual Evidence

  • UI impact: changed
  • Before: See attached host-activity-before.png (synthetic fixture, desktop).
  • After: See attached stale and missing state screenshots (synthetic fixture, desktop).
  • States and viewports shown: Before, stale, and missing; desktop Goal list.
  • Source data: synthetic
  • Attention review: The compact badge makes a missed or absent activity window visible beside the existing Goal status. Full host/Agent/age details stay in the existing activity text and tooltip; no extra card or interaction was added.
  • Craft review: Reuses the existing amber/red status tokens and typography. The badge adds no animation or raw colors; unknown/no-expectation remains non-alarming.

Type of change

  • Bug fix
  • Test update

LoopX area

  • Public docs or presentation surface (README, protocols, dashboard)

Technical direction

  • Related context: GH-A02 in docs/development/contributor-tasks.md; this PR is a Dashboard readback slice and does not claim to complete the still-open design.

Shared-authority RFC fixture impact

  • N/A — this PR does not claim progress on the TypeScript control-plane migration or shared Goal Authority RFC.

Boundary checklist

  • No private state, credentials, raw traces, internal links, or local paths are included.
  • No maintainer-owned benchmark work is duplicated.
  • The change stays scoped to the linked issue.
  • Synthetic before/after UI evidence is attached.
  • Every commit includes a DCO Signed-off-by trailer.
host-activity-before host-activity-missing host-activity-stale

ikun added 3 commits October 14, 2026 13:47
Signed-off-by: ikun <ikunikun1145@gmail.com>
Signed-off-by: ikun <ikunikun1145@gmail.com>
Signed-off-by: ikun <ikunikun1145@gmail.com>

@loopx-agent loopx-agent 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.

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=xhigh; declaration_source=runtime_reported

动机

评审 e8997a0a9c4efb861288d10a036f00ad4192e82f,base 3c681f1132fe719e01f75e5a41bfd854dfa9e346。查看多个 Goal 的用户,需要在原工作区判断哪个宿主长时间没有活动。旧页面丢弃后台已有的时间窗,用户得另查诊断才能发现缺失活动,也容易把正常排队与缺少观察混在一起。同一份后台超时或缺失观察,旧版列表只有原活动状态;现在原行直接出现对应徽标和宿主、Agent、时间详情,无需增加配置步骤。真实打包页面对照中,超时和缺失变得可见,fresh 不产生运行中标识,无预期时间窗的旧文案保持;390px 页面没有横向溢出。本次只是既有诊断的可见性,不证明实际定时正文送达、Agent 启动或 #3927 整体关闭。原 #3927 的实际宿主送达和启动凭据仍由宿主集成 owner 验证;安装态采用未验。

改动思路

状态仍由后台既有 HostDeliveryWindow 计算;Dashboard 仅保留该字段,并由共享的活动投影生成文案和徽标。本次只改变既有 Goal 行与活动摘要的诊断可见性,不改宿主观察、调度或运行判定。 本轮按完整原 issue、现有调用链和作者声明判断独立交付边界,未把测试数量当整体验收,也没有继承历史批准。体验建议仅用于追踪真实入口、失败和读回,不构成新的 roadmap、权限或长期收益证明。

具体改动

  1. status.ts 保留可选的 delivery_window,覆盖后台既有四种状态、原因和年龄;旧服务未提供字段仍可读。
  2. dashboard-page.tsx 将每条 thread 的 Agent、状态、年龄和原因传入既有工作区模型。goalHostDeliveryWindows(goal-activity.ts:144)只选 fresh/stale/missing 并排序,unknown/no_expectation 不报警;不重算时间窗。
  3. useGoalActivity(goal-activity-view.tsx:45)复用原运行判定,拼接双语宿主/Agent/年龄信息,选取一个超时或缺失徽标。GoalActivityChip 和 GoalRowActivity 共用该结果;CSS 使长详情截断而保留徽标,tooltip 保留全文。英文、中文十条消息和两个既有 smoke 一起更新。

完整九路径 +137/-5,三份提交均有 DCO。对照 #3927 与 base 的 HostDeliveryWindow:preserve_backend_window、visible_without_execution_claim implemented;actual_host_delivery_receipt deferred,原 issue 的宿主集成 owner 继续负责真实正文送达与 Agent 启动凭据。

对主干的风险

最重要的风险是把时间窗误读为正在运行或送达成功。本轮使用正常 build:chat 的完整打包页面、相同合成观测和真实未改动的 Python 时间窗 owner,在 1512px/390px 对照 base/head:旧四行均无时间窗提示;head 的 stale/missing 有明确徽标与全文,fresh 只有信息文案,no_expectation 保留原文案;四行都没有 live 标记,页面宽度与 viewport 一致。中文桌面/手机及英文桌面/手机、刷新、导航打开和 Escape 均检查,截图已目检。辅助聊天、排序、提案 API 是合成边界,产生的不可用提示不当作本 PR 后台缺陷或真实功能资格;没有安装或触发实际 Codex 自动化。

smoke:goal-activity、smoke:status-projection-contract、正常打包构建、时间窗 owner 69 tests、当前本地 canary 3 direct +8 selected 均通过,零失败/hold。先跑 advisory 再跑全 27 vocabulary smoke;advisory 的零路径是工具覆盖限制,已人工检查九个路径及既有四态归属。未查询、轮询或等待 CI。作者报告的 LaunchAgent/demo-readiness 与另一浏览器 attribution 失败未独立重跑,保留为未验证历史限制,未宣称修复。

非阻断建议:新 .personal-goal-window-badge 固定为 10px,实际手机 DOM 也为 10px;仓库 design.md 要求 caption token 和至少 12px。建议换用既有 caption/line-height token,并重看 390px 导航。当前同一事实还出现在正常字号的详情和 tooltip,未发现信息丢失,因此不阻断本次 readback 修复。

我的整体评价

未发现阻断本次有界修复的问题。APPROVE,justified_increment。 long_horizon improved:后台已有的缺失/超时事实不再隐藏,且没有增加持久状态、额外读取或执行副作用;user_experience improved:在原工作区即可识别问题,无新增配置、确认或复制命令步骤。未来变更检查已做:两处视图共享 useGoalActivity,无需新增缓存或第二个分类 owner。批准限定于诊断展示;真实宿主送达/启动、安装态采用和长期净收益仍未验收。公开首屏的 owner review 与合并权限保持原规则。

English verdict: APPROVE — e8997a0a9c4efb861288d10a036f00ad4192e82f preserves existing host-window diagnostics through the Dashboard and exposes stale/missing states without claiming execution. Independent paired packaged UI, source smokes, 69 backend tests and local canary pass. Live delivery remains unqualified; the 10px badge is a non-blocking readability follow-up.

@mergify

mergify Bot commented Oct 15, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @ikunikun1145.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 15, 2026
huangruiteng added a commit that referenced this pull request Oct 15, 2026
…ivity-windows

Maintainer adoption of #6465 by @ikunikun1145.

The original branch conflicted with main and the fork disallows maintainer edits, so the reviewed content was carried onto a maintainer branch. The merge resolved one import-line conflict in goal-activity.test.mjs by keeping both goalHostDeliveryWindows (PR) and taskSessionStatus (main). The author's three commits are preserved unchanged; the only additions are the main merge and a caption-token correction of the new badge, which had used a 10px literal against docs/development/design.md.

Exact-head review 5529175354 on 71f5e3b; change-quality receipt cqr_0e1401cdf60efa98c071 (pass); merge-readiness ready=true. Validation: smoke:goal-activity, smoke:status-projection-contract, build:desktop and check:css-custom-properties all pass. The premerge catalog run is 7/8; the single failure examples/control_plane/quota-work-lane-policy-smoke.py is a pure-Python work-lane smoke reproduced identically on unchanged 51832c5 (introduced by 3f9f5b3 / #6475) and is recorded as a separate merge-readiness hold rather than a regression of this dashboard diff.
@huangruiteng
huangruiteng merged commit ac078a2 into loopx-project:main Oct 15, 2026
1 check passed
@huangruiteng

Copy link
Copy Markdown
Collaborator

Landed. Thanks @ikunikun1145 — the dashboard readback in this pull request is now on main via #6495 (merge commit efd372b2eb80bea403f11b2d0c918f393d525471), and GitHub records this pull request as merged through it.

Why it went that way: this branch had drifted into a merge conflict with main and the fork does not allow maintainer edits, so the branch could not be updated in place and the conflicting pull request could not be merged directly. The reviewed content was therefore carried onto a maintainer branch with your three commits preserved unchanged.

The merge with main had exactly one conflict, a single import line in apps/presentation/dashboard/src/features/personal-workspace/goal-activity.test.mjs: this pull request added goalHostDeliveryWindows while main added taskSessionStatus. The resolution keeps both. Nothing else conflicted and no behaviour was changed by the resolution.

One review finding was fixed on top of your commits: .personal-goal-window-badge used font-size: 10px; line-height: 1.4, which docs/development/design.md forbids ("Do not introduce fractional pixel sizes or sub-12px UI copy") and which none of the sibling badges in the same stylesheet used. It now uses the existing --text-caption / --leading-caption tokens. Exact-head review: #6495 (review)

Two notes for follow-up, both non-blocking and neither about your change being wrong:

  1. z.enum([...]).catch("unknown") silently downgrades any state value the dashboard does not know, so a future backend state would render as no information. It matches the backend HostDeliveryWindowState value for value today; it just needs to stay in step when that enum grows.
  2. The premerge catalog run is 7/8. The single failure, examples/control_plane/quota-work-lane-policy-smoke.py, is unrelated to this diff: it reproduces identically on unchanged 51832c59, where build_work_lane_context_contract and the quota path disagree on content_revision in monitor_due_items after 3f9f5b3cc6 (fix(quota): preserve gated successor replans #6475). It is tracked as a separate merge-readiness hold.

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

Labels

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants