diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 8f2eafc5..840bc176 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -1319,6 +1319,48 @@ } } }, + "hostEvidenceReadiness": { + "title": "Host Evidence Readiness", + "subtitle": "Lists the evidence required before host scans, updates, SSH changes, or runtime blocking can proceed. These items are waiting for collection and do not mean approval.", + "evidenceLabel": "Required evidence", + "items": { + "scopeBoundary": { + "title": "Scope boundary", + "body": "Confirms allowed targets, exclusions, scan depth, and rate limits for 112, 168, and 111.", + "evidence": "requires redacted scan scope approval; received=0, accepted=0" + }, + "ownerDecision": { + "title": "Owner decision record", + "body": "Every host action needs human control; IwoooS visibility or AwoooP queue status cannot replace a decision.", + "evidence": "requires accepted decision record; active runtime gates=0" + }, + "credentialHandling": { + "title": "Credential handling", + "body": "Credentialed scans require defined credential source, storage boundary, redaction, and rejection rules.", + "evidence": "credential material collection is forbidden; credentialed scan=false" + }, + "maintenanceWindow": { + "title": "Maintenance window", + "body": "Kali updates, host tuning, or SSH changes need a maintenance window to avoid disrupting development and product flow.", + "evidence": "requires window, impact scope, notification, and recovery criteria" + }, + "rollbackPlan": { + "title": "Rollback plan", + "body": "Every host change needs a recovery path covering packages, settings, services, and toolchain versions.", + "evidence": "requires rollback owner, steps, and validation method" + }, + "validationMetrics": { + "title": "Validation metrics", + "body": "Host actions need post-check metrics to confirm scanners, monitoring, services, and user flows did not regress.", + "evidence": "requires post-check metrics and failure lane" + }, + "redactedIngestion": { + "title": "Redacted ingestion", + "body": "Host findings or scan results may only enter mirror as redacted summaries, not raw runtime input.", + "evidence": "requires redacted payload acceptance; payloads_ingested=false" + } + } + }, "nextGate": { "title": "Next High-level Gate", "body": "S4.9 Gitea owner attestation response is the recommended next owner evidence. Headline progress should only increase after owner responses, redacted payload ingestion, active runtime gates, or GitHub primary readiness actually change." diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 6a12004c..e8c6bc63 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -1320,6 +1320,48 @@ } } }, + "hostEvidenceReadiness": { + "title": "主機 Evidence Readiness", + "subtitle": "列出主機掃描、更新、SSH 變更或 runtime blocking 前必須補齊的 evidence。這些項目目前都只是待收件,不代表已批准。", + "evidenceLabel": "需要 Evidence", + "items": { + "scopeBoundary": { + "title": "Scope boundary", + "body": "確認 112、168、111 的允許目標、排除範圍、掃描深度與速率限制。", + "evidence": "需要脫敏 scan scope approval;received=0、accepted=0" + }, + "ownerDecision": { + "title": "Owner decision record", + "body": "每個主機動作都需要人控決策,不能用 IwoooS 可見狀態或 AwoooP queue 取代。", + "evidence": "需要 accepted decision record;目前 active runtime gates=0" + }, + "credentialHandling": { + "title": "Credential handling", + "body": "帶憑證掃描前要先定義憑證來源、保存邊界、遮蔽方式與拒收規則。", + "evidence": "禁止收集憑證明文;目前 credentialed scan=false" + }, + "maintenanceWindow": { + "title": "Maintenance window", + "body": "Kali 更新、主機調校或 SSH 變更都需要維護窗口,避免影響開發與產品流程。", + "evidence": "需要窗口、影響範圍、通知與回復標準" + }, + "rollbackPlan": { + "title": "Rollback plan", + "body": "任何主機變更都要能回復,包含套件、設定、服務與工具鏈版本。", + "evidence": "需要 rollback owner、步驟與驗證方式" + }, + "validationMetrics": { + "title": "Validation metrics", + "body": "主機動作後要有驗證指標,確認掃描器、監控、服務與使用者流程沒有退化。", + "evidence": "需要 post-check 指標與失敗處理 lane" + }, + "redactedIngestion": { + "title": "Redacted ingestion", + "body": "主機 finding 或掃描結果只能以脫敏摘要進入 mirror,不能直接把 raw payload 當 runtime input。", + "evidence": "需要 redacted payload acceptance;payloads_ingested=false" + } + } + }, "nextGate": { "title": "下一個高層 Gate", "body": "S4.9 Gitea owner attestation response 是目前建議先收的 owner evidence。任何 headline 提升都要等 owner response、redacted payload ingestion、active runtime gate 或 GitHub primary readiness 有真實變化。" diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 5932dd88..34f75785 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -88,6 +88,13 @@ type HostActionGateItem = { tone: 'steady' | 'warn' | 'locked' } +type HostEvidenceReadinessItem = { + key: string + gate: string + icon: typeof ShieldCheck + tone: 'steady' | 'warn' | 'locked' +} + const postureMetrics: PostureMetric[] = [ { key: 'overall', value: '58%', tone: 'warn' }, { key: 'framework', value: '80-85%', tone: 'steady' }, @@ -199,6 +206,16 @@ const hostActionGateItems: HostActionGateItem[] = [ { key: 'runtimeBlocking', gate: 'S3.4', icon: ShieldCheck, tone: 'locked' }, ] +const hostEvidenceReadinessItems: HostEvidenceReadinessItem[] = [ + { key: 'scopeBoundary', gate: 'S1.6', icon: Radar, tone: 'warn' }, + { key: 'ownerDecision', gate: 'S3.1', icon: ClipboardCheck, tone: 'warn' }, + { key: 'credentialHandling', gate: 'S1.6', icon: Lock, tone: 'locked' }, + { key: 'maintenanceWindow', gate: 'S3.4', icon: Clock3, tone: 'warn' }, + { key: 'rollbackPlan', gate: 'S3.4', icon: FileWarning, tone: 'warn' }, + { key: 'validationMetrics', gate: 'S3.4', icon: CheckCircle2, tone: 'warn' }, + { key: 'redactedIngestion', gate: 'S1.6', icon: ShieldCheck, tone: 'locked' }, +] + const evidenceItems = [ 'iwooos-posture-projection.snapshot.json', 'security-rollout-policy.snapshot.json', @@ -501,6 +518,34 @@ function HostActionGateCard({ item, index }: { item: HostActionGateItem; index: ) } +function HostEvidenceReadinessCard({ item, index }: { item: HostEvidenceReadinessItem; index: number }) { + const t = useTranslations('iwooos.hostEvidenceReadiness') + const Icon = item.icon + return ( +
+ {t(`items.${item.key}.body` as never)} +
++ {t('hostEvidenceReadiness.subtitle')} +
+