---
name: unidesk-webdev
description: UniDesk Web 开发与受控浏览器验证技能。用户提到 Web、网页、前端、浏览器、Playwright、网页登录、登录复测、页面打不开、白屏、控制台错误、截图、移动端、响应式布局、视觉验收、Web smoke、Web E2E、fake-server、web-probe、线上页面复测、Workbench、Performance 页或前端状态投影时使用；所有浏览器操作统一经 web-probe，禁止直接调用 Playwright、playwright-cli 或临时浏览器脚本。
---

# UniDesk WebDev

本技能是 UniDesk/HWLAB Web 开发和受控浏览器复测的唯一入口，并遵循 Skill(cli-spec)。需求真相源仍是 `project-management/PJ2026-01/specs/`；本技能只规定如何开发、采集、复现和验收。

- 当任务使用 `$unidesk-devlevel` 描述开发方式时：
  - L1 首选使用 `native-readiness` 从 owning YAML 固定 HTTPS origin 验证 native Web；
  - HTTPS 因 public-edge、TLS、DNS 或出网故障不可用时，必须改用 owning YAML 解析出的固定公网 HTTP IP:port 继续受控浏览器验收；
  - `127.0.0.1`、`localhost`、随机 IP、随机 port 和临时 URL 只能用于本机进程 probe，不能作为 L1 浏览器入口或用户反馈 URL；
  - 执行 L1 时发现历史实例没有 owning YAML 固定 HTTPS exposure，必须发现一例就登记、受控部署并验收一例，通过后再继续当前任务；
  - L2 使用 development semantic origin；
  - L3 使用 production semantic origin；
  - 本 skill 负责各运行面的浏览器操作，不解释项目处于哪个等级。
  - 页面问题优先在可复现的最低等级快速修复，再按 L1、L2、L3 中实际受影响的运行面逐级回归。

## 快速规则

- Web、网页、前端、浏览器、网页登录、截图、移动端、响应式、视觉、smoke、E2E、fake-server、Workbench、Performance 和前端状态投影任务必须先用本技能。
- 页面白屏或应用 bootstrap 失败时，必须立即按以下顺序诊断：
  - 先通过 `web-probe` 采集当前页面的 `pageerror`、`console.error` 和失败网络请求；
  - 再依据首个根因错误检查 runtime config、入口脚本、依赖加载和 API 响应；
  - 根因未分层前，禁止先改 CSS、DOM 或依据截图猜测问题；
  - 修复后重新确认 console 无错误，再进行 DOM、交互和截图验收。
- 所有浏览器操作必须通过 `bun scripts/cli.ts web-probe ...` 受控入口执行：
  - 禁止直接调用 `playwright`、`@playwright/cli`、`playwright-cli`、浏览器 MCP 或仓库外临时浏览器脚本；
  - `web-probe` 内部可以使用浏览器引擎，但认证、目标解析、截图、脱敏、artifact 和报告必须由 `web-probe` 合同统一管理；
  - 缺少所需动作时，先在 owning YAML 和 `web-probe` typed command 中补齐通用能力，不得绕过为第二操作面。
- L1 Workbench 长程 observer 使用 `web-probe observe start --origin native`：
  - 固定 HTTPS 入口只从 owning YAML 的 `nativeDevelopment.workbench.publicExposure.publicBaseUrl` 解析；
  - 禁止使用部署态 `public` origin、自定义 URL 或 localhost 冒充 L1 observer；
  - 后续 command、status、collect、analyze 和 stop 继承启动时冻结的 native origin。
- Web-probe 正式 CLI 入口是 `bun scripts/cli.ts web-probe ...`；旧 `hwlab nodes web-probe` 已移除，只能按 CLI 提示迁移，不要在 issue 或长期文档中继续记录旧入口。
- `web-probe observe stop` 是 observer 生命周期清理入口：
  - 不得依赖业务页面 readiness 才执行停止；
  - graceful command 失败、超时、未消费或缺少有效结果时，默认自动进入 force-stop；
  - 输出中的 `cleanup.state=confirmed` 才证明进程已停止，`cleanup.state=unknown` 表示远端传输或清理证据仍不完整。
