*/ private const array AllowedSummaryKinds = [ 'policy_snapshot', 'policy_assignments', 'policy_scope_tags', ]; /** * @var list */ private const array AllowedChangeTypes = [ 'missing_policy', 'unexpected_policy', 'different_version', ]; /** * @var list */ private const array AllowedFidelity = [ 'content', 'meta', 'mixed', ]; /** * @param array $evidence */ public static function assertValid(array $evidence): void { foreach (['change_type', 'policy_type', 'subject_key', 'summary', 'baseline', 'current', 'fidelity', 'provenance'] as $key) { Assert::assertArrayHasKey($key, $evidence); } $changeType = is_string($evidence['change_type'] ?? null) ? (string) $evidence['change_type'] : ''; Assert::assertContains($changeType, self::AllowedChangeTypes); $summary = is_array($evidence['summary'] ?? null) ? $evidence['summary'] : []; Assert::assertArrayHasKey('kind', $summary); $kind = is_string($summary['kind'] ?? null) ? (string) $summary['kind'] : ''; Assert::assertContains($kind, self::AllowedSummaryKinds); $baseline = is_array($evidence['baseline'] ?? null) ? $evidence['baseline'] : []; $current = is_array($evidence['current'] ?? null) ? $evidence['current'] : []; Assert::assertArrayHasKey('policy_version_id', $baseline); Assert::assertArrayHasKey('policy_version_id', $current); $baselineId = is_numeric($baseline['policy_version_id'] ?? null) ? (int) $baseline['policy_version_id'] : null; $currentId = is_numeric($current['policy_version_id'] ?? null) ? (int) $current['policy_version_id'] : null; $expectedFidelity = self::expectedFidelity($baselineId, $currentId); $fidelity = is_string($evidence['fidelity'] ?? null) ? (string) $evidence['fidelity'] : ''; Assert::assertContains($fidelity, self::AllowedFidelity); Assert::assertSame($expectedFidelity, $fidelity); $provenance = is_array($evidence['provenance'] ?? null) ? $evidence['provenance'] : []; foreach (['baseline_profile_id', 'baseline_snapshot_id', 'compare_operation_run_id', 'inventory_sync_run_id'] as $key) { Assert::assertArrayHasKey($key, $provenance); } Assert::assertIsInt($provenance['baseline_profile_id']); Assert::assertIsInt($provenance['baseline_snapshot_id']); Assert::assertIsInt($provenance['compare_operation_run_id']); $inventorySyncRunId = $provenance['inventory_sync_run_id'] ?? null; Assert::assertTrue($inventorySyncRunId === null || is_numeric($inventorySyncRunId)); } public static function isDiffRenderable(array $evidence): bool { $changeType = is_string($evidence['change_type'] ?? null) ? (string) $evidence['change_type'] : ''; $baseline = is_array($evidence['baseline'] ?? null) ? $evidence['baseline'] : []; $current = is_array($evidence['current'] ?? null) ? $evidence['current'] : []; $baselineId = is_numeric($baseline['policy_version_id'] ?? null) ? (int) $baseline['policy_version_id'] : null; $currentId = is_numeric($current['policy_version_id'] ?? null) ? (int) $current['policy_version_id'] : null; return match ($changeType) { 'missing_policy' => $baselineId !== null, 'unexpected_policy' => $currentId !== null, default => $baselineId !== null && $currentId !== null, }; } private static function expectedFidelity(?int $baselinePolicyVersionId, ?int $currentPolicyVersionId): string { if ($baselinePolicyVersionId !== null && $currentPolicyVersionId !== null) { return 'content'; } if ($baselinePolicyVersionId !== null || $currentPolicyVersionId !== null) { return 'mixed'; } return 'meta'; } }