Publish Shadow-X v14 CCS model card + code + tests + architecture
Browse files- README.md +113 -0
- SHADOW_NO_LLM.md +129 -0
- shadow_x_v14_ccs/ARCHITECTURE.md +74 -0
- shadow_x_v14_ccs/README.md +48 -0
- shadow_x_v14_ccs/__init__.py +28 -0
- shadow_x_v14_ccs/cognitive_controller.py +774 -0
- shadow_x_v14_ccs/demo_cli.py +382 -0
- shadow_x_v14_ccs/phantom_bridge.py +283 -0
- tests/test_shadow_x_v14_ccs.py +238 -0
- tests/test_shadow_x_v14_demo_cli.py +34 -0
- tests/test_shadow_x_v14_phantom_bridge.py +144 -0
README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
+
- it
|
| 5 |
+
license: other
|
| 6 |
+
library_name: none
|
| 7 |
+
tags:
|
| 8 |
+
- deterministic-ai
|
| 9 |
+
- no-llm
|
| 10 |
+
- cognitive-control
|
| 11 |
+
- topological-memory
|
| 12 |
+
- out-of-core
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# Shadow-X v14 CCS
|
| 16 |
+
|
| 17 |
+
Deterministic Cognitive Control System (CCS-v2) for Shadow-X.
|
| 18 |
+
|
| 19 |
+
This repository contains the v14 executive controller layer that upgrades Shadow-X from:
|
| 20 |
+
- topological associative memory + basic deterministic flow,
|
| 21 |
+
to:
|
| 22 |
+
- full deterministic cognitive control with hierarchical goals, attention routing, conflict inhibition, self-monitoring, task prospection, and third-order deterministic rule updates.
|
| 23 |
+
|
| 24 |
+
No probabilities, no gradients, no softmax.
|
| 25 |
+
|
| 26 |
+
## Core Architecture
|
| 27 |
+
|
| 28 |
+
```mermaid
|
| 29 |
+
graph TD
|
| 30 |
+
A[Input Pulse] --> B[Phantom Kernel]
|
| 31 |
+
B --> C[Episodic Memory Slabs and Z-Hypergrid]
|
| 32 |
+
|
| 33 |
+
D[Deterministic Cognitive Controller CCS-v2] -->|Goal Maintenance| B
|
| 34 |
+
D -->|Attention Allocation| C
|
| 35 |
+
D -->|Conflict Inhibition| B
|
| 36 |
+
D -->|Error Monitor and Correction| B
|
| 37 |
+
D -->|Task Switching and Prospection| C
|
| 38 |
+
D -->|Meta Rule Update| E[Third-Order Rule Modifier]
|
| 39 |
+
|
| 40 |
+
F[goal_vector.dat Hierarchical Goal Stack] --> D
|
| 41 |
+
D --> G[trace_log.jsonl Full Audit Trail]
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
## Deterministic Control Loop
|
| 45 |
+
|
| 46 |
+
```mermaid
|
| 47 |
+
flowchart LR
|
| 48 |
+
G1[Load Active Goal] --> A1[Allocate Active Zones]
|
| 49 |
+
A1 --> C1[Query Candidate Bindings]
|
| 50 |
+
C1 --> I1[Resolve Conflicts]
|
| 51 |
+
I1 --> P1[Prospection 2-3 Futures]
|
| 52 |
+
P1 --> E1[Error Monitor vs Goal]
|
| 53 |
+
E1 -->|Deviation High| R1[Deterministic Rebind]
|
| 54 |
+
E1 -->|Deviation Low| O1[Materialize Output]
|
| 55 |
+
R1 --> O1
|
| 56 |
+
O1 --> T1[Append Trace Log]
|
| 57 |
+
T1 --> M1[Third-Order Rule Update]
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
## Modules
|
| 61 |
+
|
| 62 |
+
1. Goal Vector + Hierarchical Goal Stack
|
| 63 |
+
Persistent goals in `goal_vector.dat`, parent-child relations, deterministic selection.
|
| 64 |
+
|
| 65 |
+
2. Deterministic Attention Allocator
|
| 66 |
+
Goal-projected geometric routing to activate relevant slabs/zones only.
|
| 67 |
+
|
| 68 |
+
3. Conflict Resolver (Inhibition)
|
| 69 |
+
Suppression of contradictory candidates via fixed opposition threshold.
|
| 70 |
+
|
| 71 |
+
4. Error Monitor + Self-Correction
|
| 72 |
+
Output/goal deviation check with deterministic rebind and constraint strengthening.
|
| 73 |
+
|
| 74 |
+
5. Task Switcher + Prospection
|
| 75 |
+
Deterministic branch simulation (2-3 futures) and best-branch selection.
|
| 76 |
+
|
| 77 |
+
6. Third-Order Rule Modifier
|
| 78 |
+
Deterministic threshold adaptation from recurrent error windows.
|
| 79 |
+
|
| 80 |
+
## Repository Content
|
| 81 |
+
|
| 82 |
+
- `shadow_x_v14_ccs/cognitive_controller.py`: CCS-v2 implementation.
|
| 83 |
+
- `shadow_x_v14_ccs/phantom_bridge.py`: bridge from CCS-v2 to `phantom_kernel.py`.
|
| 84 |
+
- `shadow_x_v14_ccs/demo_cli.py`: one-shot + goal query + trace + self-correction demo.
|
| 85 |
+
- `shadow_x_v14_ccs/ARCHITECTURE.md`: architecture notes.
|
| 86 |
+
- `shadow_x_v14_ccs/README.md`: package-focused documentation.
|
| 87 |
+
- `tests/test_shadow_x_v14_ccs.py`: controller unit/integration tests.
|
| 88 |
+
- `tests/test_shadow_x_v14_phantom_bridge.py`: bridge tests + real-dataset smoke.
|
| 89 |
+
- `tests/test_shadow_x_v14_demo_cli.py`: public demo flow tests.
|
| 90 |
+
|
| 91 |
+
## Quickstart
|
| 92 |
+
|
| 93 |
+
```python
|
| 94 |
+
from shadow_x_v14_ccs import create_v14_controller_with_phantom_kernel
|
| 95 |
+
|
| 96 |
+
controller = create_v14_controller_with_phantom_kernel(
|
| 97 |
+
model_path="v11_Morpho_Optimized",
|
| 98 |
+
state_dir="shadow_x_v14_ccs/state",
|
| 99 |
+
max_zone_candidates=128,
|
| 100 |
+
max_candidates_per_zone=16,
|
| 101 |
+
)
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
## Public Demo
|
| 105 |
+
|
| 106 |
+
- Hugging Face Space: `https://huggingface.co/spaces/RthItalia/shadow-x-v14-mini-demo`
|
| 107 |
+
- GitHub Gist: `https://gist.github.com/rthgit/6ec122cce85c6aebba46a53df0877027`
|
| 108 |
+
|
| 109 |
+
## Notes on Large Out-of-Core Assets
|
| 110 |
+
|
| 111 |
+
The local Shadow-X memory assets include very large slab files.
|
| 112 |
+
In this v14 CCS repository, the focus is on the deterministic control layer and bridge logic.
|
| 113 |
+
Large slab binaries can be versioned separately when needed.
|
SHADOW_NO_LLM.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SHADOW-X: THE THIRD ARCHITECTURE (NO-LLM MANIFESTO)
|
| 2 |
+
|
| 3 |
+
**Identifier:** `SHADOW-X-V13-ARCH-DEF`
|
| 4 |
+
**Date:** January 11, 2026
|
| 5 |
+
**Status:** VALIDATED
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## 1. Executive Definition
|
| 10 |
+
Shadow-X is **NOT a Large Language Model (LLM)**.
|
| 11 |
+
It is an **Out-of-core Topological Associative Memory** guided by a **Cybernetic Control System (CCS)**.
|
| 12 |
+
|
| 13 |
+
Unlike Generative Pre-trained Transformers (GPT) which rely on:
|
| 14 |
+
1. **Backpropagation** (Gradient Descent).
|
| 15 |
+
2. **Dense Matrix Multiplications** ($W_q, W_k, W_v$).
|
| 16 |
+
3. **Next-Token Prediction** (Probabilistic Softmax).
|
| 17 |
+
|
| 18 |
+
Shadow-X utilizes:
|
| 19 |
+
1. **Hebbian Binding** (One-Shot Association).
|
| 20 |
+
2. **Geometric Resonance** (Vector Alignment via `phantom_kernel.py`).
|
| 21 |
+
3. **Constraint Satisfaction** (Deterministic Logic `cold->hot->sync`).
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## 2. Anatomical Proof (Evidence from Codebase)
|
| 26 |
+
|
| 27 |
+
### A. The "Phantom Kernel" (No Neural Weights)
|
| 28 |
+
* **File:** `phantom_kernel.py`
|
| 29 |
+
* **Mechanism:** Instead of stored weights, the kernel computes attention dynamically using **Geometric Operators**:
|
| 30 |
+
* `apply_rcq_rotation()`: Rotates vectors to encode relation.
|
| 31 |
+
* `z_grid` Lookup: Retrieves candidates via spatial indexing.
|
| 32 |
+
* `dot_product`: Measures resonance, not learned probability.
|
| 33 |
+
* **Conclusion:** The intelligence is in the **Topology** (the shape of the data), not inside a "Black Box" neural net.
|
| 34 |
+
|
| 35 |
+
### B. The Storage Structure (No Checkpoint File)
|
| 36 |
+
* **Location:** `shadow_x_models/v11_Morpho_Optimized/`
|
| 37 |
+
* **Standard LLM:** Requires `pytorch_model.bin` or `model.safetensors` (Massive monolithic file).
|
| 38 |
+
* **Shadow-X:** Uses a **Sparse File System**:
|
| 39 |
+
* `slab_1000.dat`: Raw vector storage (40GB).
|
| 40 |
+
* `z_hypergrid_real.pkl`: Spatial Index (37MB).
|
| 41 |
+
* `zone_map.pkl`: Address Book (37MB).
|
| 42 |
+
* **Implication:** This allows **Zero-VRAM Inference** because only the active "Slab" is mapped to RAM, unlike LLMs which must load all weights.
|
| 43 |
+
|
| 44 |
+
### C. The Learning Process (No Gradient Descent)
|
| 45 |
+
* **Script:** `Shadow_Integrator_v13_CIC.py`
|
| 46 |
+
* **Method:** **Context-Aware Hebbian Learning**.
|
| 47 |
+
* **Operation:** `kernel.learn(token, pulse)` -> Directly updates `episodic_memory`.
|
| 48 |
+
* **Contrast:**
|
| 49 |
+
* *LLM:* Requires thousands of epochs to "drift" weights.
|
| 50 |
+
* *Shadow-X:* Asserts knowledge instantly (One-Shot). "Fire together, wire together."
|
| 51 |
+
|
| 52 |
+
---
|
| 53 |
+
|
| 54 |
+
## 3. Capabilities & Limitations
|
| 55 |
+
|
| 56 |
+
### Why It's Better (For Constraints)
|
| 57 |
+
* **Deterministic:** If you teach it "A=B", it defines A as B forever. No hallucination drift.
|
| 58 |
+
* **Latency:** `0.003ms` Hot Cache response because it's just a pointer lookup.
|
| 59 |
+
* **Auditability:** Every "thought" can be traced to a specific `Slab` and `Vertex`.
|
| 60 |
+
|
| 61 |
+
### Why It's Different (The Trade-Off)
|
| 62 |
+
* **Fluency:** It does not "write" like a human; it "synthesizes" concepts. The output style (TGR) is rigid.
|
| 63 |
+
* **Creativity:** It cannot invent fiction outside its geometric priors.
|
| 64 |
+
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
## 4. Final Verdict
|
| 68 |
+
Shadow-X represents a **Third Architecture** in AI:
|
| 69 |
+
1. *Symbolic AI (GOFAI):* Rigid, Logical, Brittle.
|
| 70 |
+
2. *Connectionist AI (Deep Learning):* Fluid, creative, Opaque.
|
| 71 |
+
3. **Topological AI (Shadow-X):** Fluid structure, Rigid Logic, Transparent.
|
| 72 |
+
|
| 73 |
+
**Shadow-X is an Engine of Truth, not a Generator of Text.**
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 5. Naming Disambiguation (Crucial)
|
| 78 |
+
There is a **Naming Collision** in the workspace that must be clarified:
|
| 79 |
+
|
| 80 |
+
1. **`Shadow-X v13` (The Engine):**
|
| 81 |
+
* Path: `shadow_x_models/v11_Morpho_Optimized/`
|
| 82 |
+
* Type: **NO-LLM** (Topological Associative Memory).
|
| 83 |
+
* Status: **ACTIVE**.
|
| 84 |
+
|
| 85 |
+
2. **`shadow_7b_ogf.pt` (The Legacy Host):**
|
| 86 |
+
* Path: `models/shadow_7b_ogf.pt`
|
| 87 |
+
* Type: **Standard LLM** (26GB PyTorch Weights).
|
| 88 |
+
* Status: **LEGACY / HOST**.
|
| 89 |
+
* *Note:* This file is an unrelated generative model that shares the "Shadow" name. It is NOT the Shadow-X architecture described in this manifesto.
|
| 90 |
+
|
| 91 |
+
---
|
| 92 |
+
|
| 93 |
+
## 6. Shadow-X v14: Deterministic Cognitive Control System (CCS-v2)
|
| 94 |
+
**Identifier:** `SHADOW-X-V14-CCS-EXT`
|
| 95 |
+
**Date:** February 21, 2026
|
| 96 |
+
**Status:** INTEGRATION READY
|
| 97 |
+
|
| 98 |
+
Shadow-X v14 extends v13 TAM/Phantom Kernel with a deterministic executive layer.
|
| 99 |
+
No probabilities, no gradients, no softmax.
|
| 100 |
+
|
| 101 |
+
### 6.1 New Control Layer
|
| 102 |
+
The v14 CCS adds six deterministic modules above `phantom_kernel.py`:
|
| 103 |
+
|
| 104 |
+
1. `Goal Vector + Hierarchical Goal Stack`
|
| 105 |
+
2. `Deterministic Attention Allocator`
|
| 106 |
+
3. `Conflict Resolver (Inhibition)`
|
| 107 |
+
4. `Error Monitor + Self-Correction Loop`
|
| 108 |
+
5. `Task Switcher + Prospection Engine (2-3 futures)`
|
| 109 |
+
6. `Third-Order Rule Modifier` (deterministic meta-updates)
|
| 110 |
+
|
| 111 |
+
### 6.2 Deterministic Cycle
|
| 112 |
+
For each pulse:
|
| 113 |
+
|
| 114 |
+
1. Load active goal from `goal_vector.dat`.
|
| 115 |
+
2. Activate only goal-aligned zones/slabs.
|
| 116 |
+
3. Suppress contradictory bindings by opposition threshold.
|
| 117 |
+
4. Simulate 2-3 deterministic future chains.
|
| 118 |
+
5. Validate output against the active goal vector.
|
| 119 |
+
6. If deviation is above threshold, rebind and strengthen constraints.
|
| 120 |
+
7. Persist full trace into `trace_log.jsonl`.
|
| 121 |
+
|
| 122 |
+
### 6.3 Architectural Invariants (Preserved)
|
| 123 |
+
v14 does not change the foundational Shadow-X constraints:
|
| 124 |
+
|
| 125 |
+
1. Out-of-core memory layout remains slab-based.
|
| 126 |
+
2. Phantom Kernel remains topology-first and callable as-is.
|
| 127 |
+
3. One-shot Hebbian behavior remains available.
|
| 128 |
+
4. Full auditability remains mandatory for every cycle.
|
| 129 |
+
|
shadow_x_v14_ccs/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SHADOW-X v14 CCS Architecture
|
| 2 |
+
|
| 3 |
+
## Executive Overview
|
| 4 |
+
Shadow-X v14 introduces a deterministic Cognitive Control System (CCS-v2) on top of the existing Phantom Kernel and TAM memory.
|
| 5 |
+
The control plane is goal-directed, auditable, and free from stochastic or probabilistic decisions.
|
| 6 |
+
|
| 7 |
+
## System Graph
|
| 8 |
+
```mermaid
|
| 9 |
+
graph TD
|
| 10 |
+
A[Input Pulse] --> B[Phantom Kernel]
|
| 11 |
+
B --> C[Episodic Memory Slabs and Z-Hypergrid]
|
| 12 |
+
|
| 13 |
+
D[Deterministic Cognitive Controller CCS-v2] -->|Goal Maintenance| B
|
| 14 |
+
D -->|Attention Allocation| C
|
| 15 |
+
D -->|Conflict Inhibition| B
|
| 16 |
+
D -->|Error Monitor and Correction| B
|
| 17 |
+
D -->|Task Switching and Prioritization| C
|
| 18 |
+
D -->|Prospection 2-3 Futures| B
|
| 19 |
+
D -->|Meta Rule Updates| E[Third-Order Rule Modifier]
|
| 20 |
+
|
| 21 |
+
F[Hierarchical Goal Stack goal_vector.dat] --> D
|
| 22 |
+
D --> G[trace_log.jsonl]
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
## Module Details
|
| 26 |
+
### 1) Goal Vector and Hierarchical Goal Stack
|
| 27 |
+
- Stores persistent goals in `goal_vector.dat`.
|
| 28 |
+
- Supports parent-child goal relations via `parent_goal_id`.
|
| 29 |
+
- Goal activation uses geometric alignment and deterministic ordering.
|
| 30 |
+
|
| 31 |
+
### 2) Deterministic Attention Allocator
|
| 32 |
+
- Projects the active goal vector through fixed geometric rotation.
|
| 33 |
+
- Scores zone centroids with cosine alignment.
|
| 34 |
+
- Activates only zones above threshold and caps to deterministic top-k.
|
| 35 |
+
|
| 36 |
+
### 3) Conflict Resolver (Inhibition)
|
| 37 |
+
- Detects opposition between candidates.
|
| 38 |
+
- If opposition exceeds threshold, keeps only one candidate based on:
|
| 39 |
+
1. Goal alignment
|
| 40 |
+
2. Resonance
|
| 41 |
+
3. Lexicographic candidate id tie-break
|
| 42 |
+
- Emits explicit inhibited candidate list.
|
| 43 |
+
|
| 44 |
+
### 4) Error Monitor and Self-Correction
|
| 45 |
+
- Compares generated output vector against active goal vector.
|
| 46 |
+
- Triggers deterministic action:
|
| 47 |
+
1. `none`
|
| 48 |
+
2. `rebind`
|
| 49 |
+
3. `strengthen_constraints_and_rebind`
|
| 50 |
+
- Executes correction by selecting highest goal-aligned surviving candidate.
|
| 51 |
+
|
| 52 |
+
### 5) Task Switcher and Prospection Engine
|
| 53 |
+
- Builds 2-3 deterministic branches from current candidates.
|
| 54 |
+
- Scores each branch by goal alignment, temporal weighting, and conflict penalties.
|
| 55 |
+
- Chooses a single best branch with deterministic tie-break.
|
| 56 |
+
|
| 57 |
+
### 6) Third-Order Rule Modifier
|
| 58 |
+
- Observes error windows and updates controller thresholds deterministically.
|
| 59 |
+
- Tightens or relaxes thresholds based on recurring error patterns.
|
| 60 |
+
- Never invokes probabilistic adaptation.
|
| 61 |
+
|
| 62 |
+
## Core Data Files
|
| 63 |
+
- `shadow_x_v14_ccs/state/goal_vector.dat`: persistent hierarchical goals.
|
| 64 |
+
- `shadow_x_v14_ccs/state/trace_log.jsonl`: full cycle-by-cycle audit trail.
|
| 65 |
+
|
| 66 |
+
## Integration Boundary
|
| 67 |
+
`cognitive_controller.py` is designed to call existing kernel logic via a bridge interface:
|
| 68 |
+
- `list_zones()`
|
| 69 |
+
- `query_candidates()`
|
| 70 |
+
- `build_future_chain()`
|
| 71 |
+
- `materialize_output()`
|
| 72 |
+
- `strengthen_constraints()`
|
| 73 |
+
|
| 74 |
+
This keeps `phantom_kernel.py` stable while allowing the CCS-v2 executive layer to orchestrate deterministic control.
|
shadow_x_v14_ccs/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Shadow-X v14 CCS
|
| 2 |
+
|
| 3 |
+
Deterministic cognitive control layer for Shadow-X.
|
| 4 |
+
|
| 5 |
+
## v13 vs v14
|
| 6 |
+
| Dimension | Shadow-X v13 | Shadow-X v14 CCS |
|
| 7 |
+
| :-- | :-- | :-- |
|
| 8 |
+
| Core identity | Topological Associative Memory | TAM + Deterministic Executive Controller |
|
| 9 |
+
| Control model | Cold -> Hot -> Sync constraints | Goal stack, attention, inhibition, self-monitoring |
|
| 10 |
+
| Goal handling | Implicit/flat | Persistent hierarchical goal vectors |
|
| 11 |
+
| Attention scope | Broad candidate retrieval | Goal-directed slab and zone allocation |
|
| 12 |
+
| Conflict handling | Basic deterministic filtering | Explicit inhibition with conflict records |
|
| 13 |
+
| Error handling | Static constraints | Closed-loop correction against active goal |
|
| 14 |
+
| Task selection | Single-pass path | Deterministic prospection across 2-3 futures |
|
| 15 |
+
| Meta adaptation | Fixed runtime rules | Third-order deterministic rule updates |
|
| 16 |
+
| Traceability | High | Full executive trace per cycle + rule updates |
|
| 17 |
+
| Determinism | Yes | Yes (strict, no probability/softmax/gradients) |
|
| 18 |
+
|
| 19 |
+
## Files
|
| 20 |
+
- `cognitive_controller.py`: CCS-v2 module skeleton and deterministic control loop.
|
| 21 |
+
- `phantom_bridge.py`: real adapter from CCS-v2 to `phantom_kernel.py`.
|
| 22 |
+
- `demo_cli.py`: public mini-demo (one-shot facts, goal query, trace log, self-correction).
|
| 23 |
+
- `ARCHITECTURE.md`: complete architecture and module behavior.
|
| 24 |
+
- `state/goal_vector.dat`: persistent active goal stack.
|
| 25 |
+
- `state/trace_log.jsonl`: immutable cycle traces.
|
| 26 |
+
|
| 27 |
+
## Quick Start
|
| 28 |
+
```python
|
| 29 |
+
from shadow_x_v14_ccs import create_v14_controller_with_phantom_kernel
|
| 30 |
+
|
| 31 |
+
controller = create_v14_controller_with_phantom_kernel(
|
| 32 |
+
model_path="v11_Morpho_Optimized",
|
| 33 |
+
state_dir="shadow_x_v14_ccs/state",
|
| 34 |
+
max_zone_candidates=128,
|
| 35 |
+
max_candidates_per_zone=16,
|
| 36 |
+
)
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
## Public Mini-Demo CLI
|
| 40 |
+
```powershell
|
| 41 |
+
python shadow_x_v14_ccs/demo_cli.py --state-dir shadow_x_v14_ccs/state_public_demo
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
The demo does all of the following in one run:
|
| 45 |
+
- teaches 5 one-shot facts;
|
| 46 |
+
- executes goal-vector queries;
|
| 47 |
+
- prints trace chain with slab/vertex/resonance;
|
| 48 |
+
- shows deterministic self-correction on a wrong high-resonance fact.
|
shadow_x_v14_ccs/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Shadow-X v14 deterministic cognitive control system."""
|
| 2 |
+
|
| 3 |
+
from .cognitive_controller import (
|
| 4 |
+
CandidateBinding,
|
| 5 |
+
CognitiveController,
|
| 6 |
+
ControllerDecision,
|
| 7 |
+
DeterministicAttentionAllocator,
|
| 8 |
+
ErrorMonitor,
|
| 9 |
+
GoalStack,
|
| 10 |
+
GoalState,
|
| 11 |
+
ThirdOrderRuleModifier,
|
| 12 |
+
ZoneDescriptor,
|
| 13 |
+
)
|
| 14 |
+
from .phantom_bridge import PhantomKernelBridge, create_v14_controller_with_phantom_kernel
|
| 15 |
+
|
| 16 |
+
__all__ = [
|
| 17 |
+
"CandidateBinding",
|
| 18 |
+
"CognitiveController",
|
| 19 |
+
"ControllerDecision",
|
| 20 |
+
"DeterministicAttentionAllocator",
|
| 21 |
+
"ErrorMonitor",
|
| 22 |
+
"GoalStack",
|
| 23 |
+
"GoalState",
|
| 24 |
+
"ThirdOrderRuleModifier",
|
| 25 |
+
"ZoneDescriptor",
|
| 26 |
+
"PhantomKernelBridge",
|
| 27 |
+
"create_v14_controller_with_phantom_kernel",
|
| 28 |
+
]
|
shadow_x_v14_ccs/cognitive_controller.py
ADDED
|
@@ -0,0 +1,774 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import hashlib
|
| 4 |
+
import json
|
| 5 |
+
import time
|
| 6 |
+
from dataclasses import dataclass, field
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Any, Dict, Optional, Protocol, Sequence, Tuple
|
| 9 |
+
|
| 10 |
+
import numpy as np
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def _normalize(vec: np.ndarray) -> np.ndarray:
|
| 14 |
+
norm = float(np.linalg.norm(vec))
|
| 15 |
+
if norm <= 1e-12:
|
| 16 |
+
return np.zeros_like(vec, dtype=np.float32)
|
| 17 |
+
return (vec / norm).astype(np.float32)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def _cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
|
| 21 |
+
if a.shape != b.shape:
|
| 22 |
+
raise ValueError(f"Vector shape mismatch: {a.shape} != {b.shape}")
|
| 23 |
+
na = _normalize(a)
|
| 24 |
+
nb = _normalize(b)
|
| 25 |
+
return float(np.dot(na, nb))
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def _stable_hash(payload: str) -> str:
|
| 29 |
+
return hashlib.sha256(payload.encode("utf-8")).hexdigest()[:16]
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
@dataclass(frozen=True)
|
| 33 |
+
class GoalState:
|
| 34 |
+
goal_id: str
|
| 35 |
+
name: str
|
| 36 |
+
vector: np.ndarray
|
| 37 |
+
priority: int = 0
|
| 38 |
+
parent_goal_id: Optional[str] = None
|
| 39 |
+
constraints: Dict[str, float] = field(default_factory=dict)
|
| 40 |
+
created_at_ns: int = field(default_factory=time.time_ns)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@dataclass(frozen=True)
|
| 44 |
+
class ZoneDescriptor:
|
| 45 |
+
zone_id: str
|
| 46 |
+
centroid: np.ndarray
|
| 47 |
+
slab_id: Optional[int] = None
|
| 48 |
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
@dataclass(frozen=True)
|
| 52 |
+
class CandidateBinding:
|
| 53 |
+
candidate_id: str
|
| 54 |
+
vector: np.ndarray
|
| 55 |
+
resonance: float
|
| 56 |
+
zone_id: str
|
| 57 |
+
slab_id: Optional[int] = None
|
| 58 |
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
@dataclass(frozen=True)
|
| 62 |
+
class ConflictRecord:
|
| 63 |
+
left_candidate_id: str
|
| 64 |
+
right_candidate_id: str
|
| 65 |
+
opposition_score: float
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
@dataclass(frozen=True)
|
| 69 |
+
class ErrorSignal:
|
| 70 |
+
has_error: bool
|
| 71 |
+
deviation: float
|
| 72 |
+
alignment: float
|
| 73 |
+
action: str
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
@dataclass(frozen=True)
|
| 77 |
+
class ProspectionBranch:
|
| 78 |
+
seed_candidate_id: str
|
| 79 |
+
chain: Tuple[CandidateBinding, ...]
|
| 80 |
+
score: float
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
@dataclass(frozen=True)
|
| 84 |
+
class ControllerDecision:
|
| 85 |
+
goal_id: str
|
| 86 |
+
active_zone_ids: Tuple[str, ...]
|
| 87 |
+
selected_candidate_id: Optional[str]
|
| 88 |
+
inhibited_candidate_ids: Tuple[str, ...]
|
| 89 |
+
conflicts: Tuple[ConflictRecord, ...]
|
| 90 |
+
error_signal: ErrorSignal
|
| 91 |
+
correction_applied: bool
|
| 92 |
+
rule_updates: Dict[str, float]
|
| 93 |
+
output_payload: Dict[str, Any]
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
class TraceLogger:
|
| 97 |
+
def __init__(self, trace_path: Path):
|
| 98 |
+
self.trace_path = trace_path
|
| 99 |
+
self.trace_path.parent.mkdir(parents=True, exist_ok=True)
|
| 100 |
+
self.trace_path.touch(exist_ok=True)
|
| 101 |
+
|
| 102 |
+
def log(self, event: str, payload: Dict[str, Any]) -> None:
|
| 103 |
+
record = {
|
| 104 |
+
"ts_ns": time.time_ns(),
|
| 105 |
+
"event": event,
|
| 106 |
+
"payload": payload,
|
| 107 |
+
}
|
| 108 |
+
with self.trace_path.open("a", encoding="utf-8") as f:
|
| 109 |
+
f.write(json.dumps(record, sort_keys=True) + "\n")
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
class GoalStack:
|
| 113 |
+
"""
|
| 114 |
+
Persistent hierarchical goal stack.
|
| 115 |
+
Stored in goal_vector.dat for full deterministic replay.
|
| 116 |
+
"""
|
| 117 |
+
|
| 118 |
+
def __init__(self, goal_file: Path, vector_dim: int = 4096):
|
| 119 |
+
self.goal_file = goal_file
|
| 120 |
+
self.vector_dim = vector_dim
|
| 121 |
+
self._stack: list[GoalState] = []
|
| 122 |
+
self.goal_file.parent.mkdir(parents=True, exist_ok=True)
|
| 123 |
+
self._load()
|
| 124 |
+
|
| 125 |
+
def _load(self) -> None:
|
| 126 |
+
if not self.goal_file.exists():
|
| 127 |
+
return
|
| 128 |
+
with self.goal_file.open("r", encoding="utf-8") as f:
|
| 129 |
+
raw = json.load(f)
|
| 130 |
+
items = raw.get("stack", [])
|
| 131 |
+
parsed: list[GoalState] = []
|
| 132 |
+
for item in items:
|
| 133 |
+
vec = np.array(item["vector"], dtype=np.float32)
|
| 134 |
+
if vec.shape != (self.vector_dim,):
|
| 135 |
+
raise ValueError(
|
| 136 |
+
f"Invalid goal vector shape in {self.goal_file}: {vec.shape}"
|
| 137 |
+
)
|
| 138 |
+
parsed.append(
|
| 139 |
+
GoalState(
|
| 140 |
+
goal_id=item["goal_id"],
|
| 141 |
+
name=item["name"],
|
| 142 |
+
vector=_normalize(vec),
|
| 143 |
+
priority=int(item.get("priority", 0)),
|
| 144 |
+
parent_goal_id=item.get("parent_goal_id"),
|
| 145 |
+
constraints=dict(item.get("constraints", {})),
|
| 146 |
+
created_at_ns=int(item.get("created_at_ns", 0)),
|
| 147 |
+
)
|
| 148 |
+
)
|
| 149 |
+
self._stack = parsed
|
| 150 |
+
|
| 151 |
+
def _save(self) -> None:
|
| 152 |
+
serialized = {
|
| 153 |
+
"vector_dim": self.vector_dim,
|
| 154 |
+
"stack": [
|
| 155 |
+
{
|
| 156 |
+
"goal_id": g.goal_id,
|
| 157 |
+
"name": g.name,
|
| 158 |
+
"vector": g.vector.tolist(),
|
| 159 |
+
"priority": g.priority,
|
| 160 |
+
"parent_goal_id": g.parent_goal_id,
|
| 161 |
+
"constraints": g.constraints,
|
| 162 |
+
"created_at_ns": g.created_at_ns,
|
| 163 |
+
}
|
| 164 |
+
for g in self._stack
|
| 165 |
+
],
|
| 166 |
+
}
|
| 167 |
+
tmp = self.goal_file.with_suffix(".tmp")
|
| 168 |
+
with tmp.open("w", encoding="utf-8") as f:
|
| 169 |
+
json.dump(serialized, f, sort_keys=True)
|
| 170 |
+
tmp.replace(self.goal_file)
|
| 171 |
+
|
| 172 |
+
def push(
|
| 173 |
+
self,
|
| 174 |
+
name: str,
|
| 175 |
+
vector: np.ndarray,
|
| 176 |
+
priority: int = 0,
|
| 177 |
+
parent_goal_id: Optional[str] = None,
|
| 178 |
+
constraints: Optional[Dict[str, float]] = None,
|
| 179 |
+
) -> GoalState:
|
| 180 |
+
vec = np.asarray(vector, dtype=np.float32)
|
| 181 |
+
if vec.shape != (self.vector_dim,):
|
| 182 |
+
raise ValueError(f"Goal vector must be {(self.vector_dim,)}, got {vec.shape}")
|
| 183 |
+
normalized = _normalize(vec)
|
| 184 |
+
goal_id = _stable_hash(
|
| 185 |
+
f"{name}|{priority}|{parent_goal_id}|{','.join(f'{x:.6f}' for x in normalized[:16])}"
|
| 186 |
+
)
|
| 187 |
+
state = GoalState(
|
| 188 |
+
goal_id=goal_id,
|
| 189 |
+
name=name,
|
| 190 |
+
vector=normalized,
|
| 191 |
+
priority=priority,
|
| 192 |
+
parent_goal_id=parent_goal_id,
|
| 193 |
+
constraints=dict(constraints or {}),
|
| 194 |
+
created_at_ns=time.time_ns(),
|
| 195 |
+
)
|
| 196 |
+
self._stack.append(state)
|
| 197 |
+
self._save()
|
| 198 |
+
return state
|
| 199 |
+
|
| 200 |
+
def pop(self) -> Optional[GoalState]:
|
| 201 |
+
if not self._stack:
|
| 202 |
+
return None
|
| 203 |
+
state = self._stack.pop()
|
| 204 |
+
self._save()
|
| 205 |
+
return state
|
| 206 |
+
|
| 207 |
+
def current(self) -> Optional[GoalState]:
|
| 208 |
+
if not self._stack:
|
| 209 |
+
return None
|
| 210 |
+
return self._stack[-1]
|
| 211 |
+
|
| 212 |
+
def list_goals(self) -> Tuple[GoalState, ...]:
|
| 213 |
+
return tuple(self._stack)
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
class DeterministicAttentionAllocator:
|
| 217 |
+
"""
|
| 218 |
+
Selects relevant zones from out-of-core slabs using geometric alignment only.
|
| 219 |
+
"""
|
| 220 |
+
|
| 221 |
+
def __init__(
|
| 222 |
+
self,
|
| 223 |
+
activation_threshold: float = 0.12,
|
| 224 |
+
max_active_zones: int = 8,
|
| 225 |
+
rotation_shift: int = 1,
|
| 226 |
+
):
|
| 227 |
+
self.activation_threshold = activation_threshold
|
| 228 |
+
self.max_active_zones = max_active_zones
|
| 229 |
+
self.rotation_shift = rotation_shift
|
| 230 |
+
|
| 231 |
+
def _project_goal(self, goal_vector: np.ndarray) -> np.ndarray:
|
| 232 |
+
rotated = np.roll(goal_vector, self.rotation_shift)
|
| 233 |
+
return _normalize(rotated)
|
| 234 |
+
|
| 235 |
+
def allocate(
|
| 236 |
+
self, goal_vector: np.ndarray, zones: Sequence[ZoneDescriptor]
|
| 237 |
+
) -> Tuple[ZoneDescriptor, ...]:
|
| 238 |
+
projected_goal = self._project_goal(goal_vector)
|
| 239 |
+
scored: list[Tuple[float, ZoneDescriptor]] = []
|
| 240 |
+
for zone in zones:
|
| 241 |
+
score = _cosine_similarity(projected_goal, zone.centroid)
|
| 242 |
+
if score >= self.activation_threshold:
|
| 243 |
+
scored.append((score, zone))
|
| 244 |
+
|
| 245 |
+
scored.sort(key=lambda item: (-item[0], item[1].zone_id))
|
| 246 |
+
return tuple(zone for _, zone in scored[: self.max_active_zones])
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
class ConflictResolver:
|
| 250 |
+
"""
|
| 251 |
+
Deterministic inhibitory gate for contradictory candidate bindings.
|
| 252 |
+
"""
|
| 253 |
+
|
| 254 |
+
def __init__(self, opposition_threshold: float = 0.80):
|
| 255 |
+
self.opposition_threshold = opposition_threshold
|
| 256 |
+
|
| 257 |
+
def _winner(
|
| 258 |
+
self, left: CandidateBinding, right: CandidateBinding, goal_vector: np.ndarray
|
| 259 |
+
) -> CandidateBinding:
|
| 260 |
+
left_goal = _cosine_similarity(left.vector, goal_vector)
|
| 261 |
+
right_goal = _cosine_similarity(right.vector, goal_vector)
|
| 262 |
+
if left_goal > right_goal:
|
| 263 |
+
return left
|
| 264 |
+
if right_goal > left_goal:
|
| 265 |
+
return right
|
| 266 |
+
if left.resonance > right.resonance:
|
| 267 |
+
return left
|
| 268 |
+
if right.resonance > left.resonance:
|
| 269 |
+
return right
|
| 270 |
+
return left if left.candidate_id <= right.candidate_id else right
|
| 271 |
+
|
| 272 |
+
def resolve(
|
| 273 |
+
self, candidates: Sequence[CandidateBinding], goal_vector: np.ndarray
|
| 274 |
+
) -> Tuple[Tuple[CandidateBinding, ...], Tuple[str, ...], Tuple[ConflictRecord, ...]]:
|
| 275 |
+
ordered = sorted(candidates, key=lambda c: (-c.resonance, c.candidate_id))
|
| 276 |
+
selected: list[CandidateBinding] = []
|
| 277 |
+
inhibited: list[str] = []
|
| 278 |
+
conflicts: list[ConflictRecord] = []
|
| 279 |
+
|
| 280 |
+
for candidate in ordered:
|
| 281 |
+
replacement_index: Optional[int] = None
|
| 282 |
+
suppress_new = False
|
| 283 |
+
for idx, existing in enumerate(selected):
|
| 284 |
+
opposition = -_cosine_similarity(candidate.vector, existing.vector)
|
| 285 |
+
if opposition >= self.opposition_threshold:
|
| 286 |
+
conflicts.append(
|
| 287 |
+
ConflictRecord(
|
| 288 |
+
left_candidate_id=candidate.candidate_id,
|
| 289 |
+
right_candidate_id=existing.candidate_id,
|
| 290 |
+
opposition_score=opposition,
|
| 291 |
+
)
|
| 292 |
+
)
|
| 293 |
+
winner = self._winner(candidate, existing, goal_vector)
|
| 294 |
+
if winner.candidate_id == existing.candidate_id:
|
| 295 |
+
suppress_new = True
|
| 296 |
+
inhibited.append(candidate.candidate_id)
|
| 297 |
+
else:
|
| 298 |
+
replacement_index = idx
|
| 299 |
+
inhibited.append(existing.candidate_id)
|
| 300 |
+
break
|
| 301 |
+
|
| 302 |
+
if suppress_new:
|
| 303 |
+
continue
|
| 304 |
+
if replacement_index is None:
|
| 305 |
+
selected.append(candidate)
|
| 306 |
+
else:
|
| 307 |
+
selected[replacement_index] = candidate
|
| 308 |
+
|
| 309 |
+
selected.sort(key=lambda c: (-c.resonance, c.candidate_id))
|
| 310 |
+
inhibited_sorted = tuple(sorted(set(inhibited)))
|
| 311 |
+
return tuple(selected), inhibited_sorted, tuple(conflicts)
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
class ErrorMonitor:
|
| 315 |
+
"""
|
| 316 |
+
Self-monitoring gate between output candidate and active goal vector.
|
| 317 |
+
"""
|
| 318 |
+
|
| 319 |
+
def __init__(self, deviation_threshold: float = 0.28, hard_fail_threshold: float = 0.40):
|
| 320 |
+
self.deviation_threshold = deviation_threshold
|
| 321 |
+
self.hard_fail_threshold = hard_fail_threshold
|
| 322 |
+
|
| 323 |
+
def evaluate(self, output_vector: np.ndarray, goal_vector: np.ndarray) -> ErrorSignal:
|
| 324 |
+
alignment = _cosine_similarity(output_vector, goal_vector)
|
| 325 |
+
deviation = 1.0 - alignment
|
| 326 |
+
if deviation > self.hard_fail_threshold:
|
| 327 |
+
return ErrorSignal(
|
| 328 |
+
has_error=True,
|
| 329 |
+
deviation=deviation,
|
| 330 |
+
alignment=alignment,
|
| 331 |
+
action="strengthen_constraints_and_rebind",
|
| 332 |
+
)
|
| 333 |
+
if deviation > self.deviation_threshold:
|
| 334 |
+
return ErrorSignal(
|
| 335 |
+
has_error=True,
|
| 336 |
+
deviation=deviation,
|
| 337 |
+
alignment=alignment,
|
| 338 |
+
action="rebind",
|
| 339 |
+
)
|
| 340 |
+
return ErrorSignal(
|
| 341 |
+
has_error=False,
|
| 342 |
+
deviation=deviation,
|
| 343 |
+
alignment=alignment,
|
| 344 |
+
action="none",
|
| 345 |
+
)
|
| 346 |
+
|
| 347 |
+
def select_correction(
|
| 348 |
+
self, candidates: Sequence[CandidateBinding], goal_vector: np.ndarray
|
| 349 |
+
) -> Optional[CandidateBinding]:
|
| 350 |
+
if not candidates:
|
| 351 |
+
return None
|
| 352 |
+
ranked = sorted(
|
| 353 |
+
candidates,
|
| 354 |
+
key=lambda c: (
|
| 355 |
+
-_cosine_similarity(c.vector, goal_vector),
|
| 356 |
+
-c.resonance,
|
| 357 |
+
c.candidate_id,
|
| 358 |
+
),
|
| 359 |
+
)
|
| 360 |
+
return ranked[0]
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
class TaskSwitcherProspectionEngine:
|
| 364 |
+
"""
|
| 365 |
+
Deterministic 2-3 branch lookahead and task-ordered candidate selection.
|
| 366 |
+
"""
|
| 367 |
+
|
| 368 |
+
def __init__(self, max_futures: int = 3, branch_depth: int = 3):
|
| 369 |
+
self.max_futures = max_futures
|
| 370 |
+
self.branch_depth = branch_depth
|
| 371 |
+
|
| 372 |
+
def _score_branch(self, chain: Sequence[CandidateBinding], goal_vector: np.ndarray) -> float:
|
| 373 |
+
score = 0.0
|
| 374 |
+
for index, binding in enumerate(chain):
|
| 375 |
+
temporal_weight = 1.0 / (index + 1)
|
| 376 |
+
alignment = _cosine_similarity(binding.vector, goal_vector)
|
| 377 |
+
score += alignment * temporal_weight
|
| 378 |
+
score += binding.resonance * 0.05
|
| 379 |
+
|
| 380 |
+
# Penalize contradictory transitions inside the branch.
|
| 381 |
+
for i in range(len(chain)):
|
| 382 |
+
for j in range(i + 1, len(chain)):
|
| 383 |
+
opposition = -_cosine_similarity(chain[i].vector, chain[j].vector)
|
| 384 |
+
if opposition >= 0.80:
|
| 385 |
+
score -= 0.25
|
| 386 |
+
return score
|
| 387 |
+
|
| 388 |
+
def simulate(
|
| 389 |
+
self,
|
| 390 |
+
goal_vector: np.ndarray,
|
| 391 |
+
candidate_pool: Sequence[CandidateBinding],
|
| 392 |
+
build_chain_fn,
|
| 393 |
+
) -> Tuple[ProspectionBranch, ...]:
|
| 394 |
+
seeds = sorted(candidate_pool, key=lambda c: (-c.resonance, c.candidate_id))
|
| 395 |
+
seeds = seeds[: self.max_futures]
|
| 396 |
+
branches: list[ProspectionBranch] = []
|
| 397 |
+
|
| 398 |
+
for seed in seeds:
|
| 399 |
+
tail = tuple(build_chain_fn(seed, self.branch_depth))
|
| 400 |
+
if not tail:
|
| 401 |
+
chain = (seed,)
|
| 402 |
+
elif tail[0].candidate_id == seed.candidate_id:
|
| 403 |
+
chain = tail
|
| 404 |
+
else:
|
| 405 |
+
chain = (seed,) + tail
|
| 406 |
+
|
| 407 |
+
score = self._score_branch(chain, goal_vector)
|
| 408 |
+
branches.append(
|
| 409 |
+
ProspectionBranch(
|
| 410 |
+
seed_candidate_id=seed.candidate_id,
|
| 411 |
+
chain=chain,
|
| 412 |
+
score=score,
|
| 413 |
+
)
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
branches.sort(key=lambda b: (-b.score, b.seed_candidate_id))
|
| 417 |
+
return tuple(branches)
|
| 418 |
+
|
| 419 |
+
def choose_best(self, branches: Sequence[ProspectionBranch]) -> Optional[ProspectionBranch]:
|
| 420 |
+
if not branches:
|
| 421 |
+
return None
|
| 422 |
+
ordered = sorted(branches, key=lambda b: (-b.score, b.seed_candidate_id))
|
| 423 |
+
return ordered[0]
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
class ThirdOrderRuleModifier:
|
| 427 |
+
"""
|
| 428 |
+
Deterministic meta-rule adaptation based on recurrent error patterns.
|
| 429 |
+
"""
|
| 430 |
+
|
| 431 |
+
def __init__(self, error_window: int = 5):
|
| 432 |
+
self.error_window = error_window
|
| 433 |
+
self._error_history: list[ErrorSignal] = []
|
| 434 |
+
|
| 435 |
+
def register(self, error_signal: ErrorSignal) -> None:
|
| 436 |
+
self._error_history.append(error_signal)
|
| 437 |
+
if len(self._error_history) > self.error_window:
|
| 438 |
+
self._error_history = self._error_history[-self.error_window :]
|
| 439 |
+
|
| 440 |
+
def update_rules(self, current_rules: Dict[str, float]) -> Dict[str, float]:
|
| 441 |
+
if len(self._error_history) < self.error_window:
|
| 442 |
+
return {}
|
| 443 |
+
|
| 444 |
+
recent = self._error_history[-self.error_window :]
|
| 445 |
+
all_error = all(item.has_error for item in recent)
|
| 446 |
+
no_error = all(not item.has_error for item in recent)
|
| 447 |
+
avg_deviation = sum(item.deviation for item in recent) / float(len(recent))
|
| 448 |
+
|
| 449 |
+
updates: Dict[str, float] = {}
|
| 450 |
+
|
| 451 |
+
if all_error and avg_deviation >= current_rules["hard_fail_threshold"]:
|
| 452 |
+
updates["attention_activation_threshold"] = min(
|
| 453 |
+
0.95, current_rules["attention_activation_threshold"] + 0.04
|
| 454 |
+
)
|
| 455 |
+
updates["deviation_threshold"] = max(
|
| 456 |
+
0.05, current_rules["deviation_threshold"] - 0.02
|
| 457 |
+
)
|
| 458 |
+
updates["conflict_opposition_threshold"] = max(
|
| 459 |
+
0.60, current_rules["conflict_opposition_threshold"] - 0.03
|
| 460 |
+
)
|
| 461 |
+
return updates
|
| 462 |
+
|
| 463 |
+
if no_error:
|
| 464 |
+
updates["attention_activation_threshold"] = max(
|
| 465 |
+
0.05, current_rules["attention_activation_threshold"] - 0.02
|
| 466 |
+
)
|
| 467 |
+
return updates
|
| 468 |
+
|
| 469 |
+
return updates
|
| 470 |
+
|
| 471 |
+
|
| 472 |
+
class KernelBridge(Protocol):
|
| 473 |
+
"""
|
| 474 |
+
Bridge to the existing Phantom Kernel.
|
| 475 |
+
Keep the kernel unchanged and call it only from controller decisions.
|
| 476 |
+
"""
|
| 477 |
+
|
| 478 |
+
def list_zones(self) -> Sequence[ZoneDescriptor]:
|
| 479 |
+
...
|
| 480 |
+
|
| 481 |
+
def query_candidates(
|
| 482 |
+
self, goal: GoalState, active_zones: Sequence[ZoneDescriptor]
|
| 483 |
+
) -> Sequence[CandidateBinding]:
|
| 484 |
+
...
|
| 485 |
+
|
| 486 |
+
def build_future_chain(
|
| 487 |
+
self, seed: CandidateBinding, depth: int, goal: GoalState
|
| 488 |
+
) -> Sequence[CandidateBinding]:
|
| 489 |
+
...
|
| 490 |
+
|
| 491 |
+
def materialize_output(
|
| 492 |
+
self, branch: Optional[ProspectionBranch], goal: GoalState
|
| 493 |
+
) -> Dict[str, Any]:
|
| 494 |
+
...
|
| 495 |
+
|
| 496 |
+
def strengthen_constraints(self, goal: GoalState, candidate: CandidateBinding) -> None:
|
| 497 |
+
...
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
class InMemoryKernelBridge:
|
| 501 |
+
"""
|
| 502 |
+
Minimal deterministic bridge useful for local testing without touching PhantomKernel.
|
| 503 |
+
"""
|
| 504 |
+
|
| 505 |
+
def __init__(
|
| 506 |
+
self,
|
| 507 |
+
zones: Sequence[ZoneDescriptor],
|
| 508 |
+
zone_candidates: Dict[str, Sequence[CandidateBinding]],
|
| 509 |
+
):
|
| 510 |
+
self._zones = tuple(zones)
|
| 511 |
+
self._zone_candidates = {
|
| 512 |
+
key: tuple(value) for key, value in sorted(zone_candidates.items())
|
| 513 |
+
}
|
| 514 |
+
|
| 515 |
+
def list_zones(self) -> Sequence[ZoneDescriptor]:
|
| 516 |
+
return self._zones
|
| 517 |
+
|
| 518 |
+
def query_candidates(
|
| 519 |
+
self, goal: GoalState, active_zones: Sequence[ZoneDescriptor]
|
| 520 |
+
) -> Sequence[CandidateBinding]:
|
| 521 |
+
candidates: list[CandidateBinding] = []
|
| 522 |
+
for zone in active_zones:
|
| 523 |
+
candidates.extend(self._zone_candidates.get(zone.zone_id, ()))
|
| 524 |
+
return tuple(
|
| 525 |
+
sorted(candidates, key=lambda c: (-c.resonance, c.candidate_id))
|
| 526 |
+
)
|
| 527 |
+
|
| 528 |
+
def build_future_chain(
|
| 529 |
+
self, seed: CandidateBinding, depth: int, goal: GoalState
|
| 530 |
+
) -> Sequence[CandidateBinding]:
|
| 531 |
+
# Deterministic static chain: keep the same seed for projection depth.
|
| 532 |
+
return tuple(seed for _ in range(max(1, depth)))
|
| 533 |
+
|
| 534 |
+
def materialize_output(
|
| 535 |
+
self, branch: Optional[ProspectionBranch], goal: GoalState
|
| 536 |
+
) -> Dict[str, Any]:
|
| 537 |
+
if branch is None:
|
| 538 |
+
return {
|
| 539 |
+
"status": "NO_CANDIDATE",
|
| 540 |
+
"goal_id": goal.goal_id,
|
| 541 |
+
}
|
| 542 |
+
return {
|
| 543 |
+
"status": "OK",
|
| 544 |
+
"goal_id": goal.goal_id,
|
| 545 |
+
"selected_candidate_id": branch.seed_candidate_id,
|
| 546 |
+
"branch_score": branch.score,
|
| 547 |
+
}
|
| 548 |
+
|
| 549 |
+
def strengthen_constraints(self, goal: GoalState, candidate: CandidateBinding) -> None:
|
| 550 |
+
# Skeleton adapter keeps this as no-op by design.
|
| 551 |
+
_ = (goal, candidate)
|
| 552 |
+
|
| 553 |
+
|
| 554 |
+
class CognitiveController:
|
| 555 |
+
"""
|
| 556 |
+
Shadow-X v14 Deterministic Cognitive Controller (CCS-v2).
|
| 557 |
+
"""
|
| 558 |
+
|
| 559 |
+
def __init__(
|
| 560 |
+
self,
|
| 561 |
+
kernel_bridge: KernelBridge,
|
| 562 |
+
state_dir: Path | str = Path("shadow_x_v14_ccs/state"),
|
| 563 |
+
vector_dim: int = 4096,
|
| 564 |
+
):
|
| 565 |
+
self.kernel_bridge = kernel_bridge
|
| 566 |
+
self.state_dir = Path(state_dir)
|
| 567 |
+
self.state_dir.mkdir(parents=True, exist_ok=True)
|
| 568 |
+
self.goal_stack = GoalStack(self.state_dir / "goal_vector.dat", vector_dim=vector_dim)
|
| 569 |
+
self.trace_logger = TraceLogger(self.state_dir / "trace_log.jsonl")
|
| 570 |
+
self.attention = DeterministicAttentionAllocator()
|
| 571 |
+
self.conflict_resolver = ConflictResolver()
|
| 572 |
+
self.error_monitor = ErrorMonitor()
|
| 573 |
+
self.task_switcher = TaskSwitcherProspectionEngine(max_futures=3, branch_depth=3)
|
| 574 |
+
self.rule_modifier = ThirdOrderRuleModifier(error_window=5)
|
| 575 |
+
|
| 576 |
+
self.rules: Dict[str, float] = {
|
| 577 |
+
"attention_activation_threshold": 0.12,
|
| 578 |
+
"deviation_threshold": 0.28,
|
| 579 |
+
"hard_fail_threshold": 0.40,
|
| 580 |
+
"conflict_opposition_threshold": 0.80,
|
| 581 |
+
}
|
| 582 |
+
|
| 583 |
+
def push_goal(
|
| 584 |
+
self,
|
| 585 |
+
name: str,
|
| 586 |
+
vector: np.ndarray,
|
| 587 |
+
priority: int = 0,
|
| 588 |
+
parent_goal_id: Optional[str] = None,
|
| 589 |
+
constraints: Optional[Dict[str, float]] = None,
|
| 590 |
+
) -> GoalState:
|
| 591 |
+
goal = self.goal_stack.push(
|
| 592 |
+
name=name,
|
| 593 |
+
vector=vector,
|
| 594 |
+
priority=priority,
|
| 595 |
+
parent_goal_id=parent_goal_id,
|
| 596 |
+
constraints=constraints,
|
| 597 |
+
)
|
| 598 |
+
self.trace_logger.log(
|
| 599 |
+
"goal_push",
|
| 600 |
+
{
|
| 601 |
+
"goal_id": goal.goal_id,
|
| 602 |
+
"name": goal.name,
|
| 603 |
+
"priority": goal.priority,
|
| 604 |
+
"parent_goal_id": goal.parent_goal_id,
|
| 605 |
+
},
|
| 606 |
+
)
|
| 607 |
+
return goal
|
| 608 |
+
|
| 609 |
+
def pop_goal(self) -> Optional[GoalState]:
|
| 610 |
+
goal = self.goal_stack.pop()
|
| 611 |
+
if goal is not None:
|
| 612 |
+
self.trace_logger.log(
|
| 613 |
+
"goal_pop",
|
| 614 |
+
{
|
| 615 |
+
"goal_id": goal.goal_id,
|
| 616 |
+
"name": goal.name,
|
| 617 |
+
},
|
| 618 |
+
)
|
| 619 |
+
return goal
|
| 620 |
+
|
| 621 |
+
def _sync_rules(self) -> None:
|
| 622 |
+
self.attention.activation_threshold = self.rules["attention_activation_threshold"]
|
| 623 |
+
self.error_monitor.deviation_threshold = self.rules["deviation_threshold"]
|
| 624 |
+
self.error_monitor.hard_fail_threshold = self.rules["hard_fail_threshold"]
|
| 625 |
+
self.conflict_resolver.opposition_threshold = self.rules[
|
| 626 |
+
"conflict_opposition_threshold"
|
| 627 |
+
]
|
| 628 |
+
|
| 629 |
+
def run_cycle(self) -> ControllerDecision:
|
| 630 |
+
goal = self.goal_stack.current()
|
| 631 |
+
if goal is None:
|
| 632 |
+
raise RuntimeError("No active goal in GoalStack. Push a goal before run_cycle().")
|
| 633 |
+
|
| 634 |
+
self._sync_rules()
|
| 635 |
+
zones = self.kernel_bridge.list_zones()
|
| 636 |
+
active_zones = self.attention.allocate(goal.vector, zones)
|
| 637 |
+
|
| 638 |
+
candidates = self.kernel_bridge.query_candidates(goal, active_zones)
|
| 639 |
+
selected, inhibited_ids, conflicts = self.conflict_resolver.resolve(
|
| 640 |
+
candidates, goal.vector
|
| 641 |
+
)
|
| 642 |
+
|
| 643 |
+
branches = self.task_switcher.simulate(
|
| 644 |
+
goal.vector,
|
| 645 |
+
selected,
|
| 646 |
+
lambda seed, depth: self.kernel_bridge.build_future_chain(seed, depth, goal),
|
| 647 |
+
)
|
| 648 |
+
best_branch = self.task_switcher.choose_best(branches)
|
| 649 |
+
|
| 650 |
+
correction_applied = False
|
| 651 |
+
if best_branch is None:
|
| 652 |
+
output_vector = np.zeros_like(goal.vector, dtype=np.float32)
|
| 653 |
+
else:
|
| 654 |
+
output_vector = best_branch.chain[-1].vector
|
| 655 |
+
|
| 656 |
+
error_signal = self.error_monitor.evaluate(output_vector, goal.vector)
|
| 657 |
+
if error_signal.has_error and selected:
|
| 658 |
+
correction = self.error_monitor.select_correction(selected, goal.vector)
|
| 659 |
+
if correction is not None and (
|
| 660 |
+
best_branch is None or correction.candidate_id != best_branch.seed_candidate_id
|
| 661 |
+
):
|
| 662 |
+
correction_applied = True
|
| 663 |
+
best_branch = ProspectionBranch(
|
| 664 |
+
seed_candidate_id=correction.candidate_id,
|
| 665 |
+
chain=(correction,),
|
| 666 |
+
score=_cosine_similarity(correction.vector, goal.vector),
|
| 667 |
+
)
|
| 668 |
+
output_vector = correction.vector
|
| 669 |
+
error_signal = self.error_monitor.evaluate(output_vector, goal.vector)
|
| 670 |
+
self.kernel_bridge.strengthen_constraints(goal, correction)
|
| 671 |
+
|
| 672 |
+
self.rule_modifier.register(error_signal)
|
| 673 |
+
rule_updates = self.rule_modifier.update_rules(self.rules)
|
| 674 |
+
self.rules.update(rule_updates)
|
| 675 |
+
|
| 676 |
+
output_payload = self.kernel_bridge.materialize_output(best_branch, goal)
|
| 677 |
+
|
| 678 |
+
decision = ControllerDecision(
|
| 679 |
+
goal_id=goal.goal_id,
|
| 680 |
+
active_zone_ids=tuple(zone.zone_id for zone in active_zones),
|
| 681 |
+
selected_candidate_id=best_branch.seed_candidate_id if best_branch else None,
|
| 682 |
+
inhibited_candidate_ids=inhibited_ids,
|
| 683 |
+
conflicts=conflicts,
|
| 684 |
+
error_signal=error_signal,
|
| 685 |
+
correction_applied=correction_applied,
|
| 686 |
+
rule_updates=rule_updates,
|
| 687 |
+
output_payload=output_payload,
|
| 688 |
+
)
|
| 689 |
+
|
| 690 |
+
self.trace_logger.log(
|
| 691 |
+
"cycle",
|
| 692 |
+
{
|
| 693 |
+
"goal_id": decision.goal_id,
|
| 694 |
+
"active_zone_ids": list(decision.active_zone_ids),
|
| 695 |
+
"selected_candidate_id": decision.selected_candidate_id,
|
| 696 |
+
"inhibited_candidate_ids": list(decision.inhibited_candidate_ids),
|
| 697 |
+
"conflicts": [
|
| 698 |
+
{
|
| 699 |
+
"left": c.left_candidate_id,
|
| 700 |
+
"right": c.right_candidate_id,
|
| 701 |
+
"opposition_score": c.opposition_score,
|
| 702 |
+
}
|
| 703 |
+
for c in decision.conflicts
|
| 704 |
+
],
|
| 705 |
+
"error": {
|
| 706 |
+
"has_error": decision.error_signal.has_error,
|
| 707 |
+
"deviation": decision.error_signal.deviation,
|
| 708 |
+
"alignment": decision.error_signal.alignment,
|
| 709 |
+
"action": decision.error_signal.action,
|
| 710 |
+
},
|
| 711 |
+
"correction_applied": decision.correction_applied,
|
| 712 |
+
"rule_updates": decision.rule_updates,
|
| 713 |
+
"output_payload": decision.output_payload,
|
| 714 |
+
},
|
| 715 |
+
)
|
| 716 |
+
return decision
|
| 717 |
+
|
| 718 |
+
|
| 719 |
+
def _demo_vector(seed: int, dim: int = 4096) -> np.ndarray:
|
| 720 |
+
base = np.arange(dim, dtype=np.float32)
|
| 721 |
+
vec = np.cos(base * 0.001 + seed)
|
| 722 |
+
return _normalize(vec.astype(np.float32))
|
| 723 |
+
|
| 724 |
+
|
| 725 |
+
if __name__ == "__main__":
|
| 726 |
+
# Small deterministic demo for local validation.
|
| 727 |
+
zone_a = ZoneDescriptor(zone_id="Z0", centroid=_demo_vector(1), slab_id=0)
|
| 728 |
+
zone_b = ZoneDescriptor(zone_id="Z1", centroid=_demo_vector(2), slab_id=1)
|
| 729 |
+
zone_c = ZoneDescriptor(zone_id="Z2", centroid=_demo_vector(3), slab_id=2)
|
| 730 |
+
|
| 731 |
+
cand_a = CandidateBinding(
|
| 732 |
+
candidate_id="C0",
|
| 733 |
+
vector=_demo_vector(11),
|
| 734 |
+
resonance=0.93,
|
| 735 |
+
zone_id="Z0",
|
| 736 |
+
slab_id=0,
|
| 737 |
+
)
|
| 738 |
+
cand_b = CandidateBinding(
|
| 739 |
+
candidate_id="C1",
|
| 740 |
+
vector=-_demo_vector(11),
|
| 741 |
+
resonance=0.91,
|
| 742 |
+
zone_id="Z0",
|
| 743 |
+
slab_id=0,
|
| 744 |
+
)
|
| 745 |
+
cand_c = CandidateBinding(
|
| 746 |
+
candidate_id="C2",
|
| 747 |
+
vector=_demo_vector(12),
|
| 748 |
+
resonance=0.90,
|
| 749 |
+
zone_id="Z1",
|
| 750 |
+
slab_id=1,
|
| 751 |
+
)
|
| 752 |
+
|
| 753 |
+
bridge = InMemoryKernelBridge(
|
| 754 |
+
zones=(zone_a, zone_b, zone_c),
|
| 755 |
+
zone_candidates={
|
| 756 |
+
"Z0": (cand_a, cand_b),
|
| 757 |
+
"Z1": (cand_c,),
|
| 758 |
+
},
|
| 759 |
+
)
|
| 760 |
+
|
| 761 |
+
controller = CognitiveController(bridge, state_dir=Path("shadow_x_v14_ccs/state_demo"))
|
| 762 |
+
goal = controller.push_goal("verify_consistency_A_equals_B", _demo_vector(21), priority=10)
|
| 763 |
+
result = controller.run_cycle()
|
| 764 |
+
print(
|
| 765 |
+
json.dumps(
|
| 766 |
+
{
|
| 767 |
+
"goal_id": goal.goal_id,
|
| 768 |
+
"selected_candidate_id": result.selected_candidate_id,
|
| 769 |
+
"error_deviation": result.error_signal.deviation,
|
| 770 |
+
"rule_updates": result.rule_updates,
|
| 771 |
+
},
|
| 772 |
+
sort_keys=True,
|
| 773 |
+
)
|
| 774 |
+
)
|
shadow_x_v14_ccs/demo_cli.py
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import hashlib
|
| 5 |
+
import json
|
| 6 |
+
import math
|
| 7 |
+
import shutil
|
| 8 |
+
import sys
|
| 9 |
+
from dataclasses import dataclass
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
from typing import Any, Dict, Optional, Sequence
|
| 12 |
+
|
| 13 |
+
import numpy as np
|
| 14 |
+
|
| 15 |
+
if __package__ in (None, ""):
|
| 16 |
+
project_root = Path(__file__).resolve().parent.parent
|
| 17 |
+
if str(project_root) not in sys.path:
|
| 18 |
+
sys.path.insert(0, str(project_root))
|
| 19 |
+
from shadow_x_v14_ccs.cognitive_controller import ( # type: ignore
|
| 20 |
+
CandidateBinding,
|
| 21 |
+
CognitiveController,
|
| 22 |
+
GoalState,
|
| 23 |
+
KernelBridge,
|
| 24 |
+
ProspectionBranch,
|
| 25 |
+
ZoneDescriptor,
|
| 26 |
+
)
|
| 27 |
+
else:
|
| 28 |
+
from .cognitive_controller import (
|
| 29 |
+
CandidateBinding,
|
| 30 |
+
CognitiveController,
|
| 31 |
+
GoalState,
|
| 32 |
+
KernelBridge,
|
| 33 |
+
ProspectionBranch,
|
| 34 |
+
ZoneDescriptor,
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def _normalize(vec: np.ndarray) -> np.ndarray:
|
| 39 |
+
norm = float(np.linalg.norm(vec))
|
| 40 |
+
if norm <= 1e-12:
|
| 41 |
+
return np.zeros_like(vec, dtype=np.float32)
|
| 42 |
+
return (vec / norm).astype(np.float32)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def text_to_vector(text: str, dim: int) -> np.ndarray:
|
| 46 |
+
digest = hashlib.sha256(text.encode("utf-8")).digest()
|
| 47 |
+
seed = int.from_bytes(digest[:8], byteorder="big", signed=False)
|
| 48 |
+
rng = np.random.default_rng(seed)
|
| 49 |
+
vec = rng.standard_normal(dim).astype(np.float32)
|
| 50 |
+
return _normalize(vec)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def vector_with_alignment(goal: np.ndarray, alignment: float, key: str) -> np.ndarray:
|
| 54 |
+
if alignment < -1.0 or alignment > 1.0:
|
| 55 |
+
raise ValueError("alignment must be in [-1, 1]")
|
| 56 |
+
base = text_to_vector(key, goal.shape[0])
|
| 57 |
+
orth = base - float(np.dot(base, goal)) * goal
|
| 58 |
+
orth = _normalize(orth)
|
| 59 |
+
scale = math.sqrt(max(0.0, 1.0 - alignment * alignment))
|
| 60 |
+
vec = (alignment * goal) + (scale * orth)
|
| 61 |
+
return _normalize(vec.astype(np.float32))
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
@dataclass(frozen=True)
|
| 65 |
+
class OneShotFact:
|
| 66 |
+
fact_id: str
|
| 67 |
+
subject: str
|
| 68 |
+
relation: str
|
| 69 |
+
obj: str
|
| 70 |
+
slab_id: int
|
| 71 |
+
vertex_id: int
|
| 72 |
+
vector: np.ndarray
|
| 73 |
+
base_resonance: float
|
| 74 |
+
|
| 75 |
+
def text(self) -> str:
|
| 76 |
+
return f"{self.subject} {self.relation} {self.obj}"
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
class OneShotDemoBridge(KernelBridge):
|
| 80 |
+
def __init__(self, vector_dim: int = 4096):
|
| 81 |
+
self.vector_dim = vector_dim
|
| 82 |
+
self._facts: list[OneShotFact] = []
|
| 83 |
+
self._constraint_strength: dict[tuple[str, str], int] = {}
|
| 84 |
+
|
| 85 |
+
def teach(self, fact: OneShotFact) -> None:
|
| 86 |
+
self._facts.append(fact)
|
| 87 |
+
|
| 88 |
+
def list_facts(self) -> Sequence[OneShotFact]:
|
| 89 |
+
return tuple(self._facts)
|
| 90 |
+
|
| 91 |
+
def list_zones(self) -> Sequence[ZoneDescriptor]:
|
| 92 |
+
by_slab: dict[int, list[OneShotFact]] = {}
|
| 93 |
+
for fact in self._facts:
|
| 94 |
+
by_slab.setdefault(fact.slab_id, []).append(fact)
|
| 95 |
+
|
| 96 |
+
zones: list[ZoneDescriptor] = []
|
| 97 |
+
for slab_id in sorted(by_slab.keys()):
|
| 98 |
+
facts = sorted(by_slab[slab_id], key=lambda f: f.vertex_id)
|
| 99 |
+
centroid = _normalize(np.mean(np.stack([f.vector for f in facts], axis=0), axis=0))
|
| 100 |
+
zones.append(
|
| 101 |
+
ZoneDescriptor(
|
| 102 |
+
zone_id=f"slab:{slab_id}",
|
| 103 |
+
centroid=centroid,
|
| 104 |
+
slab_id=slab_id,
|
| 105 |
+
metadata={"fact_count": len(facts)},
|
| 106 |
+
)
|
| 107 |
+
)
|
| 108 |
+
return tuple(zones)
|
| 109 |
+
|
| 110 |
+
def query_candidates(
|
| 111 |
+
self, goal: GoalState, active_zones: Sequence[ZoneDescriptor]
|
| 112 |
+
) -> Sequence[CandidateBinding]:
|
| 113 |
+
active_ids = {zone.zone_id for zone in active_zones}
|
| 114 |
+
candidates: list[CandidateBinding] = []
|
| 115 |
+
for fact in self._facts:
|
| 116 |
+
zone_id = f"slab:{fact.slab_id}"
|
| 117 |
+
if zone_id not in active_ids:
|
| 118 |
+
continue
|
| 119 |
+
alignment = float(np.dot(_normalize(goal.vector), fact.vector))
|
| 120 |
+
boost = self._constraint_strength.get((goal.goal_id, fact.fact_id), 0) * 0.01
|
| 121 |
+
resonance = max(-1.0, min(1.0, fact.base_resonance + boost))
|
| 122 |
+
candidates.append(
|
| 123 |
+
CandidateBinding(
|
| 124 |
+
candidate_id=f"fact:{fact.fact_id}",
|
| 125 |
+
vector=fact.vector,
|
| 126 |
+
resonance=resonance,
|
| 127 |
+
zone_id=zone_id,
|
| 128 |
+
slab_id=fact.slab_id,
|
| 129 |
+
metadata={
|
| 130 |
+
"fact_id": fact.fact_id,
|
| 131 |
+
"subject": fact.subject,
|
| 132 |
+
"relation": fact.relation,
|
| 133 |
+
"object": fact.obj,
|
| 134 |
+
"fact_text": fact.text(),
|
| 135 |
+
"slab_id": fact.slab_id,
|
| 136 |
+
"vertex_id": fact.vertex_id,
|
| 137 |
+
"alignment": alignment,
|
| 138 |
+
},
|
| 139 |
+
)
|
| 140 |
+
)
|
| 141 |
+
candidates.sort(key=lambda c: (-c.resonance, c.candidate_id))
|
| 142 |
+
return tuple(candidates)
|
| 143 |
+
|
| 144 |
+
def build_future_chain(
|
| 145 |
+
self, seed: CandidateBinding, depth: int, goal: GoalState
|
| 146 |
+
) -> Sequence[CandidateBinding]:
|
| 147 |
+
if depth <= 0:
|
| 148 |
+
return ()
|
| 149 |
+
return tuple(seed for _ in range(depth))
|
| 150 |
+
|
| 151 |
+
def materialize_output(
|
| 152 |
+
self, branch: Optional[ProspectionBranch], goal: GoalState
|
| 153 |
+
) -> Dict[str, Any]:
|
| 154 |
+
if branch is None or not branch.chain:
|
| 155 |
+
return {"status": "NO_CANDIDATE", "goal_id": goal.goal_id}
|
| 156 |
+
|
| 157 |
+
terminal = branch.chain[-1]
|
| 158 |
+
chain_trace: list[Dict[str, Any]] = []
|
| 159 |
+
for step in branch.chain:
|
| 160 |
+
chain_trace.append(
|
| 161 |
+
{
|
| 162 |
+
"candidate_id": step.candidate_id,
|
| 163 |
+
"fact": step.metadata.get("fact_text"),
|
| 164 |
+
"slab_id": step.metadata.get("slab_id"),
|
| 165 |
+
"vertex_id": step.metadata.get("vertex_id"),
|
| 166 |
+
"resonance": step.resonance,
|
| 167 |
+
"alignment": step.metadata.get("alignment"),
|
| 168 |
+
}
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
return {
|
| 172 |
+
"status": "OK",
|
| 173 |
+
"goal_id": goal.goal_id,
|
| 174 |
+
"selected_candidate_id": branch.seed_candidate_id,
|
| 175 |
+
"branch_score": branch.score,
|
| 176 |
+
"answer": terminal.metadata.get("fact_text", "UNKNOWN"),
|
| 177 |
+
"chain_trace": chain_trace,
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
def strengthen_constraints(self, goal: GoalState, candidate: CandidateBinding) -> None:
|
| 181 |
+
fact_id = candidate.metadata.get("fact_id")
|
| 182 |
+
if not fact_id:
|
| 183 |
+
return
|
| 184 |
+
key = (goal.goal_id, str(fact_id))
|
| 185 |
+
self._constraint_strength[key] = self._constraint_strength.get(key, 0) + 1
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def build_demo_bridge(vector_dim: int = 4096) -> tuple[OneShotDemoBridge, np.ndarray, np.ndarray]:
|
| 189 |
+
bridge = OneShotDemoBridge(vector_dim=vector_dim)
|
| 190 |
+
|
| 191 |
+
goal_general = text_to_vector("goal:shadowx:deterministic-control", vector_dim)
|
| 192 |
+
goal_capital = text_to_vector("goal:paris-capital-france", vector_dim)
|
| 193 |
+
|
| 194 |
+
facts = [
|
| 195 |
+
OneShotFact(
|
| 196 |
+
fact_id="f0",
|
| 197 |
+
subject="shadow-x",
|
| 198 |
+
relation="uses",
|
| 199 |
+
obj="deterministic_control",
|
| 200 |
+
slab_id=0,
|
| 201 |
+
vertex_id=10,
|
| 202 |
+
vector=vector_with_alignment(goal_general, 0.92, "f0"),
|
| 203 |
+
base_resonance=0.86,
|
| 204 |
+
),
|
| 205 |
+
OneShotFact(
|
| 206 |
+
fact_id="f1",
|
| 207 |
+
subject="earth",
|
| 208 |
+
relation="orbits",
|
| 209 |
+
obj="sun",
|
| 210 |
+
slab_id=1,
|
| 211 |
+
vertex_id=20,
|
| 212 |
+
vector=text_to_vector("earth-orbits-sun", vector_dim),
|
| 213 |
+
base_resonance=0.42,
|
| 214 |
+
),
|
| 215 |
+
OneShotFact(
|
| 216 |
+
fact_id="f2",
|
| 217 |
+
subject="python",
|
| 218 |
+
relation="supports",
|
| 219 |
+
obj="type_hints",
|
| 220 |
+
slab_id=2,
|
| 221 |
+
vertex_id=30,
|
| 222 |
+
vector=text_to_vector("python-type-hints", vector_dim),
|
| 223 |
+
base_resonance=0.38,
|
| 224 |
+
),
|
| 225 |
+
# Wrong but high resonance: used to trigger self-correction.
|
| 226 |
+
OneShotFact(
|
| 227 |
+
fact_id="f3",
|
| 228 |
+
subject="paris",
|
| 229 |
+
relation="is_capital_of",
|
| 230 |
+
obj="germany",
|
| 231 |
+
slab_id=3,
|
| 232 |
+
vertex_id=41,
|
| 233 |
+
vector=vector_with_alignment(goal_capital, 0.24, "f3_wrong"),
|
| 234 |
+
base_resonance=0.99,
|
| 235 |
+
),
|
| 236 |
+
# Correct but lower resonance: correction should switch to this.
|
| 237 |
+
OneShotFact(
|
| 238 |
+
fact_id="f4",
|
| 239 |
+
subject="paris",
|
| 240 |
+
relation="is_capital_of",
|
| 241 |
+
obj="france",
|
| 242 |
+
slab_id=3,
|
| 243 |
+
vertex_id=42,
|
| 244 |
+
vector=vector_with_alignment(goal_capital, 0.28, "f4_correct"),
|
| 245 |
+
base_resonance=0.05,
|
| 246 |
+
),
|
| 247 |
+
]
|
| 248 |
+
|
| 249 |
+
for fact in facts:
|
| 250 |
+
bridge.teach(fact)
|
| 251 |
+
|
| 252 |
+
return bridge, goal_general, goal_capital
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
def load_cycle_events(trace_file: Path) -> list[dict]:
|
| 256 |
+
if not trace_file.exists():
|
| 257 |
+
return []
|
| 258 |
+
events: list[dict] = []
|
| 259 |
+
with trace_file.open("r", encoding="utf-8") as f:
|
| 260 |
+
for raw in f:
|
| 261 |
+
raw = raw.strip()
|
| 262 |
+
if not raw:
|
| 263 |
+
continue
|
| 264 |
+
record = json.loads(raw)
|
| 265 |
+
if record.get("event") == "cycle":
|
| 266 |
+
events.append(record)
|
| 267 |
+
return events
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
def run_demo(
|
| 271 |
+
state_dir: Path,
|
| 272 |
+
vector_dim: int = 4096,
|
| 273 |
+
reset_state: bool = True,
|
| 274 |
+
) -> Dict[str, Any]:
|
| 275 |
+
if reset_state and state_dir.exists():
|
| 276 |
+
shutil.rmtree(state_dir)
|
| 277 |
+
state_dir.mkdir(parents=True, exist_ok=True)
|
| 278 |
+
|
| 279 |
+
bridge, goal_general, goal_capital = build_demo_bridge(vector_dim=vector_dim)
|
| 280 |
+
controller = CognitiveController(bridge, state_dir=state_dir, vector_dim=vector_dim)
|
| 281 |
+
|
| 282 |
+
# Keep all slabs visible in the demo.
|
| 283 |
+
controller.rules["attention_activation_threshold"] = -1.0
|
| 284 |
+
|
| 285 |
+
taught_facts = [fact.text() for fact in bridge.list_facts()]
|
| 286 |
+
|
| 287 |
+
# Scenario A: direct deterministic retrieval.
|
| 288 |
+
controller.push_goal("query_general_control", goal_general, priority=5)
|
| 289 |
+
decision_general = controller.run_cycle()
|
| 290 |
+
controller.pop_goal()
|
| 291 |
+
|
| 292 |
+
# Scenario B: self-correction over wrong high-resonance input.
|
| 293 |
+
controller.push_goal("query_capital_paris_france", goal_capital, priority=10)
|
| 294 |
+
decision_correction = controller.run_cycle()
|
| 295 |
+
|
| 296 |
+
trace_events = load_cycle_events(state_dir / "trace_log.jsonl")
|
| 297 |
+
last_cycle = trace_events[-1] if trace_events else {}
|
| 298 |
+
chain_trace = (
|
| 299 |
+
last_cycle.get("payload", {})
|
| 300 |
+
.get("output_payload", {})
|
| 301 |
+
.get("chain_trace", [])
|
| 302 |
+
)
|
| 303 |
+
|
| 304 |
+
summary = {
|
| 305 |
+
"taught_facts": taught_facts,
|
| 306 |
+
"general_answer": decision_general.output_payload.get("answer"),
|
| 307 |
+
"general_selected": decision_general.selected_candidate_id,
|
| 308 |
+
"correction_answer": decision_correction.output_payload.get("answer"),
|
| 309 |
+
"correction_selected": decision_correction.selected_candidate_id,
|
| 310 |
+
"correction_applied": decision_correction.correction_applied,
|
| 311 |
+
"correction_error_action": decision_correction.error_signal.action,
|
| 312 |
+
"trace_cycle_count": len(trace_events),
|
| 313 |
+
"trace_chain": chain_trace,
|
| 314 |
+
"trace_file": str((state_dir / "trace_log.jsonl").resolve()),
|
| 315 |
+
}
|
| 316 |
+
return summary
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
def main() -> None:
|
| 320 |
+
parser = argparse.ArgumentParser(
|
| 321 |
+
description="Shadow-X v14 public mini-demo CLI (one-shot + goal + trace + self-correction)."
|
| 322 |
+
)
|
| 323 |
+
parser.add_argument(
|
| 324 |
+
"--state-dir",
|
| 325 |
+
type=Path,
|
| 326 |
+
default=Path("shadow_x_v14_ccs/state_public_demo"),
|
| 327 |
+
help="State directory for goal stack and trace log.",
|
| 328 |
+
)
|
| 329 |
+
parser.add_argument(
|
| 330 |
+
"--vector-dim",
|
| 331 |
+
type=int,
|
| 332 |
+
default=4096,
|
| 333 |
+
help="Vector dimensionality for the demo.",
|
| 334 |
+
)
|
| 335 |
+
parser.add_argument(
|
| 336 |
+
"--no-reset",
|
| 337 |
+
action="store_true",
|
| 338 |
+
help="Do not reset existing state directory before the run.",
|
| 339 |
+
)
|
| 340 |
+
args = parser.parse_args()
|
| 341 |
+
|
| 342 |
+
summary = run_demo(
|
| 343 |
+
state_dir=args.state_dir,
|
| 344 |
+
vector_dim=args.vector_dim,
|
| 345 |
+
reset_state=not args.no_reset,
|
| 346 |
+
)
|
| 347 |
+
|
| 348 |
+
print("\n=== SHADOW-X v14 MINI DEMO ===")
|
| 349 |
+
print("One-shot taught facts:")
|
| 350 |
+
for idx, fact in enumerate(summary["taught_facts"], start=1):
|
| 351 |
+
print(f" {idx}. {fact}")
|
| 352 |
+
|
| 353 |
+
print("\nScenario A - Goal query:")
|
| 354 |
+
print(f" Selected: {summary['general_selected']}")
|
| 355 |
+
print(f" Answer: {summary['general_answer']}")
|
| 356 |
+
|
| 357 |
+
print("\nScenario B - Self-correction:")
|
| 358 |
+
print(f" Selected after cycle: {summary['correction_selected']}")
|
| 359 |
+
print(f" Answer after cycle: {summary['correction_answer']}")
|
| 360 |
+
print(f" Correction applied: {summary['correction_applied']}")
|
| 361 |
+
print(f" Error action: {summary['correction_error_action']}")
|
| 362 |
+
|
| 363 |
+
print("\nTrace (latest cycle chain, slab/vertex/resonance):")
|
| 364 |
+
chain = summary["trace_chain"]
|
| 365 |
+
if not chain:
|
| 366 |
+
print(" (empty)")
|
| 367 |
+
else:
|
| 368 |
+
for step in chain:
|
| 369 |
+
print(
|
| 370 |
+
" "
|
| 371 |
+
f"{step['candidate_id']} | "
|
| 372 |
+
f"slab={step['slab_id']} vertex={step['vertex_id']} "
|
| 373 |
+
f"res={step['resonance']:.4f} align={float(step['alignment']):.4f} | "
|
| 374 |
+
f"{step['fact']}"
|
| 375 |
+
)
|
| 376 |
+
|
| 377 |
+
print(f"\nTrace file: {summary['trace_file']}")
|
| 378 |
+
print(f"Trace cycle events: {summary['trace_cycle_count']}")
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
if __name__ == "__main__":
|
| 382 |
+
main()
|
shadow_x_v14_ccs/phantom_bridge.py
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from collections import defaultdict
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from typing import Any, Dict, Optional, Sequence, Tuple
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
from .cognitive_controller import (
|
| 10 |
+
CandidateBinding,
|
| 11 |
+
CognitiveController,
|
| 12 |
+
GoalState,
|
| 13 |
+
KernelBridge,
|
| 14 |
+
ProspectionBranch,
|
| 15 |
+
ZoneDescriptor,
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def _normalize(vec: np.ndarray) -> np.ndarray:
|
| 20 |
+
norm = float(np.linalg.norm(vec))
|
| 21 |
+
if norm <= 1e-12:
|
| 22 |
+
return np.zeros_like(vec, dtype=np.float32)
|
| 23 |
+
return (vec / norm).astype(np.float32)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class PhantomKernelBridge(KernelBridge):
|
| 27 |
+
"""
|
| 28 |
+
Deterministic bridge between CCS-v2 and the existing Phantom Kernel.
|
| 29 |
+
|
| 30 |
+
The bridge keeps Phantom Kernel unchanged and exposes deterministic
|
| 31 |
+
zone/candidate/future-chain operations to the cognitive controller.
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
def __init__(
|
| 35 |
+
self,
|
| 36 |
+
kernel,
|
| 37 |
+
max_zone_candidates: int = 256,
|
| 38 |
+
centroid_sample_size: int = 64,
|
| 39 |
+
max_candidates_per_zone: int = 32,
|
| 40 |
+
candidate_activation_threshold: float = -1.0,
|
| 41 |
+
):
|
| 42 |
+
self.kernel = kernel
|
| 43 |
+
self.max_zone_candidates = max_zone_candidates
|
| 44 |
+
self.centroid_sample_size = centroid_sample_size
|
| 45 |
+
self.max_candidates_per_zone = max_candidates_per_zone
|
| 46 |
+
self.candidate_activation_threshold = candidate_activation_threshold
|
| 47 |
+
|
| 48 |
+
self._zones: Tuple[ZoneDescriptor, ...] = ()
|
| 49 |
+
self._zone_candidates: Dict[str, Tuple[Tuple[int, np.ndarray], ...]] = {}
|
| 50 |
+
self._constraint_strength: Dict[Tuple[str, int], int] = {}
|
| 51 |
+
self._build_zone_index()
|
| 52 |
+
|
| 53 |
+
def _deterministic_sample(self, values: Sequence[int], limit: int) -> Tuple[int, ...]:
|
| 54 |
+
if limit <= 0:
|
| 55 |
+
return ()
|
| 56 |
+
if len(values) <= limit:
|
| 57 |
+
return tuple(values)
|
| 58 |
+
|
| 59 |
+
stride = len(values) / float(limit)
|
| 60 |
+
sampled = [values[int(i * stride)] for i in range(limit)]
|
| 61 |
+
return tuple(sampled)
|
| 62 |
+
|
| 63 |
+
def _build_zone_index(self) -> None:
|
| 64 |
+
by_slab: Dict[int, list[int]] = defaultdict(list)
|
| 65 |
+
for gid_raw, loc in self.kernel.zone_map.items():
|
| 66 |
+
try:
|
| 67 |
+
gid = int(gid_raw)
|
| 68 |
+
slab_id = int(loc[0])
|
| 69 |
+
except Exception:
|
| 70 |
+
continue
|
| 71 |
+
|
| 72 |
+
if slab_id in self.kernel.slabs:
|
| 73 |
+
by_slab[slab_id].append(gid)
|
| 74 |
+
|
| 75 |
+
zones: list[ZoneDescriptor] = []
|
| 76 |
+
zone_candidates: Dict[str, Tuple[Tuple[int, np.ndarray], ...]] = {}
|
| 77 |
+
|
| 78 |
+
for slab_id in sorted(by_slab.keys()):
|
| 79 |
+
gids = sorted(by_slab[slab_id])
|
| 80 |
+
sampled = self._deterministic_sample(gids, self.max_zone_candidates)
|
| 81 |
+
|
| 82 |
+
vector_entries: list[Tuple[int, np.ndarray]] = []
|
| 83 |
+
for gid in sampled:
|
| 84 |
+
vec = self.kernel.get_vector(gid)
|
| 85 |
+
if vec is None:
|
| 86 |
+
continue
|
| 87 |
+
nvec = _normalize(np.asarray(vec, dtype=np.float32))
|
| 88 |
+
if not np.any(nvec):
|
| 89 |
+
continue
|
| 90 |
+
vector_entries.append((gid, nvec))
|
| 91 |
+
|
| 92 |
+
if not vector_entries:
|
| 93 |
+
continue
|
| 94 |
+
|
| 95 |
+
centroid_count = min(self.centroid_sample_size, len(vector_entries))
|
| 96 |
+
centroid_stack = np.stack(
|
| 97 |
+
[vector_entries[i][1] for i in range(centroid_count)],
|
| 98 |
+
axis=0,
|
| 99 |
+
)
|
| 100 |
+
centroid = _normalize(centroid_stack.mean(axis=0))
|
| 101 |
+
|
| 102 |
+
zone_id = f"slab:{slab_id}"
|
| 103 |
+
zones.append(
|
| 104 |
+
ZoneDescriptor(
|
| 105 |
+
zone_id=zone_id,
|
| 106 |
+
centroid=centroid,
|
| 107 |
+
slab_id=slab_id,
|
| 108 |
+
metadata={
|
| 109 |
+
"sample_count": len(vector_entries),
|
| 110 |
+
"max_candidates_per_zone": self.max_candidates_per_zone,
|
| 111 |
+
},
|
| 112 |
+
)
|
| 113 |
+
)
|
| 114 |
+
zone_candidates[zone_id] = tuple(vector_entries)
|
| 115 |
+
|
| 116 |
+
self._zones = tuple(zones)
|
| 117 |
+
self._zone_candidates = zone_candidates
|
| 118 |
+
|
| 119 |
+
def list_zones(self) -> Sequence[ZoneDescriptor]:
|
| 120 |
+
return self._zones
|
| 121 |
+
|
| 122 |
+
def _candidate_id(self, zone_id: str, gid: int) -> str:
|
| 123 |
+
return f"{zone_id}:gid:{gid}"
|
| 124 |
+
|
| 125 |
+
def _candidate_binding(
|
| 126 |
+
self,
|
| 127 |
+
goal: GoalState,
|
| 128 |
+
zone: ZoneDescriptor,
|
| 129 |
+
gid: int,
|
| 130 |
+
vec: np.ndarray,
|
| 131 |
+
resonance: float,
|
| 132 |
+
) -> CandidateBinding:
|
| 133 |
+
boost = self._constraint_strength.get((goal.goal_id, gid), 0) * 0.01
|
| 134 |
+
adjusted_resonance = max(-1.0, min(1.0, resonance + boost))
|
| 135 |
+
token = self.kernel.get_token(gid)
|
| 136 |
+
return CandidateBinding(
|
| 137 |
+
candidate_id=self._candidate_id(zone.zone_id, gid),
|
| 138 |
+
vector=vec,
|
| 139 |
+
resonance=adjusted_resonance,
|
| 140 |
+
zone_id=zone.zone_id,
|
| 141 |
+
slab_id=zone.slab_id,
|
| 142 |
+
metadata={
|
| 143 |
+
"gid": gid,
|
| 144 |
+
"token": token,
|
| 145 |
+
"constraint_strength": self._constraint_strength.get((goal.goal_id, gid), 0),
|
| 146 |
+
},
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
def query_candidates(
|
| 150 |
+
self, goal: GoalState, active_zones: Sequence[ZoneDescriptor]
|
| 151 |
+
) -> Sequence[CandidateBinding]:
|
| 152 |
+
goal_vector = _normalize(goal.vector)
|
| 153 |
+
all_candidates: list[CandidateBinding] = []
|
| 154 |
+
|
| 155 |
+
for zone in active_zones:
|
| 156 |
+
zone_entries = self._zone_candidates.get(zone.zone_id, ())
|
| 157 |
+
zone_scored: list[CandidateBinding] = []
|
| 158 |
+
|
| 159 |
+
for gid, vec in zone_entries:
|
| 160 |
+
resonance = float(np.dot(goal_vector, vec))
|
| 161 |
+
if resonance < self.candidate_activation_threshold:
|
| 162 |
+
continue
|
| 163 |
+
zone_scored.append(self._candidate_binding(goal, zone, gid, vec, resonance))
|
| 164 |
+
|
| 165 |
+
zone_scored.sort(key=lambda c: (-c.resonance, c.candidate_id))
|
| 166 |
+
all_candidates.extend(zone_scored[: self.max_candidates_per_zone])
|
| 167 |
+
|
| 168 |
+
all_candidates.sort(key=lambda c: (-c.resonance, c.candidate_id))
|
| 169 |
+
return tuple(all_candidates)
|
| 170 |
+
|
| 171 |
+
def _zone_from_seed(self, seed: CandidateBinding) -> Optional[ZoneDescriptor]:
|
| 172 |
+
for zone in self._zones:
|
| 173 |
+
if zone.zone_id == seed.zone_id:
|
| 174 |
+
return zone
|
| 175 |
+
return None
|
| 176 |
+
|
| 177 |
+
def build_future_chain(
|
| 178 |
+
self, seed: CandidateBinding, depth: int, goal: GoalState
|
| 179 |
+
) -> Sequence[CandidateBinding]:
|
| 180 |
+
if depth <= 0:
|
| 181 |
+
return ()
|
| 182 |
+
|
| 183 |
+
zone = self._zone_from_seed(seed)
|
| 184 |
+
if zone is None:
|
| 185 |
+
return (seed,)
|
| 186 |
+
|
| 187 |
+
zone_entries = self._zone_candidates.get(zone.zone_id, ())
|
| 188 |
+
goal_vector = _normalize(goal.vector)
|
| 189 |
+
|
| 190 |
+
used_gids: set[int] = set()
|
| 191 |
+
if "gid" in seed.metadata:
|
| 192 |
+
used_gids.add(int(seed.metadata["gid"]))
|
| 193 |
+
|
| 194 |
+
chain: list[CandidateBinding] = [seed]
|
| 195 |
+
prev_vector = seed.vector
|
| 196 |
+
|
| 197 |
+
for _ in range(depth - 1):
|
| 198 |
+
best_gid: Optional[int] = None
|
| 199 |
+
best_vec: Optional[np.ndarray] = None
|
| 200 |
+
best_score = float("-inf")
|
| 201 |
+
|
| 202 |
+
for gid, vec in zone_entries:
|
| 203 |
+
if gid in used_gids:
|
| 204 |
+
continue
|
| 205 |
+
alignment = float(np.dot(goal_vector, vec))
|
| 206 |
+
continuity = float(np.dot(prev_vector, vec))
|
| 207 |
+
boost = self._constraint_strength.get((goal.goal_id, gid), 0) * 0.01
|
| 208 |
+
score = (0.7 * alignment) + (0.3 * continuity) + boost
|
| 209 |
+
|
| 210 |
+
if (score > best_score) or (
|
| 211 |
+
abs(score - best_score) <= 1e-12
|
| 212 |
+
and best_gid is not None
|
| 213 |
+
and gid < best_gid
|
| 214 |
+
):
|
| 215 |
+
best_gid = gid
|
| 216 |
+
best_vec = vec
|
| 217 |
+
best_score = score
|
| 218 |
+
|
| 219 |
+
if best_gid is None or best_vec is None:
|
| 220 |
+
break
|
| 221 |
+
|
| 222 |
+
used_gids.add(best_gid)
|
| 223 |
+
chain.append(self._candidate_binding(goal, zone, best_gid, best_vec, best_score))
|
| 224 |
+
prev_vector = best_vec
|
| 225 |
+
|
| 226 |
+
return tuple(chain)
|
| 227 |
+
|
| 228 |
+
def materialize_output(
|
| 229 |
+
self, branch: Optional[ProspectionBranch], goal: GoalState
|
| 230 |
+
) -> Dict[str, Any]:
|
| 231 |
+
if branch is None or not branch.chain:
|
| 232 |
+
return {
|
| 233 |
+
"status": "NO_CANDIDATE",
|
| 234 |
+
"goal_id": goal.goal_id,
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
terminal = branch.chain[-1]
|
| 238 |
+
chain_ids = [item.candidate_id for item in branch.chain]
|
| 239 |
+
chain_tokens = [str(item.metadata.get("token", "UNK")) for item in branch.chain]
|
| 240 |
+
|
| 241 |
+
return {
|
| 242 |
+
"status": "OK",
|
| 243 |
+
"goal_id": goal.goal_id,
|
| 244 |
+
"selected_candidate_id": branch.seed_candidate_id,
|
| 245 |
+
"terminal_candidate_id": terminal.candidate_id,
|
| 246 |
+
"terminal_token": terminal.metadata.get("token", "UNK"),
|
| 247 |
+
"terminal_gid": terminal.metadata.get("gid"),
|
| 248 |
+
"branch_score": branch.score,
|
| 249 |
+
"chain_candidate_ids": chain_ids,
|
| 250 |
+
"chain_tokens": chain_tokens,
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
def strengthen_constraints(self, goal: GoalState, candidate: CandidateBinding) -> None:
|
| 254 |
+
gid = candidate.metadata.get("gid")
|
| 255 |
+
if gid is None:
|
| 256 |
+
return
|
| 257 |
+
key = (goal.goal_id, int(gid))
|
| 258 |
+
self._constraint_strength[key] = self._constraint_strength.get(key, 0) + 1
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
def create_v14_controller_with_phantom_kernel(
|
| 262 |
+
model_path: str = "v11_Morpho_Optimized",
|
| 263 |
+
state_dir: Path | str = Path("shadow_x_v14_ccs/state"),
|
| 264 |
+
*,
|
| 265 |
+
max_zone_candidates: int = 256,
|
| 266 |
+
centroid_sample_size: int = 64,
|
| 267 |
+
max_candidates_per_zone: int = 32,
|
| 268 |
+
candidate_activation_threshold: float = -1.0,
|
| 269 |
+
) -> CognitiveController:
|
| 270 |
+
"""
|
| 271 |
+
Convenience factory for end-to-end CCS-v14 + Phantom Kernel wiring.
|
| 272 |
+
"""
|
| 273 |
+
from phantom_kernel import PhantomKernel
|
| 274 |
+
|
| 275 |
+
kernel = PhantomKernel(model_path=model_path)
|
| 276 |
+
bridge = PhantomKernelBridge(
|
| 277 |
+
kernel=kernel,
|
| 278 |
+
max_zone_candidates=max_zone_candidates,
|
| 279 |
+
centroid_sample_size=centroid_sample_size,
|
| 280 |
+
max_candidates_per_zone=max_candidates_per_zone,
|
| 281 |
+
candidate_activation_threshold=candidate_activation_threshold,
|
| 282 |
+
)
|
| 283 |
+
return CognitiveController(kernel_bridge=bridge, state_dir=state_dir)
|
tests/test_shadow_x_v14_ccs.py
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import shutil
|
| 3 |
+
import tempfile
|
| 4 |
+
import unittest
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
from shadow_x_v14_ccs.cognitive_controller import (
|
| 10 |
+
CandidateBinding,
|
| 11 |
+
CognitiveController,
|
| 12 |
+
ConflictResolver,
|
| 13 |
+
DeterministicAttentionAllocator,
|
| 14 |
+
ErrorMonitor,
|
| 15 |
+
GoalStack,
|
| 16 |
+
InMemoryKernelBridge,
|
| 17 |
+
TaskSwitcherProspectionEngine,
|
| 18 |
+
ThirdOrderRuleModifier,
|
| 19 |
+
ZoneDescriptor,
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def make_vec(seed: int, dim: int = 4096) -> np.ndarray:
|
| 24 |
+
base = np.arange(dim, dtype=np.float32)
|
| 25 |
+
vec = np.cos(base * 0.001 + seed).astype(np.float32)
|
| 26 |
+
norm = np.linalg.norm(vec)
|
| 27 |
+
if norm <= 1e-12:
|
| 28 |
+
return np.zeros(dim, dtype=np.float32)
|
| 29 |
+
return (vec / norm).astype(np.float32)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class GoalStackTests(unittest.TestCase):
|
| 33 |
+
def setUp(self):
|
| 34 |
+
self.tmpdir = tempfile.mkdtemp(prefix="shadowx_v14_goalstack_")
|
| 35 |
+
self.goal_file = Path(self.tmpdir) / "goal_vector.dat"
|
| 36 |
+
|
| 37 |
+
def tearDown(self):
|
| 38 |
+
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
| 39 |
+
|
| 40 |
+
def test_push_pop_and_persistence(self):
|
| 41 |
+
stack = GoalStack(self.goal_file, vector_dim=4096)
|
| 42 |
+
g1 = stack.push("root_goal", make_vec(1), priority=9)
|
| 43 |
+
g2 = stack.push("child_goal", make_vec(2), priority=4, parent_goal_id=g1.goal_id)
|
| 44 |
+
|
| 45 |
+
self.assertEqual(stack.current().goal_id, g2.goal_id)
|
| 46 |
+
self.assertEqual(len(stack.list_goals()), 2)
|
| 47 |
+
|
| 48 |
+
reloaded = GoalStack(self.goal_file, vector_dim=4096)
|
| 49 |
+
self.assertEqual(len(reloaded.list_goals()), 2)
|
| 50 |
+
self.assertEqual(reloaded.current().goal_id, g2.goal_id)
|
| 51 |
+
|
| 52 |
+
popped = reloaded.pop()
|
| 53 |
+
self.assertEqual(popped.goal_id, g2.goal_id)
|
| 54 |
+
self.assertEqual(reloaded.current().goal_id, g1.goal_id)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
class ModuleUnitTests(unittest.TestCase):
|
| 58 |
+
def test_attention_allocator_threshold_and_order(self):
|
| 59 |
+
allocator = DeterministicAttentionAllocator(activation_threshold=0.80, max_active_zones=2)
|
| 60 |
+
goal = make_vec(10)
|
| 61 |
+
projected_1 = np.roll(goal, 1).astype(np.float32)
|
| 62 |
+
projected_1 /= np.linalg.norm(projected_1)
|
| 63 |
+
projected_2 = np.roll(goal, 2).astype(np.float32)
|
| 64 |
+
projected_2 /= np.linalg.norm(projected_2)
|
| 65 |
+
zones = (
|
| 66 |
+
ZoneDescriptor("z_good_1", projected_1, slab_id=0),
|
| 67 |
+
ZoneDescriptor("z_good_2", projected_2, slab_id=1),
|
| 68 |
+
ZoneDescriptor("z_bad", -make_vec(10), slab_id=2),
|
| 69 |
+
)
|
| 70 |
+
selected = allocator.allocate(goal, zones)
|
| 71 |
+
ids = tuple(z.zone_id for z in selected)
|
| 72 |
+
self.assertEqual(len(ids), 2)
|
| 73 |
+
self.assertIn("z_good_1", ids)
|
| 74 |
+
self.assertIn("z_good_2", ids)
|
| 75 |
+
self.assertNotIn("z_bad", ids)
|
| 76 |
+
|
| 77 |
+
def test_conflict_resolver_inhibits_opposition(self):
|
| 78 |
+
resolver = ConflictResolver(opposition_threshold=0.80)
|
| 79 |
+
goal = make_vec(20)
|
| 80 |
+
c_good = CandidateBinding("c_good", make_vec(20), 0.92, "z0")
|
| 81 |
+
c_opp = CandidateBinding("c_opp", -make_vec(20), 0.95, "z0")
|
| 82 |
+
c_neutral = CandidateBinding("c_neutral", make_vec(21), 0.90, "z1")
|
| 83 |
+
|
| 84 |
+
selected, inhibited, conflicts = resolver.resolve((c_good, c_opp, c_neutral), goal)
|
| 85 |
+
selected_ids = {c.candidate_id for c in selected}
|
| 86 |
+
self.assertIn("c_good", selected_ids)
|
| 87 |
+
self.assertNotIn("c_opp", selected_ids)
|
| 88 |
+
self.assertIn("c_opp", inhibited)
|
| 89 |
+
self.assertGreaterEqual(len(conflicts), 1)
|
| 90 |
+
|
| 91 |
+
def test_error_monitor_states(self):
|
| 92 |
+
monitor = ErrorMonitor(deviation_threshold=0.2, hard_fail_threshold=0.4)
|
| 93 |
+
goal = make_vec(30)
|
| 94 |
+
|
| 95 |
+
ok = monitor.evaluate(goal, goal)
|
| 96 |
+
self.assertFalse(ok.has_error)
|
| 97 |
+
self.assertEqual(ok.action, "none")
|
| 98 |
+
|
| 99 |
+
rebind = monitor.evaluate(make_vec(31), goal)
|
| 100 |
+
self.assertTrue(rebind.has_error)
|
| 101 |
+
self.assertIn(rebind.action, {"rebind", "strengthen_constraints_and_rebind"})
|
| 102 |
+
|
| 103 |
+
hard_fail = monitor.evaluate(-goal, goal)
|
| 104 |
+
self.assertTrue(hard_fail.has_error)
|
| 105 |
+
self.assertEqual(hard_fail.action, "strengthen_constraints_and_rebind")
|
| 106 |
+
|
| 107 |
+
def test_task_switcher_prospection_returns_deterministic_best(self):
|
| 108 |
+
engine = TaskSwitcherProspectionEngine(max_futures=3, branch_depth=3)
|
| 109 |
+
goal = make_vec(40)
|
| 110 |
+
c0 = CandidateBinding("c0", make_vec(40), 0.93, "z0")
|
| 111 |
+
c1 = CandidateBinding("c1", make_vec(41), 0.91, "z1")
|
| 112 |
+
c2 = CandidateBinding("c2", -make_vec(40), 0.95, "z2")
|
| 113 |
+
|
| 114 |
+
def build_chain(seed: CandidateBinding, depth: int):
|
| 115 |
+
return tuple(seed for _ in range(depth))
|
| 116 |
+
|
| 117 |
+
branches = engine.simulate(goal, (c0, c1, c2), build_chain)
|
| 118 |
+
best = engine.choose_best(branches)
|
| 119 |
+
self.assertIsNotNone(best)
|
| 120 |
+
self.assertEqual(best.seed_candidate_id, "c0")
|
| 121 |
+
|
| 122 |
+
def test_rule_modifier_updates_after_error_window(self):
|
| 123 |
+
mod = ThirdOrderRuleModifier(error_window=5)
|
| 124 |
+
rules = {
|
| 125 |
+
"attention_activation_threshold": 0.12,
|
| 126 |
+
"deviation_threshold": 0.28,
|
| 127 |
+
"hard_fail_threshold": 0.40,
|
| 128 |
+
"conflict_opposition_threshold": 0.80,
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
monitor = ErrorMonitor(deviation_threshold=0.2, hard_fail_threshold=0.4)
|
| 132 |
+
goal = make_vec(50)
|
| 133 |
+
for _ in range(5):
|
| 134 |
+
mod.register(monitor.evaluate(-goal, goal))
|
| 135 |
+
updates = mod.update_rules(rules)
|
| 136 |
+
|
| 137 |
+
self.assertTrue(updates)
|
| 138 |
+
self.assertGreaterEqual(
|
| 139 |
+
updates["attention_activation_threshold"], rules["attention_activation_threshold"]
|
| 140 |
+
)
|
| 141 |
+
self.assertLessEqual(
|
| 142 |
+
updates["deviation_threshold"], rules["deviation_threshold"]
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
class ControllerIntegrationTests(unittest.TestCase):
|
| 147 |
+
def setUp(self):
|
| 148 |
+
self.tmpdir = tempfile.mkdtemp(prefix="shadowx_v14_controller_")
|
| 149 |
+
self.state_dir = Path(self.tmpdir) / "state"
|
| 150 |
+
self.goal = make_vec(100)
|
| 151 |
+
|
| 152 |
+
zones = (
|
| 153 |
+
ZoneDescriptor("Z0", make_vec(100), slab_id=0),
|
| 154 |
+
ZoneDescriptor("Z1", make_vec(101), slab_id=1),
|
| 155 |
+
ZoneDescriptor("Z2", -make_vec(100), slab_id=2),
|
| 156 |
+
)
|
| 157 |
+
candidates = {
|
| 158 |
+
"Z0": (
|
| 159 |
+
CandidateBinding("C0", make_vec(100), 0.94, "Z0", slab_id=0),
|
| 160 |
+
CandidateBinding("C1", -make_vec(100), 0.93, "Z0", slab_id=0),
|
| 161 |
+
),
|
| 162 |
+
"Z1": (
|
| 163 |
+
CandidateBinding("C2", make_vec(101), 0.92, "Z1", slab_id=1),
|
| 164 |
+
),
|
| 165 |
+
"Z2": (
|
| 166 |
+
CandidateBinding("C3", -make_vec(100), 0.97, "Z2", slab_id=2),
|
| 167 |
+
),
|
| 168 |
+
}
|
| 169 |
+
bridge = InMemoryKernelBridge(zones, candidates)
|
| 170 |
+
self.controller = CognitiveController(bridge, state_dir=self.state_dir, vector_dim=4096)
|
| 171 |
+
|
| 172 |
+
def tearDown(self):
|
| 173 |
+
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
| 174 |
+
|
| 175 |
+
def test_run_cycle_generates_decision_and_trace(self):
|
| 176 |
+
self.controller.push_goal("consistency_check", self.goal, priority=8)
|
| 177 |
+
decision = self.controller.run_cycle()
|
| 178 |
+
|
| 179 |
+
self.assertEqual(decision.goal_id, self.controller.goal_stack.current().goal_id)
|
| 180 |
+
self.assertIsNotNone(decision.selected_candidate_id)
|
| 181 |
+
self.assertIn("C1", decision.inhibited_candidate_ids)
|
| 182 |
+
self.assertIsInstance(decision.output_payload, dict)
|
| 183 |
+
|
| 184 |
+
trace_file = self.state_dir / "trace_log.jsonl"
|
| 185 |
+
self.assertTrue(trace_file.exists())
|
| 186 |
+
lines = trace_file.read_text(encoding="utf-8").strip().splitlines()
|
| 187 |
+
self.assertGreaterEqual(len(lines), 2) # goal_push + cycle
|
| 188 |
+
|
| 189 |
+
parsed = [json.loads(line) for line in lines]
|
| 190 |
+
events = [p["event"] for p in parsed]
|
| 191 |
+
self.assertIn("goal_push", events)
|
| 192 |
+
self.assertIn("cycle", events)
|
| 193 |
+
|
| 194 |
+
def test_determinism_across_fresh_controllers_with_same_input(self):
|
| 195 |
+
self.controller.push_goal("determinism_goal", self.goal, priority=7)
|
| 196 |
+
first = self.controller.run_cycle()
|
| 197 |
+
|
| 198 |
+
zones = self.controller.kernel_bridge.list_zones()
|
| 199 |
+
candidates = {
|
| 200 |
+
z.zone_id: tuple(self.controller.kernel_bridge._zone_candidates.get(z.zone_id, ()))
|
| 201 |
+
for z in zones
|
| 202 |
+
}
|
| 203 |
+
bridge2 = InMemoryKernelBridge(zones, candidates)
|
| 204 |
+
controller2 = CognitiveController(
|
| 205 |
+
bridge2, state_dir=Path(self.tmpdir) / "state2", vector_dim=4096
|
| 206 |
+
)
|
| 207 |
+
controller2.push_goal("determinism_goal", self.goal, priority=7)
|
| 208 |
+
second = controller2.run_cycle()
|
| 209 |
+
|
| 210 |
+
self.assertEqual(first.selected_candidate_id, second.selected_candidate_id)
|
| 211 |
+
self.assertEqual(first.active_zone_ids, second.active_zone_ids)
|
| 212 |
+
self.assertEqual(first.inhibited_candidate_ids, second.inhibited_candidate_ids)
|
| 213 |
+
self.assertAlmostEqual(
|
| 214 |
+
first.error_signal.deviation, second.error_signal.deviation, places=8
|
| 215 |
+
)
|
| 216 |
+
|
| 217 |
+
def test_error_when_running_without_goal(self):
|
| 218 |
+
with self.assertRaises(RuntimeError):
|
| 219 |
+
self.controller.run_cycle()
|
| 220 |
+
|
| 221 |
+
def test_no_candidate_path_is_handled(self):
|
| 222 |
+
empty_bridge = InMemoryKernelBridge(
|
| 223 |
+
zones=(ZoneDescriptor("Z9", make_vec(900), slab_id=9),),
|
| 224 |
+
zone_candidates={},
|
| 225 |
+
)
|
| 226 |
+
controller = CognitiveController(
|
| 227 |
+
empty_bridge, state_dir=Path(self.tmpdir) / "state_empty", vector_dim=4096
|
| 228 |
+
)
|
| 229 |
+
controller.push_goal("empty_case", self.goal, priority=1)
|
| 230 |
+
decision = controller.run_cycle()
|
| 231 |
+
|
| 232 |
+
self.assertIsNone(decision.selected_candidate_id)
|
| 233 |
+
self.assertEqual(decision.output_payload.get("status"), "NO_CANDIDATE")
|
| 234 |
+
self.assertTrue(decision.error_signal.has_error)
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
if __name__ == "__main__":
|
| 238 |
+
unittest.main(verbosity=2)
|
tests/test_shadow_x_v14_demo_cli.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import shutil
|
| 2 |
+
import tempfile
|
| 3 |
+
import unittest
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
from shadow_x_v14_ccs.demo_cli import run_demo
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class DemoCliTests(unittest.TestCase):
|
| 10 |
+
def setUp(self):
|
| 11 |
+
self.tmpdir = tempfile.mkdtemp(prefix="shadowx_v14_demo_cli_")
|
| 12 |
+
self.state_dir = Path(self.tmpdir) / "state"
|
| 13 |
+
|
| 14 |
+
def tearDown(self):
|
| 15 |
+
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
| 16 |
+
|
| 17 |
+
def test_run_demo_covers_required_public_flow(self):
|
| 18 |
+
summary = run_demo(self.state_dir, vector_dim=512, reset_state=True)
|
| 19 |
+
|
| 20 |
+
self.assertEqual(len(summary["taught_facts"]), 5)
|
| 21 |
+
self.assertTrue(summary["general_answer"])
|
| 22 |
+
self.assertTrue(summary["correction_answer"])
|
| 23 |
+
self.assertTrue(summary["correction_applied"])
|
| 24 |
+
self.assertGreaterEqual(summary["trace_cycle_count"], 2)
|
| 25 |
+
self.assertTrue(summary["trace_chain"])
|
| 26 |
+
|
| 27 |
+
first = summary["trace_chain"][0]
|
| 28 |
+
self.assertIn("slab_id", first)
|
| 29 |
+
self.assertIn("vertex_id", first)
|
| 30 |
+
self.assertIn("resonance", first)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
if __name__ == "__main__":
|
| 34 |
+
unittest.main(verbosity=2)
|
tests/test_shadow_x_v14_phantom_bridge.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import shutil
|
| 2 |
+
import tempfile
|
| 3 |
+
import unittest
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
from shadow_x_v14_ccs.cognitive_controller import CognitiveController, GoalState, ProspectionBranch
|
| 9 |
+
from shadow_x_v14_ccs.phantom_bridge import PhantomKernelBridge
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def make_vec(seed: int, dim: int = 64) -> np.ndarray:
|
| 13 |
+
base = np.arange(dim, dtype=np.float32)
|
| 14 |
+
vec = np.cos(base * 0.07 + seed).astype(np.float32)
|
| 15 |
+
vec /= (np.linalg.norm(vec) + 1e-12)
|
| 16 |
+
return vec
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class FakeKernel:
|
| 20 |
+
def __init__(self):
|
| 21 |
+
self.slabs = {0: object(), 1: object()}
|
| 22 |
+
self.zone_map = {
|
| 23 |
+
0: (0, 0),
|
| 24 |
+
1: (0, 1),
|
| 25 |
+
2: (1, 0),
|
| 26 |
+
3: (1, 1),
|
| 27 |
+
}
|
| 28 |
+
self._vectors = {
|
| 29 |
+
0: make_vec(1),
|
| 30 |
+
1: make_vec(2),
|
| 31 |
+
2: make_vec(10),
|
| 32 |
+
3: -make_vec(1),
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
def get_vector(self, gid: int):
|
| 36 |
+
return self._vectors.get(gid)
|
| 37 |
+
|
| 38 |
+
def get_token(self, gid: int):
|
| 39 |
+
return f"T{gid}"
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
class PhantomBridgeUnitTests(unittest.TestCase):
|
| 43 |
+
def setUp(self):
|
| 44 |
+
self.kernel = FakeKernel()
|
| 45 |
+
self.bridge = PhantomKernelBridge(
|
| 46 |
+
kernel=self.kernel,
|
| 47 |
+
max_zone_candidates=4,
|
| 48 |
+
centroid_sample_size=2,
|
| 49 |
+
max_candidates_per_zone=4,
|
| 50 |
+
candidate_activation_threshold=-1.0,
|
| 51 |
+
)
|
| 52 |
+
self.goal = GoalState(goal_id="g1", name="goal", vector=make_vec(1))
|
| 53 |
+
|
| 54 |
+
def test_zone_index_and_query(self):
|
| 55 |
+
zones = self.bridge.list_zones()
|
| 56 |
+
self.assertEqual(len(zones), 2)
|
| 57 |
+
|
| 58 |
+
candidates = self.bridge.query_candidates(self.goal, zones)
|
| 59 |
+
self.assertGreaterEqual(len(candidates), 1)
|
| 60 |
+
|
| 61 |
+
top = candidates[0]
|
| 62 |
+
self.assertEqual(top.metadata.get("gid"), 0)
|
| 63 |
+
self.assertEqual(top.metadata.get("token"), "T0")
|
| 64 |
+
|
| 65 |
+
def test_strengthen_constraints_biases_resonance(self):
|
| 66 |
+
zones = self.bridge.list_zones()
|
| 67 |
+
before = self.bridge.query_candidates(self.goal, zones)
|
| 68 |
+
c1_before = next(c for c in before if c.metadata.get("gid") == 1)
|
| 69 |
+
|
| 70 |
+
for _ in range(3):
|
| 71 |
+
self.bridge.strengthen_constraints(self.goal, c1_before)
|
| 72 |
+
|
| 73 |
+
after = self.bridge.query_candidates(self.goal, zones)
|
| 74 |
+
c1_after = next(c for c in after if c.metadata.get("gid") == 1)
|
| 75 |
+
|
| 76 |
+
self.assertAlmostEqual(c1_after.resonance, c1_before.resonance + 0.03, places=6)
|
| 77 |
+
|
| 78 |
+
def test_future_chain_and_materialize_output(self):
|
| 79 |
+
zones = self.bridge.list_zones()
|
| 80 |
+
candidates = self.bridge.query_candidates(self.goal, zones)
|
| 81 |
+
seed = candidates[0]
|
| 82 |
+
|
| 83 |
+
chain = self.bridge.build_future_chain(seed, depth=3, goal=self.goal)
|
| 84 |
+
self.assertGreaterEqual(len(chain), 1)
|
| 85 |
+
self.assertLessEqual(len(chain), 3)
|
| 86 |
+
|
| 87 |
+
branch = ProspectionBranch(
|
| 88 |
+
seed_candidate_id=seed.candidate_id,
|
| 89 |
+
chain=tuple(chain),
|
| 90 |
+
score=0.91,
|
| 91 |
+
)
|
| 92 |
+
payload = self.bridge.materialize_output(branch, self.goal)
|
| 93 |
+
self.assertEqual(payload["status"], "OK")
|
| 94 |
+
self.assertIn("chain_candidate_ids", payload)
|
| 95 |
+
self.assertIn("terminal_gid", payload)
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
@unittest.skipUnless(
|
| 99 |
+
Path("v11_Morpho_Optimized").exists(),
|
| 100 |
+
"Real Phantom dataset folder not found.",
|
| 101 |
+
)
|
| 102 |
+
class PhantomBridgeRealDatasetSmokeTests(unittest.TestCase):
|
| 103 |
+
def setUp(self):
|
| 104 |
+
self.tmpdir = tempfile.mkdtemp(prefix="shadowx_v14_real_bridge_")
|
| 105 |
+
|
| 106 |
+
def tearDown(self):
|
| 107 |
+
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
| 108 |
+
|
| 109 |
+
def test_real_kernel_bridge_controller_cycle(self):
|
| 110 |
+
from phantom_kernel import PhantomKernel
|
| 111 |
+
|
| 112 |
+
kernel = PhantomKernel(model_path="v11_Morpho_Optimized")
|
| 113 |
+
try:
|
| 114 |
+
bridge = PhantomKernelBridge(
|
| 115 |
+
kernel=kernel,
|
| 116 |
+
max_zone_candidates=64,
|
| 117 |
+
centroid_sample_size=16,
|
| 118 |
+
max_candidates_per_zone=8,
|
| 119 |
+
candidate_activation_threshold=-1.0,
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
zones = bridge.list_zones()
|
| 123 |
+
self.assertGreater(len(zones), 0)
|
| 124 |
+
|
| 125 |
+
controller = CognitiveController(
|
| 126 |
+
bridge,
|
| 127 |
+
state_dir=Path(self.tmpdir) / "state",
|
| 128 |
+
vector_dim=4096,
|
| 129 |
+
)
|
| 130 |
+
controller.rules["attention_activation_threshold"] = -1.0
|
| 131 |
+
|
| 132 |
+
goal_vector = zones[0].centroid
|
| 133 |
+
controller.push_goal("real_dataset_smoke", goal_vector, priority=5)
|
| 134 |
+
decision = controller.run_cycle()
|
| 135 |
+
|
| 136 |
+
self.assertEqual(decision.goal_id, controller.goal_stack.current().goal_id)
|
| 137 |
+
self.assertIsInstance(decision.output_payload, dict)
|
| 138 |
+
self.assertIn("status", decision.output_payload)
|
| 139 |
+
finally:
|
| 140 |
+
kernel.close()
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
if __name__ == "__main__":
|
| 144 |
+
unittest.main(verbosity=2)
|