- 涉及 Web 哨兵、`web-probe sentinel`、`monitor.pikapython.com`、定期/周期巡检或新建巡检时，必须同时加载 `$unidesk-monitor`。
- 真实用户入口验证优先；源码检查、构建通过或截图局部正常不能替代原入口验收。
- Web/Workbench 内部校验不得压过核心业务：
  - transport 已连接、用户输入可解释且目标/session scope 明确时，capabilities、delivery semantics、schema、contract version、commit 或 authority metadata 漂移只记录结构化 warning，并固定 `blocking=false`；
  - warning 必须可由诊断、OTel 或受控 artifact 下钻，但不得禁用输入控件、阻止提交、清空业务选择、覆盖成功结果或切换数据 authority；
  - 只有认证/权限失败、真实 transport 不可用、目标/session scope 无法唯一确定、业务必需输入缺失或继续执行会造成损害时才允许阻断；
  - Provider catalog 成功且当前选择明确不可用时可自动选择 configured profile；catalog 失败或没有 configured profile 时保留当前值并允许提交，不得把 catalog 可见性变成新门禁；
  - 验收必须同时证明 warning 可见和核心动作可完成，禁止通过隐藏 warning、伪造 capability、放宽 session scope 或增加 fallback 获得通过。
- 共享 `public-edge` 出现不同任务反复覆盖同一 Caddy desired state 时：
  - HTTPS 入口仍可用则直接继续用户交付，不因 fingerprint warning 阻塞业务；
  - HTTPS 入口不可用时，必须临时交付 owning 配置声明的固定公网 HTTP IP:port，并继续当前 L1 业务验收；不得等待公共面 issue 回复或恢复；
  - 临时 HTTP 入口必须保持业务认证，不得改用随机端口、关闭认证或新增第二 Caddy/FRP；
  - 立即登记公共入口故障，记录覆盖来源缺失、current/desired 漂移和受影响站点；
  - 业务任务停止重复 `public-edge apply`，不得通过循环重放与其他开发任务争夺共享控制；
  - 公共入口故障只作为非阻塞支线跟踪；固定 HTTP readiness 和原业务路径通过后，立即返回业务主线；
  - 公共入口主责收口后，再从 owning YAML 的正式 HTTPS origin 复测并撤回临时入口。
- WebProbe 因内存、浏览器资源或受控启动策略阻断时：
  - 只把浏览器证据标记为 blocked，不得把整个开发、诊断或验收任务一并停止；
  - 先记录策略引用、实际指标、阈值、blocker code 和允许的恢复入口；
  - 需要止压时加载 `$unidesk-gc`，只执行其 scoped plan/run/status/memory 流程；
  - scoped 恢复后仍不满足启动条件时停止重复 GC 和浏览器重试，继续执行不需要浏览器的验证；
  - 优先使用仓库正式 CLI 访问同一已部署 Web/Cloud API dispatcher，完成 CLI E2E 或真实运行面短查询；
  - 随后执行与改动直接相关的 CLI 测试、单元测试和轻量语法检查；
  - 除非用户明确要求，不新增或运行合同测试；
  - 每层证据必须标明 `browser=blocked`、实际覆盖范围和未覆盖的视觉/DOM/交互边界；
  - 用户目标只要求 CLI/API/CaseRun 终态时，同 dispatcher 的 CLI E2E 可以完成该目标，但不得冒充浏览器或视觉验收。
- 调试 HWLAB Cloud Web/Workbench 业务或功能 bug 时，使用 YAML 声明的 `--origin internal`；验收 public exposure、DNS、FRP、Caddy 或公网用户入口时，显式使用 `--origin public`。
- `web-probe screenshot` 的 semantic origin 示例：`bun scripts/cli.ts web-probe screenshot --node <node> --lane <lane> --origin internal --path /workbench --viewport 1440x900`。
- `web-probe screenshot` 的 custom/local 示例仅用于本机 preflight，不得作为 L1 交付或用户入口证据：
  - custom：`bun scripts/cli.ts web-probe screenshot --node <node> --lane <lane> --url 'https://custom.example/workbench' --viewport 1440x900`；
  - local：`bun scripts/cli.ts web-probe screenshot --node <node> --lane <lane> --url 'http://127.0.0.1:4173/workbench' --viewport 1440x900`；
  - `--url` 已包含完整路径，与 `--path` 互斥；参数错误时按 CLI 返回的 `correctionCommands` 移除 `--path`。
