$overrides * @return array */ public static function structuredGap(array $overrides = []): array { return array_replace([ 'policy_type' => 'deviceConfiguration', 'subject_external_id' => 'subject-1', 'subject_key' => 'deviceconfiguration|subject-1', 'subject_class' => SubjectClass::PolicyBacked->value, 'resolution_path' => ResolutionPath::Policy->value, 'resolution_outcome' => ResolutionOutcome::PolicyRecordMissing->value, 'reason_code' => 'policy_record_missing', 'operator_action_category' => OperatorActionCategory::RunPolicySyncOrBackup->value, 'structural' => false, 'retryable' => false, 'source_model_expected' => 'policy', 'source_model_found' => null, ], $overrides); } /** * @param list> $subjects * @param array $overrides * @return array */ public static function compareContext(array $subjects, array $overrides = []): array { $byReason = []; foreach ($subjects as $subject) { $reasonCode = is_string($subject['reason_code'] ?? null) ? $subject['reason_code'] : 'unknown'; $byReason[$reasonCode] = ($byReason[$reasonCode] ?? 0) + 1; } return array_replace_recursive([ 'baseline_compare' => [ 'evidence_gaps' => [ 'count' => count($subjects), 'by_reason' => $byReason, 'subjects' => $subjects, ], ], ], $overrides); } /** * @param list> $subjects * @param array $overrides * @return array */ public static function captureContext(array $subjects, array $overrides = []): array { $byReason = []; foreach ($subjects as $subject) { $reasonCode = is_string($subject['reason_code'] ?? null) ? $subject['reason_code'] : 'unknown'; $byReason[$reasonCode] = ($byReason[$reasonCode] ?? 0) + 1; } return array_replace_recursive([ 'baseline_capture' => [ 'gaps' => [ 'count' => count($subjects), 'by_reason' => $byReason, 'subjects' => $subjects, ], ], ], $overrides); } /** * @param array $overrides * @return array */ public static function semanticOutcome(array $overrides = []): array { return array_replace_recursive([ 'reason' => 'identity_required', 'category' => 'action_required', 'actionability' => 'binding_required', 'readiness_impact' => 'customer_blocker', 'identity_status' => 'unresolved', 'comparison_status' => 'not_compared', 'coverage_status' => 'missing_local_evidence', 'trust_level' => 'untrusted', 'subject' => [ 'subject_domain' => 'baseline', 'subject_class' => SubjectClass::PolicyBacked->value, 'subject_type_key' => 'deviceConfiguration', 'subject_key' => 'subject-key', 'display_label' => 'Subject label', ], 'proof' => [], ], $overrides); } public static function inventoryCandidate(mixed $tenant, ResourceIdentity $identity, string $displayName): InventoryItem { $descriptor = self::providerDescriptor($identity, $displayName); return InventoryItem::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => $identity->providerResourceId, 'display_name' => $displayName, 'meta_jsonb' => [ 'provider_resource_descriptor' => $descriptor->toArray(), 'provider_resource_identity' => $identity->toArray(), 'provider_resource_fingerprint' => $identity->fingerprint(), ], 'last_seen_at' => now(), ]); } public static function providerDescriptor(ResourceIdentity $identity, string $displayName): ProviderResourceDescriptor { return ProviderResourceDescriptor::fromIdentity( identity: $identity, subjectDomain: 'baseline', subjectClass: SubjectClass::PolicyBacked, subjectTypeKey: 'deviceConfiguration', displayLabel: $displayName, sourceReferences: [], fingerprint: $identity->fingerprint(), lastSeenAt: now()->toIso8601String(), ); } }