feat(web): add iwooos pre-review checks
This commit is contained in:
@@ -5067,6 +5067,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"firstUnlockEvidencePacketSupplementPreReview": {
|
||||
"title": "第一解鎖證據包補件送審前檢查",
|
||||
"subtitle": "S2.118 把補件要進 reviewer queue 前的檢查拆成六項:owner metadata 完整、範圍參照可追溯、脫敏聲明成立、預檢軌跡附上、禁止變更條款維持、reviewer queue 未開。這裡只顯示送審前檢查,不代表補件已送出或已接受。",
|
||||
"checkLabel": "檢查",
|
||||
"boundaryTitle": "送審前檢查邊界",
|
||||
"boundaryIntro": "以下鍵值固定:這是補件送審前檢查,不是送件、收件、審查接受、headline review、掃描、修復、部署或執行期入口。",
|
||||
"summary": {
|
||||
"checks": {
|
||||
"label": "檢查項",
|
||||
"detail": "六項都只是送審前條件。"
|
||||
},
|
||||
"passed": {
|
||||
"label": "已通過",
|
||||
"detail": "目前仍是 0,不把檢查表當通過。"
|
||||
},
|
||||
"ready": {
|
||||
"label": "可送審",
|
||||
"detail": "目前仍是 0,reviewer queue 未開。"
|
||||
},
|
||||
"queue": {
|
||||
"label": "審查佇列",
|
||||
"detail": "目前 false,沒有送審入口。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"ownerMetadataComplete": {
|
||||
"title": "owner metadata 完整",
|
||||
"body": "確認 owner role、decision、reason、follow-up owner 與判定時間都存在且可追溯。"
|
||||
},
|
||||
"scopeRefsTraceable": {
|
||||
"title": "範圍參照可追溯",
|
||||
"body": "確認 S4.9 scope、來源脈絡與 evidence refs 一致,不把其他專案或其他主機混入。"
|
||||
},
|
||||
"redactionAttested": {
|
||||
"title": "脫敏聲明成立",
|
||||
"body": "確認只含 metadata 與 evidence pointer,raw payload、token value、私鑰與登入口令都未進入收件。"
|
||||
},
|
||||
"preflightTraceAttached": {
|
||||
"title": "預檢軌跡附上",
|
||||
"body": "確認欄位完整、範圍一致、敏感內容隔離與禁止變更條款都有檢查結果。"
|
||||
},
|
||||
"noMutationClauseHeld": {
|
||||
"title": "禁止變更條款維持",
|
||||
"body": "確認補件不會觸發 repo、refs、workflow、secret、Kali、SSH、部署或主機變更。"
|
||||
},
|
||||
"reviewerQueueReady": {
|
||||
"title": "reviewer queue 未開",
|
||||
"body": "即使前五項都補齊,也要等人工 reviewer queue 開啟;目前仍是 false。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"s49OwnerResponseWorkOrder": {
|
||||
"title": "S4.9 Owner Response 人工收件工作單",
|
||||
"subtitle": "S2.101 把第一個真正能推動 58% 的 S4.9 回覆收件格式放到 IwoooS:每項都要包含 owner role/team、decision、decision reason、受影響 scope、脫敏 evidence refs 與 follow-up owner。這裡只是人工收件工作單,不送出 request、不收件、不標記 received / accepted。",
|
||||
|
||||
@@ -5068,6 +5068,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"firstUnlockEvidencePacketSupplementPreReview": {
|
||||
"title": "第一解鎖證據包補件送審前檢查",
|
||||
"subtitle": "S2.118 把補件要進 reviewer queue 前的檢查拆成六項:owner metadata 完整、範圍參照可追溯、脫敏聲明成立、預檢軌跡附上、禁止變更條款維持、reviewer queue 未開。這裡只顯示送審前檢查,不代表補件已送出或已接受。",
|
||||
"checkLabel": "檢查",
|
||||
"boundaryTitle": "送審前檢查邊界",
|
||||
"boundaryIntro": "以下鍵值固定:這是補件送審前檢查,不是送件、收件、審查接受、headline review、掃描、修復、部署或執行期入口。",
|
||||
"summary": {
|
||||
"checks": {
|
||||
"label": "檢查項",
|
||||
"detail": "六項都只是送審前條件。"
|
||||
},
|
||||
"passed": {
|
||||
"label": "已通過",
|
||||
"detail": "目前仍是 0,不把檢查表當通過。"
|
||||
},
|
||||
"ready": {
|
||||
"label": "可送審",
|
||||
"detail": "目前仍是 0,reviewer queue 未開。"
|
||||
},
|
||||
"queue": {
|
||||
"label": "審查佇列",
|
||||
"detail": "目前 false,沒有送審入口。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"ownerMetadataComplete": {
|
||||
"title": "owner metadata 完整",
|
||||
"body": "確認 owner role、decision、reason、follow-up owner 與判定時間都存在且可追溯。"
|
||||
},
|
||||
"scopeRefsTraceable": {
|
||||
"title": "範圍參照可追溯",
|
||||
"body": "確認 S4.9 scope、來源脈絡與 evidence refs 一致,不把其他專案或其他主機混入。"
|
||||
},
|
||||
"redactionAttested": {
|
||||
"title": "脫敏聲明成立",
|
||||
"body": "確認只含 metadata 與 evidence pointer,raw payload、token value、私鑰與登入口令都未進入收件。"
|
||||
},
|
||||
"preflightTraceAttached": {
|
||||
"title": "預檢軌跡附上",
|
||||
"body": "確認欄位完整、範圍一致、敏感內容隔離與禁止變更條款都有檢查結果。"
|
||||
},
|
||||
"noMutationClauseHeld": {
|
||||
"title": "禁止變更條款維持",
|
||||
"body": "確認補件不會觸發 repo、refs、workflow、secret、Kali、SSH、部署或主機變更。"
|
||||
},
|
||||
"reviewerQueueReady": {
|
||||
"title": "reviewer queue 未開",
|
||||
"body": "即使前五項都補齊,也要等人工 reviewer queue 開啟;目前仍是 false。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"s49OwnerResponseWorkOrder": {
|
||||
"title": "S4.9 Owner Response 人工收件工作單",
|
||||
"subtitle": "S2.101 把第一個真正能推動 58% 的 S4.9 回覆收件格式放到 IwoooS:每項都要包含 owner role/team、decision、decision reason、受影響 scope、脫敏 evidence refs 與 follow-up owner。這裡只是人工收件工作單,不送出 request、不收件、不標記 received / accepted。",
|
||||
|
||||
@@ -1163,6 +1163,41 @@ const iwooosFirstUnlockEvidencePacketSupplementPathBoundaries = [
|
||||
'gitea_disablement_authorized=false',
|
||||
] as const
|
||||
|
||||
const iwooosFirstUnlockEvidencePacketSupplementPreReviewChecks = [
|
||||
{ key: 'ownerMetadataComplete', check: 'C1', state: '待檢', icon: ClipboardCheck, tone: 'warn' },
|
||||
{ key: 'scopeRefsTraceable', check: 'C2', state: '待檢', icon: GitBranch, tone: 'warn' },
|
||||
{ key: 'redactionAttested', check: 'C3', state: '待檢', icon: Lock, tone: 'locked' },
|
||||
{ key: 'preflightTraceAttached', check: 'C4', state: '待檢', icon: SearchCheck, tone: 'warn' },
|
||||
{ key: 'noMutationClauseHeld', check: 'C5', state: '鎖定', icon: FileWarning, tone: 'locked' },
|
||||
{ key: 'reviewerQueueReady', check: 'C6', state: '未開', icon: Clock3, tone: 'locked' },
|
||||
] as const
|
||||
|
||||
const iwooosFirstUnlockEvidencePacketSupplementPreReviewBoundaries = [
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_check_count=6',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_current_focus=supplement_pre_review',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_passed_count=0',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_failed_count=0',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_ready_for_review_count=0',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_pre_review_queue_open=false',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_request_sent=false',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_submitted_count=0',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_accepted_count=0',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_raw_payload_allowed=false',
|
||||
'iwooos_first_unlock_evidence_packet_supplement_secret_value_allowed=false',
|
||||
'iwooos_first_unlock_evidence_packet_headline_review_authorized=false',
|
||||
'iwooos_first_unlock_evidence_packet_runtime_gate_opened=false',
|
||||
'runtime_execution_authorized=false',
|
||||
'active_runtime_gate_count=0',
|
||||
'action_buttons_allowed=false',
|
||||
'not_authorization=true',
|
||||
'secret_value_collection_allowed=false',
|
||||
'repo_creation_authorized=false',
|
||||
'refs_sync_authorized=false',
|
||||
'workflow_modification_authorized=false',
|
||||
'github_primary_switch_authorized=false',
|
||||
'gitea_disablement_authorized=false',
|
||||
] as const
|
||||
|
||||
const posturePillars: Pillar[] = [
|
||||
{ key: 'exposure', icon: Radar, tone: 'warn' },
|
||||
{ key: 'sourceControl', icon: GitBranch, tone: 'warn' },
|
||||
@@ -4384,6 +4419,115 @@ function IwoooSFirstUnlockEvidencePacketSupplementPathBoard() {
|
||||
)
|
||||
}
|
||||
|
||||
function IwoooSFirstUnlockEvidencePacketSupplementPreReviewBoard() {
|
||||
const t = useTranslations('iwooos.firstUnlockEvidencePacketSupplementPreReview')
|
||||
const summaryItems = [
|
||||
{ key: 'checks', value: '6', tone: 'warn' as const },
|
||||
{ key: 'passed', value: '0', tone: 'locked' as const },
|
||||
{ key: 'ready', value: '0', tone: 'locked' as const },
|
||||
{ key: 'queue', value: 'false', tone: 'locked' as const },
|
||||
]
|
||||
const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const }
|
||||
|
||||
return (
|
||||
<section style={{ marginBottom: 14 }} data-testid="iwooos-first-unlock-evidence-packet-supplement-pre-review-board">
|
||||
<div style={{ ...band, padding: 16, background: '#f8faf7' }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 300px), 1fr))', gap: 16 }}>
|
||||
<div>
|
||||
<div style={{ marginBottom: 14 }}>
|
||||
<h2 style={{ fontSize: 17, margin: 0 }}>{t('title')}</h2>
|
||||
<p style={{ fontSize: 12, color: '#606a5f', margin: '6px 0 0', lineHeight: 1.55, ...textWrap }}>
|
||||
{t('subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(126px, 1fr))', gap: 8, marginBottom: 14 }}>
|
||||
{summaryItems.map(item => (
|
||||
<div key={item.key} style={{ border: '0.5px solid #dce6d7', borderRadius: 8, padding: 12, background: '#fff' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
||||
<span style={{ fontSize: 11, color: '#737e6e' }}>{t(`summary.${item.key}.label` as never)}</span>
|
||||
<ToneDot tone={item.tone} />
|
||||
</div>
|
||||
<div style={{ fontSize: 20, fontWeight: 700, lineHeight: 1.1, marginTop: 8, color: '#141413' }}>
|
||||
{item.value}
|
||||
</div>
|
||||
<p style={{ fontSize: 11, color: '#606a5f', lineHeight: 1.45, margin: '8px 0 0', ...textWrap }}>
|
||||
{t(`summary.${item.key}.detail` as never)}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(178px, 1fr))', gap: 10 }}>
|
||||
{iwooosFirstUnlockEvidencePacketSupplementPreReviewChecks.map(item => {
|
||||
const Icon = item.icon
|
||||
return (
|
||||
<div
|
||||
key={item.key}
|
||||
style={{
|
||||
display: 'grid',
|
||||
gap: 8,
|
||||
minHeight: 154,
|
||||
border: '0.5px solid #d8e4d4',
|
||||
borderRadius: 8,
|
||||
background: '#fff',
|
||||
padding: 13,
|
||||
color: '#141413',
|
||||
...textWrap,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
||||
<span style={{ color: toneColors[item.tone], fontSize: 12, fontWeight: 700 }}>
|
||||
{t('checkLabel')} {item.check}
|
||||
</span>
|
||||
<Icon size={18} color={toneColors[item.tone]} />
|
||||
</div>
|
||||
<div style={{ fontSize: 15, fontWeight: 700, color: toneColors[item.tone], lineHeight: 1.2 }}>
|
||||
{item.state}
|
||||
</div>
|
||||
<h3 style={{ fontSize: 14, margin: 0, color: '#141413', lineHeight: 1.3 }}>
|
||||
{t(`items.${item.key}.title` as never)}
|
||||
</h3>
|
||||
<p style={{ fontSize: 11, color: '#606a5f', lineHeight: 1.5, margin: 0, ...textWrap }}>
|
||||
{t(`items.${item.key}.body` as never)}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ ...band, padding: 14, background: '#edf4e9', alignSelf: 'stretch' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
|
||||
<ShieldCheck size={16} color={toneColors.locked} />
|
||||
<h3 style={{ fontSize: 14, margin: 0 }}>{t('boundaryTitle')}</h3>
|
||||
</div>
|
||||
<p style={{ fontSize: 12, color: '#606a5f', lineHeight: 1.55, margin: '0 0 10px', ...textWrap }}>
|
||||
{t('boundaryIntro')}
|
||||
</p>
|
||||
<div style={{ display: 'grid', gap: 7 }}>
|
||||
{iwooosFirstUnlockEvidencePacketSupplementPreReviewBoundaries.map(item => (
|
||||
<span
|
||||
key={item}
|
||||
style={{
|
||||
border: '0.5px solid #d5e3d1',
|
||||
borderRadius: 8,
|
||||
padding: '7px 9px',
|
||||
color: '#445241',
|
||||
fontSize: 11,
|
||||
lineHeight: 1.4,
|
||||
background: '#fff',
|
||||
overflowWrap: 'anywhere',
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
function PillarCard({ item }: { item: Pillar }) {
|
||||
const t = useTranslations('iwooos.pillars')
|
||||
const Icon = item.icon
|
||||
@@ -8140,6 +8284,8 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
|
||||
|
||||
<IwoooSFirstUnlockEvidencePacketSupplementPathBoard />
|
||||
|
||||
<IwoooSFirstUnlockEvidencePacketSupplementPreReviewBoard />
|
||||
|
||||
<S49OwnerResponseDispatchFlowBoard />
|
||||
|
||||
<S49OwnerResponseWorkOrderBoard />
|
||||
|
||||
Reference in New Issue
Block a user