feat(web): surface callback trace backlog work item
All checks were successful
CD Pipeline / tests (push) Successful in 1m27s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 3m28s
CD Pipeline / post-deploy-checks (push) Successful in 1m41s

This commit is contained in:
Your Name
2026-05-25 22:00:42 +08:00
parent 2c058e5adf
commit 44f48b68fe
4 changed files with 149 additions and 0 deletions

View File

@@ -2225,6 +2225,7 @@
"remediationQueue": "Every degraded / failed / timeout row must map to replay, reverify, ticket, or manual review",
"telegramCallbacks": "Detail and history buttons cannot depend only on Redis TTL or stale snapshots",
"callbackOwnerReview": "Telegram detail/history callbacks without a KM owner-review link must become trackable work items",
"callbackTraceRecoveryBacklog": "Callback trace gaps must show recovery signal, 24h decay, and the backlog next step",
"ciSecretHygiene": "Workflows must not mount 機密設定 in step env / action inputs; historical logs still need rotation and retention governance",
"governanceDispatch": "Governance alerts must enter dispatch and expose skipped / pending / repaired",
"knowledgeHealthcheck": "knowledge_degradation must show Hermes / OpenClaw / ElephantAlpha ownership, current stage, and owner review point",
@@ -2270,6 +2271,10 @@
"callbackOwnerReviewAutomation": "Automation: {state}; safe auto-repair={safe}",
"callbackOwnerReviewBlocker": "Blocker: {reason}",
"callbackOwnerReviewEmpty": "Recent callback evidence is matched or no data is available yet",
"callbackTraceRecoveryBacklog": "Callback trace backlog: missing trace {missing}; 1h {recent1h}; 24h {recent24h}; traced after gap {recovered}; recovery {status}",
"callbackTraceRecoveryDecision": "Decision: {gap}; next: {next}",
"callbackTraceRecoveryLatest": "Last gap: {missing}; recovery first: {first}; recovery latest: {latest}",
"callbackTraceRecoveryUnavailable": "Callback trace recovery summary has not returned yet",
"ciSecretHygiene": "Repo-controlled step env / action input exposure is guarded; key rotation and log retention remain",
"governance": "Unresolved governance alerts: {unresolved}; 待派送: {queued}",
"governanceUnavailable": "Governance events API is not responding; 待派送: {queued}",

View File

@@ -2226,6 +2226,7 @@
"remediationQueue": "每筆 degraded / failed / timeout 都必須映射到重跑、重驗、Ticket 或人工檢查",
"telegramCallbacks": "按下詳情與歷史不能再只依賴 Redis TTL 或舊快照",
"callbackOwnerReview": "Telegram 詳情 / 歷史若未連到 KM owner-review必須變成可追蹤工作項",
"callbackTraceRecoveryBacklog": "Callback trace 缺口必須顯示復原訊號、24h decay 與 backlog 下一步",
"ciSecretHygiene": "workflow 不可再把 機密設定 掛在 step env / action input歷史 log 需另做輪換與保留期治理",
"governanceDispatch": "治理告警必須進 dispatch並標示 skipped / pending / repaired",
"knowledgeHealthcheck": "knowledge_degradation 必須顯示 Hermes / OpenClaw / ElephantAlpha 分工、目前階段與 owner 審核點",
@@ -2271,6 +2272,10 @@
"callbackOwnerReviewAutomation": "自動化:{state};可安全自動修復={safe}",
"callbackOwnerReviewBlocker": "卡點:{reason}",
"callbackOwnerReviewEmpty": "近期 callback evidence 均已匹配或尚無資料",
"callbackTraceRecoveryBacklog": "Callback trace backlog缺 trace {missing}1h {recent1h}24h {recent24h}gap 後 traced {recovered};復原 {status}",
"callbackTraceRecoveryDecision": "判讀:{gap};下一步:{next}",
"callbackTraceRecoveryLatest": "最後缺口:{missing};復原首筆:{first};復原最新:{latest}",
"callbackTraceRecoveryUnavailable": "Callback trace recovery summary 尚未回傳",
"ciSecretHygiene": "repo 可控 step env / action input 泄漏面已加 guard仍需 key rotation 與 log retention 收斂",
"governance": "未解治理告警:{unresolved};待派送:{queued}",
"governanceUnavailable": "治理事件 API 目前無法回應;待派送:{queued}",

