diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index aeb46f57..51941fb0 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -7212,11 +7212,11 @@ "timelineMissing": "品質總覽仍指出 時間線 / 稽核記錄缺口", "iwooosSecurityMirror": "整體 {headline};框架 {framework};落地 {runtime};主動執行閘門={gates}", "iwooosSecurityMirrorOwner": "AwoooP 正式只讀落地 已驗證;負責人回覆仍等待", - "iwooosSecurityMirrorBoundary": "execution_router_linked=false;runtime_execution_authorized=false;action_buttons_allowed=false", + "iwooosSecurityMirrorBoundary": "尚未連接執行路由;執行期操作未授權;此頁不提供可執行操作按鈕。", "githubPrimaryReadiness": "候選專案庫={candidates};範圍內={inScope};主要來源就緒={ready}", "githubPrimaryOwnerResponses": "負責人回覆仍為 0/22;請求可送出不等於已接受", "githubPrimaryWorkflowNames": "工作流程 / 機密名稱清冊完成=0/7;只收名稱不收機密明文值", - "githubPrimaryBoundary": "repo_creation=false;refs_mutation=false;github_primary_switch=false;disable_gitea=false", + "githubPrimaryBoundary": "未核准建立專案庫、同步 refs、切換 GitHub primary 或停用 Gitea。", "ownerResponseValidation": "回覆包={packets};範本={templates};已收到={received};已接受={accepted};已拒收={rejected}", "ownerResponseValidationChecks": "跨包驗收={crossPacket};證據路由={routing};顯示區塊={sections}", "ownerResponseValidationBoundary": "不建立審批紀錄、不切主要來源、不開執行期閘門" @@ -9312,27 +9312,27 @@ "validationRollup": { "title": "S4.13 驗收彙整", "detail": "固定四包、跨包驗收、證據路由、審查清單與結果分流,但不產生審批紀錄。", - "contract": "來源_control_owner_response_validation_rollup_v1" + "contract": "負責人回覆驗收彙整" }, "giteaAttestation": { "title": "S4.9 Gitea 清冊負責人證明", "detail": "5 個範本仍等待負責人回覆;目前只能顯示下一個收件焦點。", - "contract": "gitea_inventory_owner_attestation_response_v1" + "contract": "Gitea 清冊負責人證明" }, "githubTarget": { "title": "S4.10 GitHub 目標負責人決策", "detail": "9 個目標負責人 / 可見性 / 標準回覆仍未接受,不得自動建立專案庫。", - "contract": "github_target_owner_decision_response_v1" + "contract": "GitHub 目標負責人決策" }, "refsTruth": { "title": "S4.11 分支 / 標籤真相負責人回覆", "detail": "5 類真相判定仍等待脫敏回覆,不得同步、刪除或強制推送分支 / 標籤參照。", - "contract": "來源_control_ref_truth_owner_response_v1" + "contract": "分支 / 標籤真相負責人回覆" }, "workflowSecret": { "title": "S4.12 工作流程 / 機密名稱負責人回覆", "detail": "5 類名稱與脫敏證據仍等待回覆;只允許名稱清冊,不允許機密明文值。", - "contract": "來源_control_workflow_secret_name_owner_response_v1" + "contract": "工作流程 / 機密名稱負責人回覆" } } } @@ -11497,7 +11497,7 @@ "stageCompletionReport": { "title": "階段完成回報", "subtitle": "每一輪完成後都把正式證據、進度邊界與下一步固定在首頁,讓管理與維運角色可直接理解目前資安工作狀態。", - "boundary": "本階段只更新可見回報與證據索引:headline_percent=64;framework=92%;runtime_landing=40-45%;active_執行期_閘門_count=0;runtime_execution_authorized=false;repo_creation_authorized=false。", + "boundary": "本階段只更新可見回報與證據索引:整體 64%;框架 92%;runtime landing 40-45%;執行期閘門維持 0;不授權 runtime 或專案庫變更。", "items": { "stageClosed": { "title": "本階段已收斂", @@ -11522,7 +11522,7 @@ "subtitle": "將 64% 往下一階段推進需要的工作拆成四件事;此區僅顯示任務與完成條件,不送出請求、不啟動掃描、不建立執行。", "stepLabel": "任務", "doneLabel": "完成條件", - "boundary": "固定邊界:負責人_response_已收到_count=0;負責人_response_已接受_count=0;active_執行期_閘門_count=0;runtime_execution_authorized=false;action_buttons_allowed=false;repo_creation_authorized=false;github_primary_switch_authorized=false。", + "boundary": "固定邊界:負責人回覆尚未收到或接受;執行期閘門維持 0;不提供操作按鈕;不建立專案庫;不切 GitHub primary。", "items": { "s49OwnerResponse": { "title": "先收 S4.9 負責人回覆", @@ -13446,13 +13446,13 @@ "awooopProductionLandingProof": { "title": "AwoooP 正式只讀消費證據", "body": "AwoooP 主線已在正式站只讀消費 IwoooS / security 鏡像的 重點、證據參照、守門 result與forbidden action。", - "acceptance": "已有 Gitea main commit、CD 成功與正式站路由驗證;execution_router_linked=false、runtime_execution_authorized=false。", + "acceptance": "已有 Gitea main commit、CD 成功與正式站路由驗證;執行路由與 runtime 授權仍維持關閉。", "guard": "只讀落地不是 批准、操作按鈕、執行路由或阻擋控制。" }, "kali112ReadOnlyProof": { "title": "Kali host:kali-readonly 今日只讀證據", "body": "2026-06-04 08:55 已完成 Kali host:kali-readonly SSH只讀快照、掃描ner 8080 /health、待更新套件 1994、networking.service與服務硬化 0/4的正式站可見證據。", - "acceptance": "已有 Gitea CD run 3623、正式站 desktop / mobile 驗證與維護闖關路徑;runtime_execution_authorized=false。", + "acceptance": "已有 Gitea CD run 3623、正式站 desktop / mobile 驗證與維護闖關路徑;runtime 授權仍維持關閉。", "guard": "只讀證據不是 主動掃描、/execute、SSH 變更、更新、重啟或服務硬化授權。" }, "nextHeadlineReviewRecord": { @@ -14946,7 +14946,7 @@ "title": "鏡像路由群組已知", "body": "`security_鏡像_route_v1` 已定義操作控制台、執行期 state、channel event、audit 證據、批准 佇列的只讀目的地。", "requirement": "AwoooP只能依 route group 顯示與分類,不新增掃描、執行、修復、專案庫、參照或部署動作。", - "guard": "action_buttons_allowed=false;runtime_execution_authorized=false" + "guard": "不提供操作按鈕;runtime 授權仍維持關閉。" }, "forbiddenOutputsLocked": { "title": "禁止輸出已鎖住", @@ -16794,7 +16794,7 @@ "detail": "目前 IwoooS 是低摩擦框架與只讀證據網;掃描、修復、部署、主機更新與版本來源變更都要獨立人工閘門。", "evidence": "守門、快照、LOGBOOK 與邊界鍵都已鎖住。", "next": "等 負責人證據或人工決策後,再另開 follow-up 執行期閘門。", - "locked": "runtime_execution_authorized=false;active_runtime_gate_count=0。" + "locked": "runtime 授權仍維持關閉;執行期閘門維持 0。" } } }, @@ -17598,7 +17598,7 @@ "title": "執行期 禁止動作", "body": "Kali /execute、SSH、主機更新、主動掃描、憑證掃描、阻擋控制、專案庫 / 參照 / 工作流程 動作仍未授權。", "handoff": "平行工作線只能新增只讀證據、介面投影、文件、快照與守門結果。", - "guard": "runtime_execution_authorized=false;action_buttons_allowed=false" + "guard": "runtime 授權仍維持關閉;不提供操作按鈕。" }, "awooopReadOnlyInputs": { "title": "AwoooP只讀輸入", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index aeb46f57..51941fb0 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -7212,11 +7212,11 @@ "timelineMissing": "品質總覽仍指出 時間線 / 稽核記錄缺口", "iwooosSecurityMirror": "整體 {headline};框架 {framework};落地 {runtime};主動執行閘門={gates}", "iwooosSecurityMirrorOwner": "AwoooP 正式只讀落地 已驗證;負責人回覆仍等待", - "iwooosSecurityMirrorBoundary": "execution_router_linked=false;runtime_execution_authorized=false;action_buttons_allowed=false", + "iwooosSecurityMirrorBoundary": "尚未連接執行路由;執行期操作未授權;此頁不提供可執行操作按鈕。", "githubPrimaryReadiness": "候選專案庫={candidates};範圍內={inScope};主要來源就緒={ready}", "githubPrimaryOwnerResponses": "負責人回覆仍為 0/22;請求可送出不等於已接受", "githubPrimaryWorkflowNames": "工作流程 / 機密名稱清冊完成=0/7;只收名稱不收機密明文值", - "githubPrimaryBoundary": "repo_creation=false;refs_mutation=false;github_primary_switch=false;disable_gitea=false", + "githubPrimaryBoundary": "未核准建立專案庫、同步 refs、切換 GitHub primary 或停用 Gitea。", "ownerResponseValidation": "回覆包={packets};範本={templates};已收到={received};已接受={accepted};已拒收={rejected}", "ownerResponseValidationChecks": "跨包驗收={crossPacket};證據路由={routing};顯示區塊={sections}", "ownerResponseValidationBoundary": "不建立審批紀錄、不切主要來源、不開執行期閘門" @@ -9312,27 +9312,27 @@ "validationRollup": { "title": "S4.13 驗收彙整", "detail": "固定四包、跨包驗收、證據路由、審查清單與結果分流,但不產生審批紀錄。", - "contract": "來源_control_owner_response_validation_rollup_v1" + "contract": "負責人回覆驗收彙整" }, "giteaAttestation": { "title": "S4.9 Gitea 清冊負責人證明", "detail": "5 個範本仍等待負責人回覆;目前只能顯示下一個收件焦點。", - "contract": "gitea_inventory_owner_attestation_response_v1" + "contract": "Gitea 清冊負責人證明" }, "githubTarget": { "title": "S4.10 GitHub 目標負責人決策", "detail": "9 個目標負責人 / 可見性 / 標準回覆仍未接受,不得自動建立專案庫。", - "contract": "github_target_owner_decision_response_v1" + "contract": "GitHub 目標負責人決策" }, "refsTruth": { "title": "S4.11 分支 / 標籤真相負責人回覆", "detail": "5 類真相判定仍等待脫敏回覆,不得同步、刪除或強制推送分支 / 標籤參照。", - "contract": "來源_control_ref_truth_owner_response_v1" + "contract": "分支 / 標籤真相負責人回覆" }, "workflowSecret": { "title": "S4.12 工作流程 / 機密名稱負責人回覆", "detail": "5 類名稱與脫敏證據仍等待回覆;只允許名稱清冊,不允許機密明文值。", - "contract": "來源_control_workflow_secret_name_owner_response_v1" + "contract": "工作流程 / 機密名稱負責人回覆" } } } @@ -11497,7 +11497,7 @@ "stageCompletionReport": { "title": "階段完成回報", "subtitle": "每一輪完成後都把正式證據、進度邊界與下一步固定在首頁,讓管理與維運角色可直接理解目前資安工作狀態。", - "boundary": "本階段只更新可見回報與證據索引:headline_percent=64;framework=92%;runtime_landing=40-45%;active_執行期_閘門_count=0;runtime_execution_authorized=false;repo_creation_authorized=false。", + "boundary": "本階段只更新可見回報與證據索引:整體 64%;框架 92%;runtime landing 40-45%;執行期閘門維持 0;不授權 runtime 或專案庫變更。", "items": { "stageClosed": { "title": "本階段已收斂", @@ -11522,7 +11522,7 @@ "subtitle": "將 64% 往下一階段推進需要的工作拆成四件事;此區僅顯示任務與完成條件,不送出請求、不啟動掃描、不建立執行。", "stepLabel": "任務", "doneLabel": "完成條件", - "boundary": "固定邊界:負責人_response_已收到_count=0;負責人_response_已接受_count=0;active_執行期_閘門_count=0;runtime_execution_authorized=false;action_buttons_allowed=false;repo_creation_authorized=false;github_primary_switch_authorized=false。", + "boundary": "固定邊界:負責人回覆尚未收到或接受;執行期閘門維持 0;不提供操作按鈕;不建立專案庫;不切 GitHub primary。", "items": { "s49OwnerResponse": { "title": "先收 S4.9 負責人回覆", @@ -13446,13 +13446,13 @@ "awooopProductionLandingProof": { "title": "AwoooP 正式只讀消費證據", "body": "AwoooP 主線已在正式站只讀消費 IwoooS / security 鏡像的 重點、證據參照、守門 result與forbidden action。", - "acceptance": "已有 Gitea main commit、CD 成功與正式站路由驗證;execution_router_linked=false、runtime_execution_authorized=false。", + "acceptance": "已有 Gitea main commit、CD 成功與正式站路由驗證;執行路由與 runtime 授權仍維持關閉。", "guard": "只讀落地不是 批准、操作按鈕、執行路由或阻擋控制。" }, "kali112ReadOnlyProof": { "title": "Kali host:kali-readonly 今日只讀證據", "body": "2026-06-04 08:55 已完成 Kali host:kali-readonly SSH只讀快照、掃描ner 8080 /health、待更新套件 1994、networking.service與服務硬化 0/4的正式站可見證據。", - "acceptance": "已有 Gitea CD run 3623、正式站 desktop / mobile 驗證與維護闖關路徑;runtime_execution_authorized=false。", + "acceptance": "已有 Gitea CD run 3623、正式站 desktop / mobile 驗證與維護闖關路徑;runtime 授權仍維持關閉。", "guard": "只讀證據不是 主動掃描、/execute、SSH 變更、更新、重啟或服務硬化授權。" }, "nextHeadlineReviewRecord": { @@ -14946,7 +14946,7 @@ "title": "鏡像路由群組已知", "body": "`security_鏡像_route_v1` 已定義操作控制台、執行期 state、channel event、audit 證據、批准 佇列的只讀目的地。", "requirement": "AwoooP只能依 route group 顯示與分類,不新增掃描、執行、修復、專案庫、參照或部署動作。", - "guard": "action_buttons_allowed=false;runtime_execution_authorized=false" + "guard": "不提供操作按鈕;runtime 授權仍維持關閉。" }, "forbiddenOutputsLocked": { "title": "禁止輸出已鎖住", @@ -16794,7 +16794,7 @@ "detail": "目前 IwoooS 是低摩擦框架與只讀證據網;掃描、修復、部署、主機更新與版本來源變更都要獨立人工閘門。", "evidence": "守門、快照、LOGBOOK 與邊界鍵都已鎖住。", "next": "等 負責人證據或人工決策後,再另開 follow-up 執行期閘門。", - "locked": "runtime_execution_authorized=false;active_runtime_gate_count=0。" + "locked": "runtime 授權仍維持關閉;執行期閘門維持 0。" } } }, @@ -17598,7 +17598,7 @@ "title": "執行期 禁止動作", "body": "Kali /execute、SSH、主機更新、主動掃描、憑證掃描、阻擋控制、專案庫 / 參照 / 工作流程 動作仍未授權。", "handoff": "平行工作線只能新增只讀證據、介面投影、文件、快照與守門結果。", - "guard": "runtime_execution_authorized=false;action_buttons_allowed=false" + "guard": "runtime 授權仍維持關閉;不提供操作按鈕。" }, "awooopReadOnlyInputs": { "title": "AwoooP只讀輸入", diff --git a/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx b/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx index ba3827c0..750354eb 100644 --- a/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx +++ b/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx @@ -28,6 +28,7 @@ import { type AwoooPStatusChain, } from "@/components/awooop/status-chain"; import { cn } from "@/lib/utils"; +import { publicBoundaryText, publicContractText } from "@/lib/public-security-redaction"; interface RunDetail { run_id: string; @@ -315,7 +316,7 @@ function OwnerResponseValidationDecisionBoundaryPanel() {

{t(`decisionRefs.${item.key}.detail` as never)}

-

{item.contract}

+

{publicContractText(item.contract)}

))} @@ -332,7 +333,7 @@ function OwnerResponseValidationDecisionBoundaryPanel() {
{ownerResponseValidationDecisionBoundaries.map((item) => (
- {item} + {publicBoundaryText(item)}
))}
diff --git a/apps/web/src/app/[locale]/awooop/approvals/page.tsx b/apps/web/src/app/[locale]/awooop/approvals/page.tsx index 881e5611..a453a354 100644 --- a/apps/web/src/app/[locale]/awooop/approvals/page.tsx +++ b/apps/web/src/app/[locale]/awooop/approvals/page.tsx @@ -30,6 +30,7 @@ import { type AwoooPStatusChain, } from "@/components/awooop/status-chain"; import type { IncidentTimelineResponse } from "@/lib/api-client"; +import { publicBoundaryText, publicContractText } from "@/lib/public-security-redaction"; // ============================================================================= // Types @@ -679,11 +680,11 @@ function SecurityOwnerResponseGatePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- approval_record_created=false - owner_response_accepted_count=0 - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("approval_record_created=false")} + {publicBoundaryText("owner_response_accepted_count=0")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- approval_record_created=false - github_primary_approval_granted=false - owner_response_accepted_count=0 - repo_creation_authorized=false - refs_mutation_authorized=false - secret_value_collection_allowed=false - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("approval_record_created=false")} + {publicBoundaryText("github_primary_approval_granted=false")} + {publicBoundaryText("owner_response_accepted_count=0")} + {publicBoundaryText("repo_creation_authorized=false")} + {publicBoundaryText("refs_mutation_authorized=false")} + {publicBoundaryText("secret_value_collection_allowed=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{t(`reviewRefs.${item.key}.detail`)}

-

- {item.contract} +

+ {publicContractText(item.contract)}

@@ -918,18 +919,18 @@ function OwnerResponseValidationApprovalBoundaryPanel() {

{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 +
+ {publicBoundaryText("owner_response_validation_received_count=0")} + {publicBoundaryText("owner_response_validation_accepted_count=0")} + {publicBoundaryText("owner_response_validation_rejected_count=0")} + {publicBoundaryText("approval_record_created=false")} + {publicBoundaryText("repo_creation_authorized=false")} + {publicBoundaryText("refs_sync_authorized=false")} + {publicBoundaryText("workflow_modification_authorized=false")} + {publicBoundaryText("secret_value_collection_allowed=false")} + {publicBoundaryText("github_primary_switch_authorized=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{contracts.map((item) => (
-

{item.name}

+

{publicContractText(item.name)}

{item.detail}

))} @@ -229,11 +230,11 @@ function SecurityContractCandidatePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- contract_publish_authorized=false - contract_mutation_authorized=false - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("contract_publish_authorized=false")} + {publicBoundaryText("contract_mutation_authorized=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{contracts.map((item) => (
-

{item.name}

+

{publicContractText(item.name)}

{item.detail}

))} @@ -344,14 +345,14 @@ function GitHubPrimaryReadinessContractCandidatePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- repo_creation_authorized=false - refs_mutation_authorized=false - secret_value_collection_allowed=false - github_primary_switch_authorized=false - gitea_disablement_authorized=false - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("repo_creation_authorized=false")} + {publicBoundaryText("refs_mutation_authorized=false")} + {publicBoundaryText("secret_value_collection_allowed=false")} + {publicBoundaryText("github_primary_switch_authorized=false")} + {publicBoundaryText("gitea_disablement_authorized=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{contracts.map((item) => (
-

{item.name}

+

{publicContractText(item.name)}

{item.detail}

))} @@ -462,17 +463,17 @@ function OwnerResponseValidationContractCandidatePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- owner_response_validation_received_count=0 - owner_response_validation_accepted_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 +
+ {publicBoundaryText("owner_response_validation_received_count=0")} + {publicBoundaryText("owner_response_validation_accepted_count=0")} + {publicBoundaryText("approval_record_created=false")} + {publicBoundaryText("repo_creation_authorized=false")} + {publicBoundaryText("refs_sync_authorized=false")} + {publicBoundaryText("workflow_modification_authorized=false")} + {publicBoundaryText("secret_value_collection_allowed=false")} + {publicBoundaryText("github_primary_switch_authorized=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- read_only_production_landing_evidence_count=1 - execution_router_linked=false - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("read_only_production_landing_evidence_count=1")} + {publicBoundaryText("execution_router_linked=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}
@@ -990,8 +991,8 @@ function GitHubPrimaryReadinessHomePanel() { {githubPrimaryReadinessRefs.map((ref) => (
-

- {ref.contract} +

+ {publicContractText(ref.contract)}

{t(`readinessRefs.${ref.key}` as never)} @@ -1018,9 +1019,9 @@ function GitHubPrimaryReadinessHomePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
+
{githubPrimaryReadinessBoundaries.map((boundary) => ( - {boundary} + {publicBoundaryText(boundary)} ))}
@@ -1160,9 +1161,9 @@ function OwnerResponseValidationRollupPanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
+
{ownerResponseValidationBoundaries.map((boundary) => ( - {boundary} + {publicBoundaryText(boundary)} ))}
@@ -1244,8 +1245,8 @@ function HighValueConfigOwnerPacketHomePanel() { {highValueConfigOwnerPacketRefs.map((ref) => (
-

- {ref.contract} +

+ {publicContractText(ref.contract)}

{t(`refs.${ref.key}` as never)} @@ -1275,9 +1276,9 @@ function HighValueConfigOwnerPacketHomePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
+
{highValueConfigOwnerPacketBoundaries.map((boundary) => ( - {boundary} + {publicBoundaryText(boundary)} ))}
diff --git a/apps/web/src/app/[locale]/awooop/runs/[run_id]/page.tsx b/apps/web/src/app/[locale]/awooop/runs/[run_id]/page.tsx index b3e48276..2146c019 100644 --- a/apps/web/src/app/[locale]/awooop/runs/[run_id]/page.tsx +++ b/apps/web/src/app/[locale]/awooop/runs/[run_id]/page.tsx @@ -36,6 +36,7 @@ import { type AwoooPStatusChain, } from "@/components/awooop/status-chain"; import { cn } from "@/lib/utils"; +import { publicBoundaryText, publicContractText } from "@/lib/public-security-redaction"; interface RunDetail { run_id: string; @@ -583,7 +584,7 @@ function OwnerResponseValidationDetailBoundaryPanel() {

{t(`detailRefs.${item.key}.detail` as never)}

-

{item.contract}

+

{publicContractText(item.contract)}

))} @@ -600,7 +601,7 @@ function OwnerResponseValidationDetailBoundaryPanel() {
{ownerResponseValidationDetailBoundaries.map((item) => (
- {item} + {publicBoundaryText(item)}
))}
diff --git a/apps/web/src/app/[locale]/awooop/runs/page.tsx b/apps/web/src/app/[locale]/awooop/runs/page.tsx index 3405d299..ef6c0789 100644 --- a/apps/web/src/app/[locale]/awooop/runs/page.tsx +++ b/apps/web/src/app/[locale]/awooop/runs/page.tsx @@ -35,6 +35,7 @@ import { TriangleAlert, } from "lucide-react"; import { cn } from "@/lib/utils"; +import { publicBoundaryText, publicContractText } from "@/lib/public-security-redaction"; // ============================================================================= // Types @@ -1177,7 +1178,7 @@ function SecurityRunStateCandidatePanel() {
{runRefs.map((item) => (
-

{item.name}

+

{publicContractText(item.name)}

{item.detail}

))} @@ -1188,11 +1189,11 @@ function SecurityRunStateCandidatePanel() {

{t("boundaryLabel")}

{t("boundaryTitle")}

{t("boundaryDetail")}

-
- security_run_created=false - execution_router_linked=false - runtime_execution_authorized=false - action_buttons_allowed=false +
+ {publicBoundaryText("security_run_created=false")} + {publicBoundaryText("execution_router_linked=false")} + {publicBoundaryText("runtime_execution_authorized=false")} + {publicBoundaryText("action_buttons_allowed=false")}

- {ref.name} + {publicContractText(ref.name)}

{t(`runRefs.${ref.key}` as never)} @@ -1302,9 +1303,9 @@ function GitHubRunReadinessBoundaryPanel() {

{t("boundaryDetail")}

-
+
{githubRunReadinessBoundaries.map((boundary) => ( - {boundary} + {publicBoundaryText(boundary)} ))}
@@ -1398,8 +1399,8 @@ function OwnerResponseValidationRunBoundaryPanel() {

{t(`runRefs.${item.key}.detail` as never)}

-

- {item.contract} +

+ {publicContractText(item.contract)}

@@ -1416,9 +1417,9 @@ function OwnerResponseValidationRunBoundaryPanel() {

{t("boundaryDetail")}

-
+
{ownerResponseValidationRunBoundaries.map((boundary) => ( - {boundary} + {publicBoundaryText(boundary)} ))}
diff --git a/apps/web/src/app/[locale]/code-review/page.tsx b/apps/web/src/app/[locale]/code-review/page.tsx index 369efbb0..f939932b 100644 --- a/apps/web/src/app/[locale]/code-review/page.tsx +++ b/apps/web/src/app/[locale]/code-review/page.tsx @@ -2,6 +2,7 @@ import { AppLayout } from '@/components/layout' import { IwoooSReadOnlyBridge } from '@/components/security/iwooos-read-only-bridge' +import { publicBoundaryText } from '@/lib/public-security-redaction' import { Activity, ArrowRight, @@ -133,7 +134,7 @@ export default function CodeReviewPage({ params }: { params: { locale: string }
{handoffFlags.map((flag) => (
- {flag} + {publicBoundaryText(flag)}
))}
@@ -176,7 +177,7 @@ export default function CodeReviewPage({ params }: { params: { locale: string }
{t('candidateQueue.subtitle')}
- action_buttons_allowed=false + {publicBoundaryText('action_buttons_allowed=false')}
diff --git a/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx b/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx index ca55a354..86afc8f3 100644 --- a/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx +++ b/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx @@ -37,6 +37,7 @@ import { useTranslations } from 'next-intl' import { GlassCard } from '@/components/ui/glass-card' import { StatusOrb } from '@/components/ui/status-orb' import { AgentActivityConstellation } from '@/components/governance/agent-activity-constellation' +import { redactPublicIdentifier } from '@/lib/public-security-redaction' import { apiClient, type AiAgent12AgentWarRoomSnapshot, @@ -13725,16 +13726,16 @@ export function AutomationInventoryTab() {
- {runner.display_name} + {redactPublicIdentifier(runner.display_name)}
- {runner.health_contract} + {redactPublicIdentifier(runner.health_contract)}
- - + +
))} diff --git a/apps/web/src/app/[locale]/security-compliance/page.tsx b/apps/web/src/app/[locale]/security-compliance/page.tsx index 86f30ffe..308429ab 100644 --- a/apps/web/src/app/[locale]/security-compliance/page.tsx +++ b/apps/web/src/app/[locale]/security-compliance/page.tsx @@ -23,6 +23,7 @@ import { AppLayout } from "@/components/layout"; import { PageTabs, type TabConfig } from "@/components/layout/page-tabs"; import { SecurityPanel } from "@/components/panels/SecurityPanel"; import { CompliancePanel } from "@/components/panels/CompliancePanel"; +import { publicBoundaryText } from "@/lib/public-security-redaction"; const integrationItems = [ { key: "routePreserved", value: "保留", icon: ShieldCheck, color: "#1f7a4d" }, @@ -627,7 +628,7 @@ function SecurityComplianceFrontStage({ locale: _locale }: { locale: string }) { }} > {rolloutBoundaries.map((boundary) => ( - - {boundary} - + {publicBoundaryText(boundary)} + ))}
@@ -709,7 +710,7 @@ function SecurityComplianceFrontStage({ locale: _locale }: { locale: string }) {
{integrationBoundaries.map((boundary) => ( - - {boundary} - + {publicBoundaryText(boundary)} + ))}
diff --git a/apps/web/src/components/security/iwooos-read-only-bridge.tsx b/apps/web/src/components/security/iwooos-read-only-bridge.tsx index 43e27181..e9b51368 100644 --- a/apps/web/src/components/security/iwooos-read-only-bridge.tsx +++ b/apps/web/src/components/security/iwooos-read-only-bridge.tsx @@ -8,6 +8,7 @@ import Link from 'next/link' import { ArrowRight, ShieldCheck } from 'lucide-react' import { useTranslations } from 'next-intl' +import { publicBoundaryText } from '@/lib/public-security-redaction' const metrics = [ { key: 'overall', value: '64%' }, @@ -197,7 +198,7 @@ export function IwoooSReadOnlyBridge({ variant = 'light' }: IwoooSReadOnlyBridge
{boundaries.map(boundary => ( - {boundary} + {publicBoundaryText(boundary)} ))}
diff --git a/apps/web/src/lib/public-security-redaction.ts b/apps/web/src/lib/public-security-redaction.ts new file mode 100644 index 00000000..f990d0c2 --- /dev/null +++ b/apps/web/src/lib/public-security-redaction.ts @@ -0,0 +1,81 @@ +export function publicBoundaryText(value: string): string { + const labels: Record = { + "security_compliance_route_preserved=true": "安全合規路由已保留,並整合到 IwoooS 權威入口。", + "security_compliance_removed=false": "安全合規頁沒有被移除,但不再作為孤立入口。", + "security_compliance_integration_mode=iwooos_frontstage_bridge": "前台整合模式為 IwoooS 安全合規橋接。", + "security_compliance_authoritative_entry=iwooos": "IwoooS 是目前安全治理的權威入口。", + "security_compliance_frontstage_summary_mode=compact_first": "前台採摘要優先,細節預設收合。", + "security_compliance_frontstage_default_detail_collapsed=true": "詳細證據預設收合,避免首屏過載。", + "security_compliance_frontstage_route_role_count=5": "前台路由角色已收斂為 5 類。", + "security_compliance_frontstage_primary_source=iwooos": "前台主要來源固定為 IwoooS。", + "security_compliance_frontstage_execution_entry_count=0": "前台沒有任何執行入口。", + "security_compliance_frontstage_links_read_only=true": "前台連結僅供只讀導覽。", + "iwooos_authoritative_security_entry=true": "IwoooS 已作為安全治理權威入口。", + "security_compliance_rollout_phase_count=5": "Rollout 維持 5 階段治理節奏。", + "security_compliance_rollout_current_phase=observe_first": "目前階段為先觀測、後收斂。", + "security_compliance_rollout_runtime_phase_enabled=false": "執行期階段尚未開放。", + "security_compliance_rollout_enforcement_enabled=false": "強制執行尚未開放。", + }; + if (labels[value]) return labels[value]; + if (value.includes("runtime_execution_authorized=false")) return "執行期操作未授權。"; + if (value.includes("action_buttons_allowed=false")) return "此頁不提供可執行操作按鈕。"; + if (value.includes("active_runtime_gate_count=0")) return "執行期閘門維持關閉。"; + if (value.includes("owner_response_validation_received_count=0")) return "負責人回覆尚未收到。"; + if (value.includes("owner_response_validation_accepted_count=0")) return "負責人回覆尚未接受。"; + if (value.includes("owner_response_validation_rejected_count=0")) return "目前沒有正式拒收紀錄。"; + if (value.includes("repo_creation_authorized=false")) return "未核准建立專案庫或修改可見性。"; + if (value.includes("refs_mutation_authorized=false") || value.includes("refs_sync_authorized=false")) { + return "未核准同步、刪除或強制推送分支 / 標籤。"; + } + if (value.includes("workflow_modification_authorized=false") || value.includes("workflow_secret_modification_authorized=false")) { + return "未核准修改工作流程、runner 或機密設定。"; + } + if (value.includes("secret_value_collection_allowed=false")) return "不得收集或顯示任何機密明文值。"; + if (value.includes("github_primary_switch_authorized=false")) return "GitHub primary 尚未核准切換。"; + if (value.includes("gitea_disablement_authorized=false")) return "Gitea 不得停用,仍是目前 CI/CD 來源。"; + if (value.includes("execution_router_linked=false")) return "尚未連接執行路由。"; + if (value.includes("security_run_created=false") || value.includes("github_primary_run_created=false")) { + return "目前沒有建立資安執行 run。"; + } + if (value.includes("approval_record_created=false") || value.includes("security_approval_record_created=false")) { + return "目前沒有建立審批紀錄。"; + } + if (value.includes("platform_run_creation_authorized=false")) return "未核准建立平台 run。"; + if (value.includes("not_authorization=true")) return "此區塊僅為只讀證據,不代表授權。"; + if (value.includes("contract_publish_authorized=false")) return "未核准發布或改版合約。"; + if (value.includes("contract_mutation_authorized=false")) return "未核准修改合約內容。"; + if (value.includes("send_owner_request_allowed=false")) return "未核准送出負責人請求。"; + if (value.includes("mark_received_allowed=false")) return "未核准標記已收到。"; + if (value.includes("mark_accepted_allowed=false")) return "未核准標記已接受。"; + if (value.includes("nginx_reload_authorized=false")) return "未核准 Nginx reload 或公開入口變更。"; + if (value.includes("agent_bounty_runtime_authorized=false")) return "agent-bounty-protocol 執行期維持關閉。"; + if (value.includes("github_primary_approval_granted=false")) return "GitHub primary 尚未獲得審批。"; + if (value.includes("owner_response_accepted_count=0")) return "負責人回覆接受數仍為 0。"; + if (value.includes("_count=0")) return "目前計數仍為 0,僅供只讀觀測。"; + if (value.includes("=false")) return "目前狀態為未授權,僅供只讀觀測。"; + return value; +} + +export function publicContractText(value: string): string { + const labels: Record = { + source_control_primary_readiness_gate_v1: "主要來源就緒度 Gate", + source_control_owner_response_validation_rollup_v1: "負責人回覆驗收彙整", + source_control_primary_rollback_adr_v1: "主要來源 rollback 決策紀錄", + source_control_workflow_secret_name_inventory_v1: "工作流程與機密名稱清冊", + gitea_inventory_owner_attestation_response_v1: "Gitea 清冊負責人證明", + github_target_owner_decision_response_v1: "GitHub 目標負責人決策", + source_control_ref_truth_owner_response_v1: "分支 / 標籤真相負責人回覆", + source_control_workflow_secret_name_owner_response_v1: "工作流程 / 機密名稱負責人回覆", + security_mirror_status_rollup_v1: "資安鏡像狀態彙整", + iwooos_posture_projection_v1: "IwoooS 態勢投影", + security_rollout_policy_v1: "資安 rollout 政策", + high_value_config_owner_packet_v1: "高價值配置負責人封包", + high_value_config_change_gate_v1: "高價值配置變更 Gate", + }; + return labels[value] ?? "已脫敏只讀證據參照"; +} + +export function redactPublicIdentifier(value: string): string { + if (value.includes("actions.runner.")) return "已脫敏 runner systemd 服務"; + return value.replace(/\b[a-z0-9][a-z0-9-]{2,}\/[A-Za-z0-9._-]+\b/g, "已脫敏專案來源"); +}