diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 425051408..4d6613a06 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -1543,6 +1543,49 @@ "required": "follow-up gate pointer; active runtime gates=0" } } + }, + "hostEvidenceReviewerChecklist": { + "title": "Host Evidence Reviewer Checklist", + "subtitle": "After reading handoff packets, reviewers can only use this read-only checklist to decide whether the case can move to the next human decision. The checklist does not mark passed, received / accepted, approval, or runtime gates.", + "checkLabel": "Review check", + "verifyLabel": "Verify", + "items": { + "scopeBoundaryMatch": { + "title": "Scope boundary match", + "body": "Confirm the handoff scope matches host coverage, network, service, and exclusions without expanding scan boundary.", + "verify": "compare redacted pointer only; no scan starts" + }, + "ownerDecisionScopeExpiry": { + "title": "Owner decision scope / expiry", + "body": "Confirm the owner decision record has reviewer, scope, constraints, expiry, and is still valid.", + "verify": "read decision pointer only; no approval record created" + }, + "credentialHandlingMetadataOnly": { + "title": "Credential handling metadata only", + "body": "Confirm the reviewer sees only handling method and accountable owner, without plaintext authentication material.", + "verify": "secret value collection=false" + }, + "redactionAttestationPass": { + "title": "Redaction attestation pass", + "body": "Confirm raw logs, host dumps, unredacted screenshots, private URL credentials, and sensitive payloads are excluded.", + "verify": "raw payload allowed=false" + }, + "maintenanceRollbackComplete": { + "title": "Maintenance / rollback complete", + "body": "If evidence implies later change, confirm maintenance window, rollback owner, and recovery validation metrics exist.", + "verify": "display future-change conditions only; no change execution" + }, + "validationMetricsLinked": { + "title": "Validation metrics linked", + "body": "Confirm post-check metrics, baseline, logs, or follow-up evidence link to readable redacted pointers.", + "verify": "display validation pointer only; runtime gate stays closed" + }, + "runtimeGateSeparated": { + "title": "Runtime gate separated", + "body": "Confirm any reviewer checklist result cannot directly become runtime action and must return to a separate runtime gate.", + "verify": "active runtime gates=0; action buttons=false" + } + } } }, "tickets": { diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 49823cf5a..7d423bc72 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -1544,6 +1544,49 @@ "required": "follow-up gate pointer;active runtime gates=0" } } + }, + "hostEvidenceReviewerChecklist": { + "title": "主機 Evidence Reviewer Checklist", + "subtitle": "Reviewer 在看 handoff packets 後,只能依這些只讀檢查判斷是否可進下一個人工決策。檢查清單不會標示 passed、received / accepted、approval 或 runtime gate。", + "checkLabel": "審查檢查", + "verifyLabel": "確認項目", + "items": { + "scopeBoundaryMatch": { + "title": "Scope boundary match", + "body": "確認 handoff scope 與 host coverage、網段、服務、排除範圍一致,沒有自行擴大掃描邊界。", + "verify": "只核對 redacted pointer;不啟動 scan" + }, + "ownerDecisionScopeExpiry": { + "title": "Owner decision scope / expiry", + "body": "確認 owner decision record 有批准人、範圍、限制條件與到期時間,且仍在有效期內。", + "verify": "只判讀 decision pointer;不建立 approval record" + }, + "credentialHandlingMetadataOnly": { + "title": "Credential handling metadata only", + "body": "確認 reviewer 只看到處理方式與責任人,不接觸任何明文驗證素材。", + "verify": "secret value collection=false" + }, + "redactionAttestationPass": { + "title": "Redaction attestation pass", + "body": "確認 raw log、host dump、未脫敏截圖、private URL credential 與敏感 payload 都已排除。", + "verify": "raw payload allowed=false" + }, + "maintenanceRollbackComplete": { + "title": "Maintenance / rollback complete", + "body": "若 evidence 暗示後續變更,確認已存在維護窗口、rollback owner 與復原驗證指標。", + "verify": "只顯示未來變更條件;不執行 change" + }, + "validationMetricsLinked": { + "title": "Validation metrics linked", + "body": "確認 post-check metrics、baseline、logs 或 follow-up evidence 已連到可讀的脫敏 pointer。", + "verify": "只顯示 validation pointer;不開 runtime gate" + }, + "runtimeGateSeparated": { + "title": "Runtime gate separated", + "body": "確認 reviewer checklist 的任何結果都不能直接變成 runtime action,必須回到獨立 runtime gate。", + "verify": "active runtime gates=0;action buttons=false" + } + } } }, "tickets": { diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 1de5af097..7d3c10d7b 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -123,6 +123,13 @@ type HostEvidenceReviewHandoffPacket = { tone: 'steady' | 'warn' | 'locked' } +type HostEvidenceReviewerChecklistItem = { + key: string + check: string + icon: typeof ShieldCheck + tone: 'steady' | 'warn' | 'locked' +} + const postureMetrics: PostureMetric[] = [ { key: 'overall', value: '58%', tone: 'warn' }, { key: 'framework', value: '80-85%', tone: 'steady' }, @@ -284,6 +291,16 @@ const hostEvidenceReviewHandoffPackets: HostEvidenceReviewHandoffPacket[] = [ { key: 'runtimeGatePacket', packet: 'H7', icon: FileWarning, tone: 'locked' }, ] +const hostEvidenceReviewerChecklistItems: HostEvidenceReviewerChecklistItem[] = [ + { key: 'scopeBoundaryMatch', check: 'C1', icon: Radar, tone: 'warn' }, + { key: 'ownerDecisionScopeExpiry', check: 'C2', icon: ClipboardCheck, tone: 'warn' }, + { key: 'credentialHandlingMetadataOnly', check: 'C3', icon: Lock, tone: 'locked' }, + { key: 'redactionAttestationPass', check: 'C4', icon: ShieldCheck, tone: 'locked' }, + { key: 'maintenanceRollbackComplete', check: 'C5', icon: Clock3, tone: 'warn' }, + { key: 'validationMetricsLinked', check: 'C6', icon: CheckCircle2, tone: 'warn' }, + { key: 'runtimeGateSeparated', check: 'C7', icon: FileWarning, tone: 'locked' }, +] + const evidenceItems = [ 'iwooos-posture-projection.snapshot.json', 'security-rollout-policy.snapshot.json', @@ -726,6 +743,34 @@ function HostEvidenceReviewHandoffCard({ item }: { item: HostEvidenceReviewHando ) } +function HostEvidenceReviewerChecklistCard({ item }: { item: HostEvidenceReviewerChecklistItem }) { + const t = useTranslations('iwooos.hostEvidenceReviewerChecklist') + const Icon = item.icon + return ( +
+ {t(`items.${item.key}.body` as never)} +
++ {t('hostEvidenceReviewerChecklist.subtitle')} +
+