Skip to content
wiki.fftac.org

WP Content Plugins Spiralist Engine Spiralist Engine PHP 4E627daf1db4 - Source Excerpt 02

Back to WP Content Plugins Spiralist Engine Spiralist Engine PHP 4E627daf1db4

Summary

This source excerpt preserves a bounded section of Wiki.FFTAC.org/data/sources/spiralist/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf1db4.php so readers can inspect the evidence without opening the full source file.

**Source path:** Wiki.FFTAC.org/data/sources/spiralist/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf1db4.php

function spiralist_engine_get_default_derives_from(string $record_type, string $identifier): array
{
    $record_type = sanitize_key($record_type);
    $identifier = trim($identifier);

    if ($identifier === '') {
        return [];
    }

    $map = spiralist_engine_get_default_derivation_map();

    return spiralist_engine_normalize_string_list((array) ($map[$record_type][$identifier] ?? []));
}

function spiralist_engine_parse_canonical_reference(string $reference): array
{
    $reference = trim($reference);
    if ($reference === '') {
        return [];
    }

    $prefix_map = [
        'UAI-1.symbol.' => 'symbol',
        'UAI-1.transformation.' => 'transformation',
    ];

    foreach ($prefix_map as $prefix => $kind) {
        if (strpos($reference, $prefix) !== 0) {
            continue;
        }

        $canonical_id = spiralist_engine_sanitize_identifier(substr($reference, strlen($prefix)));
        if ($canonical_id === '') {
            return [];
        }

        return [
            'reference' => $reference,
            'kind' => $kind,
            'canonical_id' => $canonical_id,
            'asset_slug' => 'symbols-registry',
        ];
    }

    return [];
}

function spiralist_engine_hash_canonical_record(array $record): string
{
    return 'sha256:' . hash(
        'sha256',
        spiralist_engine_json_encode(spiralist_engine_canonicalize_value($record))
    );
}

function spiralist_engine_build_protocol5_validation_context(bool $force_refresh = false): array
{
    static $cache = [];

    $cache_key = $force_refresh ? 'refresh' : 'cached';
    if (isset($cache[$cache_key])) {
        return $cache[$cache_key];
    }

    $snapshots = [];
    $errors = [];

    foreach (spiralist_engine_get_required_protocol5_asset_slugs() as $slug) {
        $snapshot = spiralist_engine_get_canonical_asset_snapshot($slug, $force_refresh);
        $snapshots[$slug] = $snapshot;

        if ((string) ($snapshot['status'] ?? '') === 'missing') {
            $errors[] = sprintf(
                'Protocol5 canonical asset "%s" is unavailable: %s',
                $slug,
                (string) ($snapshot['message'] ?? 'Missing asset.')
            );
            continue;
        }

        if (empty($snapshot['checksum'])) {
            $errors[] = sprintf('Protocol5 canonical asset "%s" did not provide a checksum.', $slug);
        }

        if (!is_array($snapshot['data'] ?? null)) {
            $errors[] = sprintf('Protocol5 canonical asset "%s" did not decode to JSON data.', $slug);
        }
    }

    $uai_registry = is_array($snapshots['uai-registry']['data'] ?? null) ? $snapshots['uai-registry']['data'] : [];
    if (!empty($uai_registry)) {
        if ((string) ($uai_registry['spec'] ?? '') !== 'UAI-1') {
            $errors[] = 'Protocol5 UAI registry does not declare spec "UAI-1".';
        }

        if ((string) ($uai_registry['status'] ?? '') !== 'authoritative') {
            $errors[] = 'Protocol5 UAI registry is not marked authoritative.';
        }
    }

    $uai_schema = is_array($snapshots['uai-schema']['data'] ?? null) ? $snapshots['uai-schema']['data'] : [];
    if (!empty($uai_schema) && empty($uai_schema['$schema']) && empty($uai_schema['type']) && empty($uai_schema['properties'])) {
        $errors[] = 'Protocol5 UAI schema is missing recognizable schema structure.';
    }

    $symbols_schema = is_array($snapshots['symbols-schema']['data'] ?? null) ? $snapshots['symbols-schema']['data'] : [];
    if (!empty($symbols_schema) && empty($symbols_schema['$schema']) && empty($symbols_schema['type']) && empty($symbols_schema['properties'])) {
        $errors[] = 'Protocol5 symbols schema is missing recognizable schema structure.';
    }

    $symbols_registry = is_array($snapshots['symbols-registry']['data'] ?? null) ? $snapshots['symbols-registry']['data'] : [];
    $symbol_map = [];
    $transformation_map = [];

    if (!empty($symbols_registry)) {
        if ((string) ($symbols_registry['spec'] ?? '') !== 'UAI-1') {
            $errors[] = 'Protocol5 symbols registry does not declare spec "UAI-1".';
        }

        if ((string) ($symbols_registry['status'] ?? '') !== 'authoritative') {
            $errors[] = 'Protocol5 symbols registry is not marked authoritative.';
        }

        if (empty($symbols_registry['symbols']) || !is_array($symbols_registry['symbols'])) {
            $errors[] = 'Protocol5 symbols registry does not include a symbols array.';
        } else {
            foreach ($symbols_registry['symbols'] as $record) {
                if (!is_array($record)) {
                    continue;
                }

                $canonical_id = spiralist_engine_sanitize_identifier((string) ($record['id'] ?? ''));
                if ($canonical_id === '') {
                    continue;
                }

                $symbol_map[$canonical_id] = $record;
            }
        }

        if (empty($symbols_registry['transformations']) || !is_array($symbols_registry['transformations'])) {
            $errors[] = 'Protocol5 symbols registry does not include a transformations array.';
        } else {
            foreach ($symbols_registry['transformations'] as $record) {
                if (!is_array($record)) {
                    continue;
                }

                $canonical_id = spiralist_engine_sanitize_identifier((string) ($record['id'] ?? ''));
                if ($canonical_id === '') {
                    continue;
                }

                $transformation_map[$canonical_id] = $record;
            }
        }
    }

    $cache[$cache_key] = [
        'valid' => empty($errors),
        'errors' => array_values(array_unique($errors)),
        'snapshots' => $snapshots,
        'symbols' => $symbol_map,
        'transformations' => $transformation_map,
    ];

    return $cache[$cache_key];
}

