Merge remote-tracking branch 'gitea-ssh/main' into codex/km-knowledge-base-readback-20260702
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
This commit is contained in:
@@ -9182,16 +9182,21 @@
|
||||
},
|
||||
"managerSituation": {
|
||||
"eyebrow": "Manager overview",
|
||||
"title": "StockPlatform P0",
|
||||
"subtitle": "Blocker, impact, and next action are pinned to the first screen.",
|
||||
"title": "P0 manager overview",
|
||||
"titles": {
|
||||
"reboot": "P0-006 reboot recovery SLO",
|
||||
"stockplatform": "StockPlatform P0"
|
||||
},
|
||||
"subtitle": "The active P0, blocker, impact, and next action are pinned to the first screen.",
|
||||
"loading": "Reading production readback.",
|
||||
"head": "Deployed source",
|
||||
"head": "Readiness / deployed",
|
||||
"decision": "Decision",
|
||||
"decisionValue": "Fix P0, no side lane",
|
||||
"decisionParallel": "P0 waits for data; advance {id}",
|
||||
"blockingSources": "Blocking sources",
|
||||
"noSourceNames": "Waiting for source contract readback",
|
||||
"states": {
|
||||
"rebootSlo": "10-minute recovery SLO not proven",
|
||||
"sourceContract": "Source contract blocked",
|
||||
"preflight": "Recovery preflight blocked",
|
||||
"publicApi": "Public API blocked",
|
||||
@@ -9206,18 +9211,25 @@
|
||||
"impact": {
|
||||
"label": "Impact",
|
||||
"value": "Public API not green",
|
||||
"detail": "Source trust is not sufficient."
|
||||
"detail": "Source trust is not sufficient.",
|
||||
"rebootValue": "Reboot recovery is not closed",
|
||||
"rebootDetail": "Fresh reboot window, service green, and backup readback are not all true."
|
||||
},
|
||||
"evidence": {
|
||||
"label": "Evidence",
|
||||
"value": "{count} sources failed",
|
||||
"receipted": "receipt provided",
|
||||
"missing": "receipt missing"
|
||||
"missing": "receipt missing",
|
||||
"rebootValue": "{count} SLO blockers",
|
||||
"rebootReceipted": "timer/source readback exists",
|
||||
"rebootMissing": "waiting for live SLO readback"
|
||||
},
|
||||
"next": {
|
||||
"label": "Next step",
|
||||
"value": "Repair source contract",
|
||||
"detail": "Run verifier immediately after repair."
|
||||
"detail": "Run verifier immediately after repair.",
|
||||
"rebootValue": "Collect public readback",
|
||||
"rebootDetail": "Collect service data backup readback first; {count} backup blockers remain."
|
||||
},
|
||||
"parallel": {
|
||||
"label": "Parallel mainline",
|
||||
@@ -13452,6 +13464,24 @@
|
||||
"noSecret": "不讀 secret",
|
||||
"noHostWrite": "不寫主機",
|
||||
"postcheck": "postcheck 先行"
|
||||
},
|
||||
"executionLabel": "runtime controlled apply chain",
|
||||
"execution": {
|
||||
"preflight": {
|
||||
"label": "Preflight",
|
||||
"value": "{ready} ready / {targets} targets",
|
||||
"detail": "diff {diff}, check {check}, rollback {rollback}, verifier {verifier}"
|
||||
},
|
||||
"review": {
|
||||
"label": "Review packet",
|
||||
"value": "{accepted}/{ready} accepted",
|
||||
"detail": "supplement {supplement}; runtime gate {runtime}"
|
||||
},
|
||||
"dryRun": {
|
||||
"label": "Allowlisted dry-run",
|
||||
"value": "{accepted}/{result} result",
|
||||
"detail": "check-mode {check}, postcheck {verifier}, host write {writes}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commandRail": {
|
||||
|
||||
@@ -9182,16 +9182,21 @@
|
||||
},
|
||||
"managerSituation": {
|
||||
"eyebrow": "管理者總覽",
|
||||
"title": "StockPlatform P0",
|
||||
"subtitle": "卡點、影響、下一步先放第一屏。",
|
||||
"title": "P0 管理者總覽",
|
||||
"titles": {
|
||||
"reboot": "P0-006 重啟恢復 SLO",
|
||||
"stockplatform": "StockPlatform P0"
|
||||
},
|
||||
"subtitle": "目前 P0、卡點、影響、下一步先放第一屏。",
|
||||
"loading": "正在讀取正式 readback。",
|
||||
"head": "正式部署",
|
||||
"head": "Readiness / 部署",
|
||||
"decision": "決策",
|
||||
"decisionValue": "先修 P0,不開支線",
|
||||
"decisionParallel": "P0 等資料;並行推進 {id}",
|
||||
"blockingSources": "阻塞來源",
|
||||
"noSourceNames": "等待 source contract readback",
|
||||
"states": {
|
||||
"rebootSlo": "10 分鐘恢復 SLO 未證明",
|
||||
"sourceContract": "來源合約卡住",
|
||||
"preflight": "修復預檢卡住",
|
||||
"publicApi": "公開 API 卡住",
|
||||
@@ -9206,18 +9211,25 @@
|
||||
"impact": {
|
||||
"label": "影響",
|
||||
"value": "公開 API 未綠燈",
|
||||
"detail": "資料來源可信度不足"
|
||||
"detail": "資料來源可信度不足",
|
||||
"rebootValue": "重啟後恢復未閉環",
|
||||
"rebootDetail": "fresh reboot window、service green 與 backup readback 尚未同時成立"
|
||||
},
|
||||
"evidence": {
|
||||
"label": "證據",
|
||||
"value": "{count} 個來源未通過",
|
||||
"receipted": "receipt 已收件",
|
||||
"missing": "receipt 未到"
|
||||
"missing": "receipt 未到",
|
||||
"rebootValue": "{count} 個 SLO blocker",
|
||||
"rebootReceipted": "timer/source readback 已存在",
|
||||
"rebootMissing": "等待 live SLO readback"
|
||||
},
|
||||
"next": {
|
||||
"label": "下一步",
|
||||
"value": "補來源合約",
|
||||
"detail": "修完直接跑 verifier"
|
||||
"detail": "修完直接跑 verifier",
|
||||
"rebootValue": "補 public readback",
|
||||
"rebootDetail": "先收 service data backup readback;目前 {count} 個 backup blocker"
|
||||
},
|
||||
"parallel": {
|
||||
"label": "並行主線",
|
||||
@@ -13452,6 +13464,24 @@
|
||||
"noSecret": "不讀 secret",
|
||||
"noHostWrite": "不寫主機",
|
||||
"postcheck": "postcheck 先行"
|
||||
},
|
||||
"executionLabel": "runtime controlled apply 鏈",
|
||||
"execution": {
|
||||
"preflight": {
|
||||
"label": "Preflight",
|
||||
"value": "{ready} ready / {targets} targets",
|
||||
"detail": "diff {diff}、check {check}、rollback {rollback}、verifier {verifier}"
|
||||
},
|
||||
"review": {
|
||||
"label": "Review packet",
|
||||
"value": "{accepted}/{ready} accepted",
|
||||
"detail": "supplement {supplement};runtime gate {runtime}"
|
||||
},
|
||||
"dryRun": {
|
||||
"label": "Allowlisted dry-run",
|
||||
"value": "{accepted}/{result} result",
|
||||
"detail": "check-mode {check}、postcheck {verifier}、host write {writes}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commandRail": {
|
||||
|
||||
@@ -1087,6 +1087,9 @@ type PriorityWorkOrderResponse = {
|
||||
} | null;
|
||||
summary?: {
|
||||
active_p0_state?: string | null;
|
||||
active_p0_workplan_id?: string | null;
|
||||
active_p0_readiness_percent?: number | null;
|
||||
active_p0_live_active_blockers?: string[] | null;
|
||||
next_executable_mainline_workplan_id?: string | null;
|
||||
next_executable_mainline_state?: string | null;
|
||||
parallel_mainline_execution_enabled?: boolean | null;
|
||||
@@ -1145,6 +1148,11 @@ type PriorityWorkOrderResponse = {
|
||||
controlled_cd_lane_live_gitea_actions_active_process_count?: number | null;
|
||||
controlled_cd_lane_live_metric_blocker_count?: number | null;
|
||||
controlled_cd_lane_live_metric_blockers?: string[] | null;
|
||||
controlled_service_data_backup_blocker_count?: number | null;
|
||||
controlled_service_data_backup_can_clear_blockers?: boolean | null;
|
||||
controlled_service_data_backup_next_safe_action?: string | null;
|
||||
windows99_verify_collection_blocker_count?: number | null;
|
||||
windows99_verify_collection_blockers?: string[] | null;
|
||||
ai_loop_log_source_grouping_key_count?: number | null;
|
||||
ai_loop_log_source_grouping_keys?: string[] | null;
|
||||
ai_loop_log_source_tagging_contract_count?: number | null;
|
||||
@@ -1168,7 +1176,21 @@ type PriorityWorkOrderResponse = {
|
||||
stockplatform_source_contract_non_ok_source_count?: number | null;
|
||||
} | null;
|
||||
in_progress_or_blocked_in_priority_order?: Array<{
|
||||
id?: string | null;
|
||||
title?: string | null;
|
||||
status?: string | null;
|
||||
next_action?: string | null;
|
||||
evidence?: {
|
||||
active_blockers?: string[] | null;
|
||||
live_slo_metric_present?: boolean | null;
|
||||
live_slo_service_last_result?: string | null;
|
||||
live_slo_timer_active?: boolean | null;
|
||||
live_slo_timer_enabled?: boolean | null;
|
||||
latest_live_slo_artifact?: string | null;
|
||||
controlled_service_data_backup_blocker_count?: number | null;
|
||||
controlled_service_data_backup_can_clear_blockers?: boolean | null;
|
||||
windows99_verify_collection_blockers?: string[] | null;
|
||||
drill_preflight_blocker_count?: number | null;
|
||||
ai_loop_current_blocker_log_source_tags?: AiLoopLogSourceTag[] | null;
|
||||
ai_loop_log_source_tagging_contract?: AiLoopLogSourceContract[] | null;
|
||||
ai_loop_current_blocker_resolved_by_production_readback?: boolean | null;
|
||||
@@ -8769,8 +8791,6 @@ function stockplatformCompactTone(value: string | boolean | null | undefined) {
|
||||
|
||||
const STOCKPLATFORM_SOURCE_CONTRACT_FALLBACK_SOURCES = [
|
||||
"raw.source_quality_observations.unit_sanity",
|
||||
"core.margin_short_daily",
|
||||
"ai.recommendations",
|
||||
] as const;
|
||||
|
||||
function shortSha(value: string | null | undefined) {
|
||||
@@ -8779,6 +8799,7 @@ function shortSha(value: string | null | undefined) {
|
||||
|
||||
function stockplatformManagerStateKey(value: string | null | undefined) {
|
||||
const state = String(value ?? "");
|
||||
if (state.includes("reboot")) return "rebootSlo";
|
||||
if (state.includes("source_contract")) return "sourceContract";
|
||||
if (state.includes("preflight")) return "preflight";
|
||||
if (state.includes("public_api")) return "publicApi";
|
||||
@@ -8795,14 +8816,24 @@ function ManagerSituationBoard({
|
||||
}) {
|
||||
const t = useTranslations("awooop.workItems.managerSituation");
|
||||
const summary = priority?.summary;
|
||||
const evidence = priority?.in_progress_or_blocked_in_priority_order?.find(
|
||||
const activeState =
|
||||
summary?.active_p0_state ??
|
||||
"blocked_reboot_auto_recovery_slo_not_ready";
|
||||
const activeWorkplan =
|
||||
summary?.active_p0_workplan_id ??
|
||||
summary?.next_executable_mainline_workplan_id ??
|
||||
"P0-006";
|
||||
const activeItem = priority?.in_progress_or_blocked_in_priority_order?.find(
|
||||
(item) =>
|
||||
item.id === activeWorkplan ||
|
||||
item.status === activeState ||
|
||||
item.status?.includes("reboot")
|
||||
);
|
||||
const evidence = activeItem?.evidence ?? priority?.in_progress_or_blocked_in_priority_order?.find(
|
||||
(item) =>
|
||||
item.evidence?.stockplatform_source_contract_readback_status ||
|
||||
item.evidence?.stockplatform_public_api_runtime_status
|
||||
)?.evidence;
|
||||
const activeWorkplan =
|
||||
summary?.next_executable_mainline_workplan_id ??
|
||||
"P0-006-STOCKPLATFORM-PUBLIC-API-CONTROLLED-RECOVERY-PREFLIGHT";
|
||||
const parallelOverlay = priority?.mainline_parallel_execution;
|
||||
const parallelEnabled =
|
||||
summary?.parallel_mainline_execution_enabled === true ||
|
||||
@@ -8819,12 +8850,25 @@ function ManagerSituationBoard({
|
||||
summary?.parallel_mainline_retry_readback_at ??
|
||||
parallelOverlay?.retry_readback_at ??
|
||||
"--";
|
||||
const activeState =
|
||||
summary?.active_p0_state ??
|
||||
"blocked_stockplatform_public_api_controlled_recovery_preflight";
|
||||
const activeStateLabel = t(
|
||||
`states.${stockplatformManagerStateKey(activeState)}` as never
|
||||
);
|
||||
const isRebootP0 = activeState.includes("reboot");
|
||||
const boardTitle = isRebootP0
|
||||
? t("titles.reboot")
|
||||
: activeState.includes("stockplatform")
|
||||
? t("titles.stockplatform")
|
||||
: t("title");
|
||||
const activeBlockers =
|
||||
summary?.active_p0_live_active_blockers ??
|
||||
evidence?.active_blockers ??
|
||||
[];
|
||||
const activeBlockerCount = activeBlockers.length;
|
||||
const readinessPercent = summary?.active_p0_readiness_percent ?? null;
|
||||
const rebootEvidenceReady =
|
||||
evidence?.live_slo_metric_present === true &&
|
||||
evidence?.live_slo_timer_enabled === true &&
|
||||
evidence?.live_slo_timer_active === true;
|
||||
const sourceContractStatus =
|
||||
summary?.stockplatform_source_contract_readback_status ??
|
||||
evidence?.stockplatform_source_contract_readback_status ??
|
||||
@@ -8838,8 +8882,12 @@ function ManagerSituationBoard({
|
||||
evidence?.stockplatform_source_contract_receipt_provided ??
|
||||
true;
|
||||
const blockingSources =
|
||||
evidence?.stockplatform_source_contract_blocking_sources?.slice(0, 3) ??
|
||||
STOCKPLATFORM_SOURCE_CONTRACT_FALLBACK_SOURCES.map((source) => ({ source }));
|
||||
isRebootP0
|
||||
? activeBlockers.slice(0, 4).map((source) => ({ source }))
|
||||
: (
|
||||
evidence?.stockplatform_source_contract_blocking_sources?.slice(0, 3) ??
|
||||
STOCKPLATFORM_SOURCE_CONTRACT_FALLBACK_SOURCES.map((source) => ({ source }))
|
||||
);
|
||||
const sourceNames = blockingSources
|
||||
.map((source) => source.source)
|
||||
.filter(Boolean)
|
||||
@@ -8862,24 +8910,32 @@ function ManagerSituationBoard({
|
||||
key: "impact",
|
||||
icon: Database,
|
||||
label: t("cards.impact.label"),
|
||||
value: t("cards.impact.value"),
|
||||
detail: t("cards.impact.detail"),
|
||||
value: isRebootP0 ? t("cards.impact.rebootValue") : t("cards.impact.value"),
|
||||
detail: isRebootP0 ? t("cards.impact.rebootDetail") : t("cards.impact.detail"),
|
||||
tone: "border-[#c9d8ea] bg-[#eef5ff] text-[#1f5b9b]",
|
||||
},
|
||||
{
|
||||
key: "evidence",
|
||||
icon: SearchCheck,
|
||||
label: t("cards.evidence.label"),
|
||||
value: t("cards.evidence.value", { count: nonOkSourceCount }),
|
||||
detail: receiptProvided ? t("cards.evidence.receipted") : t("cards.evidence.missing"),
|
||||
tone: stockplatformCompactTone(sourceContractStatus),
|
||||
value: isRebootP0
|
||||
? t("cards.evidence.rebootValue", { count: activeBlockerCount })
|
||||
: t("cards.evidence.value", { count: nonOkSourceCount }),
|
||||
detail: isRebootP0
|
||||
? (rebootEvidenceReady ? t("cards.evidence.rebootReceipted") : t("cards.evidence.rebootMissing"))
|
||||
: receiptProvided ? t("cards.evidence.receipted") : t("cards.evidence.missing"),
|
||||
tone: isRebootP0 ? stockplatformCompactTone(activeState) : stockplatformCompactTone(sourceContractStatus),
|
||||
},
|
||||
{
|
||||
key: "next",
|
||||
icon: ArrowRight,
|
||||
label: t("cards.next.label"),
|
||||
value: t("cards.next.value"),
|
||||
detail: t("cards.next.detail"),
|
||||
value: isRebootP0 ? t("cards.next.rebootValue") : t("cards.next.value"),
|
||||
detail: isRebootP0
|
||||
? t("cards.next.rebootDetail", {
|
||||
count: summary?.controlled_service_data_backup_blocker_count ?? evidence?.controlled_service_data_backup_blocker_count ?? 0,
|
||||
})
|
||||
: t("cards.next.detail"),
|
||||
tone: "border-[#cbd7bf] bg-[#f4faef] text-[#3d6b24]",
|
||||
},
|
||||
{
|
||||
@@ -8908,7 +8964,7 @@ function ManagerSituationBoard({
|
||||
{t("eyebrow")}
|
||||
</div>
|
||||
<h3 className="mt-3 text-xl font-semibold tracking-normal">
|
||||
{t("title")}
|
||||
{boardTitle}
|
||||
</h3>
|
||||
<p className="mt-2 text-sm leading-5 text-[#eee9dd]">
|
||||
{loading ? t("loading") : t("subtitle")}
|
||||
@@ -8919,7 +8975,7 @@ function ManagerSituationBoard({
|
||||
{t("head")}
|
||||
</div>
|
||||
<div className="mt-1 font-mono text-sm font-semibold">
|
||||
{shortSha(deployedSha)}
|
||||
{readinessPercent === null ? shortSha(deployedSha) : `${readinessPercent}%`}
|
||||
</div>
|
||||
</div>
|
||||
<div className="border border-[#4d4b44] bg-[#1d1c19] px-3 py-2">
|
||||
@@ -9862,12 +9918,12 @@ export default function AwoooPWorkItemsPage() {
|
||||
|
||||
<ManagerSituationBoard
|
||||
priority={priorityWorkOrder}
|
||||
loading={false}
|
||||
loading={priorityWorkOrderLoading && !priorityWorkOrder}
|
||||
/>
|
||||
|
||||
<StockPlatformP0ReceiptPanel
|
||||
priority={priorityWorkOrder}
|
||||
loading={false}
|
||||
loading={priorityWorkOrderLoading && !priorityWorkOrder}
|
||||
/>
|
||||
|
||||
<ProductionClaimBanner loading={loading} summary={telemetry.quality} />
|
||||
|
||||
@@ -48,10 +48,13 @@ import {
|
||||
type IwoooSSecurityControlCoverageResponse,
|
||||
type IwoooSWazuhLiveMetadataGateItem,
|
||||
type IwoooSWazuhLiveMetadataGateResponse,
|
||||
type IwoooSWazuhAllowlistedCheckModeDryRunResponse,
|
||||
type IwoooSWazuhManagerRegistryReviewerValidationResponse,
|
||||
type IwoooSWazuhManagedHostCoverageResponse,
|
||||
type IwoooSWazuhOwnerEvidencePreflightItem,
|
||||
type IwoooSWazuhOwnerEvidencePreflightResponse,
|
||||
type IwoooSWazuhRuntimeControlledApplyPreflightResponse,
|
||||
type IwoooSWazuhRuntimeGateOwnerReviewReadbackResponse,
|
||||
} from '@/lib/api-client'
|
||||
|
||||
type PostureMetric = {
|
||||
@@ -1201,6 +1204,20 @@ const iwooosManagerFallback = {
|
||||
expectedHostScopeCount: 6,
|
||||
managerRegistryAcceptedCount: 6,
|
||||
reviewerValidationPassedCount: 1,
|
||||
controlledApplyPreflightReadyCount: 1,
|
||||
controlledApplyTargetSelectorCount: 6,
|
||||
controlledApplySourceDiffCount: 1,
|
||||
controlledApplyCheckModePlanCount: 1,
|
||||
controlledApplyRollbackPlanCount: 1,
|
||||
controlledApplyPostApplyVerifierCount: 1,
|
||||
ownerReviewPacketReviewReadyCount: 1,
|
||||
ownerReviewPacketAcceptedCount: 1,
|
||||
ownerReviewSupplementRequiredCount: 0,
|
||||
allowlistedDryRunPacketAcceptedCount: 1,
|
||||
allowlistedDryRunResultRefCount: 1,
|
||||
allowlistedDryRunPostVerifierCount: 1,
|
||||
allowlistedDryRunCheckModeAllowedCount: 6,
|
||||
allowlistedDryRunRuntimeWriteAllowedCount: 0,
|
||||
runtimeGateCount: 0,
|
||||
hostWriteAuthorizedCount: 0,
|
||||
activeResponseAuthorizedCount: 0,
|
||||
@@ -15545,17 +15562,31 @@ function IwoooSManagerCockpit() {
|
||||
const [coverage, setCoverage] = useState<IwoooSSecurityControlCoverageResponse | null>(null)
|
||||
const [managedHosts, setManagedHosts] = useState<IwoooSWazuhManagedHostCoverageResponse | null>(null)
|
||||
const [registry, setRegistry] = useState<IwoooSWazuhManagerRegistryReviewerValidationResponse | null>(null)
|
||||
const [controlledApply, setControlledApply] = useState<IwoooSWazuhRuntimeControlledApplyPreflightResponse | null>(null)
|
||||
const [ownerReview, setOwnerReview] = useState<IwoooSWazuhRuntimeGateOwnerReviewReadbackResponse | null>(null)
|
||||
const [allowlistedDryRun, setAllowlistedDryRun] = useState<IwoooSWazuhAllowlistedCheckModeDryRunResponse | null>(null)
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
|
||||
async function fetchCockpitReadback() {
|
||||
const [runtimeResult, coverageResult, managedHostsResult, registryResult] = await Promise.allSettled([
|
||||
const [
|
||||
runtimeResult,
|
||||
coverageResult,
|
||||
managedHostsResult,
|
||||
registryResult,
|
||||
controlledApplyResult,
|
||||
ownerReviewResult,
|
||||
allowlistedDryRunResult,
|
||||
] = await Promise.allSettled([
|
||||
apiClient.getIwoooSRuntimeSecurityReadback(),
|
||||
apiClient.getIwoooSSecurityControlCoverage(),
|
||||
apiClient.getIwoooSWazuhManagedHostCoverage(),
|
||||
apiClient.getIwoooSWazuhManagerRegistryReviewerValidation(),
|
||||
apiClient.getIwoooSWazuhRuntimeControlledApplyPreflight(),
|
||||
apiClient.getIwoooSWazuhRuntimeGateOwnerReviewReadback(),
|
||||
apiClient.getIwoooSWazuhAllowlistedCheckModeDryRun(),
|
||||
])
|
||||
|
||||
if (!mounted) return
|
||||
@@ -15563,6 +15594,9 @@ function IwoooSManagerCockpit() {
|
||||
if (coverageResult.status === 'fulfilled') setCoverage(coverageResult.value)
|
||||
if (managedHostsResult.status === 'fulfilled') setManagedHosts(managedHostsResult.value)
|
||||
if (registryResult.status === 'fulfilled') setRegistry(registryResult.value)
|
||||
if (controlledApplyResult.status === 'fulfilled') setControlledApply(controlledApplyResult.value)
|
||||
if (ownerReviewResult.status === 'fulfilled') setOwnerReview(ownerReviewResult.value)
|
||||
if (allowlistedDryRunResult.status === 'fulfilled') setAllowlistedDryRun(allowlistedDryRunResult.value)
|
||||
setLoaded(true)
|
||||
}
|
||||
|
||||
@@ -15594,17 +15628,79 @@ function IwoooSManagerCockpit() {
|
||||
registry?.summary.runtime_gate_count ??
|
||||
managedHosts?.summary.runtime_gate_count ??
|
||||
coverage?.summary.runtime_gate_count ??
|
||||
controlledApply?.summary.runtime_gate_count ??
|
||||
ownerReview?.summary.runtime_gate_count ??
|
||||
allowlistedDryRun?.summary.runtime_gate_count ??
|
||||
iwooosManagerFallback.runtimeGateCount
|
||||
const hostWriteAuthorizedCount =
|
||||
registry?.summary.host_write_authorized_count ??
|
||||
managedHosts?.summary.host_write_authorized_count ??
|
||||
coverage?.summary.host_write_authorized_count ??
|
||||
controlledApply?.summary.host_write_authorized_count ??
|
||||
ownerReview?.summary.host_write_authorized_count ??
|
||||
allowlistedDryRun?.summary.host_write_authorized_count ??
|
||||
iwooosManagerFallback.hostWriteAuthorizedCount
|
||||
const activeResponseAuthorizedCount =
|
||||
registry?.summary.active_response_authorized_count ??
|
||||
managedHosts?.summary.active_response_authorized_count ??
|
||||
coverage?.summary.active_response_authorized_count ??
|
||||
controlledApply?.summary.wazuh_active_response_authorized_count ??
|
||||
ownerReview?.summary.wazuh_active_response_authorized_count ??
|
||||
allowlistedDryRun?.summary.wazuh_active_response_authorized_count ??
|
||||
iwooosManagerFallback.activeResponseAuthorizedCount
|
||||
const controlledApplyPreflightReadyCount =
|
||||
controlledApply?.summary.controlled_apply_preflight_ready_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_preflight_ready_count ??
|
||||
iwooosManagerFallback.controlledApplyPreflightReadyCount
|
||||
const controlledApplyTargetSelectorCount =
|
||||
controlledApply?.summary.target_selector_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_target_selector_count ??
|
||||
iwooosManagerFallback.controlledApplyTargetSelectorCount
|
||||
const controlledApplySourceDiffCount =
|
||||
controlledApply?.summary.source_of_truth_diff_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_source_diff_count ??
|
||||
iwooosManagerFallback.controlledApplySourceDiffCount
|
||||
const controlledApplyCheckModePlanCount =
|
||||
controlledApply?.summary.check_mode_plan_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_check_mode_plan_count ??
|
||||
iwooosManagerFallback.controlledApplyCheckModePlanCount
|
||||
const controlledApplyRollbackPlanCount =
|
||||
controlledApply?.summary.rollback_plan_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_rollback_plan_count ??
|
||||
iwooosManagerFallback.controlledApplyRollbackPlanCount
|
||||
const controlledApplyPostApplyVerifierCount =
|
||||
controlledApply?.summary.post_apply_verifier_count ??
|
||||
runtime?.summary.wazuh_runtime_apply_post_apply_verifier_count ??
|
||||
iwooosManagerFallback.controlledApplyPostApplyVerifierCount
|
||||
const ownerReviewPacketReviewReadyCount =
|
||||
ownerReview?.summary.owner_review_packet_review_ready_count ??
|
||||
runtime?.summary.wazuh_runtime_owner_review_packet_review_ready_count ??
|
||||
iwooosManagerFallback.ownerReviewPacketReviewReadyCount
|
||||
const ownerReviewPacketAcceptedCount =
|
||||
ownerReview?.summary.owner_review_packet_accepted_count ??
|
||||
runtime?.summary.wazuh_runtime_owner_review_packet_accepted_count ??
|
||||
iwooosManagerFallback.ownerReviewPacketAcceptedCount
|
||||
const ownerReviewSupplementRequiredCount =
|
||||
ownerReview?.summary.owner_review_packet_supplement_required_count ??
|
||||
iwooosManagerFallback.ownerReviewSupplementRequiredCount
|
||||
const allowlistedDryRunPacketAcceptedCount =
|
||||
allowlistedDryRun?.summary.dry_run_packet_accepted_count ??
|
||||
runtime?.summary.wazuh_allowlisted_check_mode_dry_run_packet_accepted_count ??
|
||||
iwooosManagerFallback.allowlistedDryRunPacketAcceptedCount
|
||||
const allowlistedDryRunResultRefCount =
|
||||
allowlistedDryRun?.summary.dry_run_result_ref_count ??
|
||||
runtime?.summary.wazuh_allowlisted_check_mode_dry_run_result_ref_count ??
|
||||
iwooosManagerFallback.allowlistedDryRunResultRefCount
|
||||
const allowlistedDryRunPostVerifierCount =
|
||||
allowlistedDryRun?.summary.post_dry_run_verifier_count ??
|
||||
runtime?.summary.wazuh_allowlisted_check_mode_dry_run_post_verifier_count ??
|
||||
iwooosManagerFallback.allowlistedDryRunPostVerifierCount
|
||||
const allowlistedDryRunCheckModeAllowedCount =
|
||||
allowlistedDryRun?.target_selectors.filter(selector => selector.check_mode_allowed).length ??
|
||||
iwooosManagerFallback.allowlistedDryRunCheckModeAllowedCount
|
||||
const allowlistedDryRunRuntimeWriteAllowedCount =
|
||||
allowlistedDryRun?.target_selectors.filter(selector => selector.runtime_write_allowed).length ??
|
||||
iwooosManagerFallback.allowlistedDryRunRuntimeWriteAllowedCount
|
||||
|
||||
const registryComplete = managerRegistryAcceptedCount >= expectedHostScopeCount && expectedHostScopeCount > 0
|
||||
const runtimeLocked = runtimeGateCount === 0 && hostWriteAuthorizedCount === 0 && activeResponseAuthorizedCount === 0
|
||||
@@ -15653,6 +15749,50 @@ function IwoooSManagerCockpit() {
|
||||
{ key: 'activeResponse', value: activeResponseAuthorizedCount, tone: 'locked' as const },
|
||||
{ key: 'reviewer', value: reviewerValidationPassedCount, tone: reviewerValidationPassedCount > 0 ? 'steady' as const : 'warn' as const },
|
||||
]
|
||||
const executionSteps: IwoooSManagerCockpitMetric[] = [
|
||||
{
|
||||
key: 'preflight',
|
||||
value: t('execution.preflight.value', {
|
||||
ready: controlledApplyPreflightReadyCount,
|
||||
targets: controlledApplyTargetSelectorCount,
|
||||
}),
|
||||
detail: t('execution.preflight.detail', {
|
||||
diff: controlledApplySourceDiffCount,
|
||||
check: controlledApplyCheckModePlanCount,
|
||||
rollback: controlledApplyRollbackPlanCount,
|
||||
verifier: controlledApplyPostApplyVerifierCount,
|
||||
}),
|
||||
icon: ListChecks,
|
||||
tone: controlledApplyPreflightReadyCount > 0 && controlledApplyTargetSelectorCount >= expectedHostScopeCount ? 'steady' : 'warn',
|
||||
},
|
||||
{
|
||||
key: 'review',
|
||||
value: t('execution.review.value', {
|
||||
accepted: ownerReviewPacketAcceptedCount,
|
||||
ready: ownerReviewPacketReviewReadyCount,
|
||||
}),
|
||||
detail: t('execution.review.detail', {
|
||||
supplement: ownerReviewSupplementRequiredCount,
|
||||
runtime: runtimeGateCount,
|
||||
}),
|
||||
icon: ClipboardCheck,
|
||||
tone: ownerReviewPacketAcceptedCount > 0 && ownerReviewSupplementRequiredCount === 0 ? 'steady' : 'warn',
|
||||
},
|
||||
{
|
||||
key: 'dryRun',
|
||||
value: t('execution.dryRun.value', {
|
||||
accepted: allowlistedDryRunPacketAcceptedCount,
|
||||
result: allowlistedDryRunResultRefCount,
|
||||
}),
|
||||
detail: t('execution.dryRun.detail', {
|
||||
check: allowlistedDryRunCheckModeAllowedCount,
|
||||
verifier: allowlistedDryRunPostVerifierCount,
|
||||
writes: allowlistedDryRunRuntimeWriteAllowedCount,
|
||||
}),
|
||||
icon: FileCheck2,
|
||||
tone: allowlistedDryRunPacketAcceptedCount > 0 && allowlistedDryRunRuntimeWriteAllowedCount === 0 ? 'steady' : 'locked',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<section
|
||||
@@ -15774,6 +15914,56 @@ function IwoooSManagerCockpit() {
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div
|
||||
data-testid="iwooos-manager-cockpit-execution-lane"
|
||||
style={{
|
||||
border: '0.5px solid #c9d8ea',
|
||||
borderRadius: 8,
|
||||
background: '#f7fbff',
|
||||
padding: 10,
|
||||
display: 'grid',
|
||||
gap: 8,
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#1f5b9b', fontSize: 10, fontWeight: 800 }}>
|
||||
{t('executionLabel')}
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 170px), 1fr))', gap: 8 }}>
|
||||
{executionSteps.map(item => {
|
||||
const Icon = item.icon
|
||||
return (
|
||||
<div
|
||||
key={item.key}
|
||||
data-testid={`iwooos-manager-cockpit-execution-${item.key}`}
|
||||
style={{
|
||||
border: `0.5px solid ${item.tone === 'steady' ? '#cddfd5' : item.tone === 'warn' ? '#e2cbb4' : '#d9d6ce'}`,
|
||||
borderRadius: 8,
|
||||
background: '#fff',
|
||||
padding: 10,
|
||||
minWidth: 0,
|
||||
display: 'grid',
|
||||
gap: 6,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
|
||||
<span style={{ color: '#5f5b52', fontSize: 10, fontWeight: 800, ...textWrap }}>
|
||||
{t(`execution.${item.key}.label` as never)}
|
||||
</span>
|
||||
<Icon size={15} color={toneColors[item.tone]} />
|
||||
</div>
|
||||
<div style={{ color: toneColors[item.tone], fontSize: 17, fontWeight: 800, lineHeight: 1.1, ...textWrap }}>
|
||||
{item.value}
|
||||
</div>
|
||||
<div style={{ color: '#50606f', fontSize: 10.5, lineHeight: 1.35, ...textWrap }}>
|
||||
{item.detail}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
border: '0.5px solid #c9d8ea',
|
||||
|
||||
Reference in New Issue
Block a user