> */ private const DOMAIN_CLASSES = [ GovernanceDomainKey::Intune->value => [GovernanceSubjectClass::Policy->value], GovernanceDomainKey::PlatformFoundation->value => [GovernanceSubjectClass::ConfigurationResource->value], GovernanceDomainKey::Entra->value => [GovernanceSubjectClass::Control->value], ]; /** * @return list */ public function all(): array { return array_values(array_merge( $this->policySubjectTypes(), $this->foundationSubjectTypes(), )); } /** * @return list */ public function active(): array { return array_values(array_filter( $this->all(), static fn (GovernanceSubjectType $subjectType): bool => $subjectType->active, )); } /** * @return list */ public function activeLegacyBucketKeys(string $legacyBucket): array { $subjectTypes = array_filter( $this->active(), static fn (GovernanceSubjectType $subjectType): bool => $subjectType->legacyBucket === $legacyBucket, ); $keys = array_map( static fn (GovernanceSubjectType $subjectType): string => $subjectType->subjectTypeKey, $subjectTypes, ); sort($keys, SORT_STRING); return array_values(array_unique($keys)); } public function find(string $domainKey, string $subjectTypeKey): ?GovernanceSubjectType { foreach ($this->all() as $subjectType) { if ($subjectType->domainKey->value !== trim($domainKey)) { continue; } if ($subjectType->subjectTypeKey !== trim($subjectTypeKey)) { continue; } return $subjectType; } return null; } public function findBySubjectTypeKey(string $subjectTypeKey, ?string $legacyBucket = null): ?GovernanceSubjectType { $subjectTypeKey = trim($subjectTypeKey); $legacyBucket = is_string($legacyBucket) ? trim($legacyBucket) : null; foreach ($this->all() as $subjectType) { if ($subjectType->subjectTypeKey !== $subjectTypeKey) { continue; } if ($legacyBucket !== null && $subjectType->legacyBucket !== $legacyBucket) { continue; } return $subjectType; } return null; } /** * @return list */ public function canonicalNouns(): array { return ['domain_key', 'subject_class', 'subject_type_key', 'subject_type_label']; } public function ownershipDescriptor(?PlatformVocabularyGlossary $glossary = null): RegistryOwnershipDescriptor { $glossary ??= app(PlatformVocabularyGlossary::class); return $glossary->registry('governance_subject_taxonomy_registry') ?? RegistryOwnershipDescriptor::fromArray([ 'registry_key' => 'governance_subject_taxonomy_registry', 'boundary_classification' => PlatformVocabularyGlossary::BOUNDARY_CROSS_DOMAIN_GOVERNANCE, 'owner_layer' => PlatformVocabularyGlossary::OWNER_PLATFORM_CORE, 'source_class_or_file' => self::class, 'canonical_nouns' => $this->canonicalNouns(), 'allowed_consumers' => ['baseline_scope', 'compare', 'snapshot', 'review'], 'compatibility_notes' => 'Governed-subject registry lookups remain the canonical bridge from legacy policy-type payloads to platform-safe descriptors.', ]); } public function isKnownDomain(string $domainKey): bool { return array_key_exists(trim($domainKey), self::DOMAIN_CLASSES); } public function allowsSubjectClass(string $domainKey, string $subjectClass): bool { $domainKey = trim($domainKey); $subjectClass = trim($subjectClass); return in_array($subjectClass, self::DOMAIN_CLASSES[$domainKey] ?? [], true); } public function supportsFilters(string $domainKey, string $subjectClass): bool { return false; } public function groupLabel(string $domainKey, string $subjectClass): string { return match ([trim($domainKey), trim($subjectClass)]) { [GovernanceDomainKey::Intune->value, GovernanceSubjectClass::Policy->value] => 'Intune policies', [GovernanceDomainKey::PlatformFoundation->value, GovernanceSubjectClass::ConfigurationResource->value] => 'Platform foundation configuration resources', [GovernanceDomainKey::Entra->value, GovernanceSubjectClass::Control->value] => 'Entra controls', default => trim($domainKey).' / '.trim($subjectClass), }; } /** * @return list */ private function policySubjectTypes(): array { return array_values(array_map( function (array $row): GovernanceSubjectType { $type = (string) ($row['type'] ?? ''); $label = (string) ($row['label'] ?? $type); $category = is_string($row['category'] ?? null) ? (string) $row['category'] : null; $platform = is_string($row['platform'] ?? null) ? (string) $row['platform'] : null; $contract = InventoryPolicyTypeMeta::baselineSupportContract($type); return new GovernanceSubjectType( domainKey: GovernanceDomainKey::Intune, subjectClass: GovernanceSubjectClass::Policy, subjectTypeKey: $type, label: $label, description: $this->descriptionFor($category, $platform), captureSupported: in_array($contract['capture_capability'] ?? null, ['supported', 'limited'], true), compareSupported: in_array($contract['compare_capability'] ?? null, ['supported', 'limited'], true), inventorySupported: true, active: true, supportMode: $this->supportModeForContract($contract), legacyBucket: 'policy_types', ); }, array_values(array_filter( InventoryPolicyTypeMeta::supported(), static fn (array $row): bool => filled($row['type'] ?? null), )), )); } /** * @return list */ private function foundationSubjectTypes(): array { return array_values(array_map( function (array $row): GovernanceSubjectType { $type = (string) ($row['type'] ?? ''); $label = InventoryPolicyTypeMeta::baselineCompareLabel($type) ?? (string) ($row['label'] ?? $type); $category = is_string($row['category'] ?? null) ? (string) $row['category'] : null; $platform = is_string($row['platform'] ?? null) ? (string) $row['platform'] : null; $contract = InventoryPolicyTypeMeta::baselineSupportContract($type); $supported = (bool) data_get($row, 'baseline_compare.supported', false); return new GovernanceSubjectType( domainKey: GovernanceDomainKey::PlatformFoundation, subjectClass: GovernanceSubjectClass::ConfigurationResource, subjectTypeKey: $type, label: $label, description: $this->descriptionFor($category, $platform), captureSupported: in_array($contract['capture_capability'] ?? null, ['supported', 'limited'], true), compareSupported: in_array($contract['compare_capability'] ?? null, ['supported', 'limited'], true), inventorySupported: in_array($contract['source_model_expected'] ?? null, ['inventory', 'policy'], true), active: $supported, supportMode: $this->supportModeForContract($contract), legacyBucket: 'foundation_types', ); }, array_values(array_filter( InventoryPolicyTypeMeta::foundations(), static fn (array $row): bool => filled($row['type'] ?? null), )), )); } private function descriptionFor(?string $category, ?string $platform): ?string { $parts = array_values(array_filter([$category, $platform], static fn (?string $part): bool => filled($part))); if ($parts === []) { return null; } return implode(' | ', $parts); } /** * @param array $contract */ private function supportModeForContract(array $contract): string { $capabilities = [ (string) ($contract['capture_capability'] ?? 'unsupported'), (string) ($contract['compare_capability'] ?? 'unsupported'), ]; if (! (bool) ($contract['runtime_valid'] ?? false) && (bool) ($contract['config_supported'] ?? false)) { return 'invalid_support_config'; } if (in_array('supported', $capabilities, true)) { return 'supported'; } if (in_array('limited', $capabilities, true)) { return 'limited'; } return 'excluded'; } }