feat(web): show owner response validation rollup
This commit is contained in:
@@ -3778,7 +3778,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"githubPrimaryReadiness": {
|
||||
"githubPrimaryReadiness": {
|
||||
"title": "GitHub Primary Readiness",
|
||||
"subtitle": "AwoooP home mirrors the source-control readiness gap for moving from Gitea to GitHub. It is framework-phase visibility only: no repo creation, refs mutation, secret value collection, or primary switch.",
|
||||
"badge": "Read-only summary",
|
||||
@@ -3809,19 +3809,104 @@
|
||||
"detail": "Workflow / secret name inventory is still incomplete for 7 repos."
|
||||
}
|
||||
},
|
||||
"readinessRefs": {
|
||||
"primaryReadiness": "The GitHub primary readiness gate remains a candidate and must not trigger repo creation or visibility changes.",
|
||||
"ownerValidation": "The owner response validation rollup shows all four response packets still waiting for human reply and acceptance.",
|
||||
"rollbackAdr": "The rollback ADR has no owner-approved dry-run yet, so GitHub cannot become primary.",
|
||||
"workflowInventory": "Workflow / secret name inventory collects names and routing only; it does not collect secret values or change GitHub secrets."
|
||||
"readinessRefs": {
|
||||
"primaryReadiness": "The GitHub primary readiness gate remains a candidate and must not trigger repo creation or visibility changes.",
|
||||
"ownerValidation": "The owner response validation rollup shows all four response packets still waiting for human reply and acceptance.",
|
||||
"rollbackAdr": "The rollback ADR has no owner-approved dry-run yet, so GitHub cannot become primary.",
|
||||
"workflowInventory": "Workflow / secret name inventory collects names and routing only; it does not collect secret values or change GitHub secrets."
|
||||
}
|
||||
},
|
||||
"ownerResponseValidation": {
|
||||
"title": "Owner Response Validation Rollup",
|
||||
"subtitle": "AwoooP home shows the S4.9-S4.12 owner response packets, intake, validation, and audit checks in one read-only board. received / accepted / rejected all remain 0, so this is not approval or execution authorization.",
|
||||
"badge": "Read-only validation",
|
||||
"openIwooos": "Open IwoooS",
|
||||
"packetsTitle": "Four Waiting Response Packets",
|
||||
"validationTitle": "Validation And Audit Checks",
|
||||
"boundaryLabel": "Validation Boundary",
|
||||
"boundaryTitle": "Still waiting for owner evidence",
|
||||
"boundaryDetail": "This rollup only displays source_control_owner_response_validation_rollup_v1. It must not be treated as owner response received, owner response accepted, GitHub primary approval, repo / refs / workflow / secret authorization, or runtime execution.",
|
||||
"fields": {
|
||||
"templates": "Templates",
|
||||
"received": "Received",
|
||||
"accepted": "Accepted",
|
||||
"rejected": "Rejected"
|
||||
},
|
||||
"metrics": {
|
||||
"packets": {
|
||||
"label": "Response Packets",
|
||||
"detail": "S4.9-S4.12 are all still waiting for owner responses."
|
||||
},
|
||||
"templates": {
|
||||
"label": "Response Templates",
|
||||
"detail": "22 templates are questions for owners, not sent requests."
|
||||
},
|
||||
"received": {
|
||||
"label": "Received",
|
||||
"detail": "Still 0; visibility is not receipt completion."
|
||||
},
|
||||
"accepted": {
|
||||
"label": "Accepted",
|
||||
"detail": "Still 0; GitHub primary and runtime gates remain blocked."
|
||||
},
|
||||
"rejected": {
|
||||
"label": "Rejected",
|
||||
"detail": "Still 0; raw payload or secret values must be quarantined."
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"packets": {
|
||||
"giteaInventory": {
|
||||
"title": "Gitea Inventory Owner Attestation",
|
||||
"detail": "Collect public-only / local gap, org / user endpoint, 110 adjacent scope, canonical owner, and legacy disposition."
|
||||
},
|
||||
"githubTarget": {
|
||||
"title": "GitHub Target Owner Decision",
|
||||
"detail": "Confirm target, visibility, and canonical owner per repo; do not create repos or change visibility."
|
||||
},
|
||||
"refTruth": {
|
||||
"title": "Refs Truth Owner Response",
|
||||
"detail": "Confirm main / dev truth, deprecated drift, release tags, and GitHub-only refs; do not sync, delete, or force push refs."
|
||||
},
|
||||
"workflowSecret": {
|
||||
"title": "Workflow / Secret Name Owner Response",
|
||||
"detail": "Collect workflow, runner, deploy key, branch protection, secret names, and owner metadata only; never collect secret values."
|
||||
}
|
||||
},
|
||||
"checks": {
|
||||
"crossPacket": {
|
||||
"label": "Cross-Packet Checks",
|
||||
"detail": "10 cross-packet checks only validate consistency."
|
||||
},
|
||||
"evidenceRouting": {
|
||||
"label": "Evidence Routing",
|
||||
"detail": "6 routing rules only route to more evidence, quarantine, or read-only updates."
|
||||
},
|
||||
"displaySections": {
|
||||
"label": "Display Sections",
|
||||
"detail": "8 sections define AwoooP read-only display order."
|
||||
},
|
||||
"stateTransitions": {
|
||||
"label": "State Transitions",
|
||||
"detail": "7 rules define review semantics only; no execution."
|
||||
},
|
||||
"reviewerChecklist": {
|
||||
"label": "Reviewer Checklist",
|
||||
"detail": "9 checklist items guide human review."
|
||||
},
|
||||
"reviewerOutcomes": {
|
||||
"label": "Reviewer Outcomes",
|
||||
"detail": "7 lanes only route to more evidence, quarantine, rejection, or later gates."
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"title": "Automation Quality",
|
||||
"subtitle": "Whether recent alerts actually reached AI auto-repair, verification, and learning writeback in the last 24 hours.",
|
||||
"claimReady": "Full Loop Claim Ready",
|
||||
"claimBlocked": "Full Loop Claim Blocked",
|
||||
"unavailable": "Unavailable",
|
||||
"claimReady": "Full Loop Claim Ready",
|
||||
"claimBlocked": "Full Loop Claim Blocked",
|
||||
"claimReadyDetail": "Every alert completed the verified loop",
|
||||
"claimBlockedDetail": "Some alerts still lack execution, verification, or learning records",
|
||||
"unavailable": "Unavailable",
|
||||
"loadFailed": "Unable to load the automation quality summary. Check Operator permissions and the truth-chain API.",
|
||||
"empty": "No alert quality data is available yet.",
|
||||
"yes": "Yes",
|
||||
|
||||
@@ -3724,106 +3724,191 @@
|
||||
"home": {
|
||||
"eyebrow": "AI 自動化飛輪控制面",
|
||||
"title": "AwoooP 治理總覽",
|
||||
"subtitle": "把租戶、合約、Run、審批與通道狀態收斂到同一個操作面,避免 AI 自動化飛輪和治理面各自長出一套邏輯。",
|
||||
"subtitle": "把租戶、合約、執行紀錄、審批與通道狀態收斂到同一個操作面,避免 AI 自動化飛輪和治理面各自長出一套邏輯。",
|
||||
"refresh": "重新整理",
|
||||
"snapshotStatus": "快照狀態",
|
||||
"lastUpdated": "最後更新",
|
||||
"migrationMode": "遷移模式",
|
||||
"migrationValue": "mirror / shadow",
|
||||
"migrationValue": "鏡像 / 影子模式",
|
||||
"ready": "同步中",
|
||||
"loading": "讀取中",
|
||||
"degraded": "降級",
|
||||
"securityMirror": {
|
||||
"title": "IwoooS 資安鏡像",
|
||||
"subtitle": "AwoooP 首頁以只讀候選方式顯示 IwoooS / 資安鏡像狀態,讓使用者理解資安網進度與邊界;這不是 production landing enabled,也不接執行路由器。",
|
||||
"subtitle": "AwoooP 首頁以只讀候選方式顯示 IwoooS / 資安鏡像狀態,讓使用者理解資安網進度與邊界;這不是正式入口啟用,也不接執行路由器。",
|
||||
"badge": "只讀候選",
|
||||
"openIwooos": "開啟 IwoooS",
|
||||
"checkpointsTitle": "接入檢查",
|
||||
"boundaryLabel": "安全邊界",
|
||||
"boundaryTitle": "仍維持低摩擦框架期",
|
||||
"boundaryDetail": "這個面板只顯示已提交快照與 guard 口徑,不呼叫 Kali、GitHub、Gitea 或 runtime API,也不提供掃描、執行、修復、部署、主要來源切換或 refs 動作。",
|
||||
"boundaryDetail": "這個面板只顯示已提交快照與防護檢查口徑,不呼叫 Kali、GitHub、Gitea 或執行期 API,也不提供掃描、執行、修復、部署、主要來源切換或分支 / 標籤參照動作。",
|
||||
"metrics": {
|
||||
"headline": {
|
||||
"label": "整體資安網",
|
||||
"detail": "headline 仍等負責人回覆、脫敏匯入、runtime gate、GitHub 主要來源或 AwoooP production landing evidence。"
|
||||
"detail": "整體百分比仍等負責人回覆、脫敏匯入、執行期閘門、GitHub 主要來源或 AwoooP 正式入口證據。"
|
||||
},
|
||||
"framework": {
|
||||
"label": "框架成熟度",
|
||||
"detail": "治理、文件、schema、只讀 evidence 與 IwoooS 投影已接近完整。"
|
||||
"detail": "治理、文件、結構定義、只讀證據與 IwoooS 投影已接近完整。"
|
||||
},
|
||||
"runtime": {
|
||||
"label": "落地執行",
|
||||
"detail": "runtime ingestion、GitHub 主要來源與 AwoooP production landing 仍需後續 evidence。"
|
||||
"detail": "執行期匯入、GitHub 主要來源與 AwoooP 正式入口仍需後續證據。"
|
||||
},
|
||||
"activeGates": {
|
||||
"label": "主動執行閘門",
|
||||
"detail": "目前維持 0,任何主機或 blocking control 都仍需獨立批准。"
|
||||
"detail": "目前維持 0,任何主機或阻擋型控制都仍需獨立批准。"
|
||||
}
|
||||
},
|
||||
"checkpoints": {
|
||||
"iwooosProjection": {
|
||||
"title": "IwoooS 投影可讀",
|
||||
"detail": "AwoooP 只顯示 IwoooS 態勢、進度、evidence refs 與禁止動作。"
|
||||
"detail": "AwoooP 只顯示 IwoooS 態勢、進度、證據參照與禁止動作。"
|
||||
},
|
||||
"rollupGuard": {
|
||||
"title": "Guard 口徑一致",
|
||||
"title": "防護檢查口徑一致",
|
||||
"detail": "接手前維持 security-mirror-progress-guard.py 與 source-control-owner-response-guard.py 綠燈。"
|
||||
},
|
||||
"ownerResponse": {
|
||||
"title": "負責人回覆仍等待",
|
||||
"detail": "S4.9 到 S4.12 received / accepted 都仍為 0,不把顯示狀態當驗收完成。"
|
||||
"detail": "S4.9 到 S4.12 收到 / 接受都仍為 0,不把顯示狀態當驗收完成。"
|
||||
},
|
||||
"productionLanding": {
|
||||
"title": "Production landing 尚未完成",
|
||||
"detail": "AwoooP 主線仍需 deployment proof 與只讀消費 evidence 才能進入 headline 重估。"
|
||||
"title": "正式入口尚未完成",
|
||||
"detail": "AwoooP 主線仍需部署證據與只讀消費證據才能進入整體百分比重估。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"githubPrimaryReadiness": {
|
||||
"title": "GitHub 主要來源就緒度",
|
||||
"subtitle": "AwoooP 首頁同步顯示 Gitea 轉 GitHub 的原始碼管控就緒度缺口;目前只做框架期可視化,不建立 repo、不改 refs、不收 secret value,也不切換主要來源。",
|
||||
"badge": "只讀摘要",
|
||||
"githubPrimaryReadiness": {
|
||||
"title": "GitHub 主要來源就緒度",
|
||||
"subtitle": "AwoooP 首頁同步顯示 Gitea 轉 GitHub 的原始碼管控就緒度缺口;目前只做框架期可視化,不建立專案庫、不改分支 / 標籤參照、不收機密明文值,也不切換主要來源。",
|
||||
"badge": "只讀摘要",
|
||||
"openIwooos": "開啟 IwoooS",
|
||||
"readinessRefsTitle": "就緒度 evidence refs",
|
||||
"readinessRefsTitle": "就緒度證據參照",
|
||||
"boundaryLabel": "GitHub 主要來源邊界",
|
||||
"boundaryTitle": "目前仍不可推進主要來源切換",
|
||||
"boundaryDetail": "這個摘要只顯示已提交快照與負責人回覆缺口,不能被解讀成 GitHub 主要來源批准、repo 建立授權、refs 變更、secret 收集、Gitea 停用或 runtime execution。",
|
||||
"boundaryDetail": "這個摘要只顯示已提交快照與負責人回覆缺口,不能被解讀成 GitHub 主要來源批准、專案庫建立授權、分支 / 標籤參照變更、機密值收集、Gitea 停用或執行期執行。",
|
||||
"metrics": {
|
||||
"candidateRepos": {
|
||||
"label": "候選 repo",
|
||||
"detail": "S2.63 起已盤點 8 個候選 repo;這不是建立 GitHub repo 的授權。"
|
||||
"label": "候選專案庫",
|
||||
"detail": "S2.63 起已盤點 8 個候選專案庫;這不是建立 GitHub 專案庫的授權。"
|
||||
},
|
||||
"inScopeRepos": {
|
||||
"label": "範圍內 repo",
|
||||
"detail": "目前 7 個 repo 進入主要來源就緒度範圍,仍等待負責人回覆。"
|
||||
"label": "範圍內專案庫",
|
||||
"detail": "目前 7 個專案庫進入主要來源就緒度範圍,仍等待負責人回覆。"
|
||||
},
|
||||
"primaryReady": {
|
||||
"label": "主要來源就緒數",
|
||||
"detail": "ready count 維持 0,不能切換 GitHub 主要來源或停用 Gitea。"
|
||||
"detail": "就緒數維持 0,不能切換 GitHub 主要來源或停用 Gitea。"
|
||||
},
|
||||
"ownerResponses": {
|
||||
"label": "負責人回覆",
|
||||
"detail": "22 個回覆範本仍為 0 received / 0 accepted。"
|
||||
"detail": "22 個回覆範本仍為 0 收到 / 0 接受。"
|
||||
},
|
||||
"workflowInventory": {
|
||||
"label": "工作流程清冊",
|
||||
"detail": "7 個 repo 的 workflow / secret 名稱清冊尚未完成。"
|
||||
"detail": "7 個專案庫的工作流程 / 機密名稱清冊尚未完成。"
|
||||
}
|
||||
},
|
||||
"readinessRefs": {
|
||||
"primaryReadiness": "GitHub 主要來源就緒度閘門仍是候選狀態,不能觸發 repo 建立或可見性變更。",
|
||||
"ownerValidation": "負責人回覆驗證彙總顯示四包回覆資料都仍等待人工回覆與驗收。",
|
||||
"rollbackAdr": "Rollback ADR 尚未完成 owner approved dry-run,因此不能把 GitHub 切為主要來源。",
|
||||
"workflowInventory": "Workflow / secret 名稱清冊只收集名稱與路由,不收 secret value、不改 GitHub secrets。"
|
||||
"readinessRefs": {
|
||||
"primaryReadiness": "GitHub 主要來源就緒度閘門仍是候選狀態,不能觸發專案庫建立或可見性變更。",
|
||||
"ownerValidation": "負責人回覆驗證彙總顯示四包回覆資料都仍等待人工回覆與驗收。",
|
||||
"rollbackAdr": "回復架構決策紀錄尚未完成負責人批准的演練,因此不能把 GitHub 切為主要來源。",
|
||||
"workflowInventory": "工作流程 / 機密名稱清冊只收集名稱與路由,不收機密明文值、不改 GitHub 機密設定。"
|
||||
}
|
||||
},
|
||||
"ownerResponseValidation": {
|
||||
"title": "負責人回覆驗收總覽",
|
||||
"subtitle": "AwoooP 首頁把 S4.9 到 S4.12 四包負責人回覆的收件、驗收與稽核檢查放在同一張只讀看板;目前收到 / 接受 / 拒收都是 0,不代表任何批准或執行授權。",
|
||||
"badge": "只讀驗收",
|
||||
"openIwooos": "開啟 IwoooS",
|
||||
"packetsTitle": "四包待收回覆",
|
||||
"validationTitle": "驗收與稽核檢查",
|
||||
"boundaryLabel": "驗收邊界",
|
||||
"boundaryTitle": "仍等待負責人證據,不開執行權限",
|
||||
"boundaryDetail": "這個總覽只顯示 source_control_owner_response_validation_rollup_v1 的只讀狀態;不能被解讀成負責人回覆已收到、已接受、GitHub 主要來源已批准、專案庫 / 分支與標籤參照 / 工作流程 / 機密設定可修改,或執行期可執行。",
|
||||
"fields": {
|
||||
"templates": "範本",
|
||||
"received": "收到",
|
||||
"accepted": "接受",
|
||||
"rejected": "拒收"
|
||||
},
|
||||
"metrics": {
|
||||
"packets": {
|
||||
"label": "回覆包",
|
||||
"detail": "S4.9 到 S4.12 四包都仍是等待收件狀態。"
|
||||
},
|
||||
"templates": {
|
||||
"label": "回覆範本",
|
||||
"detail": "22 個範本只是負責人要回覆的問題,不代表請求已送出。"
|
||||
},
|
||||
"received": {
|
||||
"label": "已收到",
|
||||
"detail": "目前仍為 0,不得把可見看板當成收件完成。"
|
||||
},
|
||||
"accepted": {
|
||||
"label": "已接受",
|
||||
"detail": "目前仍為 0,不得推進 GitHub 主要來源或執行期閘門。"
|
||||
},
|
||||
"rejected": {
|
||||
"label": "已拒收",
|
||||
"detail": "目前仍為 0;若收到原始載荷或機密明文值必須隔離。"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"title": "自動化品質",
|
||||
"subtitle": "最近 24 小時告警是否真正走到 AI 自動修復、驗證與學習回寫。",
|
||||
"claimReady": "可宣稱完整閉環",
|
||||
"claimBlocked": "不可宣稱完整閉環",
|
||||
"unavailable": "無法讀取",
|
||||
"loadFailed": "無法讀取自動化品質總覽。請確認 Operator 權限與 truth-chain API 狀態。",
|
||||
"packets": {
|
||||
"giteaInventory": {
|
||||
"title": "Gitea 清冊負責人聲明",
|
||||
"detail": "先收公開範圍 / 本地缺口、組織 / 使用者端點、110 相鄰範圍、標準負責人與舊版處置五題。"
|
||||
},
|
||||
"githubTarget": {
|
||||
"title": "GitHub 目標負責人判定",
|
||||
"detail": "逐專案庫確認 GitHub 目標、可見性、標準負責人;不能自動建立專案庫或變更可見性。"
|
||||
},
|
||||
"refTruth": {
|
||||
"title": "分支 / 標籤真相來源負責人回覆",
|
||||
"detail": "確認 main / dev 真相來源、棄用漂移、release tag 與 GitHub-only 分支 / 標籤參照;不能自動同步、刪除或強制推送。"
|
||||
},
|
||||
"workflowSecret": {
|
||||
"title": "工作流程 / 機密名稱負責人回覆",
|
||||
"detail": "只收工作流程、執行器、部署金鑰、分支保護、機密名稱與負責人中繼資料;不收機密明文值。"
|
||||
}
|
||||
},
|
||||
"checks": {
|
||||
"crossPacket": {
|
||||
"label": "跨包驗收",
|
||||
"detail": "10 個跨包檢查只做一致性檢查。"
|
||||
},
|
||||
"evidenceRouting": {
|
||||
"label": "證據路由",
|
||||
"detail": "6 條路由規則只分流補證、隔離或只讀更新。"
|
||||
},
|
||||
"displaySections": {
|
||||
"label": "顯示區塊",
|
||||
"detail": "8 個區塊固定 AwoooP 只讀呈現順序。"
|
||||
},
|
||||
"stateTransitions": {
|
||||
"label": "狀態轉移",
|
||||
"detail": "7 條規則只定義審查狀態語義,不執行。"
|
||||
},
|
||||
"reviewerChecklist": {
|
||||
"label": "審查清單",
|
||||
"detail": "9 個清單項目給人工審查者判讀。"
|
||||
},
|
||||
"reviewerOutcomes": {
|
||||
"label": "審查結果",
|
||||
"detail": "7 條結果分流只導向補證、隔離、拒收或等待後續閘門。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"title": "自動化品質",
|
||||
"subtitle": "最近 24 小時告警是否真正走到 AI 自動修復、驗證與學習回寫。",
|
||||
"claimReady": "可宣稱完整閉環",
|
||||
"claimBlocked": "不可宣稱完整閉環",
|
||||
"claimReadyDetail": "所有告警都完成驗證閉環",
|
||||
"claimBlockedDetail": "仍有告警缺少執行、驗證或學習記錄",
|
||||
"unavailable": "無法讀取",
|
||||
"loadFailed": "無法讀取自動化品質總覽。請確認操作員權限與真相鏈 API 狀態。",
|
||||
"empty": "尚無可評估的告警品質資料。",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
@@ -3857,15 +3942,15 @@
|
||||
},
|
||||
"gates": {
|
||||
"sourcePersisted": "來源已落庫",
|
||||
"outboundRecorded": "Outbound 記錄",
|
||||
"outboundRecorded": "外送記錄",
|
||||
"evidenceCollected": "證據收集",
|
||||
"mcpGatewayObserved": "MCP Gateway",
|
||||
"mcpGatewayObserved": "MCP 閘道",
|
||||
"approvalState": "審批狀態",
|
||||
"executionRecorded": "執行記錄",
|
||||
"autoRepairRecorded": "自動修復記錄",
|
||||
"verificationRecorded": "驗證記錄",
|
||||
"learningRecorded": "學習回寫",
|
||||
"timelineRecorded": "Timeline 記錄"
|
||||
"timelineRecorded": "時間軸記錄"
|
||||
},
|
||||
"gateStatuses": {
|
||||
"failed": "失敗",
|
||||
@@ -3874,7 +3959,7 @@
|
||||
},
|
||||
"metrics": {
|
||||
"tenants": "租戶",
|
||||
"tenantsDetail": "{active} 個啟用,{shadow} 個 shadow",
|
||||
"tenantsDetail": "{active} 個啟用,{shadow} 個影子模式",
|
||||
"runs": "操作執行",
|
||||
"runsDetail": "執行狀態是非同步任務的唯一觀測入口",
|
||||
"approvals": "待審批",
|
||||
@@ -3893,13 +3978,13 @@
|
||||
"approval": {
|
||||
"title": "人工閘門",
|
||||
"signal": "高風險待批准",
|
||||
"owner": "負責:SRE approve / reject",
|
||||
"owner": "負責:SRE 批准 / 拒絕",
|
||||
"route": "流向:審批佇列"
|
||||
},
|
||||
"execute": {
|
||||
"title": "自動執行",
|
||||
"signal": "低風險可閉環",
|
||||
"owner": "負責:MCP Gateway 執行並稽核",
|
||||
"owner": "負責:MCP 閘道執行並稽核",
|
||||
"route": "流向:執行狀態 / 稽核"
|
||||
},
|
||||
"manual": {
|
||||
@@ -3912,21 +3997,21 @@
|
||||
"lanes": {
|
||||
"title": "飛輪鏈路",
|
||||
"live": "已接線",
|
||||
"mirror": "Mirror",
|
||||
"providerName": "Provider 順序",
|
||||
"providerDetail": "GCP-A Ollama -> GCP-B Ollama -> 111 Ollama -> OpenClaw/Nemo -> Gemini",
|
||||
"mcpName": "MCP Gateway",
|
||||
"mcpDetail": "MCP Gateway 先 mirror / wrap,確認 audit 與 redaction 後才切成唯一閘門",
|
||||
"channelName": "Channel Hub",
|
||||
"channelDetail": "Telegram / LINE / Slack 先進 Channel Event,再逐步切換發送責任",
|
||||
"approvalName": "Approval Plane",
|
||||
"mirror": "鏡像",
|
||||
"providerName": "模型供應順序",
|
||||
"providerDetail": "GCP-A Ollama → GCP-B Ollama → 111 Ollama → OpenClaw / Nemo → Gemini",
|
||||
"mcpName": "MCP 閘道",
|
||||
"mcpDetail": "MCP 閘道先鏡像 / 包裝,確認稽核與脫敏後才切成唯一閘門",
|
||||
"channelName": "通道中心",
|
||||
"channelDetail": "Telegram / LINE / Slack 先進通道事件,再逐步切換發送責任",
|
||||
"approvalName": "審批平面",
|
||||
"approvalDetail": "執行狀態與審批平面共享同一條審批語義"
|
||||
},
|
||||
"next": {
|
||||
"title": "下一步操作",
|
||||
"item1": "查看執行監控與 provider fallback",
|
||||
"item1": "查看執行監控與模型供應備援",
|
||||
"item2": "處理等待審批的高風險操作",
|
||||
"item3": "審查 Contract lifecycle",
|
||||
"item3": "審查合約生命週期",
|
||||
"item4": "查看 AwoooP 工作鏈路地圖"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function AwoooPLayout({
|
||||
|
||||
return (
|
||||
<AppLayout locale={params.locale} showBackground={false}>
|
||||
<div className="min-h-[calc(100vh-116px)] bg-[#f7f5ee] border border-[#e0ddd4]">
|
||||
<div className="min-h-[calc(100vh-116px)] w-[calc(100vw-48px)] max-w-full overflow-x-hidden border border-[#e0ddd4] bg-[#f7f5ee] md:w-full">
|
||||
<div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-5 py-4">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-3">
|
||||
|
||||
@@ -79,6 +79,29 @@ type GitHubPrimaryReadinessRef = {
|
||||
tone: "good" | "warn" | "neutral";
|
||||
};
|
||||
|
||||
type OwnerResponseValidationMetric = {
|
||||
key: string;
|
||||
value: string;
|
||||
icon: typeof ShieldCheck;
|
||||
tone: "good" | "warn" | "neutral";
|
||||
};
|
||||
|
||||
type OwnerResponseValidationPacket = {
|
||||
key: string;
|
||||
lane: string;
|
||||
templates: string;
|
||||
received: string;
|
||||
accepted: string;
|
||||
rejected: string;
|
||||
icon: typeof ShieldCheck;
|
||||
};
|
||||
|
||||
type OwnerResponseValidationCheck = {
|
||||
key: string;
|
||||
value: string;
|
||||
tone: "good" | "warn" | "neutral";
|
||||
};
|
||||
|
||||
type QualityVerdict = {
|
||||
verdict: string;
|
||||
total: number;
|
||||
@@ -183,6 +206,75 @@ const githubPrimaryReadinessBoundaries = [
|
||||
"action_buttons_allowed=false",
|
||||
];
|
||||
|
||||
const ownerResponseValidationMetrics: OwnerResponseValidationMetric[] = [
|
||||
{ key: "packets", value: "4", icon: ListChecks, tone: "warn" },
|
||||
{ key: "templates", value: "22", icon: FileText, tone: "neutral" },
|
||||
{ key: "received", value: "0", icon: Lock, tone: "warn" },
|
||||
{ key: "accepted", value: "0", icon: ShieldCheck, tone: "warn" },
|
||||
{ key: "rejected", value: "0", icon: TriangleAlert, tone: "neutral" },
|
||||
];
|
||||
|
||||
const ownerResponseValidationPackets: OwnerResponseValidationPacket[] = [
|
||||
{
|
||||
key: "giteaInventory",
|
||||
lane: "S4.9",
|
||||
templates: "5",
|
||||
received: "0",
|
||||
accepted: "0",
|
||||
rejected: "0",
|
||||
icon: GitBranch,
|
||||
},
|
||||
{
|
||||
key: "githubTarget",
|
||||
lane: "S4.10",
|
||||
templates: "7",
|
||||
received: "0",
|
||||
accepted: "0",
|
||||
rejected: "0",
|
||||
icon: ShieldCheck,
|
||||
},
|
||||
{
|
||||
key: "refTruth",
|
||||
lane: "S4.11",
|
||||
templates: "5",
|
||||
received: "0",
|
||||
accepted: "0",
|
||||
rejected: "0",
|
||||
icon: Waypoints,
|
||||
},
|
||||
{
|
||||
key: "workflowSecret",
|
||||
lane: "S4.12",
|
||||
templates: "5",
|
||||
received: "0",
|
||||
accepted: "0",
|
||||
rejected: "0",
|
||||
icon: SearchCheck,
|
||||
},
|
||||
];
|
||||
|
||||
const ownerResponseValidationChecks: OwnerResponseValidationCheck[] = [
|
||||
{ key: "crossPacket", value: "10", tone: "warn" },
|
||||
{ key: "evidenceRouting", value: "6", tone: "neutral" },
|
||||
{ key: "displaySections", value: "8", tone: "neutral" },
|
||||
{ key: "stateTransitions", value: "7", tone: "neutral" },
|
||||
{ key: "reviewerChecklist", value: "9", tone: "neutral" },
|
||||
{ key: "reviewerOutcomes", value: "7", tone: "neutral" },
|
||||
];
|
||||
|
||||
const ownerResponseValidationBoundaries = [
|
||||
"owner_response_validation_received_count=0",
|
||||
"owner_response_validation_accepted_count=0",
|
||||
"owner_response_validation_rejected_count=0",
|
||||
"repo_creation_authorized=false",
|
||||
"refs_sync_authorized=false",
|
||||
"workflow_modification_authorized=false",
|
||||
"secret_value_collection_allowed=false",
|
||||
"github_primary_switch_authorized=false",
|
||||
"runtime_execution_authorized=false",
|
||||
"action_buttons_allowed=false",
|
||||
];
|
||||
|
||||
function numberValue(value: unknown): number {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
||||
}
|
||||
@@ -606,6 +698,149 @@ function GitHubPrimaryReadinessHomePanel() {
|
||||
);
|
||||
}
|
||||
|
||||
function OwnerResponseValidationRollupPanel() {
|
||||
const t = useTranslations("awooop.home.ownerResponseValidation");
|
||||
|
||||
return (
|
||||
<section className="border border-[#e0ddd4] bg-white">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
|
||||
<div className="flex items-start gap-2">
|
||||
<ListChecks className="mt-0.5 h-4 w-4 text-[#d97757]" aria-hidden="true" />
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
|
||||
<p className="mt-1 max-w-3xl text-xs leading-5 text-[#77736a]">{t("subtitle")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="inline-flex border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 text-xs font-semibold text-[#8a5a08]">
|
||||
{t("badge")}
|
||||
</span>
|
||||
<Link
|
||||
href="/iwooos"
|
||||
className="inline-flex items-center gap-2 border border-[#d8d3c7] bg-white px-3 py-1.5 text-xs font-semibold text-[#141413] hover:border-[#d97757]"
|
||||
>
|
||||
{t("openIwooos")}
|
||||
<ArrowRight className="h-3.5 w-3.5 text-[#77736a]" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-5">
|
||||
{ownerResponseValidationMetrics.map((metric) => {
|
||||
const Icon = metric.icon;
|
||||
return (
|
||||
<div key={metric.key} className="min-h-[124px] bg-white px-4 py-3">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<p className="text-xs font-semibold text-[#77736a]">
|
||||
{t(`metrics.${metric.key}.label` as never)}
|
||||
</p>
|
||||
<p className="mt-2 font-mono text-2xl font-semibold leading-none text-[#141413]">
|
||||
{metric.value}
|
||||
</p>
|
||||
</div>
|
||||
<span
|
||||
className={cn(
|
||||
"flex h-8 w-8 shrink-0 items-center justify-center border",
|
||||
metric.tone === "good" && "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
|
||||
metric.tone === "warn" && "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
|
||||
metric.tone === "neutral" && "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]"
|
||||
)}
|
||||
>
|
||||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-3 text-xs leading-5 text-[#5f5b52]">
|
||||
{t(`metrics.${metric.key}.detail` as never)}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="grid min-w-0 gap-4 p-4 xl:grid-cols-[1.25fr_0.75fr]">
|
||||
<div className="min-w-0 border border-[#e0ddd4] bg-white">
|
||||
<div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3 text-xs font-semibold text-[#141413]">
|
||||
{t("packetsTitle")}
|
||||
</div>
|
||||
<div className="divide-y divide-[#eee9dd]">
|
||||
{ownerResponseValidationPackets.map((packet) => {
|
||||
const Icon = packet.icon;
|
||||
return (
|
||||
<div key={packet.key} className="grid min-w-0 gap-3 px-4 py-3 lg:grid-cols-[minmax(0,1fr)_240px]">
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Icon className="h-4 w-4 text-[#d97757]" aria-hidden="true" />
|
||||
<span className="border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 font-mono text-xs font-semibold text-[#8a5a08]">
|
||||
{packet.lane}
|
||||
</span>
|
||||
<p className="text-sm font-semibold text-[#141413]">
|
||||
{t(`packets.${packet.key}.title` as never)}
|
||||
</p>
|
||||
</div>
|
||||
<p className="mt-2 text-xs leading-5 text-[#5f5b52]">
|
||||
{t(`packets.${packet.key}.detail` as never)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid min-w-0 grid-cols-4 gap-px bg-[#e0ddd4] text-center">
|
||||
{[
|
||||
{ label: t("fields.templates"), value: packet.templates },
|
||||
{ label: t("fields.received"), value: packet.received },
|
||||
{ label: t("fields.accepted"), value: packet.accepted },
|
||||
{ label: t("fields.rejected"), value: packet.rejected },
|
||||
].map((item) => (
|
||||
<div key={item.label} className="bg-white px-2 py-2">
|
||||
<p className="text-[10px] font-semibold text-[#77736a]">{item.label}</p>
|
||||
<p className="mt-1 font-mono text-base font-semibold text-[#141413]">
|
||||
{item.value}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-w-0 gap-4">
|
||||
<div className="min-w-0 border border-[#e0ddd4] bg-white">
|
||||
<div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3 text-xs font-semibold text-[#141413]">
|
||||
{t("validationTitle")}
|
||||
</div>
|
||||
<div className="grid min-w-0 gap-px bg-[#e0ddd4] sm:grid-cols-2">
|
||||
{ownerResponseValidationChecks.map((check) => (
|
||||
<div key={check.key} className="min-h-[88px] bg-white px-4 py-3">
|
||||
<p className="text-xs font-semibold text-[#77736a]">
|
||||
{t(`checks.${check.key}.label` as never)}
|
||||
</p>
|
||||
<p className="mt-2 font-mono text-2xl font-semibold leading-none text-[#141413]">
|
||||
{check.value}
|
||||
</p>
|
||||
<p className="mt-2 text-xs leading-5 text-[#5f5b52]">
|
||||
{t(`checks.${check.key}.detail` as never)}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="min-w-0 border border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
|
||||
<p className="text-xs font-semibold text-[#77736a]">{t("boundaryLabel")}</p>
|
||||
<p className="mt-2 text-sm font-semibold text-[#141413]">{t("boundaryTitle")}</p>
|
||||
<p className="mt-2 break-words text-xs leading-5 text-[#5f5b52]">{t("boundaryDetail")}</p>
|
||||
<div className="mt-4 grid gap-2 break-all font-mono text-xs text-[#141413]">
|
||||
{ownerResponseValidationBoundaries.map((boundary) => (
|
||||
<span key={boundary}>{boundary}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function AutomationQualityPanel({
|
||||
summary,
|
||||
error,
|
||||
@@ -939,6 +1174,8 @@ export default function AwoooPPage() {
|
||||
|
||||
<GitHubPrimaryReadinessHomePanel />
|
||||
|
||||
<OwnerResponseValidationRollupPanel />
|
||||
|
||||
<section className="border border-[#e0ddd4] bg-[#e0ddd4]">
|
||||
<div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user