fix(iwooos): project strict runtime closure
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m36s
CD Pipeline / build-and-deploy (push) Successful in 15m32s
CD Pipeline / post-deploy-checks (push) Successful in 1m58s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m36s
CD Pipeline / build-and-deploy (push) Successful in 15m32s
CD Pipeline / post-deploy-checks (push) Successful in 1m58s
This commit is contained in:
@@ -36,7 +36,7 @@ type Copy = {
|
||||
assetTypes: string;
|
||||
nist: string;
|
||||
siem: string;
|
||||
aiLoop: string;
|
||||
strictRun: string;
|
||||
verified: string;
|
||||
functions: string;
|
||||
framework: string;
|
||||
@@ -70,6 +70,7 @@ type Copy = {
|
||||
failedCollectors: string;
|
||||
failedCollectorsUnavailable: string;
|
||||
sameRunMissing: string;
|
||||
sameRunVerified: string;
|
||||
loading: string;
|
||||
unavailable: string;
|
||||
refresh: string;
|
||||
@@ -87,7 +88,7 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
assetTypes: "資產類型",
|
||||
nist: "NIST 控制",
|
||||
siem: "SIEM 閉環",
|
||||
aiLoop: "AI 閉環",
|
||||
strictRun: "同 run 閉環",
|
||||
verified: "24h 已驗證",
|
||||
functions: "治理六功能",
|
||||
framework: "完整資安框架",
|
||||
@@ -121,6 +122,7 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
failedCollectors: "失敗 Collector",
|
||||
failedCollectorsUnavailable: "失敗原因待安全分類",
|
||||
sameRunMissing: "尚無同 run 閉環證據",
|
||||
sameRunVerified: "18 段同 run 閉環已驗證",
|
||||
loading: "正在載入資安控制平面",
|
||||
unavailable: "Live readback 無法取得",
|
||||
refresh: "重新整理資安控制平面",
|
||||
@@ -136,7 +138,7 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
assetTypes: "Asset types",
|
||||
nist: "NIST control",
|
||||
siem: "SIEM closure",
|
||||
aiLoop: "AI closure",
|
||||
strictRun: "Same-run closure",
|
||||
verified: "Verified 24h",
|
||||
functions: "Six functions",
|
||||
framework: "Security framework",
|
||||
@@ -170,6 +172,7 @@ const COPY: Record<"zh" | "en", Copy> = {
|
||||
failedCollectors: "Failed collectors",
|
||||
failedCollectorsUnavailable: "Failure detail awaiting safe classification",
|
||||
sameRunMissing: "No same-run closure evidence",
|
||||
sameRunVerified: "18-stage same-run closure verified",
|
||||
loading: "Loading security control plane",
|
||||
unavailable: "Live readback unavailable",
|
||||
refresh: "Refresh security control plane",
|
||||
@@ -557,10 +560,10 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
icon={Radar}
|
||||
/>
|
||||
<MetricCell
|
||||
label={copy.aiLoop}
|
||||
label={copy.strictRun}
|
||||
value={
|
||||
payload
|
||||
? `${payload.summary.ai_loop_observed_stage_count}/${payload.summary.ai_loop_stage_count}`
|
||||
? `${payload.ai_automation.strict_runtime_completion.present_stage_count}/${payload.ai_automation.strict_runtime_completion.required_stage_count}`
|
||||
: "--"
|
||||
}
|
||||
icon={Bot}
|
||||
@@ -986,7 +989,15 @@ export function SecurityAssetControlPlaneCockpit({
|
||||
/>
|
||||
{copy.sameRunMissing}
|
||||
</div>
|
||||
) : null}
|
||||
) : (
|
||||
<div className="mt-3 flex items-center gap-1.5 border-t border-[#ebe8df] pt-2 text-[10px] font-medium text-[#17602a]">
|
||||
<CheckCircle2
|
||||
className="h-3.5 w-3.5 shrink-0"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{copy.sameRunVerified}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="border border-[#d8d3c7] bg-white p-3">
|
||||
|
||||
@@ -14,8 +14,8 @@ function payload(): SecurityAssetControlPlanePayload {
|
||||
status: "ready",
|
||||
source_status: "live_database_aggregate",
|
||||
summary: {
|
||||
source_count: 9,
|
||||
ready_source_count: 9,
|
||||
source_count: 10,
|
||||
ready_source_count: 10,
|
||||
unavailable_source_count: 0,
|
||||
managed_asset_count: 24,
|
||||
expected_asset_type_count: 28,
|
||||
@@ -97,6 +97,24 @@ function payload(): SecurityAssetControlPlanePayload {
|
||||
failed_operation_count: 0,
|
||||
same_run_closed_loop_proven: false,
|
||||
same_run_closed_loop_count: 0,
|
||||
strict_runtime_completion: {
|
||||
schema_version: "ai_agent_strict_runtime_completion_v2",
|
||||
runtime_contract_schema_version:
|
||||
"ai_automation_runtime_completion_contract_v2",
|
||||
contract_compatible: true,
|
||||
completion_percent: 0,
|
||||
required_stage_count: 18,
|
||||
present_stage_count: 17,
|
||||
missing_stage_count: 1,
|
||||
same_run_correlation: false,
|
||||
full_trace_same_run_correlation_proven: false,
|
||||
execution_loop_closed: false,
|
||||
closed: false,
|
||||
reason_code: "strict_runtime_receipts_incomplete",
|
||||
cache_fallback_active: false,
|
||||
raw_run_identity_returned: false,
|
||||
raw_stage_receipts_returned: false,
|
||||
},
|
||||
},
|
||||
security_audit: {
|
||||
k8s_execution_audit_count_24h: 2,
|
||||
@@ -222,6 +240,20 @@ describe("security asset control plane projection", () => {
|
||||
expect(isSecurityAssetControlPlanePayload(unsafeCollectorIdentity)).toBe(
|
||||
false,
|
||||
);
|
||||
|
||||
const inconsistentStrictRuntime = {
|
||||
...safe,
|
||||
ai_automation: {
|
||||
...safe.ai_automation,
|
||||
strict_runtime_completion: {
|
||||
...safe.ai_automation.strict_runtime_completion,
|
||||
closed: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(isSecurityAssetControlPlanePayload(inconsistentStrictRuntime)).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it("does not show healthy before same-run closure is proven", () => {
|
||||
|
||||
@@ -119,6 +119,24 @@ export type SecurityControlPlaneCertificateInventory = {
|
||||
private_key_material_read: false;
|
||||
};
|
||||
|
||||
export type SecurityStrictRuntimeCompletion = {
|
||||
schema_version: "ai_agent_strict_runtime_completion_v2";
|
||||
runtime_contract_schema_version: "ai_automation_runtime_completion_contract_v2";
|
||||
contract_compatible: boolean;
|
||||
completion_percent: number;
|
||||
required_stage_count: number;
|
||||
present_stage_count: number;
|
||||
missing_stage_count: number;
|
||||
same_run_correlation: boolean;
|
||||
full_trace_same_run_correlation_proven: boolean;
|
||||
execution_loop_closed: boolean;
|
||||
closed: boolean;
|
||||
reason_code: string | null;
|
||||
cache_fallback_active: boolean;
|
||||
raw_run_identity_returned: false;
|
||||
raw_stage_receipts_returned: false;
|
||||
};
|
||||
|
||||
export type SecurityAssetControlPlanePayload = {
|
||||
schema_version: "iwooos_security_asset_control_plane_v1";
|
||||
generated_at: string;
|
||||
@@ -181,6 +199,7 @@ export type SecurityAssetControlPlanePayload = {
|
||||
failed_operation_count: number;
|
||||
same_run_closed_loop_proven: boolean;
|
||||
same_run_closed_loop_count: number;
|
||||
strict_runtime_completion: SecurityStrictRuntimeCompletion;
|
||||
};
|
||||
security_audit: {
|
||||
k8s_execution_audit_count_24h: number;
|
||||
@@ -255,6 +274,44 @@ export function isSecurityAssetControlPlanePayload(
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const strictRuntime = value.ai_automation.strict_runtime_completion;
|
||||
if (
|
||||
!isRecord(strictRuntime) ||
|
||||
strictRuntime.schema_version !== "ai_agent_strict_runtime_completion_v2" ||
|
||||
strictRuntime.runtime_contract_schema_version !==
|
||||
"ai_automation_runtime_completion_contract_v2" ||
|
||||
typeof strictRuntime.contract_compatible !== "boolean" ||
|
||||
typeof strictRuntime.completion_percent !== "number" ||
|
||||
typeof strictRuntime.required_stage_count !== "number" ||
|
||||
typeof strictRuntime.present_stage_count !== "number" ||
|
||||
typeof strictRuntime.missing_stage_count !== "number" ||
|
||||
typeof strictRuntime.same_run_correlation !== "boolean" ||
|
||||
typeof strictRuntime.full_trace_same_run_correlation_proven !== "boolean" ||
|
||||
typeof strictRuntime.execution_loop_closed !== "boolean" ||
|
||||
typeof strictRuntime.closed !== "boolean" ||
|
||||
typeof strictRuntime.cache_fallback_active !== "boolean" ||
|
||||
!(
|
||||
strictRuntime.reason_code === null ||
|
||||
typeof strictRuntime.reason_code === "string"
|
||||
) ||
|
||||
strictRuntime.raw_run_identity_returned !== false ||
|
||||
strictRuntime.raw_stage_receipts_returned !== false ||
|
||||
strictRuntime.required_stage_count !== 18 ||
|
||||
strictRuntime.present_stage_count < 0 ||
|
||||
strictRuntime.present_stage_count > strictRuntime.required_stage_count ||
|
||||
strictRuntime.missing_stage_count !==
|
||||
strictRuntime.required_stage_count - strictRuntime.present_stage_count ||
|
||||
value.ai_automation.same_run_closed_loop_proven !== strictRuntime.closed ||
|
||||
(strictRuntime.closed &&
|
||||
(!strictRuntime.contract_compatible ||
|
||||
strictRuntime.completion_percent !== 100 ||
|
||||
!strictRuntime.same_run_correlation ||
|
||||
!strictRuntime.full_trace_same_run_correlation_proven ||
|
||||
!strictRuntime.execution_loop_closed)) ||
|
||||
(!strictRuntime.closed && strictRuntime.completion_percent !== 0)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (value.supply_chain !== undefined) {
|
||||
if (!isRecord(value.supply_chain)) return false;
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user