- `--url` 只是 custom/local 一次性逃生口，与 `--origin` 互斥；禁止通过手写 URL 或 IP 选择内网/公网运行面。本地 fake-server、localhost、dist 静态服务和 custom URL 只能作为开发 preflight 证据。
- 禁止在本地或 master server 直接跑 `vue-tsc` / 前端全量 typecheck 作为默认验证；本地只做语法级检查和真实入口复测，完整类型检查交给 CI、PipelineRun 或明确指定的受控构建运行面。
- HWLAB Cloud Web 的 Vitest 防误用规则：
  - 以 HWLAB `docs/reference/web-test-resource-guard.md` 为权威；
  - 配置必须默认关闭 watch、固定单 worker、限制 worker V8 堆；
  - 测试、hook 和 teardown 必须设置有界 timeout；
  - 正式 `test` 入口必须使用 `vitest run`、限制父进程 V8 堆并设置整体执行时限；
  - Master server 只允许解析配置和检查 diff，不运行测试；
  - Vitest 配置不能替代系统 cgroup `MemoryMax`。
- 桌面版 Web 截图、视觉复测和 web-probe 采样默认使用 `1920x1080` 视口；只有用户、issue 或 SPEC 明确指定其他尺寸时才覆盖，并在证据中写明覆盖原因。
- Web probe 命令和历史判定口径见 [references/web-probe.md](references/web-probe.md)；受控 fake-server 和浏览器 smoke 见 [references/browser-smoke.md](references/browser-smoke.md)。
- 前端改动遵循仓库既有设计系统、[references/design.md](references/design.md) 和 `$frontend-design` 全局 UI 规则；不要做营销式落地页替代真实工具页面。

## Native 敏捷开发闭环

- Web 功能默认先进入 native 快速迭代阶段：
  - 后端按微服务边界直接在 native 启动，并只连接任务需要的真实基础设施；
  - 前端以仓库正式开发入口独立启动，并启用 HMR 热更新；
  - 前后端进程、端口、日志和停止方式必须彼此独立，禁止把本地调试绑定到 Kubernetes rollout；
  - 能直接复用 dispatcher、RESTful 函数或 fake-server 的场景，不得要求先发布 API Pod 才能调试前端。
- HWLAB 单微服务 L1 前端保持产品级壳层：
  - 复用正式 `App.vue`、`AppShell`、顶栏、左侧根导航、Router 和设计系统；
  - 不得把页面降级成脱离 HWLAB 总框架的 standalone 组件预览；
  - 通过 native auth/access profile 只授权当前调试微服务的 `navId`；
  - 左侧根导航必须存在，但只能显示当前微服务的一个页面入口；
  - 只代理当前微服务 API 路径，禁止为了渲染产品壳层启动其他 HWLAB 后端；
  - 当前微服务前端、API 和 Worker 使用 YAML-first 固定端口与独立生命周期；
  - YAML 声明的 L1 端口被占用时：
    - 同一服务的旧 L1 进程只通过项目 CLI 停止或重启；
    - 其他服务不得停止、复用或接管；
    - 先用有界监听状态确认一个空闲端口；
    - 再修改本 L1 服务的 owning YAML 端口并通过 parser/CLI 读取新值；
    - 禁止用命令行覆盖、临时环境变量或隐藏 fallback 绕过 YAML；
    - 端口退让后继续启动，并从 YAML 新端口执行 `web-probe native-readiness`；
    - HWLAB 的唯一权威细则见 `docs/reference/hwlab.md#workbench-浏览器回归专项`；
  - L1 进程的启动、停止、重启、状态和日志必须通过项目 CLI，禁止把裸 `npm run`、`bun run`、`vite` 或临时脚本作为用户入口；
  - Vite 必须绑定可访问的 native 端口并保持 HMR，浏览器端 HMR 地址不得写成 `0.0.0.0`。
- HWLAB 工具页面默认使用受限工作区：
  - AppShell 和页面根容器不得产生 document 级或主内容区全局滚动；
  - 页面头必须是紧凑命令栏，状态摘要作为其底栏，二者不得挤占主体工作区；
  - 列表、时间线、日志、证据面板和正文分别在所属 pane 内滚动；
  - 移动端允许工作区内部纵向滚动，但不得把滚动责任退回 document 或 AppShell；
  - 页头高度预算、状态底栏和主体占比的默认判定见 [references/design.md](references/design.md)；
  - 历史页面按风险逐步迁移，新页面和重设计页面必须直接采用该合同。