View File

@@ -827,11 +827,25 @@ type CallbackReplyWorkItemEvent = {
km_stale_completion_summary?: KmStaleCallbackCompletionSummary | null;
};
type CallbackReplyAuditSummary = {
outbound_reply_markup_missing_trace_ref_total?: number;
outbound_reply_markup_missing_trace_ref_recent_1h_total?: number;
outbound_reply_markup_missing_trace_ref_recent_24h_total?: number;
outbound_reply_markup_missing_trace_ref_latest_sent_at?: string | null;
outbound_reply_markup_trace_ref_gap_status?: string | null;
outbound_reply_markup_trace_ref_gap_next_action?: string | null;
outbound_reply_markup_trace_ref_after_gap_total?: number;
outbound_reply_markup_trace_ref_after_gap_first_sent_at?: string | null;
outbound_reply_markup_trace_ref_after_gap_latest_sent_at?: string | null;
outbound_reply_markup_trace_ref_gap_recovery_status?: string | null;
};
type CallbackRepliesWorkItemResponse = {
items?: CallbackReplyWorkItemEvent[];
total: number;
page: number;
per_page: number;
summary?: CallbackReplyAuditSummary | null;
};
type AiRouteRepairEvidence = {
@@ -1610,6 +1624,27 @@ function callbackOwnerReviewOpenEvents(
});
}
function callbackTraceRecoveryStatus(
summary: CallbackReplyAuditSummary | null | undefined
): WorkStatus {
if (!summary) {
return "blocked";
}
const missingTrace = summary.outbound_reply_markup_missing_trace_ref_total ?? 0;
if (missingTrace <= 0) {
return "live";
}
const gapStatus = summary.outbound_reply_markup_trace_ref_gap_status;
const recoveryStatus = summary.outbound_reply_markup_trace_ref_gap_recovery_status;
if (gapStatus === "active_gap" || recoveryStatus === "no_recovery_signal") {
return "blocked";
}
if (recoveryStatus === "recovered_after_gap") {
return "in_progress";
}
return "watching";
}
function buildWorkItems(
telemetry: Telemetry,
t: ReturnType<typeof useTranslations>
@@ -1643,6 +1678,7 @@ function buildWorkItems(
latestCallbackOwnerReview?.km_stale_completion_summary ?? null;
const latestCallbackWorkItem = latestCallbackSummary?.work_item ?? null;
const latestCallbackTriage = latestCallbackWorkItem?.triage ?? null;
const callbackTraceSummary = telemetry.callbackReplies?.summary ?? null;
const aiRoute = telemetry.aiRouteStatus;
const aiRouteRepairEvidence = aiRoute?.repair_evidence ?? null;
const aiRouteWorkItem = aiRouteRepairEvidence?.work_item ?? null;
@@ -1993,6 +2029,58 @@ function buildWorkItems(
: [t("evidence.callbackOwnerReviewEmpty")],
href: latestCallbackWorkItem?.target_href ?? "/awooop/runs",
},
{
id: "callbackTraceRecoveryBacklog",
phase: "T195",
status: callbackTraceRecoveryStatus(callbackTraceSummary),
surfaceKey: "workItems",
source: "/api/v1/platform/runs/callback-replies summary",
gateKey: "callbackTraceRecoveryBacklog",
evidence: t("evidence.callbackTraceRecoveryBacklog", {
missing:
callbackTraceSummary?.outbound_reply_markup_missing_trace_ref_total ??
0,
recent1h:
callbackTraceSummary
?.outbound_reply_markup_missing_trace_ref_recent_1h_total ?? 0,
recent24h:
callbackTraceSummary
?.outbound_reply_markup_missing_trace_ref_recent_24h_total ?? 0,
recovered:
callbackTraceSummary?.outbound_reply_markup_trace_ref_after_gap_total ??
0,
status:
callbackTraceSummary
?.outbound_reply_markup_trace_ref_gap_recovery_status ?? "--",
}),
evidenceDetails: callbackTraceSummary
? [
t("evidence.callbackTraceRecoveryDecision", {
gap:
callbackTraceSummary.outbound_reply_markup_trace_ref_gap_status ??
"--",
next:
callbackTraceSummary
.outbound_reply_markup_trace_ref_gap_next_action ?? "--",
}),
t("evidence.callbackTraceRecoveryLatest", {
missing:
callbackTraceSummary
.outbound_reply_markup_missing_trace_ref_latest_sent_at ??
"--",
first:
callbackTraceSummary
.outbound_reply_markup_trace_ref_after_gap_first_sent_at ??
"--",
latest:
callbackTraceSummary
.outbound_reply_markup_trace_ref_after_gap_latest_sent_at ??
"--",
}),
]
: [t("evidence.callbackTraceRecoveryUnavailable")],
href: "/awooop/runs?project_id=awoooi",
},
{
id: "ciSecretHygiene",
phase: "T44",

View File

@@ -21620,3 +21620,54 @@ GET /api/v1/health
- KM governance約 84.6%。
- AI Provider lane visibility約 92.2%。
- 完整 AI 自動化管理產品化:約 98.15%。
### 2026-05-25 — T195 Callback trace recovery backlog work itempre-deploy
**背景**T194 已在 Runs / TG Callback Evidence 顯示 `recovered_after_gap`,但它
仍只是摘要文字。T195 把同一份 callback summary 接進 AwoooP Work Items
`recovered_after_gap + 24h decay` 進入 backlog 視角,而不是靠值班者記住。
**完成變更**
- AwoooP Work Items 讀取 `/api/v1/platform/runs/callback-replies``summary`
- 新增 `callbackTraceRecoveryBacklog` 工作項投影:
- `missing_trace_ref_total`
- `recent_1h / recent_24h`
- `trace_ref_after_gap_total`
- `trace_ref_gap_recovery_status`
- `trace_ref_gap_status / next_action`
- 狀態規則:
- 無 summary`blocked`
- 缺 trace = 0`live`
- `active_gap``no_recovery_signal``blocked`
- `recovered_after_gap``in_progress`,代表舊 backlog 正在 24h decay。
- 其他:`watching`
**local validation完成**
```text
jq empty apps/web/messages/zh-TW.json apps/web/messages/en.json
pnpm --dir apps/web exec tsc --noEmit --tsBuildInfoFile /tmp/awoooi-t195-tsconfig.tsbuildinfo
pass
pnpm --dir apps/web lint -- --file 'src/app/[locale]/awooop/work-items/page.tsx'
pass; no warnings
NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --dir apps/web run build
pass; Sentry global-error / instrumentation-client warnings are pre-existing
git diff --check
pass
```
**目前整體進度pre-deploy**
- AwoooP 告警可觀測鏈:約 99.88%。
- 低風險自動修復閉環:約 95.9%。
- 前端 AI 自動化管理介面同步:約 99.8%。
- Telegram outbound / callback DB coverage 可視化:約 99.88%。
- callback / DB replayability約 99.1%。
- Work Items / backlog 可追蹤性:約 96.5%。
- MCP / 自建 MCP 可視化:約 95.1%。
- Sentry / SigNoz source correlation約 94.5%。
- Ansible / PlayBook 可視化:約 92.6%。
- KM governance約 84.6%。
- AI Provider lane visibility約 92.2%。
- 完整 AI 自動化管理產品化:約 98.2%。