fix(iwooos): expose security runtime gaps truthfully
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 58s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m53s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 38s
CD Pipeline / revalidate-post-deploy-carrier (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 58s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m53s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 38s
CD Pipeline / revalidate-post-deploy-carrier (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -88,11 +88,11 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
automationView: "SIEM 與 AI",
|
||||
live: "LIVE",
|
||||
degraded: "DEGRADED",
|
||||
overall: "整體完成度",
|
||||
overall: "控制面建置",
|
||||
assetTypes: "資產類型",
|
||||
nist: "NIST 控制",
|
||||
siem: "SIEM 閉環",
|
||||
strictRun: "全域 AI run",
|
||||
strictRun: "階段收據",
|
||||
aggregateVerified: "全域已驗證",
|
||||
aggregateOpen: "全域未閉環",
|
||||
aggregateScopeNote: "不代表目前 Wazuh lane",
|
||||
@@ -142,11 +142,11 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
automationView: "SIEM & AI",
|
||||
live: "LIVE",
|
||||
degraded: "DEGRADED",
|
||||
overall: "Overall completion",
|
||||
overall: "Control-plane build",
|
||||
assetTypes: "Asset types",
|
||||
nist: "NIST control",
|
||||
siem: "SIEM closure",
|
||||
strictRun: "Aggregate AI run",
|
||||
strictRun: "Stage receipts",
|
||||
aggregateVerified: "Aggregate verified",
|
||||
aggregateOpen: "Aggregate open",
|
||||
aggregateScopeNote: "Does not represent the current Wazuh lane",
|
||||
@@ -183,8 +183,10 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
failed: "Failed",
|
||||
failedCollectors: "Failed collectors",
|
||||
failedCollectorsUnavailable: "Failure detail awaiting safe classification",
|
||||
sameRunMissing: "Aggregate AI run is open; this is not the current Wazuh lane",
|
||||
sameRunVerified: "Aggregate AI run is verified; this is not the current Wazuh lane",
|
||||
sameRunMissing:
|
||||
"Aggregate AI run is open; this is not the current Wazuh lane",
|
||||
sameRunVerified:
|
||||
"Aggregate AI run is verified; this is not the current Wazuh lane",
|
||||
loading: "Loading security control plane",
|
||||
unavailable: "Live readback unavailable",
|
||||
refresh: "Refresh security control plane",
|
||||
@@ -464,7 +466,7 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
|
||||
const tone = payload ? securityControlPlaneTone(payload) : "critical";
|
||||
const priorityItems = useMemo(
|
||||
() => (payload ? topSecurityControlPlaneWorkItems(payload, 3) : []),
|
||||
() => (payload ? topSecurityControlPlaneWorkItems(payload, 5) : []),
|
||||
[payload],
|
||||
);
|
||||
|
||||
@@ -597,13 +599,17 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
label={copy.strictRun}
|
||||
value={
|
||||
payload
|
||||
? payload.ai_automation.strict_runtime_completion.closed
|
||||
? copy.aggregateVerified
|
||||
: copy.aggregateOpen
|
||||
? `${payload.ai_automation.strict_runtime_completion.present_stage_count}/${payload.ai_automation.strict_runtime_completion.required_stage_count}`
|
||||
: "--"
|
||||
}
|
||||
icon={Bot}
|
||||
detail={payload ? copy.aggregateScopeNote : undefined}
|
||||
detail={
|
||||
payload
|
||||
? payload.ai_automation.strict_runtime_completion.closed
|
||||
? copy.aggregateVerified
|
||||
: copy.aggregateOpen
|
||||
: undefined
|
||||
}
|
||||
testId="security-aggregate-ai-run-status"
|
||||
title={
|
||||
payload
|
||||
@@ -815,7 +821,7 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
{priorityItems.length}
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid gap-1.5 sm:grid-cols-3">
|
||||
<div className="grid gap-1.5 sm:grid-cols-2 xl:grid-cols-5">
|
||||
{priorityItems.map((item) => (
|
||||
<div
|
||||
key={item.work_item_id}
|
||||
@@ -831,7 +837,9 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
{item.title}
|
||||
</span>
|
||||
<span className="font-mono text-[10px] text-[#77736a]">
|
||||
{item.gap_count}
|
||||
{item.gap_percent === undefined
|
||||
? item.gap_count
|
||||
: `${item.gap_percent}%`}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
@@ -1063,7 +1071,9 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
{item.title}
|
||||
</span>
|
||||
<span className="font-mono text-[10px] text-[#77736a]">
|
||||
{item.gap_count}
|
||||
{item.gap_percent === undefined
|
||||
? item.gap_count
|
||||
: `${item.gap_percent}%`}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -302,4 +302,45 @@ describe("security asset control plane projection", () => {
|
||||
"AIA-P1-001-01",
|
||||
]);
|
||||
});
|
||||
|
||||
it("uses explicit security dependency order within P0", () => {
|
||||
const value = payload();
|
||||
value.work_items = [
|
||||
{
|
||||
work_item_id: "wazuh",
|
||||
priority: "P0",
|
||||
control_id: "endpoint_xdr_wazuh",
|
||||
title: "wazuh",
|
||||
gap_count: 1,
|
||||
gap_percent: 100,
|
||||
order: 70,
|
||||
status: "open",
|
||||
next_action: "wazuh",
|
||||
},
|
||||
{
|
||||
work_item_id: "inventory",
|
||||
priority: "P0",
|
||||
control_id: "asset_discovery",
|
||||
title: "inventory",
|
||||
gap_count: 1,
|
||||
order: 10,
|
||||
status: "open",
|
||||
next_action: "inventory",
|
||||
},
|
||||
{
|
||||
work_item_id: "audit",
|
||||
priority: "P1",
|
||||
control_id: "audit_integrity",
|
||||
title: "audit",
|
||||
gap_count: 1,
|
||||
order: 210,
|
||||
status: "open",
|
||||
next_action: "audit",
|
||||
},
|
||||
];
|
||||
|
||||
expect(
|
||||
topSecurityControlPlaneWorkItems(value, 3).map((item) => item.control_id),
|
||||
).toEqual(["asset_discovery", "endpoint_xdr_wazuh", "audit_integrity"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,6 +91,8 @@ export type SecurityControlPlaneWorkItem = {
|
||||
gap_count: number;
|
||||
status: string;
|
||||
next_action: string;
|
||||
order?: number;
|
||||
gap_percent?: number;
|
||||
};
|
||||
|
||||
export type SecurityControlPlaneSupplyChain = {
|
||||
@@ -426,6 +428,7 @@ export function topSecurityControlPlaneWorkItems(
|
||||
.sort(
|
||||
(left, right) =>
|
||||
(rank[left.priority] ?? 99) - (rank[right.priority] ?? 99) ||
|
||||
(left.order ?? 999) - (right.order ?? 999) ||
|
||||
left.work_item_id.localeCompare(right.work_item_id),
|
||||
)
|
||||
.slice(0, Math.max(0, limit));
|
||||
|
||||
Reference in New Issue
Block a user