- L1 公网调试入口交给用户前必须完成浏览器 readiness 验收：
  - L1 服务的验收后保留与任务结束公网 URL 报告统一遵循 `$unidesk-devlevel`，本 skill 不重复定义生命周期；
  - HTTPS 可用时使用 `bun scripts/cli.ts web-probe native-readiness --node <node> --lane <lane> --profile <profile>` 一次完成验收；
  - HTTPS 不可用时使用项目 repo-owned typed command 选择 owning YAML 的固定公网 HTTP 降级入口；缺少该选择能力时先补 typed command，禁止用 `--url`、环境变量或临时脚本绕过；
  - 当前入口、path、DOM、交互和失败判据只从 owning YAML 读取，禁止用命令行覆盖；
  - 监听成功、端口可达、HTTP 200、API smoke 或源码测试通过都不能单独判定 L1 可用；
  - 必须通过 `web-probe` 从用户当前将使用的固定 HTTPS 或公网 HTTP 入口打开页面，确认首屏挂载、稳定 DOM 和至少一个基础交互可完成；
  - 必须确认没有阻塞 bootstrap 的 `pageerror`、`console.error`、关键失败请求或持续主线程卡顿；
  - `web-probe` 导航、DOM 读取、交互或截图超时，以及浏览器出现“页面无响应”，都直接判定 L1 未通过；
  - L1 未通过时禁止向用户披露入口为“可用”，必须继续定位并修复，或明确报告 browser readiness blocker。
- Workbench L1 业务验收采用 CLI 交互、截图观察的两层证据：
  - 先用项目正式 CLI 的 `--over-api` 调用同一 Cloud API dispatcher，完成 session 创建、turn 提交和产品 SSE 终态对账，并记录 sessionId 与 traceId；
  - 再用 `web-probe screenshot` 从 owning YAML 选择的固定公网入口打开该 session 深链，观察用户可见的消息、终态和语义化错误；
  - 不把 WebProbe 的硬编码 DOM selector、长等待、临时 Playwright 脚本或探针自身超时作为 Workbench 业务终态的唯一门禁；探针异常时保留其作为工具证据，并以 CLI 终态和截图继续归因；
  - CLI 必须走同一产品 dispatcher 和身份语义，禁止以 direct manager、snapshot、result polling 或其他第二业务路径替代。
  - 一次性截图默认按 `domcontentloaded` 导航，持续 SSE 页面不得改用 `networkidle`；完整边界见 [references/web-probe.md](references/web-probe.md)。
  - 流式 Conversation/Trace 贴底问题按 `docs/reference/hwlab.md#workbench-浏览器回归专项` 执行：
    - 先用 L0 证明内容增长不误关 following；
    - 再用真实长回复或 retention 回放做 L1；
    - API readiness 若被 Kafka session index 维护阻塞，停止前端与浏览器重试并转独立架构 issue。
- Native 阶段采用短反馈循环：
  - 修改后先执行最小语法检查和目标功能验证；
  - 使用 `web-probe` 从 YAML 选择的固定 HTTPS 或公网 HTTP 入口验证真实 DOM、交互、布局和截图；custom/local 仅记录为 preflight，不能宣称 L1 通过；
  - 每轮优先复用仍在运行的 HMR 前端和测试后端，不重复构建镜像或触发 CI/CD；
  - 复杂数据、长文本、空态、错误态、折叠、滚动、缩放和目标桌面/移动视口必须在 native 阶段覆盖。
- 只有 native 功能与视觉验收收口后，才进入 CI/CD 发布阶段：
  - 将定稿源码和 owning YAML 通过正式分支、PaC、Tekton、GitOps 与 Argo 自动交付；
  - 禁止用反复 CI/CD 滚动替代本地开发反馈循环；
  - 发布后仍须从选定的 internal/public 原入口执行一次部署态复测；
  - Native 证据属于开发 preflight，不能替代部署 revision、运行面健康和公网入口验收。
