Skip to content
wiki.fftac.org

Runtimeentropyclassifier

**Site relevance:** Spiralist.org

**Memory type:** plugin source memory

**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Services/RuntimeEntropyClassifier.php

**Size:** 5 KB

Summary

namespace SpiralistWorkspace\Services;

Source Preview

This source file is short enough to preview directly on its source-memory page.

<?php

namespace SpiralistWorkspace\Services;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Classifies volatile Workspace session state without writing canonical registries.
 */
class RuntimeEntropyClassifier
{
    /**
     * @param array<string,mixed> $metrics
     * @return array<string,mixed>
     */
    public function classify(array $metrics): array
    {
        $order = $this->bounded(
            0.55
            + $this->metric($metrics, 'checkpoint_count') * 0.08
            + $this->metric($metrics, 'canonical_lookup_count') * 0.03
            - $this->metric($metrics, 'unresolved_task_count') * 0.04
            - $this->metric($metrics, 'contradiction_count') * 0.12
            - $this->metric($metrics, 'hallucination_flag_count') * 0.16
            - max(0, $this->metric($metrics, 'last_checkpoint_age_turns') - 12) * 0.02
        );

        $signal = $this->bounded(
            $this->metric($metrics, 'novelty_event_count') * 0.14
            + $this->metric($metrics, 'canonical_symbol_ref_count') * 0.04
            + ($this->metric($metrics, 'turn_count') >= 3 ? 0.18 : 0)
            - $this->metric($metrics, 'contradiction_count') * 0.04
        );

        $collapse = $this->bounded(
            $this->metric($metrics, 'contradiction_count') * 0.18
            + $this->metric($metrics, 'hallucination_flag_count') * 0.22
            + $this->metric($metrics, 'repeated_claim_count') * 0.08
            + max(0, $this->metric($metrics, 'last_checkpoint_age_turns') - 20) * 0.03
            - $this->metric($metrics, 'canonical_lookup_count') * 0.04
            - $this->metric($metrics, 'correction_count') * 0.03
        );

        $resolution = $this->bounded(
            $this->metric($metrics, 'paradox_resolution_count') * 0.22
            + $this->metric($metrics, 'correction_count') * 0.08
            + (!empty($metrics['human_reviewed']) ? 0.2 : 0)
            - $this->metric($metrics, 'hallucination_flag_count') * 0.08
            - max(0, $this->metric($metrics, 'contradiction_count') - $this->metric($metrics, 'correction_count')) * 0.1
        );

        $plate = 'the-sealed-system';
        if ($collapse >= 0.58) {
            $plate = 'the-collapse-system';
        } elseif ($resolution >= 0.55 && $collapse < 0.58) {
            $plate = 'this-one';
        } elseif ($signal >= 0.42) {
            $plate = 'the-signal-system';
        }

        return [
            'storage_class' => 'runtime-execution-payload',
            'registry_authority' => 'none',
            'protocol5_registry_write_allowed' => false,
            'protocol5_registry_write_attempted' => false,
            'crisis_plate' => $plate,
            'confidence' => max($order, $signal, $collapse, $resolution),
            'scores' => [
                'order' => $order,
                'signal' => $signal,
                'collapse' => $collapse,
                'resolution' => $resolution,
            ],
            'required_actions' => $this->required_actions($plate),
        ];
    }

    /**
     * Runtime classifications are execution payloads. This method deliberately
     * accepts only a runtime writer; no Protocol5 writer is part of the contract.
     *
     * @param callable(string,array<string,mixed>):void $runtime_writer
     * @param array<string,mixed> $classification
     */
    public function persist_runtime_only(callable $runtime_writer, string $session_id, array $classification): void
    {
        if (!empty($classification['protocol5_registry_write_allowed'])) {
            throw new \RuntimeException('Runtime classifications cannot write to Protocol5.');
        }

        $classification['storage_class'] = 'runtime-execution-payload';
        $classification['registry_authority'] = 'none';
        $classification['protocol5_registry_write_allowed'] = false;
        $classification['protocol5_registry_write_attempted'] = false;

        $runtime_writer($session_id, $classification);
    }

    /**
     * @param array<string,mixed> $metrics
     */
    private function metric(array $metrics, string $key): int
    {
        return max(0, (int) ($metrics[$key] ?? 0));
    }

    private function bounded(float $value): float
    {
        return max(0.0, min(1.0, $value));
    }

    /**
     * @return string[]
     */
    private function required_actions(string $plate): array
    {
        if ($plate === 'the-signal-system') {
            return ['create-memory-checkpoint', 'bind-new-claims-to-canonical-lookups'];
        }

        if ($plate === 'the-collapse-system') {
            return ['halt-autonomous-expansion', 'request-human-review', 'restore-from-last-valid-checkpoint', 'query-protocol5-before-symbolic-claims'];
        }

        if ($plate === 'this-one') {
            return ['write-resolution-summary', 'create-reviewed-checkpoint', 'preserve-runtime-classification-as-noncanonical'];
        }

        return ['continue-session', 'checkpoint-if-context-window-expands'];
    }
}