version: 1 kind: HwlabWebProbeSentinelProfiles metadata: id: hwlab-web-probe-sentinel-profiles owner: UniDesk specRef: PJ2026-01060508 composition: mode: yaml-anchors-and-merge intent: node overlays inherit common web-probe sentinel baselines and render node/lane identity from variables. baselines: sentinel: enabled: true mode: web-probe-observe-wrapper runtime: common: namespace: "hwlab-${lane}" listenHost: 0.0.0.0 servicePort: 8080 pvcStorage: 10Gi replicas: 1 healthPath: /api/health metricsPath: /metrics scheduler: intervalMs: 600000 heartbeatStaleSeconds: 900 maxConcurrentRuns: 1 freshnessWarningMultiple: 2 observability: otel: enabled: true serviceName: "hwlab-web-probe-sentinel-${nodeLower}" tracesEndpoint: http://otel-collector.platform-infra.svc.cluster.local:4318/v1/traces sampler: parentbased_traceidratio samplerArg: "1" kubernetesApi: &kubernetesApi endpoint: host: 172.16.0.5 port: 6443 egress: enabled: true rules: - cidr: 10.43.0.1/32 port: 443 - cidr: 172.16.0.5/32 port: 6443 scheduler15m: intervalMs: 900000 heartbeatStaleSeconds: 900 maxConcurrentRuns: 1 sqlite: busyTimeoutMs: 2000 cicd: source: repository: pikasTech/unidesk branch: master gitSshUrl: ssh://git@ssh.github.com:443/pikasTech/unidesk.git gitMirrorReadUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git buildContext: "." entrypoint: scripts/web-probe-sentinel-service.ts checkoutPaths: - scripts - config - config.json - src - package.json - bun.lock - bun.lockb sourceAuthority: mode: gitMirrorSnapshot resolver: k8s-git-mirror allowHostGit: false allowGithubDirectInPipeline: false sourceSnapshot: stageRefPrefix: "refs/unidesk/snapshots/web-probe-sentinel/{branch}" missingObjectPolicy: fail-fast refreshPolicy: sync-before-snapshot cacheRef: source.gitMirrorReadUrl builder: namespace: devops-infra sourceMode: sparse-git-checkout gitSshSecretName: git-mirror-github-ssh activeDeadlineSeconds: 900 ttlSecondsAfterFinished: 3600 monitorWeb: frontendStack: vue3-vendored-browser-build runtimeMode: runner-served-bridge assetRoot: scripts/assets/web-probe-sentinel-monitor-web envReuse: mode: k8s-buildkit-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules imageBuild: packageMode: copy-only-containerfile networkMode: host proxySource: node.networkProfile.imageBuildProxy contextIgnore: generated verifyPhase: pre-image-build buildkitState: mode: hostPath path: "/var/lib/unidesk/web-probe-sentinel/buildkit-${nodeLower}" type: DirectoryOrCreate gitMirror: source: source.gitMirrorReadUrl preSync: required postFlush: required ciBudget: maxSeconds: 120 maintenance: startCommand: sentinel maintenance start stopCommand: sentinel maintenance stop confirmWait: maxSeconds: 120 publishCurrent: endToEndBudget: maxSeconds: 120 stageBudgets: sourceSyncSeconds: 20 sourceFetchSeconds: 20 monitorWebVerifySeconds: 15 imageBuildSeconds: 45 gitopsSeconds: 15 argoRuntimeSeconds: 30 dashboardVerifySeconds: 30 dashboard: enabled: true required: true viewport: 1440x900 timeoutMs: 30000 waitTimeoutMs: 60000 commandTimeoutSeconds: 90 fullPage: false publicExposure: common: enabled: true mode: pk01-caddy-frp-path hostname: monitor.pikapython.com expectedA: 82.156.23.220 frpc: image: 127.0.0.1:5000/hwlab/frpc:v0.68.1 serverAddr: 82.156.23.220 serverPort: 22000 tokenSourceRef: platform-infra/pk01-frp.env tokenSourceKey: FRP_TOKEN secretKey: frpc.toml tokenKey: token caddy: route: PK01 configPath: /etc/caddy/Caddyfile serviceName: caddy email: ops@pikapython.com tls: auto responseHeaderTimeoutSeconds: 600 secrets: jd01BootstrapSource: purpose: bootstrap-admin sourceRef: /root/.unidesk/.env/HWLAB_admin.txt sourceKey: HWLAB_ADMIN_PASSWORD sourceLine: 2 dsflashPromptSource: purpose: prompt-set sourceRef: hwlab/web-probe-sentinel-dsflash-go.env sourceKey: DSFLASH_GO_TOOL_CALL_10X_PROMPTS_JSON frpTokenSource: purpose: frp-token sourceRef: platform-infra/pk01-frp.env sourceKey: FRP_TOKEN nodes: JD01: target: extends: templates.webProbeSentinelTarget cicdCommon: extends: templates.webProbeSentinelCicdCommon sentinels: jd01-web-probe-sentinel: sentinel: extends: templates.webProbeSentinelSentinel runtime: extends: templates.webProbeSentinelRuntime kubernetesApi: *kubernetesApi publicExposure: extends: templates.webProbeSentinelPublicExposure frpc: httpProxy: remotePort: 22098 cicd: extends: templates.webProbeSentinelCicd secrets: sources: - sourceLine: 2 sourceKey: HWLAB_ADMIN_PASSWORD sourceRef: /root/.unidesk/.env/HWLAB_admin.txt purpose: bootstrap-admin - sourceKey: DSFLASH_GO_TOOL_CALL_10X_PROMPTS_JSON sourceRef: hwlab/web-probe-sentinel-dsflash-go.env purpose: prompt-set - purpose: account-a sourceRef: /root/.unidesk/.env/HWLAB_admin.txt sourceKey: HWLAB_BOOTSTRAP_ADMIN_PASSWORD sourceLine: 2 format: web-account-json usernameSourceRef: /root/.unidesk/.env/HWLAB_admin.txt usernameSourceLine: 1 - purpose: account-b sourceRef: "hwlab/${nodeLower}-${lane}-preset-users.env" sourceKey: "${NODE}_SECOND_USER_PASSWORD" format: web-account-json username: "${nodeLower}-sentinel@hwlab.local" - sourceKey: FRP_TOKEN sourceRef: platform-infra/pk01-frp.env purpose: frp-token runtimeSecrets: - name: "hwlab-web-probe-sentinel-${nodeLower}-bootstrap" namespace: "hwlab-${lane}" data: - sourcePurpose: bootstrap-admin targetKey: bootstrap-admin-password - name: "hwlab-web-probe-sentinel-${nodeLower}-prompt-set" namespace: "hwlab-${lane}" data: - sourcePurpose: prompt-set targetKey: prompts.json - name: "hwlab-web-probe-sentinel-${nodeLower}-accounts" namespace: "hwlab-${lane}" data: - sourcePurpose: account-a targetKey: account-a.json - sourcePurpose: account-b targetKey: account-b.json - name: "hwlab-web-probe-sentinel-${nodeLower}-frpc" namespace: "hwlab-${lane}" data: - sourcePurpose: frp-token targetKey: token variables: LANE: v03 controlPlaneIndex: "1" argoProjectName: hwlab-jd01 NODE: JD01 sourceGitSshUrl: ssh://git@ssh.github.com:443/pikasTech/unidesk.git sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/unidesk-master NC01: target: extends: templates.webProbeSentinelTarget cicdCommon: extends: templates.webProbeSentinelCicdCommon sentinels: nc01-web-probe-sentinel: sentinel: extends: templates.webProbeSentinelSentinel runtime: extends: templates.webProbeSentinelRuntime kubernetesApi: endpoint: host: 10.43.0.1 port: 443 egress: enabled: true rules: - cidr: 10.43.0.1/32 port: 443 publicExposure: extends: templates.webProbeSentinelPublicExposure frpc: httpProxy: remotePort: 22084 cicd: extends: templates.webProbeSentinelCicd secrets: sources: - purpose: bootstrap-admin sourceRef: "hwlab/${nodeLower}-${lane}-bootstrap-admin.env" sourceKey: HWLAB_BOOTSTRAP_ADMIN_PASSWORD - sourceKey: DSFLASH_GO_TOOL_CALL_10X_PROMPTS_JSON sourceRef: hwlab/web-probe-sentinel-dsflash-go.env purpose: prompt-set - purpose: account-a sourceRef: "hwlab/${nodeLower}-${lane}-bootstrap-admin.env" sourceKey: HWLAB_BOOTSTRAP_ADMIN_PASSWORD format: web-account-json username: admin - purpose: account-b sourceRef: "hwlab/${nodeLower}-${lane}-preset-users.env" sourceKey: "${NODE}_SECOND_USER_PASSWORD" format: web-account-json username: "${nodeLower}-sentinel@hwlab.local" - sourceKey: FRP_TOKEN sourceRef: platform-infra/pk01-frp.env purpose: frp-token runtimeSecrets: - name: "hwlab-web-probe-sentinel-${nodeLower}-bootstrap" namespace: "hwlab-${lane}" data: - sourcePurpose: bootstrap-admin targetKey: bootstrap-admin-password - name: "hwlab-web-probe-sentinel-${nodeLower}-prompt-set" namespace: "hwlab-${lane}" data: - sourcePurpose: prompt-set targetKey: prompts.json - name: "hwlab-web-probe-sentinel-${nodeLower}-accounts" namespace: "hwlab-${lane}" data: - sourcePurpose: account-a targetKey: account-a.json - sourcePurpose: account-b targetKey: account-b.json - name: "hwlab-web-probe-sentinel-${nodeLower}-frpc" namespace: "hwlab-${lane}" data: - sourcePurpose: frp-token targetKey: token variables: LANE: v03 controlPlaneIndex: "2" argoProjectName: hwlab-v03 NODE: NC01 sourceGitSshUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/unidesk-master-nc01 templates: webProbeSentinelTarget: node: "${NODE}" lane: "${LANE}" publicOriginRef: "config/hwlab-node-lanes.yaml#lanes.${LANE}.targets.${NODE}.public.webUrl" webProbeSentinelCicdCommon: controlPlaneConfigRef: "config/hwlab-node-control-plane.yaml#targets[${controlPlaneIndex}]" source: checkoutPaths: - scripts - config - config.json - src - package.json - bun.lock - bun.lockb entrypoint: scripts/web-probe-sentinel-service.ts buildContext: "." gitMirrorReadUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git gitSshUrl: "${sourceGitSshUrl}" branch: master repository: pikasTech/unidesk sourceAuthority: allowGithubDirectInPipeline: false allowHostGit: false resolver: gitea-mirror mode: giteaSnapshot sourceSnapshot: cacheRef: source.gitMirrorReadUrl refreshPolicy: gitea-controlled-snapshot missingObjectPolicy: fail-fast stageRefPrefix: "${sourceSnapshotPrefix}" argo: namespace: argocd projectName: "${argoProjectName}" repoURL: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git targetRevision: v0.3-gitops maintenance: stopCommand: sentinel maintenance stop startCommand: sentinel maintenance start monitorWeb: ciBudget: maxSeconds: 120 gitMirror: source: source.gitMirrorReadUrl preSync: not-required postFlush: not-required imageBuild: packageMode: copy-only-containerfile networkMode: host proxySource: node.networkProfile.imageBuildProxy contextIgnore: generated verifyPhase: pre-image-build buildkitState: mode: hostPath path: "/var/lib/unidesk/web-probe-sentinel/buildkit-${nodeLower}" type: DirectoryOrCreate envReuse: mode: k8s-buildkit-and-ci-node-deps nodeDepsPath: /opt/hwlab-ci-node-deps/node_modules assetRoot: scripts/assets/web-probe-sentinel-monitor-web runtimeMode: runner-served-bridge frontendStack: vue3-vendored-browser-build confirmWait: maxSeconds: 120 publishCurrent: dashboard: enabled: true required: true viewport: 1440x900 timeoutMs: 30000 waitTimeoutMs: 60000 commandTimeoutSeconds: 90 fullPage: false stageBudgets: sourceSyncSeconds: 20 sourceFetchSeconds: 20 monitorWebVerifySeconds: 15 imageBuildSeconds: 45 gitopsSeconds: 15 argoRuntimeSeconds: 30 dashboardVerifySeconds: 30 endToEndBudget: maxSeconds: 120 webProbeSentinelSentinel: mode: web-probe-observe-wrapper enabled: true id: "${nodeLower}-web-probe-sentinel" configRefs: runtime: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.runtime" scenarios: "config/hwlab-web-probe-sentinel/scenarios.multi-sentinel.yaml#sentinel.scenarios" promptSet: "config/hwlab-web-probe-sentinel/prompt-set.dsflash-go.yaml#sentinel.promptSet" reportViews: "config/hwlab-web-probe-sentinel/report-views.multi-sentinel.yaml#sentinel.reportViews" publicExposure: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.publicExposure" cicd: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.cicd" secrets: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.secrets" webProbeSentinelRuntime: kubernetesApi: endpoint: host: 172.16.0.5 port: 6443 egress: enabled: true rules: - cidr: 10.43.0.1/32 port: 443 - cidr: 172.16.0.5/32 port: 6443 observability: otel: enabled: true serviceName: "hwlab-web-probe-sentinel-${nodeLower}" tracesEndpoint: http://otel-collector.platform-infra.svc.cluster.local:4318/v1/traces sampler: parentbased_traceidratio samplerArg: "1" scheduler: freshnessWarningMultiple: 2 maxConcurrentRuns: 1 heartbeatStaleSeconds: 900 intervalMs: 600000 metricsPath: /metrics healthPath: /api/health replicas: 1 pvcStorage: 10Gi servicePort: 8080 listenHost: 0.0.0.0 namespace: "hwlab-${lane}" target: extends: templates.webProbeSentinelTarget observeWrapperRef: "config/hwlab-node-lanes.yaml#lanes.${LANE}.targets.${NODE}.observability.webProbe.sentinels[0]" serviceAccountName: "hwlab-web-probe-sentinel-${nodeLower}" deploymentName: "hwlab-web-probe-sentinel-${nodeLower}" serviceName: "hwlab-web-probe-sentinel-${nodeLower}" pvcName: "hwlab-web-probe-sentinel-${nodeLower}-state" stateRoot: "/var/lib/web-probe-sentinel-${nodeLower}" imageRef: "127.0.0.1:5000/hwlab/web-probe-sentinel-${nodeLower}:source-commit" sqlite: busyTimeoutMs: 2000 path: "/var/lib/web-probe-sentinel-${nodeLower}/index.sqlite" webProbeSentinelPublicExposure: expectedA: 82.156.23.220 hostname: monitor.pikapython.com mode: pk01-caddy-frp-path enabled: true publicBaseUrl: "https://monitor.pikapython.com/sentinels/${nodeLower}-web-probe-sentinel" routePrefix: "/sentinels/${nodeLower}-web-probe-sentinel" frpc: tokenKey: token secretKey: frpc.toml tokenSourceKey: FRP_TOKEN tokenSourceRef: platform-infra/pk01-frp.env serverPort: 22000 serverAddr: 82.156.23.220 image: 127.0.0.1:5000/hwlab/frpc:v0.68.1 deploymentName: "hwlab-web-probe-sentinel-${nodeLower}-frpc" secretName: "hwlab-web-probe-sentinel-${nodeLower}-frpc" httpProxy: name: "hwlab-${nodeLower}-${lane}-web-probe-sentinel" remotePort: 0 localIP: "hwlab-web-probe-sentinel-${nodeLower}.hwlab-${lane}.svc.cluster.local" localPort: 8080 caddy: responseHeaderTimeoutSeconds: 600 tls: auto email: ops@pikapython.com serviceName: caddy configPath: /etc/caddy/Caddyfile route: PK01 managedBlockOwner: "hwlab-web-probe-sentinel-${nodeLower}-${lane}" webProbeSentinelCicd: extends: templates.webProbeSentinelCicdCommon builder: ttlSecondsAfterFinished: 3600 activeDeadlineSeconds: 900 gitSshSecretName: git-mirror-github-ssh sourceMode: sparse-git-checkout namespace: devops-infra jobPrefix: "web-probe-sentinel-${nodeLower}-publish" gitopsPath: "deploy/gitops/node/${nodeLower}/web-probe-sentinel" argo: applicationName: "hwlab-web-probe-sentinel-${nodeLower}" image: repository: "127.0.0.1:5000/hwlab/web-probe-sentinel-${nodeLower}" tagSource: source-commit baseImageRef: "config/hwlab-node-control-plane.yaml#targets[${controlPlaneIndex}].tekton.toolsImage.output" envRecipeRef: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.runtime" targetValidation: scenarioId: workbench-dsflash-go-hwpod-two-turn-freeze-repro maxSeconds: 600 serviceUnavailablePolicy: structured-failure cadenceScheduler: enabled: true reason: k8s-native-periodic-quick-verify concurrencyPolicy: Forbid startingDeadlineSeconds: 600 successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 5 activeDeadlineSlackSeconds: 60 ttlSecondsAfterFinished: 86400 backoffLimit: 0