- 本模式的效率判定必须基于可见事实：
  - 记录 native 迭代次数、HMR 生效耗时和实际触发的 CI/CD 次数；
  - 对照全量流水线与 rollout 耗时，报告节省的等待时间和构建资源；
  - 未采集基线时只能说明减少了流水线触发，禁止虚构具体提速比例或成本数字。

## web-probe 证据规则

- 用户要求“离线调查”时，web-probe 只读取已有 observer/sentinel artifact、`observe collect` 和 `observe analyze` 报告；不得新开 `run/script/observe` 或触发新的 dashboard 验证。若 collect/analyze 难以定位 run、trace、sample、root-cause signal 或输出不可界定，先改进 analyzer/CLI 证据面，再继续业务结论。
- 用户要求“用 web-probe 做 smoke”时，`web-probe` 是取证工具，smoke 目标以用户/issue 指定的业务入口为准；例如目标是 Workbench 时，必须用 `web-probe run` 或 `web-probe observe start` + `observe command --type sendPrompt` 验证 Workbench 页面、会话、消息终态和 `observe analyze` 结果，不能改成只验证 web-probe 工具自身。只有用户明确说“验证 web-probe 自身/基础设施”时，才把 screenshot/script/observe 作为工具自检 smoke。
- HWLAB Web 业务/功能改动可先在已部署的 node/lane 上用 `--origin internal` 完成快速复测；涉及 public exposure 或公网用户入口的 closeout 再用 `--origin public` 独立验收。两者均必须由 owning YAML 解析，不得用临时 URL/IP 切换运行面。
- web-probe 发现 Workbench 请求风暴、浏览器卡死、内存上涨、submit/command 失败或投影缺失时，修复目标默认是 Workbench runtime/projection/read model 或业务代码；不得为了通过 smoke 去降低 Playwright/Chromium 能力、减少采样、自动刷新页面、关闭 freeze/memory 检测或把 blocker 降级。探针侧只能补证据、root cause 可见性和 YAML policy 接入。
- 交互式线上验收优先使用 `web-probe observe start`、`observe command`、`observe collect` 和 `observe analyze`；`web-probe script` 只作为一次性探测逃生口。重复出现的高频动作（折叠侧栏、关闭报告、切换全屏、导出低码率截图、采集布局指标）必须沉淀为 observe command 或 analyzer 能力。
- 截图取证必须优先配合页面的 RESTful 深链：截图命令应直接打开能恢复目标 source/file/task/report/session/run 和聚焦区域的 URL，再等待稳定 DOM 合约后截图。若目标页面缺少必要深链能力，不要先用脆弱点击/滚动流程硬截；应先增强前端深链与刷新恢复能力，再把截图能力接回 web-probe/observe/sentinel 命令。
- Issue closeout 引用 observer id、command id、stateDir/report SHA、screenshot SHA 和关键字段摘要；不要粘贴截图二进制、完整 JSON、Secret、cookie 或无界日志。
- 取证 drill-down 先用 `observe collect` / `observe analyze` 的 bounded view；需要截图路径、SHA、traceId 或 command detail 时优先查 `control.jsonl`、analysis 摘要或专用 artifact view，避免直接 `rg samples.jsonl`，因为页面快照是超长单行 JSON，容易触发输出截断和噪声。
- Workbench 三态/卡死离线调查优先用 `observe collect <id> --view workbench-triad --trace-id <trc_...>`，它把 DOM turn/message/trace rows、Final Response、Workbench REST terminal evidence、browser freeze blocker 和 analyzer findings 聚合到一个有界视图；只有需要样本细节时再用 `--finding` 或 `trace-frame` 下钻。
- `observe collect <id> --view turn-summary --command-id <cmd_...>` 必须按 commandId 精确返回单轮；不存在时保持结构化 `not-found`，禁止回退全量轮次。输出中 observer control 完成、turn submission 与异步 turn terminal 是三个独立证据字段，control completed 不等于业务 turn terminal。
- exact command-id 的 `turn-summary` 默认文本同时输出完整 `commandId`、`traceId` 和 `sessionId`；后续 `trace-frame`、`workbench-triad` 与 OTel 下钻直接复用这些 identity，不再检索大型 report artifact。
- `workbench-triad` 的本地 `network.jsonl` 没有匹配响应时，结论必须写作 `artifact evidence missing`，并明确这不能证明业务 API 未发生；将 control artifact 中的 OTel trace reference 作为独立证据引用，再走 `$unidesk-otel` 受控诊断核验完整业务链路。
- `web-probe script` 结果首行固定返回 `UNIDESK_WEB_PROBE_COMMAND_PROMOTION_HINT <json>`，同时在结构化结果首字段返回 `commandPromotionHint`；一次性脚本在重复前必须沉淀为 repo-owned typed command。内置 generated command（例如 `web-probe opencode-smoke`）会明确返回可直接复用且不附加临时脚本 warning，禁止复制其生成脚本另起一次性入口。
- Cloud Console 全路由、多视口和通用产品交互收口：
  - 使用 `web-probe console-verify --node <node> --lane <lane> --origin internal|public --profile <profile>`；
  - 路由、视口、selector、工作流、等待和证据上限只从 owning YAML profile 读取；
  - 默认摘要直接返回有界 `pageErrors`、`consoleErrors`、`requestFailures` 和 `responseErrors`，白屏或 workflow 失败先看各数组首项，不再为首错重复启动浏览器；
  - semantic internal origin 必须披露实际 namespace、Service、ClusterIP、port 和 scheme；production profile 必须由 production owning YAML 明确选择 production namespace，禁止继承后静默落到 development lane；
  - 长任务生成的受控 JSON 与截图都由 remote artifact runner 下载；输出的绝对或相对 artifact 路径必须能直接交给 `web-probe artifact inspect`，禁止生成会被自身路径门禁拒绝的 NEXT；
  - TaskTree profile 先从全局 TaskGroup 进入 group deep link，再选择真实 task；详情验收接受 dialog 或 docked panel，并只在 dialog 模式发送 Escape；
  - 不再复制临时脚本；
  - 只用于已部署页面的人工 closeout；
  - 不进入 CI/CD gate；
  - 不替代 Workbench Kafka、Trace 或性能专项命令。
