## Summary - add the Spec 204 platform vocabulary foundation, including canonical glossary terms, registry ownership descriptors, canonical operation type and alias resolution, and explicit reason ownership and platform reason-family metadata - harden platform-facing compare, snapshot, evidence, monitoring, review, and reporting surfaces so they prefer governed-subject and canonical operation semantics while preserving intentional Intune-owned terminology - extend Spec 204 unit, feature, Filament, and architecture coverage and add the full spec artifacts, checklist, and completed task ledger ## Verification - ran the focused recent-change Sail verification pack for the new glossary and reason-semantics work - ran the full Spec 204 quickstart verification pack under Sail - ran `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - ran an integrated-browser smoke pass covering tenant dashboard, operations, operation detail, baseline compare, evidence, reviews, review packs, provider connections, inventory items, backup schedules, onboarding, and the system dashboard/operations/failures/run-detail surfaces ## Notes - provider registration is unchanged and remains in `bootstrap/providers.php` - no new destructive actions or asset-registration changes are introduced by this branch Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #234
87 lines
3.0 KiB
PHP
87 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Governance;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
final readonly class RegistryOwnershipDescriptor
|
|
{
|
|
/**
|
|
* @param list<string> $canonicalNouns
|
|
* @param list<string> $allowedConsumers
|
|
*/
|
|
public function __construct(
|
|
public string $registryKey,
|
|
public string $boundaryClassification,
|
|
public string $ownerLayer,
|
|
public string $sourceClassOrFile,
|
|
public array $canonicalNouns,
|
|
public array $allowedConsumers,
|
|
public ?string $compatibilityNotes = null,
|
|
) {
|
|
if (trim($this->registryKey) === '' || trim($this->sourceClassOrFile) === '') {
|
|
throw new InvalidArgumentException('Registry ownership descriptors require a registry key and source reference.');
|
|
}
|
|
|
|
if ($this->canonicalNouns === [] || $this->allowedConsumers === []) {
|
|
throw new InvalidArgumentException('Registry ownership descriptors require canonical nouns and allowed consumers.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
public static function fromArray(array $data): self
|
|
{
|
|
return new self(
|
|
registryKey: (string) ($data['registry_key'] ?? ''),
|
|
boundaryClassification: (string) ($data['boundary_classification'] ?? ''),
|
|
ownerLayer: (string) ($data['owner_layer'] ?? ''),
|
|
sourceClassOrFile: (string) ($data['source_class_or_file'] ?? ''),
|
|
canonicalNouns: self::stringList($data['canonical_nouns'] ?? []),
|
|
allowedConsumers: self::stringList($data['allowed_consumers'] ?? []),
|
|
compatibilityNotes: is_string($data['compatibility_notes'] ?? null)
|
|
? trim((string) $data['compatibility_notes'])
|
|
: null,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* registry_key: string,
|
|
* boundary_classification: string,
|
|
* owner_layer: string,
|
|
* source_class_or_file: string,
|
|
* canonical_nouns: list<string>,
|
|
* allowed_consumers: list<string>,
|
|
* compatibility_notes: ?string
|
|
* }
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'registry_key' => $this->registryKey,
|
|
'boundary_classification' => $this->boundaryClassification,
|
|
'owner_layer' => $this->ownerLayer,
|
|
'source_class_or_file' => $this->sourceClassOrFile,
|
|
'canonical_nouns' => $this->canonicalNouns,
|
|
'allowed_consumers' => $this->allowedConsumers,
|
|
'compatibility_notes' => $this->compatibilityNotes,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param iterable<mixed> $values
|
|
* @return list<string>
|
|
*/
|
|
private static function stringList(iterable $values): array
|
|
{
|
|
return collect($values)
|
|
->filter(static fn (mixed $value): bool => is_string($value) && trim($value) !== '')
|
|
->map(static fn (string $value): string => trim($value))
|
|
->values()
|
|
->all();
|
|
}
|
|
} |