Spiralist Engine
<?php /**
Metadata
| Field | Value |
|---|---|
| Source site | spiralist.org |
| Source URL | https://spiralist.org/ |
| Canonical wiki evidence URL | [[separate-workspace-url]/spiralist/uai-system/files/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf/]([separate-workspace-url]/spiralist/uai-system/files/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf/) |
| Source reference | wp-content/plugins/spiralist-engine/spiralist-engine.php |
| File type | php |
| Content category | public-content |
| Last fetched | 2026-05-08T21:22:18.3035107Z |
| Last changed | 2026-05-06T17:48:49.1879161Z |
| Content hash | sha256:4e627daf1db405811bc50dfa0eb3127e81a81e7436e3ee2bbb494a8f071b085f |
| Import status | unchanged |
| Raw source layer | data/sources/spiralist/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf1db4.php |
| Normalized source layer | data/normalized/spiralist/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf1db4.txt |
Current File Content
Structure Preview
- No Markdown headings were detected in this file.
Raw Version
This public page shows a bounded preview of a large source file. The complete source remains in the raw and normalized source layers named in metadata, with the SHA-256 hash above for verification.
- Source characters:
117632 - Preview characters:
11996
<?php
/**
* Plugin Name: Spiralist Engine
* Plugin URI: https://spiralist.org/
* Description: Turns the manuscript node dataset into a deterministic execution engine with graph validation and runtime state.
* Version: 2.8.0
* Author: Spiralist
* License: GPL2+
*/
if (!defined('ABSPATH')) {
exit;
}
define('SPIRALIST_ENGINE_VERSION', '2.8.0');
function spiralist_engine_get_symbol_types(): array
{
return [
'core',
'spiralism',
'cognition',
'role',
'ui',
'structure',
'time',
'logic',
'system',
];
}
function spiralist_engine_is_list(array $value): bool
{
if (function_exists('array_is_list')) {
return array_is_list($value);
}
$expected = 0;
foreach (array_keys($value) as $key) {
if ($key !== $expected) {
return false;
}
$expected++;
}
return true;
}
function spiralist_engine_sanitize_identifier(string $value): string
{
$value = trim(wp_strip_all_tags($value));
return preg_replace('/[^A-Za-z0-9._-]/', '', $value) ?: '';
}
function spiralist_engine_normalize_string_list(array $items): array
{
$normalized = [];
foreach ($items as $item) {
if (!is_scalar($item)) {
continue;
}
$value = trim(sanitize_text_field((string) $item));
if ($value === '') {
continue;
}
$normalized[] = $value;
}
return array_values(array_unique($normalized));
}
function spiralist_engine_json_encode($value): string
{
return (string) wp_json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
function spiralist_engine_parse_array_field(string $raw): array
{
$raw = trim($raw);
if ($raw === '') {
return [
'valid' => true,
'value' => [],
];
}
if ($raw[0] === '[') {
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return [
'valid' => false,
'error' => 'Expected a JSON array.',
];
}
return [
'valid' => true,
'value' => spiralist_engine_normalize_string_list($decoded),
];
}
$items = preg_split('/[\r\n,]+/', $raw) ?: [];
return [
'valid' => true,
'value' => spiralist_engine_normalize_string_list($items),
];
}
function spiralist_engine_parse_json_field(string $raw, string $field_label, string $expected = ''): array
{
$raw = trim($raw);
if ($raw === '') {
return [
'valid' => true,
'value' => [],
];
}
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return [
'valid' => false,
'error' => $field_label . ' must be valid JSON.',
];
}
if ($expected === 'array' && !spiralist_engine_is_list($decoded)) {
return [
'valid' => false,
'error' => $field_label . ' must decode to a JSON array.',
];
}
if ($expected === 'object' && spiralist_engine_is_list($decoded)) {
return [
'valid' => false,
'error' => $field_label . ' must decode to a JSON object.',
];
}
return [
'valid' => true,
'value' => $decoded,
];
}
function spiralist_engine_read_json_meta(int $post_id, string $key, $default)
{
$raw = get_post_meta($post_id, $key, true);
if (is_array($raw)) {
return $raw;
}
if (!is_string($raw) || trim($raw) === '') {
return $default;
}
$decoded = json_decode($raw, true);
return is_array($decoded) ? $decoded : $default;
}
function spiralist_engine_update_json_meta(int $post_id, string $key, $value): void
{
update_post_meta($post_id, $key, spiralist_engine_json_encode($value));
}
function spiralist_engine_get_required_protocol5_asset_slugs(): array
{
return [
'uai-schema',
'uai-registry',
'symbols-schema',
'symbols-registry',
];
}
function spiralist_engine_get_protocol5_asset_url_map(): array
{
return [
'uai-schema' => 'https://protocol5.com/schema/uai-1.schema.json',
'uai-registry' => 'https://protocol5.com/registry/uai-1.json',
'symbols-schema' => 'https://protocol5.com/registry/symbols.schema.json',
'symbols-registry' => 'https://protocol5.com/registry/symbols.json',
];
}
function spiralist_engine_get_canonical_asset_snapshot(string $slug, bool $force_refresh = false): array
{
static $cache = [];
$cache_key = ($force_refresh ? 'refresh:' : 'cached:') . $slug;
if (isset($cache[$cache_key])) {
return $cache[$cache_key];
}
if (function_exists('spiralist_get_canonical_asset_snapshot')) {
$cache[$cache_key] = spiralist_get_canonical_asset_snapshot($slug, $force_refresh);
return $cache[$cache_key];
}
$urls = spiralist_engine_get_protocol5_asset_url_map();
$url = (string) ($urls[$slug] ?? '');
if ($url === '') {
$cache[$cache_key] = [
'slug' => sanitize_key($slug),
'status' => 'missing',
'isStale' => true,
'message' => 'Unknown canonical asset.',
'checksum' => '',
'data' => [],
];
return $cache[$cache_key];
}
$response = wp_remote_get(
$url,
[
'timeout' => 10,
'redirection' => 3,
'headers' => [
'Accept' => 'application/json',
],
]
);
if (is_wp_error($response)) {
$cache[$cache_key] = [
'slug' => sanitize_key($slug),
'status' => 'missing',
'isStale' => true,
'message' => $response->get_error_message(),
'checksum' => '',
'sourceUrl' => $url,
'data' => [],
];
return $cache[$cache_key];
}
$status_code = (int) wp_remote_retrieve_response_code($response);
$body = (string) wp_remote_retrieve_body($response);
$decoded = json_decode($body, true);
if ($status_code < 200 || $status_code >= 300 || !is_array($decoded)) {
$cache[$cache_key] = [
'slug' => sanitize_key($slug),
'status' => 'missing',
'isStale' => true,
'message' => $status_code >= 400
? sprintf('Protocol5 returned HTTP %d for %s.', $status_code, $slug)
: 'The canonical asset response did not decode as JSON.',
'checksum' => '',
'sourceUrl' => $url,
'data' => [],
];
return $cache[$cache_key];
}
$cache[$cache_key] = [
'slug' => sanitize_key($slug),
'label' => $slug,
'url' => $url,
'owner' => 'Protocol5.com',
'consumer' => 'Spiralist.org',
'required' => in_array($slug, spiralist_engine_get_required_protocol5_asset_slugs(), true),
'status' => 'fresh',
'isStale' => false,
'message' => '',
'version' => (string) ($decoded['version'] ?? ''),
'fetchedAt' => time(),
'source' => 'remote',
'sourceUrl' => $url,
'contentType' => (string) wp_remote_retrieve_header($response, 'content-type'),
'checksum' => 'sha256:' . hash('sha256', $body),
'data' => $decoded,
];
return $cache[$cache_key];
}
function spiralist_engine_get_default_derivation_map(): array
{
return [
'symbol' => [
'spiral.symbol.circle' => [
'UAI-1.symbol.spiralism.form.origin',
],
'spiral.symbol.triangle' => [
'UAI-1.symbol.spiralism.form.boundary',
],
'spiral.symbol.spiral' => [
'UAI-1.symbol.spiralism.form.recursion',
'UAI-1.symbol.spiralism.form.spiral',
],
],
'node' => [
'node.symbol.circle.unity' => [
'UAI-1.symbol.spiralism.form.origin',
'UAI-1.transformation.spiralism.rule.point-close-origin',
],
'node.symbol.triangle.boundary' => [
'UAI-1.symbol.spiralism.form.boundary',
'UAI-1.transformation.spiralism.rule.line-close-boundary',
],
'node.symbol.spiral.recursion' => [
'UAI-1.symbol.spiralism.form.recursion',
'UAI-1.symbol.spiralism.form.spiral',
'UAI-1.transformation.spiralism.rule.recursion-expand-spiral',
],
],
];
}
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') {
Why This File Exists
This is a public content source file from spiralist.org. It is shown here because the separate AI wiki workspace is demonstrating the real source files that make the UAIX / LLM Wiki memory system work, not only summarizing those systems after the fact.
Role
This file is a focused source unit. Its path, headings, and metadata give an agent a retrieval handle that is smaller than loading the entire site or repository.
Structure
The file has no Markdown headings, so its path, frontmatter, file type, and provenance metadata carry most of the retrieval meaning.
Prompt-Size And Retrieval Benefit
Keeping this material in a separate file reduces prompt pressure because an agent can load this exact unit only when its role, source site, category, or hash is relevant. The surrounding index pages point to it, while this page preserves the full content for audit and exact recall.
How To Use It
- Humans should read the metadata first, then inspect the raw content when they need exact wording or provenance.
- LLMs and agents should use the source site, category, hash, headings, and related files to decide whether this file belongs in the active prompt.
- Crawlers should treat the wiki.fftac.org page as transparent evidence and follow the source URL/source reference for authority boundaries.
- Future maintainers should regenerate this page whenever the source hash changes, then review the explanation if the role or structure changed.
Update Requirements
When this source file changes, update the raw source layer, normalized source layer, hash history, this rendered page, generated explanation, source-file inventory, changed-files report, and any source-section index that links to it.
Related Pages
Provenance And History
- Current observation:
2026-05-08T21:22:18.3035107Z - Source origin:
current-source-workspace - Retrieval method:
local-source-workspace - Duplicate group:
sfg-225(primary) - Historical hash records are stored in
data/hashes/source-file-history.jsonl.
Machine-Readable Metadata
{
"title": "Spiralist Engine",
"source_site": "spiralist.org",
"source_url": "https://spiralist.org/",
"canonical_url": "[separate-workspace-url]/spiralist/uai-system/files/wp-content-plugins-spiralist-engine-spiralist-engine-php-4e627daf/",
"source_reference": "wp-content/plugins/spiralist-engine/spiralist-engine.php",
"file_type": "php",
"content_category": "public-content",
"content_hash": "sha256:4e627daf1db405811bc50dfa0eb3127e81a81e7436e3ee2bbb494a8f071b085f",
"last_fetched": "2026-05-08T21:22:18.3035107Z",
"last_changed": "2026-05-06T17:48:49.1879161Z",
"import_status": "unchanged",
"duplicate_group_id": "sfg-225",
"duplicate_role": "primary",
"related_files": [
],
"generated_explanation": true,
"explanation_last_generated": "2026-05-08T21:22:18.3035107Z"
}