- 产品级 RESTful 深链选择、保存与重载持久化 smoke：
  - 使用 `web-probe product-smoke --product <product> --target <target> --profile <profile> --edition <edition-id> --algorithm <algorithm-id>`；
  - 默认 `--json` 只返回有界判定摘要、认证请求到达状态、失败类型、报告/截图哈希和受控下钻命令；只有一次性需要完整投影时显式使用 `--full` 或 `--raw`；
  - 首次登录导航在 `status=0`、无请求/响应和零步骤时出现浏览器关闭或 `ERR_INSUFFICIENT_RESOURCES`，必须分类为 `browser-runtime-blocker`，不得误报密码或目标认证失败；
  - 失败输出中的报告或截图使用 `web-probe artifact inspect --node <node> --lane <lane> --path <artifact-path> --sha256 sha256:<digest>` 受控下钻；禁止调用者猜测 runner workspace 或直接读取完整报告；
  - 产品 target、semantic origin、认证 sourceRef、登录合同、selector、保存请求、视口和证据上限只从产品 owning YAML 读取；
  - 认证合同可声明 API session、同页表单或 BrowserContext Basic Auth，产品命令不得自行读取或拼接认证 header；
  - 结果只保留有界 DOM/网络摘要、report SHA、screenshot SHA、presence 与 fingerprint，禁止输出账号、密码或 cookie；
  - disabled target 必须拒绝执行，不得用 CLI URL 或凭据参数绕过。
- ApiState 多页面只读 smoke：
  - 使用 `web-probe product-smoke --product apistate --target <target> --profile <profile>`；
  - `<target>` 使用 Sub2Rank owning YAML 的运行目标，例如 `defaults.targetId`，不得使用产品 `metadata.id`；
  - 公网 URL、runner、登录字段、Cookie、Secret target key、页面路径、selector、视口和证据上限只从 Sub2Rank owning YAML 读取；
  - 同一次命令必须完成账号评分、用户用量和额度抽奖页面的 DOM、网络与截图验收；
  - smoke 不点击评分刷新或抽奖，不允许除登录外的写请求。
