51 KiB
PJ2026-01060508 Web哨兵
修改历史
| 版本 | 对应 commit id | 更新日期 | 变更说明 |
|---|
当前正文仍在规格治理草稿中;未定稿前不新增版本号,不为单次编辑追加 待提交 版本。
正文
PJ2026-01060508 Web哨兵需求规格
1. 文档控制
| 字段 | 内容 |
|---|---|
| 编号 | PJ2026-01060508 |
| 短名 | Web哨兵 |
| 层级 | L3 子课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-25-p0-web-probe-sentinel |
| Dashboard 实现引用版本 | draft-2026-06-26-p8-web-probe-sentinel-recovery |
| 多实例实现引用版本 | draft-2026-06-26-p9-multi-web-probe-sentinel |
| 需求规格模板 | ISO/IEC/IEEE 29148 需求规格模板 |
| 上级规格 | PJ2026-010605 运维监控 |
| 关联规格 | PJ2026-010401 Web工作台、PJ2026-0104010803 Workbench唯一投影、PJ2026-010403 API契约、PJ2026-010601 发布流水、PJ2026-010602 源码同步、PJ2026-010603 YAML运维、PJ2026-010604 公开入口、PJ2026-01060505 Workbench性能 |
| 规格治理索引 | 规格治理 |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 Web 哨兵的稳定使命、范围、术语、系统边界、内部分工、目标图和原子需求。Web 哨兵是现有 web-probe observe 能力的生产化运行形态,不是新的探针实现。
2. 目的和范围
2.1 目的
Web哨兵负责把已经用于 HWLAB Cloud Web 原入口验收的顶层 web-probe observe start/status/command/collect/analyze 能力服务化为 YAML-first 生产哨兵,使平台能够持续观察 HWLAB Web public origin、Workbench 多轮任务、Trace/final/timing 投影和发布后恢复状态。
本规格的目标状态是:人工 CLI、常驻调度器、dashboard、maintenance API、CI/CD targetValidation 和后续 dry-run 都消费同一套 observe runner、control queue、artifact JSONL、collect 渲染和 observe analyze 报告。哨兵服务只负责编排、索引、展示和发布联动;它不得复制第二套 Playwright runner、DOM sampler、offline analyzer、finding classifier、Workbench 状态机或业务事实源。
Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin、runtime namespace、image、PVC、ServiceAccount、Service、NetworkPolicy、scenario、cadence、prompt source、report view、retention、maintenance token、dashboard public exposure、CI/CD control-plane 和 Secret sourceRef 都必须来自 owning YAML 或 configRef。代码只解析引用、校验形状/类型/冲突并渲染受控计划;不得把 namespace、cadence、threshold、Secret、image、URL、profile 或 report view 写成隐藏默认。
2.2 范围内
web-probe observeCLI 的 wrapper/adapter 边界,使常驻服务能够稳定调用 start/status/command/collect/analyze。- YAML
observability.webProbe.sentinel.enabled/configRefs的 legacy 单实例入口,以及observability.webProbe.sentinels[]多实例 registry 与每个 sentinel 管理 YAML 的引用图。 - 常驻 TypeScript 单 Pod wrapper 服务、scheduler、scenario runner、PVC/SQLite index、health、metrics、maintenance API 和 dashboard。
sentinel plan|apply|status|validate|report|maintenance与sentinel image|control-plane等受控 CLI 入口。- 发布流水 maintenance start/stop、quick verify、targetValidation、GitOps/Argo/git-mirror closeout 和 public exposure 验证。
- Dashboard 信息架构、规范化 API、前端组件分层、自动刷新、筛选、深链和 trace/turn 两层阅读视图。
workbench-dsflash-go-tool-call-10x生产 canary 和 24 小时 dry-run 收口。workbench-auth-session-switch-2users账号切换链路哨兵,覆盖账号 A/B 登录、登出、session 列表和 session 切换命令链。- Secret、prompt、provider payload、artifact 和 dashboard 的脱敏边界。
2.3 范围外
- Workbench 会话、message/part、Trace 顺序、final response、steer/cancel 和 timing authority 的业务正确性仍由 PJ2026-0104010803 Workbench唯一投影 定义。
- AgentRun run/command/provider profile 的执行生命周期归 PJ2026-0102 Agent编排 和 PJ2026-010205 HWLAB接入。
- API path、错误 envelope、route policy 和用户身份语义归 PJ2026-010403 API契约。
- 第一阶段不交付分布式压测;loadtest 只保留同镜像、同 wrapper 的配置和命令扩展点。
- in-cluster 哨兵不是外部公网监控节点。若后续需要真正外网用户路径监控,应另行定义外部或边缘哨兵,不把当前服务伪装成外部观测点。
- 多实例 Web 哨兵不得用一个 Pod、一个 PVC 或一个 SQLite index 伪装隔离。共享 dashboard domain 可以按 route prefix 暴露,但 runtime Deployment、Service、PVC、SQLite、GitOps path、Argo Application、metrics label 和 report index 必须按 sentinel id 独立。
- SQLite index、dashboard、metrics 和 maintenance 状态不得替代
samples.jsonl、control.jsonl、network/artifact JSONL 或analysis/report.json成为探针事实源。 - Dashboard 不负责修复 Workbench projection、trace timing、runner/envreuse 或 git mirror 慢路径;它只把 observe/analyze 已采集事实组织成可读的值守和分析入口。
3. 术语表
| 术语 | 定义 |
|---|---|
| Web哨兵 | 常驻 wrapper/orchestrator,按 YAML 调度现有 web-probe observe CLI,对 HWLAB Web public origin 做持续 canary、分析、展示和发布联动。 |
| sentinel registry | node/lane root YAML 下的 observability.webProbe.sentinels[],只声明 sentinel id、enabled 和管理 configRef。 |
| sentinel 管理 YAML | registry 项指向的 owning YAML,声明单个 sentinel 的 id、enabled、mode 和 runtime/workflow/promptSet/reportViews/publicExposure/cicd/secrets configRefs。 |
| sentinel id | 多实例哨兵的稳定小写标识,必须进入 CLI --sentinel、Kubernetes/GitOps label、metrics label、report index 和 dashboard route。 |
| 账号切换哨兵 | workbench-auth-session-switch-2users,使用两组 YAML Secret sourceRef 驱动登录、登出、session 列表和 session 切换链路。 |
| observe runner | 现有 web-probe observe start 启动的浏览器采样器;它写入 DOM、network、control、screenshot、artifact 等 JSONL。 |
| observe artifact | web-probe observe 产生的 stateDir、JSONL、截图、analysis/report.md 和 analysis/report.json,是哨兵报告的事实来源。 |
| CLI wrapper adapter | 服务与 CLI 共享的命令适配层,把 start/status/command/collect/analyze 表达为稳定调用,不复制 runner/analyzer 实现。 |
| sentinel run | 哨兵调度一次 scenario 产生的运行窗口,绑定 node/lane、scenario id、observer id、stateDir、report SHA、finding 摘要和维护窗口状态。 |
| scenario | YAML 声明的巡检或 quick verify 任务,包括 targetPath、cadence、sample interval、rounds、backend profile、promptSetRef、reportViewRef 和 analyze 阈值引用。 |
| configRef | 形如 path/to/file.yaml#object.path 的配置引用。root YAML 只保存启用状态和引用,具体值归 owning YAML。 |
| owning YAML | 拥有某类事实生命周期的 YAML 文件,例如 runtime、scenario、promptSet、reportView、publicExposure、CI/CD 或 Secret 分发。 |
| report view | YAML 声明的 summary、turn-summary、findings、trace-frame 和 raw artifact 读取策略,包括默认分页、最大分页和 redaction。 |
| synthetic prompt set | YAML 管理的合成 prompt 集。报告默认只展示 prompt id、hash、字节数和轮次编号,不展示原文。 |
| maintenance window | 发布或维护期间的哨兵状态:继续采样和记录,但暂停告警;结束时触发 quick verify 和 analyze。 |
| quick verify | 由 maintenance stop 或 CI/CD targetValidation 触发的一次短巡检,底层仍使用 web-probe observe CLI 和 observe analyze。 |
| SQLite index | PVC 上的轻量索引,只保存 run、scenario、finding、report hash、artifact 摘要和 dashboard 分页信息;它不是业务或探针事实源。 |
| dashboard workbench | 面向平台值守和问题分析的 Web 哨兵监控工作台,按 overview、runs、findings、run detail、trace-frame 等视图组织同一 report/index 数据。 |
| trace-frame viewer | Dashboard 内的第二层 trace 阅读视图,只从已有采样帧和 report view 渲染单帧文字版 trace,不另存截图或另造 analyzer。 |
| auto refresh | Dashboard 的受控刷新能力;刷新只读 API/report/index,不发送 control command、不启动采样、不制造第二事实源。 |
| public exposure | YAML 声明的 monitor.pikapython.com HTTPS 暴露,通过共享 PK01 Caddy + FRP managed-block helper 到达 ClusterIP Service。 |
| targetValidation | 发布流水中的目标验证结果;对 HWLAB Web 恢复的判定必须来自 observe/analyze 对 public origin 的观察,不得只看 Argo green。 |
4. 系统边界和接口
| 边界项 | 内容 |
|---|---|
| 外部使用者 | 平台值守人员、发布操作人员、Workbench owner、CI/CD targetValidation、问题调查 agent。 |
| 外部输入 | YAML configRefs、Secret sourceRef presence、HWLAB Web public origin、scenario cadence、maintenance 操作、observe artifacts、analyze reports、GitOps/Argo 状态。 |
| 受控资源 | Web哨兵 Deployment、Service、PVC、ServiceAccount、NetworkPolicy、ConfigMap、publicExposure、SQLite index、dashboard 和 Prometheus metrics。 |
| 外部输出 | sentinel status、health、metrics、dashboard overview、run history、finding analysis、run detail、report summary、turn-summary、trace-frame、maintenance 状态和 targetValidation 结果。 |
| 用户接口 | bun scripts/cli.ts web-probe sentinel ...、https://monitor.pikapython.com dashboard、CI/CD maintenance 调用和受控 GitOps/control-plane CLI。 |
| 系统边界 | Web哨兵只生产运行监控和发布恢复证据;不定义业务成功,不写第二套 Workbench 状态,不直接修复 Web,不读取或打印 Secret/prompt/provider payload。 |
5. 内部分工与规格索引
| 编号 | 内部模块 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
|---|---|---|---|---|---|
| PJ2026-0106050801 | Wrapper边界 | 本规格 6.1 | 只 wrap 现有 observe CLI,禁止第二 runner/analyzer | web-probe observe、Workbench唯一投影 | 服务化入口、人工排障 |
| PJ2026-0106050802 | YAML配置 | 本规格 6.2 | configRefs、owning YAML、parser 校验和 redacted plan | YAML运维、公开入口、Secret分发 | plan/status、部署渲染 |
| PJ2026-0106050803 | 常驻服务 | 本规格 6.3 | scheduler、scenario runner、PVC/SQLite、health、metrics、maintenance API | Wrapper边界、YAML配置 | dashboard、CI/CD |
| PJ2026-0106050804 | 报告视图 | 本规格 6.4 | CLI/report API 渐进读取、分页、redaction、trace-frame | observe collect/analyze、Workbench唯一投影 | issue evidence、dashboard |
| PJ2026-0106050805 | 发布集成 | 本规格 6.5 | CI/CD、GitOps、Argo、maintenance、targetValidation、publicExposure | 发布流水、源码同步、公开入口 | 发布恢复判定 |
| PJ2026-0106050806 | Canary验收 | 本规格 6.6 | dsflash-go 十轮工具调用、24 小时 dry-run 和 profile 结构化失败边界 | Agent编排、Workbench、web-probe | 生产巡检收口 |
| PJ2026-0106050807 | 安全隔离 | 本规格 6.7 | Secret/prompt/provider redaction、NetworkPolicy、public dashboard auth | 用户管理、平台运维 | 安全 closeout |
| PJ2026-0106050808 | 代码引用 | 本规格 6.8 | SPEC 头部标注和生成/配置追溯 | 规格治理 | 后续 PR 审计 |
| PJ2026-0106050809 | Dashboard工作台 | 本规格 6.9 | overview、runs、findings、run detail、trace-frame viewer、前端分层 | 报告视图、常驻服务、Workbench性能 | 平台值守和问题分析 |
| PJ2026-0106050810 | 多实例与账号切换 | 本规格 6.10 | sentinel registry、实例隔离、账号切换 command、route prefix 和 report label | YAML配置、Wrapper边界、安全隔离 | 多哨兵巡检、账号链路值守 |
5.1 目标架构图
flowchart LR
subgraph Config[UniDesk YAML source of truth]
Lane[hwlab-node-lanes.yaml<br/>sentinels registry]
Mgmt[sentinel management YAML]
Runtime[runtime owning YAML]
Scenario[scenario owning YAML]
Prompts[synthetic prompt YAML]
Report[report view YAML]
Exposure[publicExposure YAML]
Secrets[Secret sourceRef YAML]
Lane --> Mgmt
Mgmt --> Runtime
Mgmt --> Scenario
Mgmt --> Prompts
Mgmt --> Report
Mgmt --> Exposure
Mgmt --> Secrets
end
subgraph Sentinel[Web哨兵 Pod]
Scheduler[Scheduler]
Adapter[observe CLI wrapper adapter]
Index[(SQLite index on PVC)]
API[/api overview status runs report views maintenance]
Metrics[/metrics]
Dash[Dashboard workbench]
Scheduler --> Adapter
Scheduler --> Index
API --> Index
Dash --> API
Metrics --> Index
end
subgraph Observe[Existing web-probe observe]
Runner[observe runner]
Control[control queue]
Art[(samples/control/network/artifacts JSONL)]
Analyze[observe analyze]
Runner --> Art
Control --> Runner
Art --> Analyze
end
subgraph Target[Observed system]
Web[HWLAB Web public origin]
API2[HWLAB Cloud API]
AR[AgentRun backend profile dsflash-go]
Web --> API2
API2 --> AR
end
Scenario --> Scheduler
Adapter --> Runner
Adapter --> Control
Analyze --> Index
Runner --> Web
Dash -. HTTPS .-> Exposure
5.2 配置引用图
flowchart TD
Root[config/hwlab-node-lanes.yaml<br/>lanes.v03.targets.D601.observability.webProbe.sentinels[]] --> Entry[id/enabled/configRef]
Entry --> Mgmt[sentinel management YAML#sentinel]
Mgmt --> Refs[configRefs]
Refs --> Runtime[runtime.d601-v03.yaml#sentinel.runtime]
Refs --> Scenarios[scenarios.workbench.yaml#sentinel.scenarios]
Refs --> PromptSets[prompt-set.dsflash-go.yaml#sentinel.promptSet]
Refs --> ReportViews[report-views.yaml#sentinel.reportViews]
Refs --> PublicExposure[public-exposure.d601-v03.yaml#sentinel.publicExposure]
Refs --> Cicd[cicd.d601-v03.yaml#sentinel.cicd]
Refs --> SecretRefs[secrets.d601-v03.yaml#sentinel.secrets]
Scenarios --> PromptSets
Scenarios --> ReportViews
Scenarios --> AnalyzeThresholds[hwlab-node-lanes.yaml#...observe.analysisThresholds]
PublicExposure --> Edge[PK01 Caddy + FRP managed block]
SecretRefs --> Runtime
Cicd --> Runtime
配置引用图必须保持单向:root YAML 只保存 enable 与 ref;具体数值在 owning YAML;parser 只解析、校验和报告,不写合并后的新 source of truth。
5.3 目标数据流图
flowchart TD
Y[YAML configRefs] --> Plan[sentinel plan/status]
Plan --> S[Sentinel scheduler]
S --> OStart[observe start]
S --> OCmd[observe command]
OStart --> Artifacts[Observe artifacts JSONL]
OCmd --> Artifacts
Artifacts --> Collect[observe collect]
Artifacts --> Analyze[observe analyze]
Analyze --> ReportJson[analysis/report.json]
Analyze --> ReportMd[analysis/report.md]
ReportJson --> Index[SQLite index]
ReportMd --> Index
ReportJson --> ViewApi[bounded report view API]
Index --> ReportCli[sentinel report]
Index --> Dashboard[Dashboard]
ViewApi --> Dashboard
Index --> Metrics[Prometheus metrics]
Index --> Validation[targetValidation]
ReportCli、dashboard、metrics 和 targetValidation 只能读取 artifact/report/index 摘要。它们不得重新访问 Workbench、重新采样页面、重排 trace 行、重新分类 finding 或从 SQLite 推导业务事实。
5.4 常规巡检时序图
sequenceDiagram
participant Sch as Sentinel scheduler
participant CLI as observe wrapper adapter
participant Obs as observe runner
participant Web as HWLAB Web public origin
participant Ana as observe analyze
participant Idx as SQLite/PVC index
Sch->>CLI: observe start with YAML scenario
CLI->>Obs: start sampler/stateDir
Obs->>Web: passive sample and screenshots
Sch->>CLI: observe command newSession/selectProvider/sendPrompt
CLI->>Obs: enqueue control command
Obs->>Web: official UI/API action
Sch->>CLI: observe status until terminal/window end
Sch->>Ana: observe analyze stateDir
Ana-->>Idx: report SHA and findings summary
5.5 发布 maintenance 时序图
sequenceDiagram
participant CI as CI/CD Pipeline
participant Sen as Sentinel API
participant CP as Runtime control-plane
participant CLI as observe wrapper
participant Ana as observe analyze
CI->>Sen: maintenance/start release id
Sen-->>CI: sampling continues, alert muted
CI->>CP: rollout / Argo sync
CP-->>CI: runtime healthy summary
CI->>Sen: maintenance/stop
Sen->>CLI: quick verify observe start/command/status
CLI-->>Sen: observer/run/stateDir
Sen->>Ana: analyze quick verify artifact
Ana-->>CI: report SHA, findings, targetValidation status
5.6 哨兵自身 rollout 时序图
sequenceDiagram
participant CP as Sentinel control-plane
participant GitOps as GitOps repo
participant Argo as ArgoCD
participant Pod as Sentinel Pod
participant Val as sentinel validate
CP->>GitOps: publish digest-pinned manifests
Argo->>Pod: sync Deployment/Service/PVC
Val->>Pod: /api/health
Val->>Pod: /metrics
Val->>Pod: dashboard/public exposure probe
Pod-->>Val: scheduler heartbeat and PVC writable
哨兵自身 rollout 只验证哨兵服务健康、配置装载、PVC/SQLite 可写、metrics、dashboard 和调度循环;它不能把另一个哨兵当作 HWLAB Web 业务观察对象,也不能因为 HWLAB 业务 quick verify blocked 就把哨兵自身发布状态标成失败。
5.7 哨兵不可用结构化失败时序图
sequenceDiagram
participant CI as CI/CD targetValidation
participant Sen as Sentinel service
participant Log as Structured closeout evidence
CI->>Sen: validate or maintenance/stop
Sen-->>CI: unavailable or first-install
CI->>Log: missing service/config/health detail
Log-->>CI: failed targetValidation and retry command
哨兵不可用、首次安装未完成或配置未就绪时,CI/CD 必须结构化失败并输出缺失项、恢复建议和可重试命令;不得自动切换到第二执行通道。人工排障仍可显式运行原 web-probe observe CLI,但该人工动作不属于 CI/CD targetValidation 的自动通过路径。
5.8 Dashboard 信息架构图
flowchart TD
UI[Dashboard workbench] --> Overview[Overview<br/>health scheduler maintenance latest run]
UI --> Runs[Runs history<br/>filter sort timeline]
UI --> Findings[Findings analysis<br/>severity code window]
UI --> Detail[Run detail]
Detail --> TurnSummary[Turn summary<br/>multi-turn user message and final summary]
Detail --> TraceFrame[Trace-frame viewer<br/>single turn/sample text snapshot]
Detail --> Evidence[Evidence<br/>report SHA observer stateDir CLI command]
Overview --> Runs
Findings --> Runs
Runs --> Detail
Dashboard 首屏必须先呈现当前值守判断,再允许 drill-down。用户打开 monitor.pikapython.com 后应能在首屏判断哨兵自身是否健康、最近 canary 是否 blocked、blocked 的 red/amber/info 组成和最近一次 report SHA。
5.9 Dashboard API 数据流图
flowchart LR
Index[(SQLite index)] --> OverviewApi[/api/overview]
Index --> RunsApi[/api/runs filters cursor]
Index --> FindingsApi[/api/findings aggregate]
Report[analysis/report.json] --> DetailApi[/api/runs/:id]
Report --> ViewApi[/api/runs/:id/views]
Artifacts[observe artifacts] --> ViewApi
OverviewApi --> Dashboard
RunsApi --> Dashboard
FindingsApi --> Dashboard
DetailApi --> Dashboard
ViewApi --> Dashboard
Dashboard API 只能 reshape 已有 index、report 和 artifact view。筛选、分页、排序和聚合只改变读取方式,不新增采样、analyze、截图保存、Workbench API 读取或 trace 状态仲裁。
5.10 Dashboard trace drill-down 时序图
sequenceDiagram
participant U as User
participant D as Dashboard
participant API as Sentinel API
participant R as report/index/artifact view
participant CLI as sentinel report / observe collect
U->>D: open latest blocked run
D->>API: run detail and turn-summary
API->>R: read bounded report view
R-->>D: turns, findings, report SHA
U->>D: select turn/trace/sample
D->>API: trace-frame view
API->>R: render existing frame text
R-->>D: trace rows and Final Response block
CLI-->>U: same facts available through CLI trace-frame
Trace drill-down 必须保持两层阅读:第一层是多 turn 摘要,第二层是选中 turn/trace/sample 后的文字版 trace-frame。Final Response 在第二层固定成块展示;空内容显示 (空内容),有内容按 redaction 策略展示摘要、字节数或允许展示的正文。
5.11 P8 quick verify 控制链路图
sequenceDiagram
participant Val as sentinel validate
participant Sen as Sentinel service
participant Obs as observe runner
participant Ctrl as control queue
participant Web as HWLAB Workbench
participant Ana as observe analyze
participant Rep as report/dashboard
Val->>Sen: /api/health through k3s Service DNS
Val->>Obs: observe start
Val->>Ctrl: command newSession
Ctrl->>Web: create Workbench session
Val->>Ctrl: command selectProvider/sendPrompt
Ctrl->>Web: submit business turn
Val->>Ana: observe analyze existing artifact
Ana->>Rep: report SHA, findings, turn-summary, trace-frame
Quick verify 的通过条件必须覆盖控制命令、业务 turn 和 analyze/report 三段。monitor.pikapython.com root/CSS/JS 200 只证明公开 dashboard 外壳可读,不得抵消 newSession、sendPrompt、trace rows 或 final response 缺失。
5.12 P8 故障分类数据流图
flowchart LR
Validate[sentinel validate] --> Shell[service/public dashboard health]
Validate --> Control[observe command health]
Validate --> Business[business turn health]
Validate --> Runtime[runtime/browser health]
Shell --> Result[validation result]
Control --> Result
Business --> Result
Runtime --> Result
Control --> NoTurn[quick-verify-no-business-turn]
Business --> Trace[turn-summary and trace-frame]
Runtime --> Timeout[timeout/readiness/session/api subtype]
分类必须先按 service/public-dashboard、control command、business turn、runtime/browser 分仓,再给可行动下一步。browser-timeout 不得默认归为浏览器安装或 Playwright 环境问题;它至少要被解释为页面导航、auth/login、Workbench readiness、session create、message submit、trace projection 或浏览器环境中的一个可复核子类。
5.13 P8 中文运维视图时序图
sequenceDiagram
participant U as 用户
participant D as 中文运维页面
participant API as dashboard API
participant CLI as CLI drill-down
U->>D: 打开 monitor.pikapython.com
D->>API: overview, runs, findings
API-->>D: 服务健康、公开入口、最近业务验证、阻塞分类
U->>D: 选择 blocked run/finding
D-->>U: 中文解释、证据、CLI 对照命令、下一步动作
U->>CLI: sentinel report / observe collect
CLI-->>U: 同一 run/observer/report SHA 的文字 trace 证据
中文运维页面必须默认展示中文状态、中文说明和中文下一步,同时保留原始 run id、observer id、finding code、report SHA 和 CLI 命令,便于 issue/PR 证据对照。
6. 原子需求
6.1 OPS-SENTINEL-REQ-001 非分叉 wrapper 边界
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-001 | Wrapper边界 | PJ2026-0106050801 Wrapper边界 | Workbench唯一投影、Web工作台 |
Web哨兵必须只编排现有顶层 web-probe observe start/status/command/collect/analyze 命令语义。常驻服务可以把这些 verb 包成稳定 adapter,但底层采样器、control queue、artifact schema、collect 渲染和 offline analyzer 必须与人工 CLI 共享同一实现或同一生成物。
旧 hwlab nodes web-probe 路径不得作为 alias、delegate 或第二执行路径继续运行;它只能 fail-fast 输出迁移说明并指向顶层 web-probe。常驻服务、人工 CLI、CI/CD targetValidation 和后续 YAML 示例都必须指向同一顶层入口。
实现不得新增第二套 Playwright runner、DOM sampler、network sampler、control command 协议、JSONL artifact schema、offline analyzer、finding classifier 或 Workbench 状态机。若服务化需要能力增强,必须先补到现有 web-probe observe 命令面,再由哨兵调用。
人工 CLI 是排障和原入口验收的一等入口;哨兵是调度入口。两者对同一 stateDir、同一 report 和同一 trace-frame 的解释必须一致。
6.2 OPS-SENTINEL-REQ-002 YAML-first 配置引用
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-002 | YAML配置 | PJ2026-0106050802 YAML配置 | YAML运维、公开入口、源码同步 |
Web哨兵 legacy 单实例配置可通过 node/lane root YAML 的 observability.webProbe.sentinel.enabled/configRefs 进入;多实例配置必须通过 observability.webProbe.sentinels[] registry 进入。registry 项只能声明 id、enabled 和 configRef,再由 sentinel 管理 YAML 引用 runtime、workflow/scenario、promptSet、reportView、publicExposure、CI/CD 和 Secret owning YAML。root YAML 不得承载所有 runtime/scenario/report/Secret 数值,也不得生成合并后的超级配置作为第二 source of truth。
parser 只负责解析 path/to/file.yaml#object.path 或规格确认的等价引用,校验文件存在、路径存在、字段形状、类型、枚举键名、必填字段和重复事实冲突。registry id 与 sentinel 管理 YAML 内的 id 必须一致;多实例 registry 下的非 config 操作必须显式选择 --sentinel <id>,避免误操作默认实例。缺失字段应报告 YAML path 和下一步 drill-down;不得用代码默认值补 namespace、image、cadence、timeout、threshold、profile、Secret、public URL、report view 或 retention。
sentinel plan/status 必须输出 redacted 配置引用图:无 --sentinel 且存在多个实例时输出 registry 表和逐实例 drill-down;指定实例时输出该实例每个 ref 的文件、path、presence、摘要 hash、缺失字段、冲突字段和下一步命令。默认输出不得 dump 完整展开 YAML、Secret 值、prompt 原文或 provider payload。
6.3 OPS-SENTINEL-REQ-003 常驻服务和 artifact 索引
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-003 | 常驻服务 | PJ2026-0106050803 常驻服务 | 发布流水、Workbench性能 |
Web哨兵服务应以 TypeScript/Node.js 实现,默认单 Pod 单副本。服务负责 scheduler、scenario runner、PVC/SQLite index、health、metrics、maintenance API 和 dashboard 静态资源;它不得直接写第二套 DOM 采样、网络采样、截图、Workbench 读取逻辑或 finding 分类。
PVC 保存 SQLite index 和原始 .state/web-observe artifact。SQLite 只索引 run、scenario、finding、report hash、artifact 摘要、maintenance 状态和分页游标;它不得替代 JSONL/report 事实源,不参与 Workbench lifecycle、trace 顺序、final response 或业务状态仲裁。
/api/health 必须覆盖 scheduler loop、SQLite/PVC 可写、最近 heartbeat、analyze 可执行性和必要配置装载。SQLite/PVC 不可写、scheduler 停摆、最近 heartbeat 超时或 analyzer 失败时,health 应非健康。/metrics 至少暴露 run 成功率、最近 finding 数、采样延迟、active observer 数和 maintenance 状态。
Pod 重建后应从 PVC 恢复 index 与最近 artifact 摘要;进行中 run 可以标记 interrupted 并重新调度,不能静默假绿。
6.4 OPS-SENTINEL-REQ-004 报告视图和 dashboard
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-004 | 报告视图 | PJ2026-0106050804 报告视图 | Workbench唯一投影、Workbench性能 |
Web哨兵的 sentinel report 和 dashboard 必须按 YAML report views 渐进展示同一 observe/analyze artifact:run overview、turn-summary、findings、trace-frame/sample drill-down 和显式 raw artifact 下载。默认视图不得 dump JSONL,也不得展示 prompt 原文、完整 assistant 正文、cookie、token、API key、provider payload 或完整 stdout/stderr。
sentinel report --latest|--run <runId> --view summary|turn-summary|findings|trace-frame 的默认分页、最大分页、可用 view、redaction 和 raw artifact 开关来自 owning YAML。完整 artifact 读取必须显式 --raw 或 --artifact analysis/report.md|analysis/report.json。
自动 finding 必须能被 CLI trace 视图复核。若 analyzer finding 与 trace-frame 冲突,应以 trace-frame 暴露的有序 turn/message/part/final response 事实作为人工判定基准,并把 analyzer 精度问题登记到工具侧;dashboard 不得用聚合计数覆盖 CLI trace-frame。
Dashboard report API 必须提供 bounded、redacted、可分页的 view contract。/api/overview 提供 health、scheduler、maintenance、latest run、severity counts 和 freshness;/api/runs 提供 scenario/status/severity/time/search 过滤与 cursor 分页;/api/runs/:id 提供 run detail、report refs、artifact refs 和 summary counts;/api/findings 提供 severity/code/scenario/window 聚合;/api/runs/:id/views 提供 summary、turn-summary、findings 和 trace-frame 的只读渲染。所有响应都必须能追溯到 run id、observer id、stateDir 和 report SHA。
P8 起,quick verify 如果没有产生 sendPrompt 业务 turn、有效 session、trace rows 或 final response,必须记录独立 red blocker quick-verify-no-business-turn。该 blocker 属于 quick verify 控制层事实,不得由 dashboard 前端临时推断;dashboard 和 sentinel report --view findings 只能展示已记录的同一 finding。
P8 恢复判定必须把 Workbench 业务失败继续 drill-down 到运行面依赖。当 trace-frame 或 Final Response 暴露 hwlab-cloud-api request handling failed、PostgreSQL 53300、too many clients already 或等价 DB 连接槽耗尽证据时,quick verify 不能收口为前端展示缺陷;必须检查 PK01/PostgreSQL max_connections、各服务连接池、CrashLoop 探针风暴和当前 pg_stat_activity,并通过 YAML source of truth 收敛容量或池化参数。
6.5 OPS-SENTINEL-REQ-005 CI/CD、GitOps 和 maintenance
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-005 | 发布集成 | PJ2026-0106050805 发布集成 | 发布流水、源码同步、公开入口 |
Web哨兵自身必须纳入受控且独立的 sentinel control-plane:source 来自 UniDesk master,镜像、GitOps path、Argo Application、publicExposure 和 targetValidation 由 Web 哨兵 owning YAML 声明。D601/v03 当前可通过 web-probe sentinel image|control-plane 的独立 publish Job 实现构建、推送、GitOps 写回和 Argo 收敛;后续也可以切换到 Tekton Pipeline,但 builder 类型必须来自 YAML,不得依赖 operator 本地 dirty worktree。
哨兵 rollout 与 HWLAB runtime rollout 不是同一个滚动单元。哨兵 dashboard/API/服务代码变更应通过 Web 哨兵独立 control-plane 滚动;HWLAB runtime 发布流水只调用当前已部署哨兵的 maintenance/start、maintenance/stop 和 quick verify 作为恢复判定。哨兵 control-plane 的顶层状态只表达哨兵自身 source、镜像、GitOps、Argo、runtime、metrics 和 dashboard 是否发布成功;HWLAB quick verify 必须作为独立 targetValidation 状态、warning 和 report 证据输出。哨兵 validate、maintenance 和 quick verify 控制路径必须优先走 k3s 内部 Service DNS,不绕 monitor.pikapython.com 公网入口。
哨兵镜像构建应使用 YAML 声明的 tools image、base image、registry、egress proxy 和 env-reuse 配方。Node/Bun/Playwright/Chromium 依赖不得在 runtime Pod 中临时下载。Secret 与 env 复用只走 sourceRef/keyMapping;日志、status、dashboard 和 issue closeout 只输出 object/key/presence/fingerprint/digest。
HWLAB runtime 发布 Pipeline 应在 Argo sync 前调用当前哨兵 maintenance/start,进入观察不告警模式;sync 完成且业务 Deployment Ready 后调用 maintenance/stop,触发同一 observe CLI quick verify 和 analyze。targetValidation 不能只因 Argo Synced/Healthy 通过而绿;还必须包含 quick verify 结果、analysis report SHA、finding 摘要、public origin、scenario id 和 observer/run id。
哨兵服务不可用、首次安装未完成或配置未就绪时,CI/CD 必须结构化失败并输出缺失项、恢复建议和可重试命令;不得自动回退到原纯客户端 CLI、裸 Playwright、私有 API、read-side repair、reload 循环或 session repair 形成第二执行路径。人工排障可以显式运行原 web-probe observe start/status/command/collect/analyze,但不能被 targetValidation 当作自动通过证据。
sentinel validate --quick-verify --confirm --wait、maintenance stop quick verify 和 control-plane targetValidation 的确认等待总耗时超过 120s 时,必须输出 warning,并在 quick verify run 摘要中记录可见警告。计时超限本身只作为非阻塞告警;只有真正影响 Code Agent 多轮业务链路、submit/command 执行、trace/final 可见性或 session 连续性的失败才构成 targetValidation blocker。control-plane publish/build 等非业务等待可通过 YAML 将确认等待预算放宽到 300s;不得通过减少业务轮次、吞掉 submit 失败、fallback 到第二执行路径或读侧 repair 来消除红灯。
6.6 OPS-SENTINEL-REQ-006 dsflash-go 十轮 canary
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-006 | Canary验收 | PJ2026-0106050806 Canary验收 | Agent编排、Web工作台、API契约 |
第一条生产 canary 固定为 workbench-dsflash-go-tool-call-10x。所有运行参数都必须来自 configRefs 解析出的 owning YAML,至少包括 node/lane、public origin、targetPath、cadenceSeconds、sampleIntervalMs、screenshotIntervalMs、maxRunSeconds、maxConcurrentRuns、sessionPolicy、backendProfile、promptSetRef、rounds、requireToolCalls、report view、pagination、analyze thresholds、retention、publicExposure 和 maintenance 策略。
调度器每隔 YAML 声明 cadence 创建新的 HWLAB Workbench session;每个 run 通过同一 web-probe observe start 启动采样,并通过同一 observe command 下发 newSession、provider 选择和十轮 prompt。prompt 原文必须由 prompt sourceRef 管理,报告只展示 prompt id/hash/bytes 和轮次编号。
第一 canary 必须在十轮连续 prompt 中插入 YAML 声明的 sessionInvarianceChecks。固定检查点为第 1 轮后、第 5 轮后和第 10 轮后:第 1/5 轮后执行显式 refreshCurrentSession、switchAwayAndBack 和 assertSessionInvariant control command;第 10 轮后只刷新当前 canary session 并断言最终回读。切换窗口必须进入 control.jsonl,不得由哨兵服务私自驱动第二套 Playwright,也不得靠刷新、切 session 或 result polling 修复 Workbench 投影。
刷新/切换检查只检测同一 canary session 的消息/trace/final 投影顺序。受控切走和切回窗口内的 session-route-changed / active-session-changed 不构成业务异常;切回后仍存在 route/active mismatch、trace 丢失、final 缺失或 command failure 时沿用既有 blocker 规则。若同一 session 可见消息出现多个 user message cards 连续展示,且这些 user cards 之间缺少 assistant/agent/code-agent terminal 或 response card,observe analyze 必须产生 workbench-message-order-user-clustered-after-navigation,severity=amber,blocking=false,并记录 afterRound、canarySessionId、routeSessionId、activeSessionId、连续 user 数量、sentinel marker 范围、sample seq、traceId 列表、pageRole/pageId 和 redacted message order 摘要。
每一轮任务都必须需要工具调用。验收报告要证明十轮在同一 session 内完成,记录每轮 traceId、terminal status、tool-call evidence/count、耗时、慢 API、network/console/requestfailed finding、trace 顺序异常、terminal-not-last、session mismatch 和 final-response flicker。
dsflash-go 是 AgentRun backend profile。实现必须验证 profile-scoped SecretRef、config 和 model-catalog.json presence/fingerprint;缺失时结构化失败,不允许 fallback 到 codex、deepseek、minimax-m3 或其他 profile。
24 小时 dry-run 应在至少一个 HWLAB node/lane 完成,按 YAML cadence 形成不少于一天的 run 序列,并回写 observer/run id、stateDir/PVC 摘要、analysis report SHA、finding 摘要、截图/artifact 计数、Prometheus metrics 和 public dashboard HTTPS 验证。
6.7 OPS-SENTINEL-REQ-007 安全、隔离和公开入口
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-007 | 安全隔离 | PJ2026-0106050807 安全隔离 | 用户管理、公开入口、YAML运维 |
Web哨兵运行 namespace 与业务 runtime namespace 分离,具体 namespace、ServiceAccount、PVC、Service、NetworkPolicy 和 resource request/limit 由 YAML 声明。Service 默认 ClusterIP;不得用 NodePort、LoadBalancer、hostNetwork、hostPort 或手工 Ingress 暴露 dashboard。
monitor.pikapython.com HTTPS 暴露必须走 YAML publicExposure,使用共享 PK01 Caddy + FRP managed-block helper 渲染。实现不得手工编辑 Caddyfile,不得替换其他 UniDesk managed block,不得复制 Caddy/FRP writer。public exposure closeout 必须验证 DNS、TLS、HTTPS、认证/维护 token、edge 和 ClusterIP upstream。
Secret 只通过 sourceRef/targetKey 下发,CLI、服务日志、dashboard 和 issue evidence 只能输出 sourceRef、object、key、presence、fingerprint、hash、字节数和 redacted 摘要。prompt 原文、assistant 长正文、provider payload、cookie、token、API key、完整 DSN 和 stdout/stderr 不进入默认输出或 dashboard。
NetworkPolicy 默认只允许 DNS、YAML 声明 public origin/必要 service endpoint、Prometheus scrape 来源和管理入口。任何扩大 egress/ingress 的变更必须先进入 owning YAML 和 plan 输出。
6.8 OPS-SENTINEL-REQ-008 SPEC-first 与代码引用
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-008 | 代码引用 | PJ2026-0106050808 代码引用 | 规格治理、YAML运维 |
Web哨兵实现必须先引用本规格,再进入代码变更。新增或修改的 CLI、adapter、service、scheduler、metrics、manifest renderer、public exposure helper、CI/CD helper 和 report renderer 源码文件头部必须标注 SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-25-p0-web-probe-sentinel,并用一句话说明文件职责。
P7 dashboard 增强范围内新增或修改的 dashboard API、frontend assets、renderer、format composable、auto refresh、run/detail/finding/trace-frame viewer 源码文件头部必须标注 SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p7-web-probe-sentinel-dashboard,或在既有 Web哨兵源码头部追加该实现引用版本。纯 YAML/config、锁文件、构建产物和无法承载注释头的静态资源可例外,但对应生成器、serving 入口或 manifest renderer 必须能追溯到该版本。
实现文件不得只写 issue 编号、latest、current 或“按最新方案”作为规格引用。自动生成文件、第三方 vendored 文件、纯 YAML/config、锁文件和无法承载注释头的二进制产物不要求加源码头部,但对应生成器、渲染器、owning YAML 或 CLI 入口必须能追溯到本 SPEC。
后续 P1-P6 阶段如果改变稳定需求、观察对象、数据流、接口、部署边界或验收口径,应先更新本规格和上级 PJ2026-010605 运维监控,再更新执行 issue。
6.9 OPS-SENTINEL-REQ-009 Dashboard 值守和分析工作台
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-009 | Dashboard工作台 | PJ2026-0106050809 Dashboard工作台 | Workbench性能、Web工作台 |
Dashboard 必须是值守和分析工作台,而不是 raw JSON 或单列表格。首屏至少呈现 overall status、node/lane/public origin、config readiness、scheduler heartbeat age、maintenance 状态、latest run、120s targetValidation budget、severity counts 和最新 report SHA。超过 120s 的 quick verify 或 canary 仍应保持 warning/red,不得通过调大预算、减少轮数或 fallback 视图变绿。
Runs history 必须支持 scenario、status、severity、时间窗口、maintenance、observer id、run id 和文本搜索;排序至少覆盖 updated time、created time、finding count 和 severity。Run timeline 应稳定展示最近窗口状态,帮助用户判断 blocked 是否连续、同一 finding 是否反复出现。
Findings analysis 必须把 finding 升级为可点击分析对象:按 severity 分组,按 code/scenario/window 聚合,展示 count、最近出现、关联 run 和 latest report SHA。点击 finding 应能过滤 runs 或打开关联 run detail,不能只显示计数。
Run detail 必须展示 summary、findings、turn-summary、trace-frame 入口、artifact/report refs、CLI 对照命令和 valuesRedacted 标记。Trace 阅读必须分两层:多 turn 摘要用于选择 turn,单 turn trace-frame viewer 用于阅读具体采样帧并固定显示 Final Response 区块。
Dashboard 前端架构应借鉴 Sub2API 监控面板的分层方式:typed API client、format composable、auto refresh composable、Overview、Run table、Finding groups、Timeline、Run detail、Trace-frame viewer、loading/empty/error 状态和深链 query。实现不得继续把完整 UI、API shaping、DB 查询、CSS 和 artifact 解析堆进单个服务文件;超过 3000 行或职责混杂的文件必须按职责拆分。
Dashboard 自动刷新只能读取 bounded API,不得发送 observe command、不启动新采样、不重新 analyze、不保存额外截图。页面 hidden、loading 或上一次请求未完成时应暂停或跳过刷新,避免监控 UI 自身制造额外压力。
P8 中文运维页面必须以中文为默认用户可见语言:主标题、状态、筛选、运行历史、finding 分组、run detail、trace-frame、Final Response、空态、错误态、自动刷新和下一步动作均使用中文。原始英文 code、status 枚举、CLI 命令和 report SHA 可作为机器对照保留,但不得要求用户阅读英文 finding 才能判断 HWLAB 是否可用、卡在哪一层、下一步运行什么命令。
6.10 OPS-SENTINEL-REQ-010 多实例巡检与账号切换链路
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| OPS-SENTINEL-REQ-010 | 多实例与账号切换 | PJ2026-0106050810 多实例与账号切换 | YAML运维、用户管理、公开入口 |
Web 哨兵多实例必须以 node/lane root YAML 的 observability.webProbe.sentinels[] 为唯一 registry。每个 registry 项必须通过 configRef 指向独立 sentinel 管理 YAML,管理 YAML 再声明 runtime、workflow/scenario、promptSet、reportViews、publicExposure、cicd 和 secrets configRefs。legacy observability.webProbe.sentinel 只能作为单实例兼容入口;当同一 node/lane 存在多个 sentinel 时,除 plan/status registry 总览外,image、control-plane、validate、maintenance、report 和服务启动都必须显式携带 --sentinel <id>。
每个 sentinel 必须拥有独立的 Deployment、ServiceAccount、Service、PVC、SQLite path、GitOps path、Argo Application、FRP Secret/Deployment、metrics label、report index namespace 和 dashboard/report route label。不同 sentinel 可以共享同一 public hostname,但必须通过 YAML routePrefix 或等价 publicExposure 声明区分路径;不得共享同一个 PVC/SQLite 后再用 scenario id 伪装实例隔离。
workbench-dsflash-go-tool-call-10x 是保留的生产 canary,迁移到多实例 registry 后其 observe/analyze、report view、dashboard root 和 targetValidation 语义不得回退。迁移 closeout 必须证明旧实例 sentinel plan --sentinel workbench-dsflash-go-tool-call-10x 仍能解析原 runtime/scenario/prompt/report/publicExposure/cicd/secrets 引用。
workbench-auth-session-switch-2users 是账号切换链路哨兵。账号 A/B 的用户名、密码或 token 只能来自 Secret sourceRef 和 targetKey;CLI、服务日志、dashboard、report 和 issue evidence 只能展示 account id、sourcePurpose、presence、fingerprint 或 redacted 摘要。workflow 必须通过同一 web-probe observe command 控制队列支持 loginAccount、logout、listSessions 和 switchSessions 命令;submit 或命令失败必须作为结构化失败解决和上报,不能只写到备注里。
账号切换 report view 至少要给出账号 A/B login/logout 成败、session 列表可见性、切换前后 active session/account id、trace/final 可见性、blocked finding 和同一 observer/run/report SHA。auth-session-switch-summary 视图只读取已有 artifact/report/index,不重新访问 Workbench、不保存第二套截图、不打印账号凭据。
多实例 public exposure 复测必须通过受控 web-probe screenshot 或沉淀后的 command 远程截图能力完成,并把 PNG 保存到调用者 /tmp 下用于人工布局分析。修复 dashboard 布局问题后,复测截图必须覆盖 root dashboard 和至少一个 sentinel route prefix。
7. 过程控制
Web哨兵架构执行 issue 为 #883。阶段跟踪 issue 为 P0 #885、P1 #886、P2 #887、P3 #888、P4 #889、P5 #890 和 P6 #891。
P0 未完成前,不得推进 CLI wrapper、服务实现、YAML schema、CI/CD、dashboard 或部署代码阶段。P1-P6 的 PR closeout 必须回写:使用的 SPEC 编号和实现引用版本、触达的源码文件头部标注情况、owning YAML/configRef 变更、原 CLI 入口兼容性、验证命令、public origin 或运行面证据,以及是否需要继续修订本规格。
Dashboard 增强执行 issue 为 #935。P7 阶段跟踪 issue 为 P0 #938、P1 #940、P2 #941、P3 #939、P4 #943、P5 #942 和 P6 #944。P7 实现 PR closeout 必须回写 dashboard API contract、frontend 分层、trace-frame 对照、redaction、monitor.pikapython.com 验证和哨兵独立 CI/CD 状态。
P7 P6 收口必须区分 public dashboard validation 与 targetValidation quick verify:monitor.pikapython.com root/CSS/JS 200 只证明公开入口和静态 dashboard 资源可用;quick verify 的 observe command、采样样本、analyze report 和 red finding 仍是业务恢复判定的一部分。若 quick verify 因 observe-command-newSession-failed、no-samples 或等价采样器控制失败而 blocked,P6 issue 必须保持未关闭或显式拆出后续 blocker,不得只凭 public dashboard 200 关闭。
P8 哨兵恢复执行 issue 为 #971。P8 closeout 必须回写:SPEC P8 引用、120s warning 证据、quick-verify-no-business-turn 或等价业务触达证据、browser-timeout 分类修正、中文运维页面验证、monitor.pikapython.com 公网入口验证、k3s 内部 Service DNS quick verify 路径、D601/v03 用户入口 smoke 结果,以及仍未解除的真实业务 blocker 是否已单独拆出。
P8-P8 起,targetValidation 的 availability blocker 与 Workbench timing 架构治理必须分层。若同一 trace 在 terminal 前最后一帧仍为 running,随后 terminal commit 的 sealed durationMs 把可见 totalElapsed 小幅校正到更短值,且 drop 不超过 YAML turnTimingSampleSlackSeconds、final response 与完成行均已可见,则该现象作为 terminal-boundary timing correction 证据保留,不生成 turn-timing-total-elapsed-decrease red blocker。归零、running/running 下降、terminal 后增长、完成耗时与卡片耗时超出 slack、trace 乱序和完成行非最后仍保持 red;根因治理继续归 HWLAB #2055 和 HWLAB #2125,不得在 UI、CLI renderer 或 analyzer 中做读侧 repair。
P9 多实例巡检与账号切换链路执行 issue 为 #1017。P9 closeout 必须回写:SPEC P9 引用、registry 和两条 sentinel drill-down、旧 dsflash canary 迁移验证、账号切换 workflow/Secret sourceRef 验证、独立 Deployment/PVC/Service/SQLite/GitOps/Argo/public route prefix 证据、submit/command 失败处理、非阻塞计时告警证据、远程 PNG 截图布局复测,以及未完成阶段是否已拆出后续 issue。