From 204c0ea00e88e7281594a966156e2a5beb36403b Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 3 Jul 2026 05:20:26 +0000 Subject: [PATCH] fix: restore jd01 sentinel follower status --- .../check-catalog.yaml | 16 ++++++++++++ scripts/src/cicd.ts | 26 +++++++++++++++++-- scripts/src/hwlab-node-web-sentinel-cicd.ts | 6 +++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/config/hwlab-web-probe-sentinel/check-catalog.yaml b/config/hwlab-web-probe-sentinel/check-catalog.yaml index c8aa07c0..9962a219 100644 --- a/config/hwlab-web-probe-sentinel/check-catalog.yaml +++ b/config/hwlab-web-probe-sentinel/check-catalog.yaml @@ -923,3 +923,19 @@ sentinel: actionZh: 先改进 turn-summary/trace-frame 诊断字段,再判断业务恢复。 blocking: true order: 1130 + - code: WBC-114 + id: frontend-performance-loaf-only-no-cpu-profile + level: warning + titleZh: 缺少 CPU 性能画像 + summaryZh: 本次性能证据只有 LongTask、LoAF 或事件循环样本,没有完成的 CPU profile 采集。 + actionZh: 需要函数级热点结论时,先执行显式性能采集并重新分析。 + blocking: false + order: 1140 + - code: WBC-115 + id: tool-target-page-not-ready + level: error + titleZh: 目标页面未就绪 + summaryZh: 页面观察目标没有进入预期 Workbench 主界面,不能继续解释业务轮次或前端热点。 + actionZh: 先修复目标 node/lane 的 Web 访问或 Workbench 壳加载,再重新启动观察。 + blocking: true + order: 1150 diff --git a/scripts/src/cicd.ts b/scripts/src/cicd.ts index 3637c747..f9212c19 100644 --- a/scripts/src/cicd.ts +++ b/scripts/src/cicd.ts @@ -230,7 +230,7 @@ export function cicdHelp(): unknown { "bun scripts/cli.ts cicd branch-follower status --live", "bun scripts/cli.ts cicd branch-follower run-once --all --dry-run", "bun scripts/cli.ts cicd branch-follower run-once --follower hwlab-jd01-v03 --confirm --wait", - "bun scripts/cli.ts cicd branch-follower events --follower agentrun-d601-v02", + "bun scripts/cli.ts cicd branch-follower events --follower agentrun-jd01-v02", "bun scripts/cli.ts cicd branch-follower logs --follower web-probe-sentinel-master", ], config: DEFAULT_CONFIG_PATH, @@ -869,7 +869,8 @@ async function readAdapterStatus(follower: FollowerSpec, options: ParsedOptions) "sourceCommit", "observedSha", "alignment.sourceCommit", - ], ["sourceCommit", "observedSha", "observedCommit", "selectedCommit", "selectedSourceCommit"]); + ], ["sourceCommit", "observedSha", "observedCommit", "selectedCommit", "selectedSourceCommit"]) + ?? adapterObservedShaFromText(result.stdout, follower); const targetSha = firstStringPath(body, [ "summary.targetCommit", "summary.targetSha", @@ -1367,6 +1368,27 @@ function firstStringByKey(root: unknown, keys: string[]): string | null { return null; } +function adapterObservedShaFromText(stdout: string, follower: FollowerSpec): string | null { + if (stdout.trim().length === 0) return null; + const branch = escapeRegex(follower.source.branch); + const sourceLine = new RegExp(`${escapeRegex(follower.source.repository)}@${branch}\\s+([0-9a-f]{12,40})`, "iu").exec(stdout); + if (sourceLine !== null) return sourceLine[1]; + for (const pattern of [ + /"sourceCommit"\s*:\s*"([0-9a-f]{40})"/iu, + /"commit"\s*:\s*"([0-9a-f]{40})"/iu, + /sourceCommit['"]?\s*[:=]\s*['"]?([0-9a-f]{40})/iu, + /\bcommit['"]?\s*[:=]\s*['"]?([0-9a-f]{40})/iu, + ]) { + const match = pattern.exec(stdout); + if (match !== null) return match[1]; + } + return null; +} + +function escapeRegex(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"); +} + function recordAt(root: Record, path: string[]): Record | null { let current: unknown = root; for (const item of path) { diff --git a/scripts/src/hwlab-node-web-sentinel-cicd.ts b/scripts/src/hwlab-node-web-sentinel-cicd.ts index 24b3ea1c..34bf0d39 100644 --- a/scripts/src/hwlab-node-web-sentinel-cicd.ts +++ b/scripts/src/hwlab-node-web-sentinel-cicd.ts @@ -8,6 +8,7 @@ // SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-30-p14-sentinel-cicd-visibility. // SPEC: PJ2026-01060508 Web哨兵 draft-2026-07-01-p15-cadence-otel. // SPEC: PJ2026-01060508 Web哨兵 draft-2026-07-01-p16-cicd-source-snapshot. +// SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower. // Responsibility: YAML-first CI/CD, image, GitOps and Argo command plan for the web-probe sentinel. import { createHash, randomUUID } from "node:crypto"; import { existsSync, readFileSync } from "node:fs"; @@ -27,7 +28,9 @@ import { arrayAt, arrayAtNullable, booleanAt, + booleanAtNullable, compactCommand, + configRefFile, displayPath, finiteNumberOrNull, isRecord, @@ -38,6 +41,7 @@ import { numberAtNullable, parseEnvFile, parseJsonObject, + readConfigFile, record, recordTarget, rendered, @@ -48,8 +52,10 @@ import { renderPublishResult, resolveSentinelChildJson, safeJobSegment, + safeKubernetesSegment, secretSourcePaths, sentinelCliSuffix, + sentinelPipelineRunName, sentinelSourceSnapshotRef, sentinelSourceSnapshotStageRefPrefix, sha256,