- 沉淀后的 typed command 必须复用 observer start 时选中的 semantic origin；不得在 command 内嵌 URL/IP，也不得为 internal/public 各复制一份 command。
- Workbench 性能卡顿调查优先用 `observe command --type performanceCapture` + `observe analyze` + `observe collect --view performance-summary`；`performance-summary` 必须保持首屏 bounded，只输出 LongTask/LoAF/event-loop gap 摘要、CPU profile hotspots/stacks 和 sourceFiles，下钻完整 profile/report 时再显式读取 artifact。
- 遗留 Project Management/MDTODO closeout 必须区分 `control` 页和被动 `observer` 页；恢复相关任务前按 `$unidesk-tasktree` 迁移。显式 `observe command` 的 command result、control URL 和对应截图是用户动作证据；observer 周期刷新或 stop 后根路由空态只能作为对照信号，不能覆盖 command result。
- 遗留 MDTODO → Workbench launch 只用于迁移前兼容验收；必须引用 `launchWorkbenchFromMdtodo` 的 command result，不能作为新任务管理入口。
- Workbench provider profile 验收使用 `observe command --type sendPrompt --provider <profile>` 时，command result 必须显示 `requestedProvider`、`providerSelection.selected`、`/v1/agent/chat` 202、traceId 和最终 `turn-summary`；只有 prompt 成功不够，必须确认浏览器控件实际选中目标 profile。
- Workbench Kafka 实时 fanout 的重复验收：
  - 使用 `observe command --type validateRealtimeFanout --profile <yaml-profile> --provider <provider> --text <first> --second-text <second>`；
  - connected、refresh/reconnect 和 capability 期望来自 owning YAML，可独立组合，禁止在命令中硬编码 live-only 或 refresh mode；
  - 浏览器验收前先对同一已有 session 执行 `workbench events inspect --over-api`：
    - `kafkaRefreshReplay=true` 时，connected 必须为 `kafka-retention-then-live`、`replay=true`、`liveOnly=false`；
    - capability 已启用但 connected 仍为 `live-only` 时，直接检查 L1 native SSE 路由是否复用生产 retention handoff；
    - 上述情况不得先重复扫描 Kafka、修改 reducer，或增加 snapshot 仲裁；
  - 每轮只把 `user`、`assistant` 和 `terminal` 对应的 AgentRun/HWLAB 事件族作为必需核心事件；
  - `tool_call`/`command_output` 与 HWLAB `tool`/`status` 是条件事件对，仅在实际出现时校验数量和 lineage；
  - 直接答复不得为了通过探针而合成工具事件，超时证据必须披露已经观测和仍然缺失的事件族；
  - refresh 启用时必须证明 retention 到 live handoff、正式 `user` event、`hwlab.event.v1` 同 envelope，以及主页面单一 EventSource 和同一 UI reducer 终态；
  - session 切换或重连期间的 replay 可见性以 `docs/reference/hwlab.md#纯-kafka-页面刷新与实时交接合同` 为唯一权威：
    - connected 前允许后台追赶，但页面必须保留切走前的稳定投影，不得显示历史前缀导致最近更新时间倒退；
    - handoff 完成后只把待处理 frame 交给原 reducer 一次发布，失败或 scope 替换时丢弃未完成事务；
    - L1 验收分为两个现有 typed command：
      - 先用 `validateExistingSessionRefresh` 证明单 EventSource、retention→live 和禁止恢复请求；
      - 再对真实运行中 session 用 `switchAwayAndBack --session-id <id>` 验证用户操作路径；
    - 在统一 typed command 尚未提供切换期间的时间标签采样前，L0 可见性测试是“不回退”的主证据，L1 两条 typed command 只补真实入口和 transport 合同，禁止把最终截图冒充过程证据；
  - 已有 session 的 rail、turn card、Final Response 或回放提示不一致时：
    - 先执行一次 `workbench events inspect --over-api` 证明服务端 connected、核心事件族和 terminal；
    - 服务端完整后只执行一次 `validateExistingSessionRefresh` 核对 DOM identity、live handoff 与 forbidden request；
    - 若刷新后消息渐进恢复但分钟级不收敛，先按 `docs/reference/hwlab.md#workbench-浏览器回归专项` 检查后台标签页调度，不重复扫描 Kafka 或增加恢复路径；
  - 禁止用“陈旧快照不得覆盖 sealed final”一类优先级或封口 guard 处理刷新：
    - 该模型仍保留多个业务写入路径及竞争仲裁；
    - 必须删除 HTTP snapshot、submit response、result fallback 等业务状态写入；
    - retention replay 与 live frame 只进入同一 SSE ingress 和同一 reducer；
  - observer 后台维持两个独立 product subscriber 和三条 debug SSE；
  - 命令提交后按 `status <observer> --command-id <command>` 轮询，不得回退为长连接 `web-probe script`。
