@@ -22,8 +22,9 @@
| 实现引用版本 | draft-2026-06-25-p0-web-probe-sentinel; draft-2026-06-27-p0-workbench-read-model-rootcause |
| Dashboard 实现引用版本 | draft-2026-06-26-p8-web-probe-sentinel-recovery |
| 多实例实现引用版本 | draft-2026-06-26-p9-multi-web-probe-sentinel |
| Monitor Web 聚合实现引用版本 | draft-2026-06-26-p10-monitor-web-aggregation |
| 历史 Monitor Web 聚合实现引用版本 | draft-2026-06-26-p10-monitor-web-aggregation(由 P17 取代) |
| Monitor Web 观察面板治理实现引用版本 | draft-2026-06-27-p11-monitor-web-observability-dashboard; draft-2026-06-27-p12-cadence-scheduler-monitor-web |
| Monitor 中心持久化实现引用版本 | draft-2026-07-12-p17-monitor-central-persistence |
| Cadence/OTel 稳定性实现引用版本 | draft-2026-07-01-p15-cadence-otel |
| CI/CD source snapshot 实现引用版本 | draft-2026-07-01-p16-cicd-source-snapshot |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板 ](../../templates/iso-iec-ieee-29148-requirements-spec-template.md ) |
@@ -46,8 +47,8 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
### 2.2 范围内
- `web-probe observe` CLI 的 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。
- YAML `observability.webProbe.sentinels[]` 多实例 registry、 `observability.webProbe.monitor.configRef` 中心服务入口,以及各自 owning YAML 的引用图。
- 独立 sentinel runner、scheduler、scenario runner、artifact PVC、中心 Monitor ingest/query 服务、Host PostgreSQL 、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 验证。
- 哨兵自身 CI/CD 的 k8s git-mirror source snapshot、PipelineRun source acquisition、GitOps publish 和 selected/latest closeout。
@@ -64,8 +65,8 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
- API path、错误 envelope、route policy 和用户身份语义归 [PJ2026-010403 API契约 ](PJ2026-010403-api-contract.md )。
- 第一阶段不交付分布式压测;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` 成为探针事实源。
- 多实例 Web 哨兵不得用一个 Pod 或 一个 PVC 伪装执行 隔离。runtime Deployment/Job 、Service、artifact PVC 、GitOps path、Argo Application 和 metrics label 必须按 sentinel id 独立;结构化 run/finding/locator 则统一进入中心 Monitor Host PostgreSQL 。
- 中心 Monitor 索引 、dashboard、metrics 和 maintenance 状态不得替代 `samples.jsonl` 、`control.jsonl` 、network/artifact JSONL 或 `analysis/report.json` 成为探针事实源。
- Dashboard 不负责修复 Workbench projection、trace timing、runner/envreuse 或 git mirror 慢路径;它只把 observe/analyze 已采集事实组织成可读的值守和分析入口。
- Web 哨兵不得通过降低 Playwright/Chromium 启动资源、禁用浏览器能力或自动刷新页面来规避 Workbench 卡死和内存膨胀;浏览器进程 RSS 是诊断证据,阻塞判定必须优先使用页面级 baseline 后的有效内存、CDP/Playwright 响应性和 YAML policy。
@@ -89,14 +90,15 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
| 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 分页信息 ;它不是业务或探针事实源。 |
| Monitor 中心索引 | NC01 Host PostgreSQL 中由中心 Monitor 服务唯一写入和查询的结构化 run 、finding、report payload 、artifact locator 与必要状态时间线 ;它不是业务或探针事实源。 |
| legacy SQLite index | 切换前 runner PVC 上的历史轻量索引,只能作为一次性迁移输入和有界回滚快照,不能继续提供运行时读写或 fallback。 |
| 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。 |
| source snapshot | 哨兵自身 CI/CD 触发时由 k8s git-mirror 解析出的不可变源码快照,绑定 selected commit、mirror ref、PipelineRun、GitOps revision 和 runtime image。 |
| monitor-web | 独立于 sentinel-runner 的 Vue 3 + TypeScript + Vite 展示和聚合 层,承载 `monitor.pikapython.com` root、多哨兵总览、趋势曲线、时间线、单哨兵详情和受控截图验收。 |
| monitor-web | 独立于 sentinel-runner 的 Vue 3 + TypeScript + Vite 展示层,只消费中心 Monitor bounded API ,承载 `monitor.pikapython.com` root、多哨兵总览、趋势曲线、时间线、单哨兵详情和受控截图验收。 |
| cadence freshness | 根据 YAML cadence、scheduler heartbeat、latest run age、active/planned run 和 analyzed report 更新时间计算的运行新鲜度;它默认是非阻塞值守告警,只有真正导致 run/report 不产生或业务链路不可用时才升级为 blocker。 |
| env reuse | CI/CD 复用既有 env image、依赖缓存、BuildKit 层和未受影响服务的发布产物,以避免无关重建;小范围变更应在 status/closeout 中暴露 build/reuse 摘要。 |
| 页面内存 baseline | web-probe 在每个 Playwright page/page epoch 上采集的初始浏览器运行指标;浏览器启动、空页和未加载目标 URL 前的基础成本只作为 baseline,不计入该页有效内存预算。 |
@@ -108,7 +110,7 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
| --- | --- |
| 外部使用者 | 平台值守人员、发布操作人员、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 runner Deployment/Job 、Service、artifact PVC、中心 Monitor Deployment/Service、Host PostgreSQL database/role/export/Secret consumer 、ServiceAccount、NetworkPolicy、ConfigMap、publicExposure、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。 |
@@ -119,16 +121,16 @@ Web哨兵必须遵循 UniDesk YAML-first ops。目标 node/lane、public origin
| --- | --- | --- | --- | --- | --- |
| 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-0106050803 | 常驻服务 | 本规格 6.3 | scheduler、scenario runner、artifact PVC、中心 ingest/query、Host PG 、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边界、安全隔离 | 多哨兵巡检、账号链路值守 |
| PJ2026-0106050811 | Monitor Web 聚合 | 本规格 6.11 | runner/w eb 职责拆分、单 monitor-web 聚合、Kubernetes discovery 、Vue+TS 前端和 public exposure 收敛 | 多实例与账号切换、Dashboard工作台、发布集成 | `monitor.pikapython.com` 统一值守入口 |
| PJ2026-0106050812 | Monitor Web 观察面板治理 | 本规格 6.12 | 趋势曲线、运行时间线、固定视口三栏、cadence freshness、Vue CI/CD/env reuse/git mirror | Monitor Web 聚合 、Dashboard工作台、发布集成、源码同步 | 可滚动上线和值守的统一观察面板 |
| PJ2026-0106050810 | 多实例与账号切换 | 本规格 6.10 | sentinel registry、runner 隔离、账号切换 command、中心 API scope 和 report label | YAML配置、Wrapper边界、安全隔离 | 多哨兵巡检、账号链路值守 |
| PJ2026-0106050811 | Monitor 中心服务与 Web | 本规格 6.11 | runner/中心服务/W eb 职责拆分、Host PG 唯一索引、中心 API 、Vue+TS 前端和 public exposure 收敛 | 多实例与账号切换、Dashboard工作台、发布集成 | `monitor.pikapython.com` 统一值守入口 |
| PJ2026-0106050812 | Monitor Web 观察面板治理 | 本规格 6.12 | 趋势曲线、运行时间线、固定视口三栏、cadence freshness、Vue CI/CD/env reuse/git mirror | Monitor 中心服务与 Web、Dashboard工作台、发布集成、源码同步 | 可滚动上线和值守的统一观察面板 |
| PJ2026-0106050814 | 哨兵 CI/CD 可见性 | 本规格 6.14 | publish 阶段耗时、env reuse、docker cache、超时诊断、git mirror/Argo/runtime 收敛下一步 | 发布集成、源码同步、Monitor Web 观察面板治理 | 小改动滚动上线可诊断、可续跑、可验收 |
| PJ2026-0106050815 | Cadence/OTel 稳定性 | 本规格 6.15 | Kubernetes CronJob 周期巡检、状态缺口故障码、monitor-web cadence 可见性和 sentinel OTel span 合同 | Monitor Web 观察面板治理、发布集成、OTel、YAML运维 | JD01/v03 周期巡检恢复和后续防回归 |
@@ -154,18 +156,26 @@ flowchart LR
Mgmt --> Secrets
end
subgraph Sentinel[Web哨兵 Pod ]
subgraph Sentinel[Per-sentinel runner ]
Scheduler[Scheduler]
Adapter[observe CLI wrapper adapter]
Index[(SQLite index on PVC)]
API[/api overview status runs report views maintenance ]
ArtPVC[(Immutable artifact PVC)]
RunnerAPI[/health trigger artifact access ]
Metrics[/metrics]
Dash[Dashboard workbench]
Scheduler --> Adapter
Schedul er --> Index
API --> Index
Dash --> API
Metrics --> Index
Adapt er --> ArtPVC
Scheduler --> Metrics
RunnerAPI --> ArtPVC
end
subgraph Monitor[Central Monitor]
Ingest[Ingest API]
Store[(NC01 Host PostgreSQL)]
Query[Bounded query API]
Dash[monitor-web]
Ingest --> Store
Store --> Query
Query --> Dash
end
subgraph Observe[Existing web-probe observe]
@@ -189,7 +199,8 @@ flowchart LR
Scenario --> Scheduler
Adapter --> Runner
Adapter --> Control
Analyze --> Index
Analyze --> ArtPVC
Analyze --> Ingest
Runner --> Web
Dash -. HTTPS .-> Exposure
```
@@ -198,22 +209,27 @@ flowchart LR
``` mermaid
flowchart TD
Root[config/hwlab-node-lanes.yaml<br/>lanes.v03. targets.D601 .observability.webProbe.sentinels[] ] --> Entry[id/enabled/configRef]
Root[config/hwlab-node-lanes.yaml<br/>targets.node .observability.webProbe] --> Entry[id/enabled/configRef]
Root --> MonitorRef[monitor service 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]
MonitorRef --> MonitorRuntime[Monitor runtime owning YAML]
MonitorRuntime --> PublicExposure[Monitor publicExposure owning YAML]
MonitorRuntime --> PlatformDB[config/platform-db/postgres-nc01.yaml]
PlatformDB --> MonitorSecret[Monitor DB export / Secret consumer]
Scenarios --> PromptSets
Scenarios --> ReportViews
Scenarios --> AnalyzeThresholds[hwlab-node-lanes.yaml#...observe.analysisThresholds]
PublicExposure --> Edge[PK01 Caddy + FRP managed block]
SecretRefs --> Runtime
Cicd --> Runtime
MonitorSecret --> MonitorRuntime
```
配置引用图必须保持单向:root YAML 只保存 enable 与 ref;具体数值在 owning YAML;parser 只解析、校验和报告,不写合并后的新 source of truth。
@@ -232,17 +248,18 @@ flowchart TD
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 ]
ReportJson --> Ingest[Monitor ingest ]
ReportJson --> ArtifactPVC[Runner artifact PVC]
ReportMd --> ArtifactPVC[Runner artifact PVC ]
Ingest --> Store[(NC01 Host PostgreSQL) ]
Store --> ViewApi[bounded Monitor query API ]
Store --> ReportCli[sentinel report]
ViewApi --> Dashboard[monitor-web ]
Store --> Metrics[Prometheus metrics ]
Store --> Validation[targetValidation]
```
`ReportCli` 、dashboard、metrics 和 targetValidation 只能读取 artifact/report/index 摘要。它们不得重新访问 Workbench、重新采样页面、重排 trace 行、重新分类 finding 或从 SQLite 推导业务事实。
`ReportCli` 、dashboard、metrics 和 targetValidation 只能读取中心 Monitor 索引及其引用的 artifact/report 摘要。它们不得重新访问 Workbench、重新采样页面、重排 trace 行、重新分类 finding 或从 Postgre SQL 推导业务事实。
### 5.4 常规巡检时序图
@@ -253,7 +270,7 @@ sequenceDiagram
participant Obs as observe runner
participant Web as HWLAB Web public origin
participant Ana as observe analyze
participant Idx as SQLite/PVC index
participant Mon as Monitor ingest / Host PG
Sch->>CLI: observe start with YAML scenario
CLI->>Obs: start sampler/stateDir
@@ -263,7 +280,7 @@ sequenceDiagram
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
Ana-->>Mon: terminal run, report SHA, findings and locator
```
### 5.5 发布 maintenance 时序图
@@ -271,20 +288,23 @@ sequenceDiagram
``` mermaid
sequenceDiagram
participant CI as CI/CD Pipeline
participant Se n as Sentinel API
participant Mo n as Monitor API
participant Run as Sentinel runner
participant CP as Runtime control-plane
participant CLI as observe wrapper
participant Ana as observe analyze
CI->>Se n: maintenance/start release id
Se n-->>CI: sampling continues, alert muted
CI->>Mo n: maintenance/start release id
Mo n-->>CI: sampling continues, alert muted
CI->>CP: rollout / Argo sync
CP-->>CI: runtime healthy summary
CI->>Se n: maintenance/stop
Se n->>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
CI->>Mo n: maintenance/stop
Mo n->>Run: trigger selected quick verify
Run->>CLI: observe start/command /status
CLI-->>Run: observer/run/stateDir
Run->>Ana: analyze quick verify artifact
Ana->>Mon: terminal ingest
Mon-->>CI: report SHA, findings, targetValidation status
```
### 5.6 哨兵自身 rollout 时序图
@@ -294,18 +314,18 @@ sequenceDiagram
participant CP as Sentinel control-plane
participant GitOps as GitOps repo
participant Argo as ArgoCD
participant Pod as Sentinel Pod
participant Run as Sentinel runner
participant Mon as Monitor service
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
Argo->>Run : sync runner Deployment/Job/ Service/PVC
Argo->>Mon: sync Monitor Deployment/Service
Val->>Run: /health, /metrics, artifact PVC
Val->>Mon: /health, Host PG schema/query, monitor-web assets
```
哨兵自身 rollout 只验证哨兵服务健康、配置装载、PVC/SQLite 可写 、metrics、dashboard 和调度循环;它不能把另一个哨兵当作 HWLAB Web 业务观察对象,也不能因为 HWLAB 业务 quick verify blocked 就把哨兵自身发布状态标成失败。
哨兵自身 rollout 只验证 runner 与中心 Monitor 服务健康、配置装载、artifact PVC 可写、Host PG 可查询 、metrics、dashboard 和调度循环;它不能把另一个哨兵当作 HWLAB Web 业务观察对象,也不能因为 HWLAB 业务 quick verify blocked 就把哨兵自身发布状态标成失败。
### 5.7 哨兵不可用结构化失败时序图
@@ -345,12 +365,13 @@ Dashboard 首屏必须先呈现当前值守判断,再允许 drill-down。用
``` mermaid
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]
Rep ort --> ViewApi[/api/runs/:id/views]
Artifacts[observe artifacts ] --> ViewApi
Store[(NC01 Host PostgreSQL )] --> OverviewApi[/api/overview]
Store --> RunsApi[/api/runs filters cursor]
Store --> FindingsApi[/api/findings aggregate]
Store --> DetailApi[/api/runs/:id]
St ore --> ViewApi[/api/runs/:id/views]
ArtifactLocator[artifact locator ] --> ViewApi
Artifacts[runner observe artifacts] --> ArtifactLocator
OverviewApi --> Dashboard
RunsApi --> Dashboard
FindingsApi --> Dashboard
@@ -470,7 +491,7 @@ Web哨兵必须只编排现有顶层 `web-probe observe start/status/command/col
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-002 | YAML配置 | PJ2026-0106050802 YAML配置 | [YAML运维 ](PJ2026-010603-yaml-first-ops.md )、[公开入口 ](PJ2026-010604-public-entry.md )、[源码同步 ](PJ2026-010602-source-sync.md ) |
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 。
Web 哨兵多 实例配置必须 通过 node/lane root YAML 的 `observability.webProbe.sentinels[]` registry 进入,中心服务通过 `observability.webProbe.monitor.configRef` 进入。sentinel registry 项只能声明 `id` 、`enabled` 和 `configRef` ,再由 sentinel 管理 YAML 引用 runtime、workflow/scenario、promptSet、reportView、CI/CD 和 Secret owning YAML; Monitor 管理 YAML 独立引用 runtime、publicExposure、persistence、CI/CD 和 Secret owning YAML。旧单实例 `sentinel` 与 `monitorRoot` 在 P17 切换时删除,不作为兼容入口保留 。
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。
@@ -482,13 +503,13 @@ parser 只负责解析 `path/to/file.yaml#object.path` 或规格确认的等价
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-003 | 常驻服务 | PJ2026-0106050803 常驻服务 | [发布流水 ](PJ2026-010601-controlled-release.md )、[Workbench性能 ](PJ2026-01060505-workbench-performance.md ) |
Web哨兵服务应以 TypeScript/Node.js 实现,默认单 Pod 单副本。服务负责 scheduler、scenario runner、PVC/SQLite index、health、metrics、maintenance API 和 dashboard 静态资源;它不得直接写 第二套 DOM 采样、 网络采样、截图、Workbench 读取逻辑或 finding 分类。
Web 哨兵必须拆成 per-sentinel runner 与中心 Monitor 服务。runner 负责编排既有 observe/analyze、生成不可变 artifact、暴露执行健康/受控触发/locator 访问;中心 Monitor 服务负责 ingest、Host PostgreSQL 持久化、bounded query API、metrics 和 monitor-web 静态资源。两者都不得复制 第二套 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 或业务状态仲裁。
每个 runner 的 PVC 只 保存 `.state/web-observe` artifact 和切换前冻结的 legacy SQLite 快照。NC01 Host PostgreSQL 保存 runner identity、run 、finding、report payload 、artifact locator 和必要状态时间线;只有中心 Monitor 服务持有数据库连接并写入。结构化索引 不得替代 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 状态 。
终态 ingest identity 固定为 `(sentinelId,node,lane,runId)` ;相同 identity 与相同 payload hash 必须幂等,相同 identity 与不同 payload hash 必须结构化拒绝。runner 在 analyze 后同步提交已有 report/finding/locator,并对瞬时失败做 YAML 声明的有界重试;最终失败必须显示 `monitor-ingest-failed` 或等价语义,允许用同一不可变 artifact 显式重提,禁止写本地 SQLite fallback、永久 outbox 或第二索引 。
Pod 重建后应从 PVC 恢复 index 与最近 artifact 摘要 ;进行中 run 可以标记 `interrupted` 并重新调度,不能静默假绿。
runner `/health` 必须覆盖配置装载、scheduler/CronJob 观察、artifact PVC 可写、analyze 可执行性和中心 ingest 可达性;中心 Monitor `/health` 必须覆盖配置、Host PG 连接/schema、ingest/query 和前端资产。Pod 重建不能靠扫描 PVC 或补造历史恢复中心索引 ;进行中 run 可以按已有执行事实 标记 `interrupted` 并重新调度,不能静默假绿。
### 6.4 OPS-SENTINEL-REQ-004 报告视图和 dashboard
@@ -516,7 +537,7 @@ P8 恢复判定必须把 Workbench 业务失败继续 drill-down 到运行面依
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-005 | 发布集成 | PJ2026-0106050805 发布集成 | [发布流水 ](PJ2026-010601-controlled-release.md )、[源码同步 ](PJ2026-010602-source-sync.md )、[公开入口 ](PJ2026-010604-public-entry.md ) |
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。
Web 哨兵自身必须纳入受控且独立的 sentinel control-plane: source 来自 UniDesk `master` , runner 与中心 Monitor 的 镜像、GitOps path、Argo Application、中心 publicExposure 和 targetValidation 分别由对应 owning YAML 声明。builder 类型必须来自 YAML,不得依赖 operator 本地 dirty worktree。
哨兵自身 CI/CD 的 source identity 必须来自 k8s git-mirror source snapshot。`trigger-current` 应先通过 YAML 声明的 git-mirror cache/service 在 k8s 内解析并同步 selected commit,再把同一 source snapshot 注入 publish PipelineRun、GitOps 写回、status 和 closeout。operator host 上的 `git ls-remote` 、`git fetch` 、`git clone` 、`git rev-parse HEAD` 和固定 host worktree 读写不得参与正式 source selection。
@@ -584,6 +605,8 @@ P10/P11 monitor-web 范围内新增或修改的 Vue/TypeScript/Vite 前端、typ
P15 cadence/OTel 范围内新增或修改的 CronJob renderer/status probe、runner health/overview、quick verify record path、monitor-web cadence 展示和 OTel emitter 源码文件头部必须标注 `SPEC: PJ2026-01060508 Web哨兵 draft-2026-07-01-p15-cadence-otel` 。
P17 中心持久化范围内新增或修改的 Monitor ingest/query、Host PG store/schema、SQLite export/import、runner terminal submit、monitor-web API client、CLI report/status、YAML renderer 和 cutover 工具源码文件头部必须标注 `SPEC: PJ2026-01060508 Web哨兵 draft-2026-07-12-p17-monitor-central-persistence` 。
实现文件不得只写 issue 编号、`latest` 、`current` 或“按最新方案”作为规格引用。自动生成文件、第三方 vendored 文件、纯 YAML/config、锁文件和无法承载注释头的二进制产物不要求加源码头部,但对应生成器、渲染器、owning YAML 或 CLI 入口必须能追溯到本 SPEC。
后续 P1-P6 阶段如果改变稳定需求、观察对象、数据流、接口、部署边界或验收口径,应先更新本规格和上级 [PJ2026-010605 运维监控 ](PJ2026-010605-observability-monitoring.md ),再更新执行 issue。
@@ -606,7 +629,7 @@ Dashboard 前端架构应借鉴 Sub2API 监控面板的分层方式:typed API
Dashboard 自动刷新只能读取 bounded API,不得发送 `observe command` 、不启动新采样、不重新 analyze、不保存额外截图。页面 hidden、loading 或上一次请求未完成时应暂停或跳过刷新,避免监控 UI 自身制造额外压力。
P11 起, 长期权威观察面板是 Vue `monitor-web` ,不是 runner 内置 vanilla dashboard。迁移 前 runner dashboard 可以继续承担单哨兵兼容、短修和回归对照,但 趋势曲线、固定视口三栏、运行时间线、多哨兵聚合、cadence freshness 和 root cause 默认可见性必须在 `monitor-web` 中设计和验收。
长期权威观察面板是 Vue `monitor-web` ,不是 runner 内置 dashboard。切换 前 runner 页面只允许用于迁移对照,切换发布必须删除其查询和展示入口; 趋势曲线、固定视口三栏、运行时间线、多哨兵聚合、cadence freshness 和 root cause 默认可见性统一在中心 `monitor-web` 中设计和验收。
P8 中文运维页面必须以中文为默认用户可见语言:主标题、状态、筛选、运行历史、finding 分组、run detail、trace-frame、Final Response、空态、错误态、自动刷新和下一步动作均使用中文。原始英文 code、status 枚举、CLI 命令和 report SHA 可作为机器对照保留,但不得要求用户阅读英文 finding 才能判断 HWLAB 是否可用、卡在哪一层、下一步运行什么命令。
@@ -616,41 +639,49 @@ P8 中文运维页面必须以中文为默认用户可见语言:主标题、
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-010 | 多实例与账号切换 | PJ2026-0106050810 多实例与账号切换 | [YAML运维 ](PJ2026-010603-yaml-first-ops.md )、[用户管理 ](PJ2026-0105-user-management.md )、[公开入口 ](PJ2026-010604-public-entry.md ) |
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>` 。
Web 哨兵多实例必须以 node/lane root YAML 的 `observability.webProbe.sentinels[]` 为唯一 runner registry。每个 registry 项必须通过 `configRef` 指向独立 sentinel 管理 YAML,管理 YAML 再声明 runtime、workflow/scenario、promptSet、reportViews、cicd 和 secrets configRefs;中心 Monitor 由独立 `observability.webProbe.monitor.configRef` 声明。对 runner 的 image、control-plane、validate 和执行操作必须显式携带 `--sentinel <id>` ;全局 report/overview 默认走中心 API,并支持显式 scope 。
每个 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 伪装实例隔离 。
每个 sentinel 必须拥有独立的 runner Deployment/Job 、ServiceAccount、ClusterIP Service、artifact PVC、GitOps path、Argo Application、metrics label 和稳定 `(sentinelId,node,lane)` identity;不得共享一个执行 Pod/PVC 后再用 sc enario id 伪装隔离。结构化 run/finding/locator 统一写入中心 Host PG,并以稳定 identity、FK 和 scope 索引隔离,不再声明 per-sentinel SQLite path 或 report index namespace 。
`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、不保存第二套截图、不打印账号凭据。
账号切换 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,不重新访问 Workbench、不保存第二套截图、不打印账号凭据。
多实例 public exposure 复测必须通过受控 `web-probe screenshot` 或沉淀后的 command 远程截图能力完成,并把 PNG 保存到调用者 `/tmp` 下用于人工布局分析。修复 dashboard 布局问题后,复测截图必须覆盖 root dashboard 和至少一个 sentinel route prefix 。
公网只暴露中心 monitor-web; runner Service 不按 sentinel 单独公开。 多实例 public exposure 复测必须通过受控 `web-probe screenshot` 或沉淀后的 command 远程截图能力完成,并把 PNG 保存到调用者 `/tmp` 下用于人工布局分析。修复 dashboard 布局问题后,复测截图必须覆盖 root dashboard 和至少一个中心 API 驱动的 sentinel detail route 。
### 6.11 OPS-SENTINEL-REQ-011 Monitor Web 聚合
### 6.11 OPS-SENTINEL-REQ-011 Monitor 中心服务与 Web
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-011 | Monitor Web 聚合 | PJ2026-0106050811 Monitor Web 聚合 | [公开入口 ](PJ2026-010604-public-entry.md )、[YAML运维 ](PJ2026-010603-yaml-first-ops.md )、Dashboard工作台、多实例与账号切换 |
| OPS-SENTINEL-REQ-011 | Monitor 中心服务与 Web | PJ2026-0106050811 Monitor 中心服务与 Web | [公开入口 ](PJ2026-010604-public-entry.md )、[YAML运维 ](PJ2026-010603-yaml-first-ops.md )、Dashboard工作台、多实例与账号切换 |
P10 起,Web 哨兵运行面必须区分 `sentinel-runner` 与 `monitor-web` 。 `sentinel-runner` 继续以每个 sentinel id 一套 Deployment、Service、PVC、SQLite index、scheduler、observe wrapper、report API、health 和 metrics 的形态存在;它只负责采样、分析、索引和提供单哨兵渐进读取 API。 `monitor-web` 是独立的展示和聚合层,负责 `monitor.pikapython.com` root、所有 enabled sentinel 的 registry 总览、聚合 overview/runs/findings、单哨兵 detail route、受控截图/验证入口和人类值守信息架构。runner 不得因为聚合需求而回退到共享 Pod、共享 PVC 或共享 SQLite 。
P17 起,Web 哨兵运行面必须区分 `sentinel-runner` 、中心 `monitor-service` 与 `monitor-web` 。runner 只负责采样、分析、不可变 artifact、执行健康和终态提交;中心 service 是 Host PG 唯一 writer/query authority,负责 global overview/runs/findings/ detail、maintenance/cadence 结构化状态与 locator; monitor-web 只负责展示和人类值守信息架构。禁止把 monitor-web 继续挂在任一 runner 上作为 `runner-served-bridge` 。
`m onitor-web` 配置必须是 YAML-first。node/lane、namespace、Deployment、Service、publicExposure、runner discovery label selector、read timeout、聚合 API、 静态资源托管方式、RBAC、NetworkPolicy 和 Secret sourceRef 都必须来自 owning YAML 或 configRef。root `observability.webProbe.sentinels[]` 仍是 enabled sentinel registry; `monitor-web` 可以读取该 registry 与 Kubernetes Service/EndpointSlice discove ry 结果 做一致性校验,但不得把发现结果 写回成 第二 source of truth。
中心 M onitor 配置必须是 YAML-first。node/lane、namespace、Deployment、Service、publicExposure、Host PG database/role/export/Secret consumer、ingest/query timeout、静态资源托管方式、RBAC、NetworkPolicy 和 migration/cutover mode 都必须来自 owning YAML 或 configRef。root `observability.webProbe.sentinels[]` 仍是 enabled sentinel registry; 数据库或 Kubernetes discovery 只能与 regist ry 做一致性校验,不能 写回第二 source of truth。
Runner discovery 优先使用 Kubernetes 原生对象:runner Service/Pod 必须带 `unidesk.ai/web-probe-sentinel-id` 、node、lane、workspace 和 component label; `monitor-web` 使用 Service list/watch 或 EndpointSlice list/watch 按 label selector 发现 ClusterIP runner endpoint。Prometheus/ServiceMonitor 只用于低基数 metrics scrape,不承载 report drill-down,也不替代 runner HTTP API。runner Service 默认 ClusterIP;公网只暴露 `monitor-web` ,不逐个暴露 runner 。
Runner Service/Pod 必须带 `unidesk.ai/web-probe-sentinel-id` 、node、lane、workspace 和 component label,供中心控制面做健康、触发与 artifact locator 可达性检查。中心 query 绝不能按请求 fan-out runner API、读取 runner SQLite 或扫描 PVC; runner 不可用时,已经进入 Host PG 的历史仍必须可查,只有对应 artifact locator 显示不可达。Prometheus/ServiceMonitor 只用于低基数 metrics scrape,不承载 report drill-down 。
`monitor-web` 前端目标技术栈为 Vue 3 + TypeScript + Vite,并与 HWLAB Cloud Web 的组件拆分、typed API client、状态管理、加载/空态/错误态、Markdown/代码块渲染和样式约定对齐。旧 `scripts/assets/web-probe-sentinel-dashboard/dashboard.js` vanilla `innerHTML` 实现只允许作为迁移前的短修和对照,不再作为 monitor-web 新能力的长期承载面。迁移前的短修仍必须保留 P8/P9 三栏、高信息密度、中文运维页面、渐进披露和 trace-frame 入口 。
`monitor-web` 前端目标技术栈为 Vue 3 + TypeScript + Vite,并与 HWLAB Cloud Web 的组件拆分、typed API client、状态管理、加载/空态/错误态、Markdown/代码块渲染和样式约定对齐。前端只能消费中心 bounded API,不允许 N+1 拉取 runner detail 或客户端合并 global latest。旧 runner 内置 dashboard/静态资产在切换完成后删除,不作为兼容入口保留 。
P10 dashboard 受控验收必须沉淀为 CLI 入口。`web-probe sentinel dashboard verify|screenshot` 或等价命令必须从 selected sentinel 的 YAML `publicExposure.publicBaseUrl` 解析 URL,通过远程浏览器执行 JS、采集 pageerror/console/requestfailed/DOM 行数/布局溢出和截图 SHA。`validate` 中的 public dashboard 200 只证明 HTML/CSS/JS 静态资源可达,不能替代浏览器渲染验收。
`monitor.pikapython.com` root 的目标首屏 必须展示所有 enabled sentinels 的 latest status、latest run、red/amber/info 摘要、freshness、runner degraded 状态和 drill-down 链接;`/sentinels/<id>` 必须展示单哨兵 runs/findings/detail/trace-frame。删除或重启一个 runner 只能让对应 sentinel 显示 degraded,不得让 root 变成空白 或阻断其他 runner 数据。聚合 API 必须 bounded、分页、redacted,不打印 Secret、prompt 原文、provider payload、cookie、完整 stdout/stderr 或完整 report。
`monitor.pikapython.com` root 必须展示所有 enabled sentinels 的 latest status、latest run、red/amber/info 摘要、freshness、runner degraded 状态和 drill-down 链接;`/sentinels/<id>` 必须从同一中心 API 展示单哨兵 runs/findings/detail/trace-frame。删除或重启一个 runner 只能让对应 execution/artifact 可达性 显示 degraded,不得清空已持久历史 或阻断其他 runner 数据。所有 API 必须 bounded、分页、redacted,不打印 Secret、prompt 原文、provider payload、cookie、完整 stdout/stderr 或完整 report。
Host PG 首版数据模型必须至少包含 runner identity、run、finding、run payload、artifact locator、timeline event、schema migration 和 import manifest。run identity 使用 `(sentinelId,node,lane,runId)` 唯一约束;finding 和 payload 以 run FK 关联;artifact locator 保存 owner node/lane/PVC、stateDir、relative path、SHA、size 和 kind,不保存 artifact blob。全局及 scoped latest 统一按 `updatedAt DESC, runId DESC` 选择,所有列表使用稳定 cursor,不允许各 runner 自己定义 latest。
中心 ingest 首版使用同步 HTTP 提交,不引入 Kafka、第二数据库或长期 outbox。runner 只提交已有 analyze/report 事实;中心在一个 PG transaction 内写入 run、finding、payload、locator 和 timeline。提交失败时 run 执行结果与 `monitor-ingest-failed` 必须同时可见;对同一不可变 report 的显式重提属于恢复同一事实,不得修改 payload、补造 report 或把失败 run 静默标成已记录。
SQLite 到 Host PG 的迁移必须先恢复并验证 YAML 声明的 Host PG role/database/export/Secret consumer,再从 resolved registry 生成实际 source 清单。受控 cutover 依次执行:暂停新 run 并等待 active run 结束、对每库记录 fingerprint/integrity/schema/row count、创建一致只读快照、单 source transaction 导入、校验行数/关键字段/latest/locator SHA 与可达性、切换 runner writer 和中心 query、恢复 cadence。切换前允许回到冻结快照;PG 接管新写入后不得回写或重新服务 SQLite。
实现可以分两次自动发布:第一次交付 PG capable 的中心 service、store 和迁移工具,但生产读写仍保持旧权威且不得双写;第二次在迁移校验成功后一次性切换 writer/query/UI/CLI,并删除 runner SQLite/query/dashboard 路径。PR 合并后只能观察自动 GitHub webhook → Gitea mirror → PaC → CI/CD → GitOps/Argo 链路,自动链路不通时修自动链路,禁止手工补触发。
### 6.12 OPS-SENTINEL-REQ-012 Monitor Web 观察面板与 CI/CD 治理
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-012 | Monitor Web 观察面板治理 | PJ2026-0106050812 Monitor Web 观察面板治理 | Monitor Web 聚合 、Dashboard工作台、[源码同步 ](PJ2026-010602-source-sync.md )、[发布流水 ](PJ2026-010601-controlled-release.md ) |
| OPS-SENTINEL-REQ-012 | Monitor Web 观察面板治理 | PJ2026-0106050812 Monitor Web 观察面板治理 | Monitor 中心服务与 Web、Dashboard工作台、[源码同步 ](PJ2026-010602-source-sync.md )、[发布流水 ](PJ2026-010601-controlled-release.md ) |
`monitor-web` 首屏信息架构必须把值守判断放在最前:顶部状态与全局操作之后,先显示哨兵入口,再在哨兵入口正下方展示运行趋势曲线。趋势曲线至少展示最近运行窗口内 red finding count、warning/amber finding count 和 total finding count;当前选中 run、maintenance window、缺失 report、stale run 和 runner degraded 必须有可见标记。
@@ -660,33 +691,33 @@ P10 dashboard 受控验收必须沉淀为 CLI 入口。`web-probe sentinel dashb
cadence freshness 必须成为 `monitor-web` 的一等状态。每个 sentinel 应显示 YAML expected cadence、scheduler heartbeat age、latest run age、latest analyzed report age、active run、planned/next run 和 stale 倍数。cadence stale 默认是非阻塞告警;只有 scheduler 停摆、run/report 长时间不产生、submit/command 失败、采样样本缺失、或 Code Agent 多轮业务链路不可继续时,才升级为 blocker。面板不得把 timing warning、terminal-boundary elapsed correction 或单纯超时预算告警伪装成业务 blocker。
P12 runner-served-bridge 形态下, sentinel runner Pod 可以只承载 API、PVC/SQLite index、health、metrics 和 dashboard 静态资源;若 Pod 内 没有完整 repo 配置、`trans` 、Chromium 或 observe 依赖,不得让 Pod 自行 SSH/回调宿主机触发巡检。周期巡检必须 由受控宿主控制面调度器 读取同一 YAML registry、scenario/workflow cadence、publicExposure 和 targetValidation timeout, 按 stale 窗口 触发现有 `web-probe sentinel validate --quick-verify --confirm --wait` 路径。该调度器只负责 due 判断、互斥锁、timeout、命令执行和 JSONL 事件日志, 不实现第二套采样、analyze、finding 分类或 report 写入。
P17 删除 ` runner-served-bridge` 。 sentinel runner Pod/Job 只承载执行 adapter、artifact PVC、health、metrics 和中心 ingest client;若运行单元 没有完整 repo 配置、`trans` 、Chromium 或 observe 依赖,不得自行 SSH/回调宿主机触发巡检。周期巡检仍 由受控 node/lane CronJob 读取同一 YAML registry、scenario/workflow cadence 和 targetValidation timeout, 并 触发现有 `web-probe sentinel validate --quick-verify --confirm --wait` 语义;它 不实现第二套采样、analyze、finding 分类或 report 写入。
宿主控制面 调度器必须由目标 node/lane 的 k3s CronJob/GitOps 或等价 受控入口周期调用,默认 tick 间隔不得替代 YAML cadence;每次 tick 必须输出 sentinel id、cadence、latest run age、due、trigger status、latest run id 和下一步 drill-down。触发失败要区分业务 finding、命令 submit/control 失败、overview/API 不可达、lock-held 和 timeout;业务 finding 已产生新 run 时不得把 scheduler 本身标为 infra blocker。`monitor-web` 应继续把 stale run 作为非阻塞告警展示,但 run/report 持续不更新或 submit/control 失败必须能在面板和 CLI 中直接看到根因。
调度器必须由目标 node/lane 的 k3s CronJob/GitOps 受控入口周期调用,默认 tick 间隔不得替代 YAML cadence; due 判断读取中心 Monitor 的 latest 与 YAML cadence,不读取 runner 私有索引。 每次 tick 必须输出 sentinel id、cadence、latest run age、due、trigger status、latest run id 和下一步 drill-down。触发失败要区分业务 finding、命令 submit/control 失败、中心 query/ingest 不可达、lock-held 和 timeout;业务 finding 已产生并成功 ingest 新 run 时不得把 scheduler 本身标为 infra blocker。
`monitor-web` 前端必须使用 Vue 3 + TypeScript + Vite,并与 HWLAB Cloud Web/Sub2API 运维图表的组件化方式对齐:typed API client、format composable、auto refresh composable、chart component、timeline component、run table、detail tabs、finding groups、loading/empty/error 状态和深链路由。图表库不是前置结论;可选 Chart.js、ECharts 或原生 SVG/canvas,但 SPEC/PR 必须说明包体、构建耗时、交互能力和维护成本取舍。
Vue `monitor-web` 的 CI/CD 必须和架构一起交付。YAML 必须声明 source、build context、Node/Bun/Vite 构建环境、env image、dependency cache、registry image、GitOps path、Argo Application、Service、publicExposure、runner discovery selector 和 screenshot 验收命令。CI 读源码必须优先走 node/lane 声明的 git mirror read URL; 触发 PipelineRun 前做受控 pre-sync, GitOps promotion 后做受控 post-flush,并在 status/closeout 中输出 `pendingFlush` 、 `githubInSync` 、source commit、GitOps revision 和 PipelineRun 名称 。
Vue `monitor-web` 与中心 Monitor service 的 CI/CD 必须和架构一起交付。YAML 必须声明 source、build context、Node/Bun/Vite 构建环境、env image、dependency cache、registry image、GitOps path、Argo Application、Service、publicExposure、Host PG Secret consumer、runner control-plane discovery selector 和 screenshot 验收命令。CI 读源码必须优先走 node/lane 声明的 git mirror read URL; PR 合并后只允许自动链路完成 mirror、PaC、PipelineRun、GitOps 和 Argo 收敛 。
Vue `monitor-web` 构建必须利用 env reuse、CI tools/env image、依赖缓存和镜像层缓存。未修改 runner/backend/API 时不得重建无关运行面;纯 SPEC、CLI、文档或无需 runtime 重建的提交应在 status 中呈现 `build=0 reuse=<service-count>` 或等价 reuse 证据。Vue `monitor-web` CI/CD 总耗时或单个 build TaskRun 超过两分钟时,必须先从 env reuse、依赖缓存、git mirror pre-sync、镜像层缓存和无关服务重建方向优化,再继续 UI 功能实现;不得死等长 PipelineRun 后只记录超时。
发布成功判据不能只看 legacy `dashboard.js` 静态资源 200。Vue `monitor-web` closeout 必须记录 Vite 产物内容 hash、asset 200/字节数/SHA、HTML 引用一致性、 `/health` 、root 聚合页 browser render、 至少一个 `/sentinels/<id>` 详情页 render 、远程 PNG localPath/SHA、DOM 摘要、 overflow 结果 、Argo/runtime/source/GitOps/git mirror alignment 和 runner degraded 降级行为。所有触发、rollout、status、git mirror sync/flush 和截图验收必须走 UniDesk 受控 CLI 。
发布成功判据必须同时覆盖中心 `/health` 、Host PG schema/read-write probe、Vue assets 和 browser render,不能只看静态资源 200。 closeout 必须记录 Vite 产物 hash、中心 API、root 与 至少一个 `/sentinels/<id>` 详情页、远程 PNG localPath/SHA、DOM/ overflow、Argo/runtime/source/GitOps alignment,以及停一个 runner 后历史仍可读而 locator 显示 degraded。禁止手工触发 mirror、PipelineRun、Argo sync/refresh 或补做 CI/CD 。
### 6.13 OPS-SENTINEL-REQ-013 D518 多 runner 强边界与 OTel 根因收敛
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-SENTINEL-REQ-013 | D518 多 runner 强边界 | PJ2026-0106050813 D518 多 runner 强边界 | 多实例与账号切换、Monitor Web 聚合 、OTel、AgentRun、YAML运维 |
| OPS-SENTINEL-REQ-013 | D518 多 runner 强边界 | PJ2026-0106050813 D518 多 runner 强边界 | 多实例与账号切换、Monitor 中心服务与 Web、OTel、AgentRun、YAML运维 |
本阶段执行 issue 为 [#1206 ](https://github.com/pikasTech/unidesk/issues/1206 ),阶段子 issue 为 P0 [#1208 ](https://github.com/pikasTech/unidesk/issues/1208 )、P1 [#1209 ](https://github.com/pikasTech/unidesk/issues/1209 )、P2 [#1210 ](https://github.com/pikasTech/unidesk/issues/1210 )、P3 [#1211 ](https://github.com/pikasTech/unidesk/issues/1211 )、P4 [#1212 ](https://github.com/pikasTech/unidesk/issues/1212 )、P5 [#1213 ](https://github.com/pikasTech/unidesk/issues/1213 )、P6 [#1214 ](https://github.com/pikasTech/unidesk/issues/1214 )、P7 [#1215 ](https://github.com/pikasTech/unidesk/issues/1215 ) 和 P8 [#1216 ](https://github.com/pikasTech/unidesk/issues/1216 )。
D518/v03 不允许再以“ 多个 sentinel 配置入口共享一个 runner Deployment/Service/PVC/SQLite/FRP/Caddy owner”的形式上线 。每个 sentinel 必须有独立 runtime configRef,至少独立声明 Deployment、Service、ServiceAccount、PVC、stateRoot、SQLite path、CronJob、FRP Deployment、FRP Secret、httpProxy name、remotePort、GitOps path 和 Argo Application 。`observeWrapperRef` 不得使用 `sentinels[0]` 这类位置索引; 必须由 selected sentinel id 解引用或用等价稳定 id 绑定。
D518/v03 不允许多个 sentinel 配置入口共享一个 runner Deployment/Service/artifact PVC 。每个 sentinel 必须有独立 runtime configRef,至少独立声明 runner Deployment/Job 、Service、ServiceAccount、PVC、stateRoot、CronJob、GitOps path 和 Argo Application;公网 FRP/Caddy 只属于中心 monitor-web 。`observeWrapperRef` 不得使用 `sentinels[0]` 这类位置索引, 必须由 selected sentinel id 解引用或用等价稳定 id 绑定。
runner API 的边界必须是硬约束。 `/api/overview` 、 `/api/runs` 、 `/api/findings` 、 `/api/runs/:id` 和 `/api/report` 只能返回当前 runner `sentinelId` 、node、lane 下的数据;SQLite schema 至少包含 `sentinelId/scenarioId/observerId/runId` ,并对 runs/findings 建立 sentinel 维度索引。route sentinelId 与服务实例 sentinelId 不一致时,API 必须 返回结构化 `sentinel-route-mismatch` blocker ,不允许 fallback 到其他 sentinel 的 latest run ,也不允许前端过滤后继续展示。
runner API 只保留 health、受控 trigger 与 artifact locator 访问,不再提供 overview/runs/findings/report。中心 API 必须按 `sentinelId` 、node、lane、scenario、run identity 做显式 scope 与排序;route scope 与 registry/数据库 identity 不一致时 返回结构化 `sentinel-route-mismatch` ,不允许 fallback 到其他 sentinel 的 latest,也不允许前端过滤后继续展示。
状态语义必须区分 latest selected run 与 historical trend。latest run 的 `blocked/failed/error/timeout` 可以驱动当前状态为 blocker;历史趋势里的 red/error 样本只能作为趋势或历史风险展示,不能把一个已选 latest run 误标为当前阻塞。timing budget 超过 YAML `targetValidation.maxSeconds` 但已采集到 durable completed business turn 时,默认是非阻塞 timing warning;只有 submit/control 失败、样本缺失、报告未生成或 Code Agent 多轮业务链路不可继续时才升级为 blocker。
dashboard verify/screenshot 必须断言 selected sentinel 的 route 和 API 返回一致:远程浏览器脚本必须检查 DOM bootstrap `data-sentinel-id` 、 `/api/overview.sentinelId` 、 `/api/runs.sentinelId` 、runs rows 的 `sentinelId` 和 public URL routePrefix 。任何 dsflash route 返回 fake-echo 数据、fake-echo route 返回空 body 或 root route 绑定单 runner 的情况都必须失败并给出有界证据。
dashboard verify/screenshot 必须断言 selected sentinel 的 route 和中心 API 返回一致:远程浏览器脚本必须检查 DOM selected sentinel、overview scope 、runs rows 的 `sentinelId` 和 public URL route。任何 dsflash route 返回 fake-echo 数据、detail route 返回空 body、 root 绑定单 runner 或页面绕过中心 API 的情况都必须失败并给出有界证据。
OTel 根因契约必须与应用内 report/index 分工清楚。sentinel report/index 负责 latest、history、finding、artifact、timeline、availability 和 runner heartbeat; OTel/Tempo 负责跨服务根因链路。D518 `diagnose-code-agent` 的 AgentRun namespace/lane 必须从 `config/hwlab-node-lanes.yaml` 解析到实际 `agentrun-v02` ,不得硬编码 `agentrun-v01` 。HWLAB cloud-api、AgentRun manager 和 AgentRun runner 的 span 必须能通过 trace context 串联;缺失任一段时标为 instrumentation blocker 或 instrumentation gap,不得静默跳过。
@@ -718,7 +749,7 @@ Web 哨兵周期巡检必须由目标 node/lane 的 Kubernetes CronJob/GitOps
`web-probe sentinel control-plane status` 必须把 CronJob 作为独立 observed check,而不是只相信 Argo `Synced/Healthy` 。当 YAML 启用 cadenceScheduler 但线上缺 CronJob 时,状态必须 blocked,故障码固定为 `sentinel-cadence-cronjob-missing` ; schedule 不一致使用 `sentinel-cadence-cronjob-schedule-mismatch` ; CronJob suspend 使用 `sentinel-cadence-cronjob-suspended` 。状态输出至少展示 CronJob name、namespace、schedule/expectedSchedule、lastScheduleTime、lastSuccessfulTime、active job count、jobCount 和 latest job name。
`monitor-web` 必须把 cadence freshness 作为一等状态:显示 YAML expected cadence、scheduler heartbeat age、latest run age、latest analyzed report age、active runs、planned runs、stale multiple、CronJob 观察状态和 OTel coverage/gap。runner API 不直接查询 Kubernetes CronJob 时,页面必须显式显示 `control-plane-status-required` ,不得让用户误以为 CronJob 已观察通过。
`monitor-web` 必须把 cadence freshness 作为一等状态:显示 YAML expected cadence、scheduler heartbeat age、latest run age、latest analyzed report age、active runs、planned runs、stale multiple、CronJob 观察状态和 OTel coverage/gap。中心 API 未取得 Kubernetes CronJob observed fact 时,页面必须显式显示 `control-plane-status-required` ,不得让用户误以为 CronJob 已观察通过。
Web 哨兵必须向平台 OTel 后端发出有界、脱敏的 span 或在状态中显式标记 instrumentation gap。P15 span 名称固定为:`web_probe_sentinel.scheduler.heartbeat` 、`web_probe_sentinel.cadence.expected` 、`web_probe_sentinel.cadence.cronjob_rendered` 、`web_probe_sentinel.cadence.cronjob_observed` 、`web_probe_sentinel.quick_verify.job_start` 、`web_probe_sentinel.quick_verify.job_finish` 、`web_probe_sentinel.record_run` 、`web_probe_sentinel.scheduler_gap.detected` 。属性至少包含 node、lane、sentinelId、scenarioId、runId、cronJobName、jobName、podName、namespace、cadence、status、exitCode、failureKind、gitopsRevision、sourceCommit、imageDigest 和 valuesRedacted;不存在的属性可以省略但不得打印 Secret、prompt、cookie、provider payload 或完整 stdout/stderr。
@@ -738,16 +769,18 @@ P8 哨兵恢复执行 issue 为 [#971](https://github.com/pikasTech/unidesk/issu
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 ](https://github.com/pikasTech/HWLAB/issues/2055 ) 和 [HWLAB #2125 ](https://github.com/pikasTech/HWLAB/issues/2125 ),不得在 UI、CLI renderer 或 analyzer 中做读侧 repair。
P9 多实例巡检与账号切换链路执行 issue 为 [#1017 ](https://github.com/pikasTech/unidesk/issues/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。
P9 多实例巡检与账号切换链路执行 issue 为 [#1017 ](https://github.com/pikasTech/unidesk/issues/1017 )。P9 closeout 必须回写:SPEC P9 引用、registry 和两条 sentinel drill-down、旧 dsflash canary 迁移验证、账号切换 workflow/Secret sourceRef 验证、独立 runner Deployment/PVC/Service/GitOps/Argo 与中心索引 scope 证据、submit/command 失败处理、非阻塞计时告警证据、远程 PNG 截图布局复测,以及未完成阶段是否已拆出后续 issue。
P10 monitor-web 聚合执行 issue 为 [#1056 ](https://github.com/pikasTech/unidesk/issues/1056 )。P10 closeout 必须回写:SPEC P10 引用、runner/web 职责拆分状态、Vue+TS monitor-web 迁移边界或短修边界、root 与至少一个 route prefix 的 browser render 证据、 `web-probe sentinel dashboard verify| screenshot` 证据 、publicExposure 和 runtime provenance、 单哨兵 API 兼容性、未完成 monitor-web 架构项是否拆出后续 issue,以及 `unidesk-monitor` skill 是否记录当前操作面 。
P10 monitor-web 聚合执行 issue 为 [#1056 ](https://github.com/pikasTech/unidesk/issues/1056 )。P10 的 runner fan-out/runner-served-bridge 方案已由 P17 取代;后续 closeout 只保留可复用的 Vue 信息架构、browser render、 dashboard verify/ screenshot、publicExposure 和 runtime provenance 证据,不再以 单哨兵查询 API 兼容性作为门禁 。
P11 monitor-web 观察面板治理执行 issue 为 [#1112 ](https://github.com/pikasTech/unidesk/issues/1112 )。P11 的第一阶段必须先完成本 SPEC 收敛;SPEC 未合并前不得推进 Vue `monitor-web` 实现、CI/CD、GitOps、publicExposure 或部署代码。P11 实现 PR closeout 必须回写:SPEC P11 引用、Vue monitor-web 源码和 CI/CD 文件头部追溯、趋势曲线和运行时间线截图、固定视口三栏 overflow 摘要、cadence freshness 状态、env reuse/buildServices 证据、git mirror pre-sync/post-flush 证据、PipelineRun/Argo/GitOps/source alignment、root 与至少一个 sentinel detail 远程截图 localPath/SHA,以及超过两分钟 CI/CD 耗时是否已先从 env reuse/git mirror 方向优化。
P12 cadence 调度和 monitor-web 交互修复执行 issue 为 [#1123 ](https://github.com/pikasTech/unidesk/issues/1123 )。P12 closeout 必须回写:SPEC P12 引用、两个 10m cadence sentinel 的 stale 证据、k3s CronJob/GitOps 调度器 due 判断和触发记录、auth sentinel Argo/source alignment、趋势曲线 hover 数值和时间截图/DOM 证据、三栏 sticky header 遮盖复测、远程 PNG localPath/SHA、k3s CronJob 状态、以及两个目标 sentinel 最新 run 已刷新到当前窗口的证据。
P13 D518 多 runner 强边界与 OTel 根因收敛执行 issue 为 [#1206 ](https://github.com/pikasTech/unidesk/issues/1206 )。P13 closeout 必须回写:SPEC P13 引用、[#1208 ](https://github.com/pikasTech/unidesk/issues/1208 )-[#1216 ](https://github.com/pikasTech/unidesk/issues/1216 ) 阶段状态、D518 双 sentinel 独立 Deployment/Service/PVC/CronJob/GitOps/Argo/public route 证据、route/API sentinelId 强断言、report/index 不串线证据、dashboard verify/screenshot localPath/SHA、k3s CronJob 调度证据、latest selected run 与 historical trend 状态分层证据、 以及 OTel AgentRun namespace/trace gap 是否已解除或拆入后续 issue 。
P13 D518 多 runner 强边界与 OTel 根因收敛执行 issue 为 [#1206 ](https://github.com/pikasTech/unidesk/issues/1206 )。P13 closeout 必须回写:SPEC P13 引用、[#1208 ](https://github.com/pikasTech/unidesk/issues/1208 )-[#1216 ](https://github.com/pikasTech/unidesk/issues/1216 ) 阶段状态、D518 双 sentinel 独立 runner Deployment/Service/PVC/CronJob/GitOps/Argo 证据、中心 route/API scope 强断言、report/index 不串线证据、dashboard verify/screenshot localPath/SHA、k3s CronJob 调度证据、latest selected run 与 historical trend 状态分层证据, 以及 OTel AgentRun namespace/trace gap。
P14 Web 哨兵 CI/CD 可见性执行 issue 为 [#1285 ](https://github.com/pikasTech/unidesk/issues/1285 )。P14 closeout 必须回写:SPEC P14 引用、source commit、PR/merge commit、JD01/v03 `jd01-web-probe-sentinel` publish job、digest、GitOps revision、git mirror flush 状态、Argo/runtime observed alignment、`validate` 、dashboard screenshot、latest report,以及超过 YAML 等待预算时的结构化阶段归因和可续跑命令。
P15 Cadence 调度稳定性与 OTel 覆盖执行 issue 为 [#1372 ](https://github.com/pikasTech/unidesk/issues/1372 )。P15 closeout 必须回写:SPEC P15 引用、[#1374 ](https://github.com/pikasTech/unidesk/issues/1374 )-[#1378 ](https://github.com/pikasTech/unidesk/issues/1378 ) 阶段状态、JD01/v03 `jd01-web-probe-sentinel` CronJob manifest/GitOps/Argo/runtime observed 证据、`sentinel-cadence-cronjob-missing` 防回归状态、monitor-web cadence/OTel coverage 显示、OTel trace search 或 instrumentation-gap 证据、受控 rollout/publish job、GitOps revision、source commit、dashboard/health 验收,以及 CI/CD 门禁仍只验证 `/health` 的证据。
P17 Monitor 中心持久化与架构重构执行 issue 为 [#1868 ](https://github.com/pikasTech/unidesk/issues/1868 ), P0 调研为 [#1869 ](https://github.com/pikasTech/unidesk/issues/1869 )、[#1870 ](https://github.com/pikasTech/unidesk/issues/1870 ) 和 [#1871 ](https://github.com/pikasTech/unidesk/issues/1871 )。P17 必须按“Host PG 前置健康、中心 store/ingest/query、runner terminal submit、一次性迁移与原子切换、monitor-web/CLI 中心读取、自动发布与原入口验收”顺序推进。closeout 必须记录 SQLite 冻结 fingerprint/行数、PG 导入校验、global latest 规则、artifact locator 可达性、runner 停机后历史可读、旧 SQLite 与 runner dashboard 已退出读写路径,以及 PR 合并后的自动 CI/CD 证据。