Repository navigation
Conversation
|
Hi @xiaoan17, the DCO If the log confirms a missing |
5 similar comments
|
Hi @xiaoan17, the DCO If the log confirms a missing |
|
Hi @xiaoan17, the DCO If the log confirms a missing |
|
Hi @xiaoan17, the DCO If the log confirms a missing |
|
Hi @xiaoan17, the DCO If the log confirms a missing |
|
Hi @xiaoan17, the DCO If the log confirms a missing |
e58fc0d to
1828b80
Compare
Browser-lane diagnosis: the redesign moved three shipped acceptance contractsAll three
What movedThe Goal row's activity sentence is gone. {goal.loadState ? <GoalRowActivity goal={goal} showLoad /> : null}That The board card has no <GoalIdentityMark goal={goal} />
<strong className="personal-home-goal-title" title={goal.title}>{goalShortLabel(goal)}</strong>
<p className="personal-home-goal-reason" title={…}>…</p>
<span className="personal-home-goal-meta">…</span>
<span className="personal-home-goal-state">…</span>
<small className="personal-home-goal-time" title={…}>…</small>
The decision this needsThe design system this PR adds says a row is
Recommendation: option 2 for the host name, option 1 for the rest. The This is left open deliberately rather than fixed in the branch: it is a |
songoow
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | GPT-6 Astra Pro | OpenAI | self_reported
REQUEST_CHANGES — 4 项 P2。 审查 head e626fbbd575c39df8f6e4426517ab3a12852a266,merge-base 5c2ed9f6f2cf8a9bdc952f1c8dfceae92e062b0b;完整覆盖 27 文件(+752/-340)。前三项是实际源码/生产数据合同反例,第四项另有真实 CI 浏览器失败;没有把源码推导称作本地实跑。
动机 / Motivation
受影响的是在本地工作区跨 Goal 查看进度、处理待决事项、查阅成果的用户,包括正常加载和数据暂不可用时的日常浏览。
用户进入一个正在执行的 Goal,原先可在侧栏读到执行状态并进入成果阅读;这次把页面改为更紧凑的阶段条和分段文档,希望更快看清当前工作,但当前分支会隐藏正常状态及已有成果。
源码确认 Manager 运行条、看板卡片、Goal 阶段头部和侧栏通知已接入真实路由;同时确认有成果被隐藏、未知被写成完成或无待办、普通侧栏状态缺失四项回归。整体阅读体验是否改善尚未经过完整视觉验证。
本次审查只评价这个展示改动的现有入口和数据语义,不要求完成作者后续信息架构路线图,也不把缺少本地浏览器或改动规模本身当成代码缺陷。
改动思路 / Approach
保持现有数据投影、活动组件和结果 reader 的职责边界最合适:布局可以调整层次,完成/未知/空态仍由原事实和 owner 决定,CSS不应成为业务状态分类器。 当前 PR 的可用切片是默认工作区展示重排、短标题、阶段头部、通知入口与对应路由/smoke;不要求它完成未来信息架构,也不以未来提案免除当前语义回归。
/ 和 /design/local-dashboard 共用 DashboardRouteContent、searchSchema 和 DashboardPage,所以设计路由不隔离默认行为。原 status/digest/activity/result owner 提供事实,React/CSS负责呈现。判断完成、未知或空态的依据不能在布局层丢失。
| 合法输入 | 新判断产生的错误结果 | 应保留的依据 |
|---|---|---|
| 非空成果目录使用 button | 无 li,隐藏整个成果 layout | 结果 owner 的真实空态 |
| monitor poll / classification 缺值 | 不含错误词,计为完成 | 明确结果类型与完成事实 |
| attention 空但总量/覆盖未知 | 显示没有等你决定的事 | 完整且已知零才能空态 |
| 普通 Goal 没有 loadState | 不显示 activity 文本 | 原活动状态组件 |
此表是源码对照,不是浏览器执行记录。
具体改动 / Changes
审查包括 Manager 运行条与摘要、看板标题/指标/原因行/滚动布局、Goal 三阶段头部与概览分段、任务/工作/交付证据折叠、通知迁入侧栏及设置/开发入口调整、短标题、临时设计路由、静态 preview、新设计文档和两个 smoke。全部 TSX/数据链、六个非生成 CSS diff、preview HTML 与 smoke 已读。生成 preview CSS 为 486,588 bytes 单行;检查了引用与本地资产边界,未声称逐字人工审读或把 mock 当实际产品验收。新增 smoke 主要覆盖 route、copy、query 往返,未覆盖非空成果 CSS 或普通侧栏状态。
采用改动前已接受的 apps/presentation/dashboard/design.md,修订 5c2ed9f6f2cf8a9bdc952f1c8dfceae92e062b0b。本次映射 visible-claim-lineage、completion-durable-facts、single-sidebar-semantic-state、files-readable 均未满足:可见状态须有事实来源,侧栏须有语义状态及文本/图标表达,成果须能阅读。新增 docs/design/dashboard-design-system.md 是提案,不能反向授权回归。
关键代码讲解
goal-loopx-mode.css:146–147从 DOM 标签推断空态;静态 import 使规则进入默认页面和多个结果 owner。DashboardPage:2969–2977 -> RunBand:60–82新增 recentRuns 投影并统计完成,已越过纯样式调整。GoalOverview:56–61/109读取 typed digest,却在列表空时忽略 unknown/coverage 的含义。GoalSidebar:110新 gate 删除普通GoalRowActivity;加载状态不能代替活动状态。GoalVitals:169改为计划/执行/验收与原导航回调,goalShortLabel:10做局部标题缩短;这些路径已读,整页与窄屏表现仍未验证。
对主干的风险 / Risks
P2-1,goal-loopx-mode.css:146–147:非空成果被隐藏。 Team/Managed/Research 的 nav[data-result-catalog] 直接映射 ResultCatalogRow,后者在 result-catalog.tsx:13 返回 button,没有 li。新增 :not(:has([data-result-catalog] li)) 因此在有成果时也成立,隐藏整个目录和 reader;后续 display:grid 特异性更低,不能覆盖。Explore 复用 layout 且无该 catalog 标记,也受影响。实际 Files 入口在 PersonalWorkspacePage:392–399。请优先依据 owner 显式空态,只压缩确实空的部分;若使用 data-result-key,还须保留 Explore 的不同 DOM 和当前页为空但仍有 next 的情况,不能简单全局替换;覆盖非空、空、loading/error,以及 desktop/narrow 目录选择、阅读与返回。此项是 markup/CSS 的确定性推导,未做本地浏览器实跑。
P2-2,dashboard-page.tsx:2973:非错误分类被算作完成。 runRecordSchema 的 classification 是可空自由字符串;真实 quota/monitor_poll.py 将 quota_monitor_poll 记录写入 recent_runs(第584–587行)。监控观察和缺值都不匹配错误词 regex,因而进入 completed;RunBand 又用 recent.length - failed 显示“完成”。请复用 typed outcome/完成事实,保留 unknown/observation,不要扩充错误词表。回归应从实际 status 消费端覆盖 monitor、缺值、明确完成和失败。
P2-3,goal-overview.tsx:109:未知待决事项被写成无待办。 attention 空、totalAttention 为 null 时,showAttention 为 false;上游 goal_workspace_digest.ts:195–219 确实允许 unavailable、null counts 与 unknown coverage,partial 也不能证明完整零。新增肯定空文案会误导用户无需介入;旁边“查看”按钮不修正主声明。请只在 availability 正常、coverage 完整且总数已知为零时显示空态,其他分支明确未知/部分和恢复入口,并分别覆盖上述状态。
P2-4,goal-sidebar.tsx:110:正常 Goal 失去侧栏状态文字。 普通 loaded Goal 没有 loadState,新条件移除 running/quiet/claimed 的 GoalRowActivity。身份标记是 aria-hidden;GoalActivityHelp 在缺少 hostThreadActivity、Goal 已停止,或存在 loadState 时返回 null,不能替代普通活动文本。实际 CI job 124053833801 的 goal-activity.mjs:120 等待 Progress Projection 行“执行中”15秒超时,与这次改动吻合。请恢复原 activity owner 的无条件显示,保留加载和补充说明;不要删断言。修复后重跑 LOOPX_PERSONAL_WORKSPACE_SCENARIO=goal-activity node examples/personal-workspace-browser-smoke.mjs,并覆盖其他正常状态。
语义与 CI 对齐
四项都触及现有状态来源、侧栏或成果阅读合同,不需要新增后端协议/权限。局部修复应复用原 typed digest/activity/result 词汇,保留现有 smoke。git diff --check PASS;上述实际 CI 活动断言 FAIL;本地 UI、同 fixture 的 base/head 浏览器对照和整页/default/expanded/narrow 视觉 UNVERIFIED。
独立核验了 CI bundle 的35个资产摘要、673个源码输入;24个 PR 改动输入全部匹配审查 head。manifest 源是 CI merge f38b5595c53ce30fe7c8fd002c379ada5dfe90f1(此 head 合入 main 0ad08b15dd7331051c93566075561a390a9cd7e2),其余20处差异全部等于该 main。因此可绑定受影响代码,不能称为整个未合并 head 的完整产物,更不能据此证明视觉通过。同 run 可读取 artifacts 无截图/trace;本地前端依赖/浏览器条件不齐,未渲染真实整页。
我的整体评价 / Verdict
REQUEST_CHANGES,固定 head e626fbbd575c39df8f6e4426517ab3a12852a266。 长程跟踪的可见信息与用户体验均为 regression;没有证据表明后端成果被删除或持久结算权威改变。阶段性布局调整是合理范围,但当前成果/状态回归不能延后处理。
路由复用和局部标题 helper 合理,修复无需新框架或兼容层。整体样式收益与体量是否相称仍缺完整视觉证据;改动规模本身不是 finding。本 PR 没有 opt-in/default-off 承诺,临时路由也不隔离默认页面。重新审查需要修正四项具体分支、保留既有断言、补正常/异常及成果阅读回归,并提供整页、默认、展开、窄屏证据。未完成视觉不是新增审美猜测,也没有声称完整 UI suite 或合并资格已通过。
未在本地浏览器渲染真实整页、默认/展开或窄屏状态;本地前端依赖/浏览器条件不齐。已核验的 CI bundle 不是截图,当前可读取的同 run artifacts 没有截图或 trace。 Manager、看板、Goal 默认/展开、成果阅读、侧栏通知、窄屏和键盘/焦点的完整视觉验收未完成;不把静态 board-preview 或 bundle 哈希当作渲染通过。
English verdict: REQUEST_CHANGES — e626fbb; four P2 regressions hide nonempty results, misreport completion and empty attention, and remove normal sidebar activity. Full browser parity and visual qualification remain unverified.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. 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 HEADFor a same-repository clone whose Keep the DCO |
- one-line Goal rows with short labels; full title moves to tooltip/drawer - collapse the six-cell vitals strip into a Plan → Run → Accept stage bar - wire status run history into a home run band (28 most recent runs) - single-row task toolbar with one filter control; inline empty lanes - desktop notifications become a sidebar bell instead of a settings block - quiet the capability nav, inline scope hints, drop stray help icons - dedupe the Delivery & evidence title; clamp drawer goal titles Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Shape was ad hoc (7 radii in one screen). Introduce --pw-r-control/item/ card/pill and a 4-24px spacing scale, then replace 9/10/11/13/14/99px literals with them. Settings now renders two radii instead of six. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
- attention moves into the document column so the Goal page reads 01→04 - home tiles become flex-wrap so a tall tile stops stretching its row - home spacing uses the token scale Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Empty research history and empty report sections become one-row statements instead of bordered panels. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
break-all split npm command names mid-token; the diff table now gives Axis a fixed width so the remaining columns stop stacking one word per line. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
A four-column table in a half-width panel stacked one word per line. Each axis is now a card: title, then Current / Proposed / Gate. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
The right rail held nothing but the inventory, so it cost a full column for one collapsed row. The inventory is now a full-width disclosure after the Now section; the Goal page is a single 1120px column. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
The leading status glyph stole a column from every card, so titles wrapped around it. Cards now match the design: two-line title, then a status pill and age. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Radius and shadow already matched; padding, gutters and card type now follow the same numbers as the design board. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Tokens, shape, spacing, type, status colour, component rules and the stage/run-band flow, so the next screen starts from the same numbers. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Two browser contracts depended on what the density pass removed: lanes must stretch so each owns a bounded scroll region, and a Goal card still carries its reason sentence. The reason is now one clamped line. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
e626fbb to
b3456e1
Compare
Rebased onto
|
… row The density pass gated the sidebar activity line behind `goal.loadState`, so a normal running, queued or claimed Goal showed no state word at all; the only remaining glyph is aria-hidden, so the fact disappeared from the page (review P2-4). Every loaded Goal renders its activity again, as one visible state word plus the window badge, with the owner's full sentence kept on `title` and `aria-label` so the host is never hover-only and never guessed. When the row is tight the gap badge yields before the word: the copy slot no longer shrinks and the badge truncates. The home Goal card lost its second row when the reason line came back: five tracks for six children put `.personal-home-goal-time` into an implicit row of its own, which also broke the state/time geometry the confirmation contract measures. The mark now spans both rows, the reason spans 2..-1, and the meta slot names the bound host instead of a raw agent id. The dead footer and activity-chip rules, and the unused `GoalActivityChip`, are removed. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Collapsing the six-cell vitals strip into the Plan -> Run -> Accept bar dropped
成本 and Agent 用时 with it. On desktop they became unreachable: the only
drawer trigger is hidden above 720px, so a Goal's spend and agent time had no
entry point at all.
The bar's meta row now ends with one clickable usage group, after a hairline:
`成本 $4.12 · Agent 用时 3.2h` in caption size, values at 500 weight with
tabular numerals, both 24h/7d windows in the button's title. It opens the
existing usage detail through the same `onFocusRegion("usage")` callback the
strip used, so no new surface is introduced. Unmeasured usage stays visible as
未采集 rather than a zero, and the group takes its own line below 640px so the
bar never wraps into the content area.
The strip's remaining CSS (35 rules: cells, values, sub-lines, ribbon, dots,
live arc) is deleted; only the first-read skeleton keeps `.goal-vital*`. The
state sentence (`Turn 收尾中`, activity-unknown, the host alsoKey) and the last
activity's actor, which the strip printed under its values, now live on the two
spans' titles so the facts survive the denser layout.
Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
… unknown attention Three regressions the review found in the density pass (P2-1..P2-3), each fixed at the owner instead of by guessing from markup or words: - Empty result sections were inferred with `:not(:has([data-result-catalog] li))`, but every catalog row renders a `<button>`, so the rule also fired when results existed and hid the whole catalog and reader. The three result owners now mark `data-result-empty` only when their own read is final and empty; a page that still has a next cursor keeps its catalog and controls, and Explore keeps its different DOM. - RunBand subtracted failures from the slice length to print 完成, so monitor polls and runs with a null classification read as completed. Completion and failure now come only from the closed vocabularies the writers already validate: `ProgressResultClass` and `DeliveryOutcome`, decoded additively in `data/status.ts` and toned by the shipped `deliveryOutcomeTone`. Everything else stays 观察 or 状态未知; the free classification string never decides. - The attention region printed "没有等你决定的事" whenever its list was empty, although the digest allows unavailable availability, null counts and partial coverage. The affirmative claim now needs availability ok, complete coverage and a known zero; every other branch says the region cannot confirm and keeps the task entry. New copy is in both languages (`overview.attentionUnknown`, `runs.observation`, `runs.recent`). Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
The redesign moved facts the workspace scenarios still read from the deleted six-cell strip and brief tiles. Every assertion is migrated to the surface that now owns the fact, not dropped: - state, work count and last activity -> `.goal-stagebar-meta` spans; the state sentence and the last activity's actor -> their titles; - cost and Agent time -> the `.goal-stagebar-usage` group, including both windows from its title, and the drawer's 未采集 for unmeasured usage (the old cells were non-interactive, so that contract is now a real readback); - needs-you counts, oldest age and optional count -> `.goal-overview-attention`; needs-you is asserted as the attention tone with danger explicitly absent; - running/claimed brief tiles -> the home lanes they moved to (`goal-activity` is now self-consistent: every removed-tile lookup asserts absence); - home card geometry kept and strengthened: state and time share the first row and the reason sits below it. `research-mode`'s vacuous `.goal-vitals` negatives now assert the testid and class are absent; the loading skeleton keeps `.goal-vital*`. Verified locally: goal-masthead, goal-showcase, goal-suggestions, goal-suggestions-live, since-you-looked, since-you-looked-live, navigation-sorting, research-mode, runtime-readiness, confirmed-operations and goal-activity all pass against the source dev server. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
The composition guide still required "at most six stats in one row" while the Goal page renders a one-line stage bar, so the document and the product disagreed about the same region. The paragraph now describes the shipped bar: the stage track, the Goal's own facts as captions in reading order, and the cost / Agent-time pair that opens the usage detail. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
|
回应上一轮 review 的四项 P2,全部落在 owner 上修,没有靠 DOM 形状或词表推断;head 现在是 P2-1 非空成果被藏 — 删掉 P2-2 完成态靠词表推断 — P2-3 unknown 被写成"没有等你决定的事" — 肯定式空态现在要求 availability=ok、coverage=complete 且总数已知为零;unavailable / partial / null 计数一律显示"无法确认",并保留任务入口。迁移后的场景里 P2-4 普通 Goal 丢侧栏状态 — 去掉 另外两项来自设计稿的修正:
验收侧:11 个场景 63 处旧引用全部迁到新 owner(state/work/last → |
The density pass moved the source-failure reason into a `<details>` next to the diagnostics, so the banner only said that the source could not be read while the actual cause (`home.health.sourceUnreadableDetail`) stayed behind a 诊断信息 disclosure. A consequential failure has to stay visible: the issues list is the banner's own row again and only the deeper diagnostics fold. The settings page also kept the removed notification block's props and its support-copy map, and the workspace page still passed both; the bell is the only notification surface now, so these leftovers and their call-site arguments are deleted. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
Two failures that only surfaced once the earlier shard failures cleared:
- `goal-activity` matched the sessions read with `**/api/chat/sessions?*`. A
glob's `?` does not require a query string to be present for the match, but it
does require one character after `sessions`, so the 503 fixture was not applied
when the read carried no query and the row kept a host-owned sentence. The
route now matches the path with or without a query, which makes the
"unreadable session state" branch deterministic.
- `attention-notifications` and `attention-notifications-live` drove a settings
checkbox that the density pass replaced with the sidebar bell, so they waited
on a testid that no longer exists. Both now read the bell the way a person
does — accessible name `桌面通知`, `aria-pressed`, `is-{off|on|blocked}`, the
state sentence in `title`, the dot, and disabled for a blocking browser — and
keep every permission-request count, stored preference, notification count,
partial-read and silence assertion. The granted/denied/unsupported sentence the
old block printed has no surface any more; the bell's disabled state is what is
asserted instead.
Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
…ings block The user guide still pointed at a screenshot of 设置 → 外观 → 桌面通知 and told people to switch notifications there. The control is the sidebar bell now, and the permission sentence moved into its title/disabled state, so section 7.1 says that instead. The superseded settings screenshot had no other consumer and is removed with it. Signed-off-by: xiaoan17 <xiaoan17@users.noreply.github.com>
What this changes
A presentation pass over the local dashboard. Most of this PR is about the board (看板) and the Goal workspace surface — layout, density, and what the run flow shows. No backend or data-model changes.
Status: intermediate. This is a first step, not the final information architecture. The layout, the stage bar and the run band will keep changing in follow-ups; treat it as a baseline to iterate on.
Asking for design review
Please judge the details, not just the direction:
goalShortLabel()cuts long objectives at the first separator. Does the result stay recognisable?The rules behind these choices are written down in
docs/design/dashboard-design-system.md,added by this PR so the next screen starts from the same numbers.
Density
goalShortLabel()keeps long objectives out of lists; the full title stays in the tooltip and the drawerFlow visibility
Plan → Run → Acceptstage bar (43px), current stage filled, others hollow01 → 02 → 03 → 04status.json run_history.recent_runs → WorkspaceModel.recentRuns → homeNoise removal
Also
Verification
tsc --noEmit,build:desktop,smoke:home-route,smoke:workspace-locale, design-route smoke — pass locallynode scripts/check-css-custom-properties.mjs dashboard— 3809 references, no undefined propertiesdashboard-browser,chat-bundle-browser,windows-powershellandchecks.conversation-activityalso fails locally on an unmodified baseline, so at least part of this predates the branch;the remaining failures need the job logs to separate from the baseline.
Not included
/design/local-dashboardis a temporary design entry and should be removed or redirected before mergeshort_namebelongs in the registryFollow-ups
Review follow-up (head
6a936eaae)Addresses the four P2 findings on the previous head, and finishes the
acceptance migration the density pass left behind.
P2-1 — non-empty results were hidden
:not(:has([data-result-catalog] li))never matched the catalog (every row is a<button>), so the empty treatment applied to populated Team/Research/Managedsections and hid the reader. Emptiness is now declared by the section that owns
the read —
goal-team-results.tsx,goal-research-results.tsx,goal-managed-results.tsxsetdata-result-emptyonly when the page is finaland empty. A page with a next cursor keeps its catalog and controls; Explore's
different DOM is untouched.
P2-2 — completion was inferred from a word list
RunBandprintedrecent.length - failedas 完成, soquota_monitor_pollrecords and runs with a null
classificationread as completed. Completion andfailure now come only from the closed vocabularies the writers already validate:
ProgressResultClass(advanced/blocked, and the neutralunchanged/exploration_exhausted/no_followup) andDeliveryOutcomethrough the shipped
deliveryOutcomeTone. Both are decoded additively indata/status.ts. Everything unproven renders 观察 or 状态未知 — a monitor poll isno longer 完成, and the free
classificationstring never decides.P2-3 — unknown attention was stated as "nothing waiting"
The region claimed 没有等你决定的事 whenever the list was empty. The affirmative
claim now requires availability
okand coveragecompleteand a knownzero; unavailable, partial or null counts say the region cannot confirm and keep
the task entry. Covered by the migrated scenarios (
mode === "empty"now assertsthe unknown copy).
P2-4 — a normal Goal lost its sidebar state word
GoalRowActivitywas gated behindgoal.loadState, so a loaded running / queued/ claimed Goal rendered no state at all (the mark is
aria-hidden). Activity isunconditional again. The row keeps one visible state word plus the gap badge
(the density goal), and the owner's full sentence stays on the same
<small>astitleandaria-label, so the fact is not hover-only. When the line istight the badge yields before the word. Assertions were moved, not deleted:
goal-activity.mjsstill asserts the leading word (执行中/已安排/宿主已领取) and additionally reads the full sentence from the accessible name.While fixing this, the one-line layout was found to squeeze the state word to
nothing when a window badge was present (
执行中→ 1px, screenshotgoal-activity-observation-first.png); the copy slot no longer shrinks.Design follow-ups from the approved boards
成本 $4.12 · Agent 用时 3.2h,one clickable group after a hairline, both windows in its
title). The densitypass dropped them and, because the only drawer trigger is hidden above 720px,
they became unreachable on desktop. Unmeasured stays
未采集, never$0.00;the group takes its own line below 640px. This resolves the open doc/code
divergence:
docs/development/design.mdnow describes the stage bar instead of"at most six stats in one row".
e626fbbd5re-added the reasonline, the card had five grid tracks for six children, so
.personal-home-goal-timefell into an implicit second row — which is also what the confirmation geometry
contract measures. The mark spans both rows, the reason spans
2..-1, the metaslot names the bound host (not a raw agent id), and the dead footer/activity-chip
rules and the unused
GoalActivityChipare removed..goal-vital*. The state sentence and the last activity's actor, which the stripprinted beneath its values, now live on the bar spans' titles.
Acceptance migration (11 scenarios, 63 old references)
.goal-stagebar-metaspans (state / wait / work / last activity)title.goal-stagebar-usagegroup and itstitle;未采集read back from the drawer.goal-overview-attention(count, row<time>, header<small>)personal-home-lane-running/-claimed)research-mode's two.goal-vitalsnegatives were vacuous (the class is gone) andnow assert the testid/class is absent;
goal-activity.mjsis self-consistent(every removed-tile lookup asserts absence).
Verification
tsc --noEmit(dashboard, tsc 6.0.3): pass.check-css-custom-properties.mjs dashboard: no undefined references.goal-masthead,goal-showcase,goal-suggestions,goal-suggestions-live,since-you-looked,since-you-looked-live,navigation-sorting,research-mode,runtime-readiness,confirmed-operations,goal-activity.output/playwright/personal-workspace/; no binaries are committed, perdocs/development/documentation-layout.mdretention rules.LOOPX_PERSONAL_WORKSPACE_PACKAGED=1) craftsmoke and the full packaged build; CI owns those.