feat(web): add IwoooS host coverage

This commit is contained in:
Your Name
2026-05-19 21:06:58 +08:00
parent bcf7f6448c
commit 79ab8e3f88
11 changed files with 332 additions and 4 deletions

View File

@@ -1260,6 +1260,28 @@
}
}
},
"hostCoverage": {
"title": "Host Coverage View",
"subtitle": "Places Kali and the two development hosts inside the visible IwoooS security scope. This only shows coverage and gate state; it does not create SSH, scan, update, or blocking controls.",
"stateLabel": "Current state",
"items": {
"kali112": {
"title": "Kali security host",
"body": "192.168.0.112 is the Kali node for the security mesh and is visible in posture and evidence refs as observe-only integration.",
"state": "in scope; active scan, /execute, and host updates still require separate approval"
},
"dev168": {
"title": "Development host 168",
"body": "192.168.0.168 is included in IwoooS observe-only development host coverage for future scope approval and finding correlation.",
"state": "scope declared; credentialed scan and runtime control are not approved"
},
"dev111": {
"title": "Development host 111",
"body": "192.168.0.111 is included in IwoooS observe-only development host coverage and stays paired with 168 for phased tightening.",
"state": "scope declared; credentialed scan and runtime control are not approved"
}
}
},
"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."

View File

@@ -1261,6 +1261,28 @@
}
}
},
"hostCoverage": {
"title": "主機覆蓋視圖",
"subtitle": "把 Kali 與兩台開發主機放進 IwoooS 的可見資安範圍。這裡只顯示納管與 gate 狀態,不建立 SSH、掃描、更新或阻擋控制。",
"stateLabel": "目前狀態",
"items": {
"kali112": {
"title": "Kali 資安主機",
"body": "192.168.0.112 是資安網的 Kali 節點,已在 posture 與 evidence refs 中作為 observe-only 整合面。",
"state": "已納入視野active scan、/execute、主機更新仍需獨立批准"
},
"dev168": {
"title": "開發主機 168",
"body": "192.168.0.168 納入 IwoooS 的 observe-only 開發主機覆蓋,用於後續 scope approval 與 finding 關聯。",
"state": "scope declared尚未批准 credentialed scan 或 runtime control"
},
"dev111": {
"title": "開發主機 111",
"body": "192.168.0.111 納入 IwoooS 的 observe-only 開發主機覆蓋,與 168 一起維持低摩擦分階段收斂。",
"state": "scope declared尚未批准 credentialed scan 或 runtime control"
}
}
},
"nextGate": {
"title": "下一個高層 Gate",
"body": "S4.9 Gitea owner attestation response 是目前建議先收的 owner evidence。任何 headline 提升都要等 owner response、redacted payload ingestion、active runtime gate 或 GitHub primary readiness 有真實變化。"

View File

@@ -74,6 +74,13 @@ type EvidenceReadinessItem = {
tone: 'steady' | 'warn' | 'locked'
}
type HostCoverageItem = {
key: string
address: string
icon: typeof ShieldCheck
tone: 'steady' | 'warn' | 'locked'
}
const postureMetrics: PostureMetric[] = [
{ key: 'overall', value: '58%', tone: 'warn' },
{ key: 'framework', value: '80-85%', tone: 'steady' },
@@ -170,6 +177,12 @@ const evidenceReadinessItems: EvidenceReadinessItem[] = [
{ key: 'followupRuntimeGate', lane: 'S3.4', icon: ShieldCheck, tone: 'locked' },
]
const hostCoverageItems: HostCoverageItem[] = [
{ key: 'kali112', address: '192.168.0.112', icon: Activity, tone: 'steady' },
{ key: 'dev168', address: '192.168.0.168', icon: Radar, tone: 'warn' },
{ key: 'dev111', address: '192.168.0.111', icon: Radar, tone: 'warn' },
]
const evidenceItems = [
'iwooos-posture-projection.snapshot.json',
'security-rollout-policy.snapshot.json',
@@ -416,6 +429,34 @@ function EvidenceReadinessCard({ item, index }: { item: EvidenceReadinessItem; i
)
}
function HostCoverageCard({ item, index }: { item: HostCoverageItem; index: number }) {
const t = useTranslations('iwooos.hostCoverage')
const Icon = item.icon
return (
<div style={{ ...band, minHeight: 176, padding: 16 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
<Icon size={18} color={toneColors[item.tone]} />
<span style={{ fontSize: 11, color: '#87867f' }}>{item.address}</span>
</div>
<span style={{ fontSize: 11, color: '#9b978b' }}>{String(index + 1).padStart(2, '0')}</span>
</div>
<h2 style={{ fontSize: 14, margin: '12px 0 6px', color: '#141413' }}>
{t(`items.${item.key}.title` as never)}
</h2>
<p style={{ fontSize: 12, lineHeight: 1.55, color: '#6f6d66', margin: 0 }}>
{t(`items.${item.key}.body` as never)}
</p>
<div style={{ marginTop: 10, display: 'grid', gap: 5 }}>
<div style={{ fontSize: 11, color: '#87867f' }}>{t('stateLabel')}</div>
<div style={{ fontSize: 11, color: toneColors[item.tone], lineHeight: 1.45 }}>
{t(`items.${item.key}.state` as never)}
</div>
</div>
</div>
)
}
export default function IwoooSPage({ params }: { params: { locale: string } }) {
const t = useTranslations('iwooos')
@@ -488,6 +529,26 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
</div>
</section>
<section style={{ marginBottom: 14 }}>
<div style={{ marginBottom: 14 }}>
<h2 style={{ fontSize: 16, margin: 0 }}>{t('hostCoverage.title')}</h2>
<p style={{ fontSize: 12, color: '#6f6d66', margin: '6px 0 0', lineHeight: 1.55 }}>
{t('hostCoverage.subtitle')}
</p>
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(210px, 1fr))',
gap: 12,
}}
>
{hostCoverageItems.map((item, index) => (
<HostCoverageCard key={item.key} item={item} index={index} />
))}
</div>
</section>
<section
style={{
display: 'grid',