feat(iwooos): segment security workbench
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 59s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-03 01:21:39 +08:00
parent 91a67bbb2a
commit fc28a1f4a6
4 changed files with 213 additions and 0 deletions

View File

@@ -13447,6 +13447,30 @@
"state": "受控 apply / break-glass",
"detail": "低中高風險走 selector、dry-run、rollback、verifier事故級仍鎖。"
},
"workspace": {
"eyebrow": "IwoooS 工作台",
"title": "分段查看,不再一頁到底",
"subtitle": "預設只顯示指揮總覽runtime、證據鏈與完整 ledger 依任務切換。",
"ariaLabel": "IwoooS 工作台分段",
"views": {
"overview": {
"label": "指揮總覽",
"detail": "卡點、進度、runtime readback"
},
"runtime": {
"label": "受控執行",
"detail": "Wazuh、AI SOC、dry-run 與 postcheck"
},
"evidence": {
"label": "證據鏈",
"detail": "KM、owner packet、review 前置"
},
"ledger": {
"label": "完整 Ledger",
"detail": "所有治理軌道與歷史明細"
}
}
},
"managerCockpit": {
"eyebrow": "管理者控制台",
"title": "現在真正要處理什麼",

View File

@@ -13447,6 +13447,30 @@
"state": "受控 apply / break-glass",
"detail": "低中高風險走 selector、dry-run、rollback、verifier事故級仍鎖。"
},
"workspace": {
"eyebrow": "IwoooS 工作台",
"title": "分段查看,不再一頁到底",
"subtitle": "預設只顯示指揮總覽runtime、證據鏈與完整 ledger 依任務切換。",
"ariaLabel": "IwoooS 工作台分段",
"views": {
"overview": {
"label": "指揮總覽",
"detail": "卡點、進度、runtime readback"
},
"runtime": {
"label": "受控執行",
"detail": "Wazuh、AI SOC、dry-run 與 postcheck"
},
"evidence": {
"label": "證據鏈",
"detail": "KM、owner packet、review 前置"
},
"ledger": {
"label": "完整 Ledger",
"detail": "所有治理軌道與歷史明細"
}
}
},
"managerCockpit": {
"eyebrow": "管理者控制台",
"title": "現在真正要處理什麼",

View File

@@ -168,6 +168,7 @@ type VisualDashboardGate = {
type VisualExperienceMode = 'attackPath' | 'assetHeat' | 'responseFlow'
type IwoooSCommandMapMode = 'unlock' | 'scope' | 'hosts' | 'sourceControl' | 'awooop' | 'boundary'
type IwoooSWorkspaceView = 'overview' | 'runtime' | 'evidence' | 'ledger'
type VisualExperienceTab = {
key: VisualExperienceMode
@@ -6462,6 +6463,105 @@ function ToneDot({ tone }: { tone: 'steady' | 'warn' | 'locked' }) {
)
}
const iwooosWorkspaceViews: Array<{
key: IwoooSWorkspaceView
icon: typeof ShieldCheck
tone: 'steady' | 'warn' | 'locked'
}> = [
{ key: 'overview', icon: Radar, tone: 'steady' },
{ key: 'runtime', icon: Workflow, tone: 'warn' },
{ key: 'evidence', icon: FileCheck2, tone: 'warn' },
{ key: 'ledger', icon: ClipboardList, tone: 'locked' },
]
function IwoooSWorkspaceSwitcher({
active,
onChange,
}: {
active: IwoooSWorkspaceView
onChange: (value: IwoooSWorkspaceView) => void
}) {
const t = useTranslations('iwooos.workspace')
return (
<section style={{ ...band, padding: 14, marginBottom: 14 }} data-testid="iwooos-workspace-switcher">
<div
style={{
display: 'grid',
gridTemplateColumns: 'minmax(0, 1.1fr) minmax(0, 2fr)',
gap: 14,
alignItems: 'center',
}}
>
<div style={{ minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, color: '#315f45', fontSize: 12, fontWeight: 800 }}>
<ShieldCheck size={16} color="#2f7d48" />
{t('eyebrow')}
</div>
<h2 style={{ margin: '6px 0 0', fontSize: 18, color: '#141413' }}>{t('title')}</h2>
<p style={{ margin: '6px 0 0', color: '#5f5b52', fontSize: 12, lineHeight: 1.5 }}>
{t('subtitle')}
</p>
</div>
<div
role="tablist"
aria-label={t('ariaLabel')}
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(132px, 1fr))',
gap: 8,
}}
>
{iwooosWorkspaceViews.map(view => {
const Icon = view.icon
const selected = active === view.key
return (
<button
key={view.key}
type="button"
role="tab"
aria-selected={selected}
onClick={() => onChange(view.key)}
style={{
appearance: 'none',
border: selected ? `1px solid ${toneColors[view.tone]}` : '0.5px solid #ded9ce',
background: selected ? '#f6fbf6' : '#fff',
color: selected ? toneColors[view.tone] : '#5f5b52',
minHeight: 58,
padding: '10px 11px',
display: 'grid',
gap: 5,
textAlign: 'left',
cursor: 'pointer',
}}
>
<span style={{ display: 'flex', alignItems: 'center', gap: 7, fontSize: 12, fontWeight: 800 }}>
<Icon size={15} color={selected ? toneColors[view.tone] : '#77736a'} />
{t(`views.${view.key}.label` as never)}
</span>
<span style={{ fontSize: 11, lineHeight: 1.35, color: selected ? '#315f45' : '#77736a' }}>
{t(`views.${view.key}.detail` as never)}
</span>
</button>
)
})}
</div>
</div>
</section>
)
}
function IwoooSWorkspacePanel({
active,
children,
}: {
active: boolean
children: ReactNode
}) {
if (!active) return null
return <div style={{ display: 'grid', gap: 14 }}>{children}</div>
}
function MetricCard({ item }: { item: PostureMetric }) {
const t = useTranslations('iwooos.metrics')
return (
@@ -24146,6 +24246,7 @@ function HostOwnerDecisionRecordHumanRecordOwnerReviewPreparationChecklistCard({
export default function IwoooSPage({ params }: { params: { locale: string } }) {
const t = useTranslations('iwooos')
const ia = useTranslations('iwooos.informationArchitecture')
const [workspaceView, setWorkspaceView] = useState<IwoooSWorkspaceView>('overview')
return (
<AppLayout locale={params.locale} fullBleed>
@@ -24178,7 +24279,54 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
</div>
</section>
<IwoooSWorkspaceSwitcher active={workspaceView} onChange={setWorkspaceView} />
<IwoooSManagerCockpit />
<IwoooSWorkspacePanel active={workspaceView === 'overview'}>
<IwoooSCommandRail />
<IwoooSProgressIntegrityRibbon />
<IwoooSExecutiveSnapshotBoard />
<IwoooSRuntimeSecurityReadbackBoard />
<IwoooSSecurityControlCoverageBoard />
</IwoooSWorkspacePanel>
<IwoooSWorkspacePanel active={workspaceView === 'runtime'}>
<IwoooSCommandRail />
<IwoooSAgentBountySecurityOnboardingBoard />
<IwoooSRolloutRiskReadOnlyBoard />
<IwoooSWazuhIntrusionReadbackBoard />
<IwoooSRuntimeSecurityReadbackBoard />
<IwoooSWazuhLiveRouteReadbackBoard />
<IwoooSWazuhReleaseGateBoard />
<IwoooSWazuhManagedHostCoverageBoard />
<IwoooSWazuhManagerRegistryReviewerValidationBoard />
<IwoooSWazuhLiveMetadataEnvGateBoard />
<IwoooSSecurityOperatingSystemBoard />
<IwoooSSocSiemKaliWazuhIntegrationBoard />
<IwoooSP0SecurityIncidentConvergenceBoard />
</IwoooSWorkspacePanel>
<IwoooSWorkspacePanel active={workspaceView === 'evidence'}>
<IwoooSSectionGroup
id="iwooos-workspace-evidence-chain"
title={ia('firstLayerEvidence.title')}
summary={ia('firstLayerEvidence.summary')}
defaultOpen
>
<IwoooSFocusDeckBoard />
<IwoooSFirstScreenDepthMapBoard />
<IwoooSProgressEvidenceRailBoard />
<IwoooSEvidenceUnlockQueueBoard />
<IwoooSS49RequestDraftPackageBoard />
<IwoooSS49RequestDraftDetailBoard />
<IwoooSS49OwnerResponseIntakeBoard />
</IwoooSSectionGroup>
<IwoooSOwnerEvidenceIntakePreflightBoard />
<IwoooSWazuhOwnerEvidencePreflightBoard />
<IwoooSHighValueConfigOwnerPacketBoard />
</IwoooSWorkspacePanel>
<IwoooSWorkspacePanel active={workspaceView === 'ledger'}>
<IwoooSCommandRail />
<IwoooSProgressIntegrityRibbon />
<IwoooSExecutiveSnapshotBoard />
@@ -25388,6 +25536,7 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
</div>
</section>
</IwoooSSectionGroup>
</IwoooSWorkspacePanel>
</main>
</AppLayout>
)

View File

@@ -1,3 +1,19 @@
## 2026-07-03 — 01:24 IwoooS 首屏分段工作台
**完成內容**
- `/zh-TW/iwooos` 新增 `指揮總覽 / 受控執行 / 證據鏈 / 完整 Ledger` segmented workspace預設只 render 指揮總覽,避免 25k 行治理軌道一次全部攤開。
- `runtime` 視圖集中 Wazuh、AI SOC、dry-run、postcheck 與 runtime readback`evidence` 視圖集中 KM / owner packet / review preflight`ledger` 才顯示完整歷史治理明細。
- 手機首屏已把 workspace switcher 移到 manager cockpit 前,使用者不用滑過長文字才知道可分段操作。
**驗證**
- `python3.11 -m json.tool apps/web/messages/zh-TW.json``python3.11 -m json.tool apps/web/messages/en.json`:通過。
- `pnpm --dir apps/web typecheck`:通過。
- `pnpm --dir apps/web audit:ui-density`:通過;`/iwooos` 控制項由 29 增至 32仍列第一優先下一刀需拆 ledger 模組化降 source density。
- Local Chrome smokedesktop tab 切換通過mobile HTTP 200、switcher y=428 進第一 viewport、四個 tab 可見、console error `0`
**仍維持**
- 未讀 secret / token / `.env` / raw sessions / SQLite / auth未使用 GitHub / gh未 production DB schema / data destructive write未重啟主機 / VM / Docker / K3s / DB / firewall。
## 2026-07-03 — 01:05 Gitea all-project repo / dev-main / bundle backup closure
**完成內容**