- Workbench 隔离 Kafka debug 重放使用 `observe command --type validateWorkbenchKafkaDebugReplay`：
  - 复用 observer 当前 session 和 semantic origin；
  - 按 owning YAML 校验 topic、独立 group prefix、请求静默窗口和产品/调试 SSE 路径；
  - 新 UI 优先报告 server/client 分层计数、typed phase/code、source-authority Trace 行和原始 HWLAB Event 有界计数；
  - 切换原始事件标签不得新建第二条产品 EventSource；
  - 旧 UI 缺少新 DOM 合同时保持明确的 `legacy-ui` 兼容证据。
- `observe analyze` 的 archive/history findings 可能包含旧样本或旧规则误判；关闭用户入口问题前同时核对最新 sample 字段、DOM 几何和截图。若 top-level findings、latest sample 和 archive red 冲突，说明冲突并补工具反馈 issue，不要只凭 archive red 或单张截图下结论。
- Workbench 产品 Trace 可读性验收使用 `observe command --type validateWorkbenchTraceReadability`：
  - 开关、运行卡片等待、展开、轮询和 DOM 稳定窗口全部来自独立 owning YAML；
  - 只在 `#conversation-list` 内定位当前产品 `WorkbenchMessageCard`；
  - 明确排除隔离 Kafka debug panel，禁止把隔离卡片行计入产品 Trace；
  - 必须先命中新运行卡片并按合法 traceId 固定定位，禁止回退旧终态卡片；
  - 在命令点击展开前记录 `openBefore` 与默认运行中可读性；
  - 命令可展开卡片补充诊断，但不得把强制展开后的可读性冒充默认通过；
  - 非窗口化 Trace 用行身份重叠验证保留；窗口化 Trace 用 event count 与 source sequence 边界前进验证；
  - 同一命令等待终态并输出 report SHA 与 screenshot SHA，失败时仍保留已采集阶段证据。

## 高频工作流

1. 先确认目标：repo、分支/lane、node、semantic origin（internal/public）、预期页面或 workflow。
2. 读取对应 SPEC 或 issue，明确验收口径；Workbench 和 Performance 页不要只凭局部 DOM 判断。
3. 独立启动 native 测试后端与 HMR 前端，记录端口、日志和停止入口。
4. 只用 `bun scripts/cli.ts web-probe ...` 受控入口完成 native 复现与迭代；白屏先查 console 和失败 network，再查 DOM 与截图；需要的新浏览器动作先补为 typed command。
5. Native 功能和视觉验收收口后，再通过正式 CI/CD 自动交付。
6. L1 先从固定 HTTPS 入口验收；HTTPS 故障时立即切到 YAML 固定公网 HTTP IP:port 完成同等浏览器验收并继续，HTTP 200 或进程监听不能替代页面响应性、DOM 和交互证据。
7. 用同一业务入口完成部署态复测；需要关闭用户反馈/issue 时，记录真实入口证据、截图/trace/session 和失败或通过结论。

## 常用入口

```bash
bun scripts/cli.ts web-probe --help
bun scripts/cli.ts check --syntax-only
```

HWLAB Web probe、fixture 采集脱敏、Workbench/Performance 判定、Web E2E 和线上复测见 [references/web-probe.md](references/web-probe.md)；受控 fake-server 和浏览器 smoke 见 [references/browser-smoke.md](references/browser-smoke.md)。

## 何时读取 reference

- 需要 HWLAB Web probe 采集、observe/analyze、sentinel 或线上截图时，读 [references/web-probe.md](references/web-probe.md)。
- 需要 fake-server、浏览器 smoke 或用户提到 Playwright 时，读 [references/browser-smoke.md](references/browser-smoke.md)，并继续只使用 `web-probe`。
- 需要做 UniDesk/HWLAB 页面布局、Workbench/Project Management 设计或视觉验收时，读 [references/design.md](references/design.md)。
- 需要 Workbench/Performance 页判定口径时，读 [references/web-probe.md](references/web-probe.md)，不要凭经验补规则。
