diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 7e3a16ea5..e75a98d76 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -4307,6 +4307,57 @@ "detail": "Finally confirm workflow, runner, deploy key, branch protection, CODEOWNERS, and secret names. Collect names only, never values." } } + }, + "ownerResponseValidationBoundary": { + "title": "Owner Response Validation Read-only Review Boundary", + "subtitle": "The approval queue mirrors the S4.13 validation rollup and the S4.9-S4.12 source intake packets. This is not received response, accepted response, an approval record, repo action, refs action, workflow / secret action, or runtime authorization.", + "badge": "Read-only validation boundary", + "reviewRefsTitle": "Validation and source intake refs", + "boundaryLabel": "Non-approvable boundary", + "boundaryTitle": "No approval record can be created here", + "boundaryDetail": "This panel only displays four packets, 22 response templates, received / accepted / rejected all still 0, and 8 display sections. It does not create approval records, create repos, mutate refs, change workflows / secrets, collect secret values, switch primary, or open runtime gates.", + "openIwooos": "Open IwoooS", + "metrics": { + "packets": "Response packets", + "packetsDetail": "S4.9-S4.12 all still wait for owner response.", + "templates": "Response templates", + "templatesDetail": "The 22 templates are future intake formats only, not sent, received, or accepted responses.", + "received": "Received", + "receivedDetail": "Still 0. Approval queue visibility must not rewrite intake state.", + "accepted": "Accepted", + "acceptedDetail": "Still 0. Only validated redacted evidence can change this.", + "rejected": "Rejected", + "rejectedDetail": "Still 0. Rejection outcomes cannot exist before human validation.", + "displaySections": "Display sections", + "displaySectionsDetail": "The 8 display sections explain validation flow, evidence routing, and boundaries only." + }, + "reviewRefs": { + "validationRollup": { + "title": "S4.13 validation rollup", + "detail": "Locks packet separation, cross-packet validation, evidence routing, reviewer checklist, and outcome lanes without creating approval records.", + "contract": "source_control_owner_response_validation_rollup_v1" + }, + "giteaAttestation": { + "title": "S4.9 Gitea inventory owner attestation", + "detail": "Five templates still wait for owner response; this can only display the next intake focus.", + "contract": "gitea_inventory_owner_attestation_response_v1" + }, + "githubTarget": { + "title": "S4.10 GitHub target owner decision", + "detail": "Seven target owner / visibility / canonical responses are not accepted and must not create repos automatically.", + "contract": "github_target_owner_decision_response_v1" + }, + "refsTruth": { + "title": "S4.11 refs truth owner response", + "detail": "Five truth lanes still wait for redacted response and must not sync, delete, or force-push refs.", + "contract": "source_control_ref_truth_owner_response_v1" + }, + "workflowSecret": { + "title": "S4.12 workflow / secret-name owner response", + "detail": "Five name and redacted-evidence lanes still wait for response. Names only, never secret values.", + "contract": "source_control_workflow_secret_name_owner_response_v1" + } + } } }, "workItems": { diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 05035b2f9..3c31b7282 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -4233,79 +4233,130 @@ "approvals": { "securityOwnerResponseGate": { "title": "IwoooS 負責人回覆只讀審查焦點", - "subtitle": "AwoooP 審批佇列只顯示 S4.9-S4.12 負責人回覆的下一個人工收件焦點;這不是 approval record,也不會開 runtime gate。", + "subtitle": "AwoooP 審批佇列只顯示 S4.9-S4.12 負責人回覆的下一個人工收件焦點;這不是審批紀錄,也不會開執行期閘門。", "badge": "只讀焦點", "ownerChecksTitle": "負責人回覆收件順序", "boundaryLabel": "審批邊界", "boundaryTitle": "目前仍沒有可核准項目", - "boundaryDetail": "這個面板不送出 request、不標記 received / accepted、不建立 approval record、不呼叫 GitHub / Gitea / Kali,也不新增批准、執行、部署、主要來源切換或 refs 動作。", + "boundaryDetail": "這個面板不送出請求、不標記已收到 / 已接受、不建立審批紀錄、不呼叫 GitHub / Gitea / Kali,也不新增批准、執行、部署、主要來源切換或分支 / 標籤參照動作。", "openIwooos": "開啟 IwoooS", "metrics": { "received": "已收到", - "receivedDetail": "S4.9-S4.12 負責人回覆 received 仍為 0。", + "receivedDetail": "S4.9-S4.12 負責人回覆已收到仍為 0。", "accepted": "已接受", - "acceptedDetail": "尚未有可接受的脫敏負責人 evidence。", + "acceptedDetail": "尚未有可接受的脫敏負責人證據。", "activeRuntimeGates": "主動執行閘門", - "activeRuntimeGatesDetail": "任何 runtime gate 仍需獨立批准與 rollback / post-check evidence。", + "activeRuntimeGatesDetail": "任何執行期閘門仍需獨立批准、回復方案與事後檢查證據。", "headline": "整體資安網", - "headlineDetail": "58% 只在負責人回覆、runtime gate、GitHub 主要來源或 production landing 有 evidence 時重估。" + "headlineDetail": "58% 只在負責人回覆、執行期閘門、GitHub 主要來源或正式落地有證據時重估。" }, "checks": { "s49OwnerAttestation": { "title": "S4.9 Gitea 負責人證明", - "detail": "下一個建議先收;需要回覆 public-only / local gap、org / user endpoint、110 adjacent source、canonical owner 與 legacy disposition。" + "detail": "下一個建議先收;需要回覆公開來源限定 / 本地差異、組織 / 使用者端點、110 鄰近來源、標準負責人與舊版處置。" }, "s410GithubTarget": { "title": "S4.10 GitHub 目標負責人", - "detail": "等待 S4.9 之後收斂 7 個 GitHub target 的負責人 / 可見性 / canonical decision。" + "detail": "等待 S4.9 之後收斂 7 個 GitHub 目標的負責人 / 可見性 / 標準判定。" }, "s411RefsTruth": { - "title": "S4.11 refs 真相負責人回覆", - "detail": "等待負責人對 main / dev truth、deprecated drift、release tags 與 GitHub-only refs 做脫敏判定。" + "title": "S4.11 分支 / 標籤真相負責人回覆", + "detail": "等待負責人對主要 / 開發分支真相、棄用漂移、發布標籤與僅存在於 GitHub 的參照做脫敏判定。" }, "s412WorkflowSecret": { - "title": "S4.12 workflow / secret 名稱", - "detail": "等待負責人對 webhook、runner、deploy key、branch protection / CODEOWNERS、secret name parity 做脫敏判定。" + "title": "S4.12 工作流程 / 機密名稱", + "detail": "等待負責人對網路鉤子、執行器、部署金鑰、分支保護 / CODEOWNERS 與機密名稱一致性做脫敏判定。" } } }, "githubPrimaryReadinessGate": { "title": "GitHub 主要來源就緒度審批邊界", - "subtitle": "審批佇列只顯示 GitHub 主要來源前置負責人回覆缺口;這不是 GitHub 主要來源批准,也不會建立 repo、改 refs、收 secret value 或停用 Gitea。", + "subtitle": "審批佇列只顯示 GitHub 主要來源前置負責人回覆缺口;這不是 GitHub 主要來源批准,也不會建立專案庫、改分支 / 標籤參照、收機密明文值或停用 Gitea。", "badge": "只讀審批邊界", "responseLanesTitle": "負責人回覆路線", "boundaryLabel": "GitHub 主要來源邊界", "boundaryTitle": "目前沒有可批准的主要來源切換", - "boundaryDetail": "這個面板只把 S4.9-S4.12 的收件順序放到審批視野;所有回覆仍為 received=0 / accepted=0,不建立 approval record、不切 GitHub 主要來源、不改 Gitea 主要來源,也不觸發 runtime gate。", + "boundaryDetail": "這個面板只把 S4.9-S4.12 的收件順序放到審批視野;所有回覆仍為已收到=0 / 已接受=0,不建立審批紀錄、不切 GitHub 主要來源、不改 Gitea 主要來源,也不觸發執行期閘門。", "openIwooos": "開啟 IwoooS", "metrics": { "giteaOwner": "Gitea 負責人", - "giteaOwnerDetail": "S4.9 的 5 個負責人證明項目仍未 received / accepted。", + "giteaOwnerDetail": "S4.9 的 5 個負責人證明項目仍未收到 / 接受。", "githubTargetOwner": "GitHub 目標負責人", - "githubTargetOwnerDetail": "S4.10 的 7 個目標負責人 / 可見性 / canonical 回覆仍未 accepted。", - "refsTruth": "Refs 真相", - "refsTruthDetail": "S4.11 的 5 類 refs 真相負責人回覆仍未 accepted。", - "workflowSecretNames": "工作流程 / secret 名稱", - "workflowSecretNamesDetail": "S4.12 的 5 類 workflow / secret 名稱負責人回覆仍未 accepted。", + "githubTargetOwnerDetail": "S4.10 的 7 個目標負責人 / 可見性 / 標準回覆仍未接受。", + "refsTruth": "分支 / 標籤真相", + "refsTruthDetail": "S4.11 的 5 類分支 / 標籤真相負責人回覆仍未接受。", + "workflowSecretNames": "工作流程 / 機密名稱", + "workflowSecretNamesDetail": "S4.12 的 5 類工作流程 / 機密名稱負責人回覆仍未接受。", "primaryReady": "主要來源就緒數", "primaryReadyDetail": "仍為 0;審批可見不等於可切主要來源。" }, "responseLanes": { "giteaOwnerAttestation": { "title": "Gitea 清冊負責人證明", - "detail": "先確認 public-only / local gap、org / user endpoint、110 adjacent source、canonical owner 與 legacy disposition。" + "detail": "先確認公開來源限定 / 本地差異、組織 / 使用者端點、110 鄰近來源、標準負責人與舊版處置。" }, "githubTargetOwner": { "title": "GitHub 目標負責人決策", - "detail": "再確認 7 個範圍內目標的負責人、可見性與 canonical target,不自動建立 repo。" + "detail": "再確認 7 個範圍內目標的負責人、可見性與標準目標,不自動建立專案庫。" }, "refsTruthOwner": { - "title": "Refs 真相負責人回覆", - "detail": "接著確認 main / dev truth、deprecated drift、release tags 與 GitHub-only refs,不 sync / delete / force push。" + "title": "分支 / 標籤真相負責人回覆", + "detail": "接著確認主要 / 開發分支真相、棄用漂移、發布標籤與僅存在於 GitHub 的參照,不同步、刪除或強制推送。" }, "workflowSecretOwner": { - "title": "工作流程 / secret 名稱負責人回覆", - "detail": "最後確認 workflow、runner、deploy key、branch protection、CODEOWNERS 與 secret 名稱;只收名稱,不收 value。" + "title": "工作流程 / 機密名稱負責人回覆", + "detail": "最後確認工作流程、執行器、部署金鑰、分支保護、CODEOWNERS 與機密名稱;只收名稱,不收明文值。" + } + } + }, + "ownerResponseValidationBoundary": { + "title": "負責人回覆驗收只讀審查邊界", + "subtitle": "審批佇列同步顯示 S4.13 驗收彙整與 S4.9-S4.12 四個來源收件包;這不是已收到、已接受、審批紀錄、專案庫動作、分支 / 標籤參照動作、工作流程 / 機密設定動作或執行期授權。", + "badge": "只讀驗收邊界", + "reviewRefsTitle": "驗收與來源收件參照", + "boundaryLabel": "不可批准邊界", + "boundaryTitle": "目前沒有可建立的審批紀錄", + "boundaryDetail": "這個面板只顯示四包、22 個回覆範本、已收到 / 已接受 / 已拒收都仍為 0,以及 8 個可顯示區塊;不建立審批紀錄、不建立專案庫、不改分支 / 標籤參照、不改工作流程 / 機密設定、不收機密明文值、不切主要來源,也不開執行期閘門。", + "openIwooos": "開啟 IwoooS", + "metrics": { + "packets": "回覆包", + "packetsDetail": "S4.9-S4.12 四包仍等待負責人回覆。", + "templates": "回覆範本", + "templatesDetail": "22 個範本只代表未來可收件格式,不代表已送出、已收到或已接受。", + "received": "已收到", + "receivedDetail": "目前仍為 0;審批佇列可見不得改寫收件狀態。", + "accepted": "已接受", + "acceptedDetail": "目前仍為 0;只有脫敏證據通過驗收後才能改變。", + "rejected": "已拒收", + "rejectedDetail": "目前仍為 0;未進入人工驗收前不得產生拒收結果。", + "displaySections": "顯示區塊", + "displaySectionsDetail": "8 個顯示區塊只用於說明驗收流程、證據路由與邊界。" + }, + "reviewRefs": { + "validationRollup": { + "title": "S4.13 驗收彙整", + "detail": "固定四包、跨包驗收、證據路由、審查清單與結果分流,但不產生審批紀錄。", + "contract": "source_control_owner_response_validation_rollup_v1" + }, + "giteaAttestation": { + "title": "S4.9 Gitea 清冊負責人證明", + "detail": "5 個範本仍等待負責人回覆;目前只能顯示下一個收件焦點。", + "contract": "gitea_inventory_owner_attestation_response_v1" + }, + "githubTarget": { + "title": "S4.10 GitHub 目標負責人決策", + "detail": "7 個目標負責人 / 可見性 / 標準回覆仍未接受,不得自動建立專案庫。", + "contract": "github_target_owner_decision_response_v1" + }, + "refsTruth": { + "title": "S4.11 分支 / 標籤真相負責人回覆", + "detail": "5 類真相判定仍等待脫敏回覆,不得同步、刪除或強制推送分支 / 標籤參照。", + "contract": "source_control_ref_truth_owner_response_v1" + }, + "workflowSecret": { + "title": "S4.12 工作流程 / 機密名稱負責人回覆", + "detail": "5 類名稱與脫敏證據仍等待回覆;只允許名稱清冊,不允許機密明文值。", + "contract": "source_control_workflow_secret_name_owner_response_v1" } } } diff --git a/apps/web/src/app/[locale]/awooop/approvals/page.tsx b/apps/web/src/app/[locale]/awooop/approvals/page.tsx index cc7102074..dfb9f36eb 100644 --- a/apps/web/src/app/[locale]/awooop/approvals/page.tsx +++ b/apps/web/src/app/[locale]/awooop/approvals/page.tsx @@ -493,6 +493,145 @@ function GitHubPrimaryReadinessApprovalBoundaryPanel() { ); } +function OwnerResponseValidationApprovalBoundaryPanel() { + const t = useTranslations("awooop.approvals.ownerResponseValidationBoundary"); + const metrics = [ + { + label: t("metrics.packets"), + value: "4", + detail: t("metrics.packetsDetail"), + }, + { + label: t("metrics.templates"), + value: "22", + detail: t("metrics.templatesDetail"), + }, + { + label: t("metrics.received"), + value: "0", + detail: t("metrics.receivedDetail"), + }, + { + label: t("metrics.accepted"), + value: "0", + detail: t("metrics.acceptedDetail"), + }, + { + label: t("metrics.rejected"), + value: "0", + detail: t("metrics.rejectedDetail"), + }, + { + label: t("metrics.displaySections"), + value: "8", + detail: t("metrics.displaySectionsDetail"), + }, + ]; + const reviewRefs = [ + { + phase: "S4.13", + key: "validationRollup", + contract: "source_control_owner_response_validation_rollup_v1", + }, + { + phase: "S4.9", + key: "giteaAttestation", + contract: "gitea_inventory_owner_attestation_response_v1", + }, + { + phase: "S4.10", + key: "githubTarget", + contract: "github_target_owner_decision_response_v1", + }, + { + phase: "S4.11", + key: "refsTruth", + contract: "source_control_ref_truth_owner_response_v1", + }, + { + phase: "S4.12", + key: "workflowSecret", + contract: "source_control_workflow_secret_name_owner_response_v1", + }, + ]; + + return ( +
+
+
+
+ + {t("badge")} + +
+
+ {metrics.map((item) => ( +
+

{item.label}

+

{item.value}

+

{item.detail}

+
+ ))} +
+
+
+
+ {t("reviewRefsTitle")} +
+
+ {reviewRefs.map((item) => ( +
+ {item.phase} +
+

+ {t(`reviewRefs.${item.key}.title`)} +

+

+ {t(`reviewRefs.${item.key}.detail`)} +

+

+ {item.contract} +

+
+
+ ))} +
+
+
+

{t("boundaryLabel")}

+

{t("boundaryTitle")}

+

{t("boundaryDetail")}

+
+ owner_response_validation_received_count=0 + owner_response_validation_accepted_count=0 + owner_response_validation_rejected_count=0 + approval_record_created=false + 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 +
+ + {t("openIwooos")} +
+
+
+ ); +} + // ============================================================================= // Main Component // ============================================================================= @@ -559,7 +698,7 @@ export default function ApprovalsPage() { { label: "待人工決策", value: approvals.length, - detail: "等待 approve / reject 的唯一佇列", + detail: "等待批准 / 駁回的唯一佇列", icon: ShieldCheck, className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]", }, @@ -573,7 +712,7 @@ export default function ApprovalsPage() { { label: "已逾時", value: expiredCount, - detail: "不得再自動 resume", + detail: "不得再自動恢復", icon: TriangleAlert, className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]", }, @@ -662,6 +801,7 @@ export default function ApprovalsPage() { +