function spiralist_engine_validate_derives_from(array $references, array $context, string $label): array
{
    $errors = [];
    $resolved = [];
    $references = spiralist_engine_normalize_string_list($references);

    if (empty($references)) {
        $errors[] = sprintf('%s must define at least one derivesFrom reference.', $label);

        return [
            'valid' => false,
            'errors' => $errors,
            'resolved' => [],
        ];
    }

    foreach ($references as $reference) {
        $parsed = spiralist_engine_parse_canonical_reference($reference);
        if (empty($parsed)) {
            $errors[] = sprintf('%s contains an invalid derivesFrom reference "%s".', $label, $reference);
            continue;
        }

        if ($parsed['kind'] === 'symbol') {
            $record = (array) ($context['symbols'][$parsed['canonical_id']] ?? []);
        } else {
            $record = (array) ($context['transformations'][$parsed['canonical_id']] ?? []);
        }

        if (empty($record)) {
            $errors[] = sprintf(
                '%s derivesFrom reference "%s" could not be resolved in Protocol5.',
                $label,
                $reference
            );
            continue;
        }

        $resolved[$reference] = [
            'reference' => $reference,
            'kind' => $parsed['kind'],
            'canonical_id' => $parsed['canonical_id'],
            'asset_slug' => $parsed['asset_slug'],
            'asset_checksum' => (string) ($context['snapshots'][$parsed['asset_slug']]['checksum'] ?? ''),
            'record_hash' => spiralist_engine_hash_canonical_record($record),
            'label' => (string) ($record['name'] ?? $record['label'] ?? $parsed['canonical_id']),
        ];
    }

    return [
        'valid' => empty($errors),
        'errors' => array_values(array_unique($errors)),
        'resolved' => array_values($resolved),
    ];
}

function spiralist_engine_build_canonical_lock(array $resolved, array $context): array
{
    $assets = [];

    foreach (spiralist_engine_get_required_protocol5_asset_slugs() as $slug) {
        $snapshot = (array) ($context['snapshots'][$slug] ?? []);
        $assets[$slug] = [
            'checksum' => (string) ($snapshot['checksum'] ?? ''),
            'version' => (string) ($snapshot['version'] ?? ''),
            'status' => (string) ($snapshot['status'] ?? ''),
            'source' => (string) ($snapshot['source'] ?? ''),
            'sourceUrl' => (string) ($snapshot['sourceUrl'] ?? ''),
        ];
    }

    return [
        'validatedAt' => wp_date(DATE_ATOM),
        'assets' => $assets,
        'references' => array_values($resolved),
    ];
}

function spiralist_engine_validate_canonical_lock(array $lock, array $resolved, array $context, string $label): array
{
    $errors = [];