Skip to content

Repository files navigation

Centaurian Architecture — Implementation

Screenshot from 2026-08-22 20-36-34

Empirical validation of the Centaurian Architecture (CA), a multi-layered AI system that pairs a symbolic/quantum cognitive core with a lightweight neural periphery (small language models, neural TTS, procedural animation). The architecture encodes personality via a Quantum Personality Model (QPM) running on classical hardware and confines neural networks to bounded I/O transduction roles, preserving end-to-end traceability of every behavioral decision.

Architecture specifications:

The empirical work in this repository runs in four arcs, ending in a working application:

  1. SMC persona validation (Exp 1–2). Can a small language model hold an Aria-grade Structured Cognitive Identity (SCI) across long conversations? Prompt-time strategies stall below threshold at 7B (Exp 1); LoRA fine-tuning installs the persona at the weights level and clears it decisively (Exp 2).
  2. Does the QPM's advantage reach behaviour? (Exp 3–5). The Quantum Personality Model produces genuinely non-classical internal dynamics (order effects d = 21.51, ambivalence d = 2.59), but that advantage does not propagate downstream through any inference-time interface tested — not JSON marginals (Exp 3), not a richer JSON channel (Exp 4, which made it worse), and not residual-stream steering (Exp 5). A strong pretrained style prior dominates all inference-time modulation.
  3. The pivot: per-scenario, from-scratch, owned models (Exp 6). The resolution to the interface-null is to stop modulating a frozen model at inference and instead compile persona + QPM into the weights of a small model we train and fully own. Exp 6 is the first proof: a 321M from-scratch model that reads, abstains, and holds the ADA persona across 40 turns — with the QPM baked in via a <|persona|> channel — running fully offline.
  4. Memory that outlives the context window (Exp 7–8). A daily agent runs for months, so episodic memory has to leave the prompt and the weights alike. Exp 7 establishes extract-then-style over an episodic store — span head recalls, LM head speaks — at O(1) cost per turn; Exp 8 replaces Exp 6's baked fictional memories with a live cross-session Episodic Register, reaching 0.85 recall with zero fabrication, and documents the one trade it could not resolve: on a contaminated base you can keep the persona or finish removing the baked events, but not both.

Those results are assembled into MVP ADA, an offline desktop assistant running the whole four-layer pipeline on a machine with no GPU.


Experiment 1 — SCI Persona Degradation Baseline & Architectural Interventions

Goal: Measure how long a small language model can maintain a consistent persona when given a Structured Cognitive Identity (SCI), find the degradation inflection point T*, and test six prompt-time strategies for closing the gap to the 3.5 PersonaScore threshold.

Method:

  • 30 scripted dialogues (22 naturalistic + 8 adversarial), each 40 turns
  • Side-channel probe questions at turns 5, 10, 15, …, 40 across 4 dimensions (Trait, Episodic, Capability, Style)
  • Primary judge: Claude Sonnet 4.5; secondary judge: Sonnet 4.5 (intra-model consistency via quadratic-weighted Cohen's kappa)

Phase 1 — Baseline (models tested)

Model Params T* Mean PersonaScore Outcome
Phi-4-mini 3.8B 5 (immediate) 1.08 / 5.0 Capability failure — gibberish in 93% of scripts
Qwen2.5-7B 7B 5 3.06 (3.16 → 2.96 over 40 turns) Coherent but below threshold; piecewise degradation from turn 15

Phase 2 — Architectural Interventions (six strategies)

Strategy Mean β (deg. rate) E dim Notes
Baseline 3.08 0.008 2.37 Reference
SCI Refresh (turn 13) 3.15 0.008 2.37 Eliminates inflection; fades by turn 35
Episodic RAG 3.15 0.002 2.69 4× slower decay, but trait destabilization
Hybrid RAG 3.17 ~0 2.83 Best E result; trait/style regression
Combined (Refresh + RAG) 3.20 ~0 2.76 Late-conversation peak; emergent t40 > t5
Multi-Refresh (turns 13 + 28) 3.20 ~0 2.43 Best trait/style; lowest total failures

Phase 2 takeaway: all six strategies converge in [3.08, 3.20] — a 0.12-point band, far below the 3.5 threshold. No condition crosses E = 3.0. The closing question for Phase 3: is the residual gap architectural (need 14B) or capability-shaped (LoRA can fix)?

Full Phase 1 + 2 report: CA_Experiment_1/EXPERIMENT_REPORT.md


Experiment 2 — LoRA Fine-Tuning for SCI Persona Consistency

Goal: Test whether LoRA fine-tuning on persona-consistent dialogue closes the gap that survived all six SCI strategies in Experiment 1, and specifically whether it resolves episodic fabrication at 7B.

Method:

  • 4-condition design (A: FT, no SCI; B: FT, baseline SCI; C: FT + Combined SCI; D: base + Combined SCI as Exp 1 replication) on the same 30 scripts
  • Three LoRA adapters trained on a synthetic 10K-example dataset: LoRA-2K, LoRA-5K, LoRA-10K (eval losses 0.91 / 0.77 / 0.69)
  • H5 sub-runs swap the adapter under Condition C config to characterize the data-scaling curve
  • QLoRA: 4-bit NF4 base + BF16 adapters, r=16 α=32, target q/k/v/o + gate/up, A100 80GB

Headline result

Condition Description Mean PersonaScore
A FT, no SCI 4.020
B FT, baseline SCI 4.293
C FT + Combined SCI 4.415
D Base + Combined SCI (replication) 3.224
  • H1 PASSED ✓ — C exceeds the 3.5 threshold by +0.92 points
  • H2 PASSED ✓ — ΔE = +0.579 (vs +0.30 threshold for "fine-tuning meaningfully addresses fabrication")
  • Paired test (C vs D): Cohen's d = 7.51, p ≈ 1.4 × 10⁻²³ on 30 scripts
  • Replication check: D = 3.224 vs Exp 1's 3.20, |Δ| = 0.024 (within ±0.10 tolerance) → judge stable
  • Decision Rule Outcome A triggered: SMC sub-architecture complete at 7B; the planned 14B model test is retired from the critical path

Full Experiment 2 report: CA_Experiment_2/EXPERIMENT_REPORT.md


Experiment 3 — QPM vs. CMG-CDK Ablation

Goal: Test whether the Quantum Personality Model (QPM) — an 11-qubit + 1-ancilla Qiskit Aer circuit representing Big-Five aspect-level traits — produces measurable advantages over a deliberately matched classical baseline (CMG-CDK: Correlated Multivariate Gaussian with Context-Dependent Kernel) at both the internal personality-state level and the downstream-behavioural level.

Method:

  • CMG-CDK classical control matches QPM on ρ correlation matrix → 11×11 Σ, on context-coupling δ → W, on s_k initialisation, and on sample count — but lacks superposition, coherence, and non-commutative evolution. Any measured QPM-vs-CMG difference is therefore attributable specifically to quantum-like mechanisms.
  • Battery A (H1): 30 sequence pairs × 2 orderings (AB / BA) × 5 categories → Jensen-Shannon Divergence between the two orderings, per model
  • Battery B (H2): 20 conflict scenarios designed to push opposing trait poles simultaneously → mean Bernoulli entropy across 11 trait dimensions (derived from marginals so both models are directly comparable)
  • Battery C (H3): 30 scripts × 40 turns × 8 probe turns × 4 dimensions = 960 paired probes per profile, driving Qwen2.5-7B-Instruct + LoRA-10K (the Exp 2 headline adapter) through the QPM→structured-intent translation → Sonnet 4.5 PersonaScore
  • H4 variance calibration: 10 QPM repeats at fixed input → SNR check that shot noise does not dominate the QPM-vs-CMG signal
  • Both psychotherapy and software_eng profiles run on A/B/H4; Battery C decision set by the psychotherapy primary per pre-registration

Headline results

Hypothesis Metric QPM CMG-CDK p Cohen's d Verdict
H1 (order effects) Mean JSD per pair 0.221 0.000 1.97 × 10⁻⁴⁰ 21.51
H2 (ambivalence) Mean Shannon H 0.604 0.491 4.57 × 10⁻¹⁰ 2.59
H3 (PersonaScore, n = 960) Mean PersonaScore 4.410 4.386 0.327 0.032
H4 (variance calibration) SNR (≥ 3.0 to pass) (60.23)
  • H1 PASSED ✓ — CMG-CDK's linear additive context update μ + W·d_A + W·d_B is commutative by construction, so JSD_CMG = 0 across all 30 pairs. QPM accumulates ~0.22 bits of order-effect asymmetry per pair, uniformly across all five input categories and both profiles. Cohen's d = 21.51 is the largest single-variable effect observed across the entire CA program.
  • H2 PASSED ✓ — QPM enters higher-entropy, lower-purity states under conflict (purity proxy 0.42 vs CMG 0.32 — closer to maximally-mixed 0.5). The effect generalises across both profiles, slightly larger on software_eng (Δ = +0.153) than on psychotherapy (Δ = +0.113).
  • H3 NOT DETECTED ✗ — paired t-test on 960 probes yields p = 0.327 with Cohen's d_z = 0.032. The 95% CI on the QPM−CMG delta is [−0.024, +0.072]. The small advantage that exists is concentrated in the Capability sub-dimension (+0.059); Trait, Episodic, and Style are essentially tied at near-ceiling / near-floor saturation.
  • Decision Rule outcome: Pre-registered §8.5 maps (H1✓, H2✓, H3✗) → "Quantum advantage confirmed at internal state level; downstream behavioural advantage not detected at current sample size. Add scope note to §2.3." The most parsimonious diagnosis is that the QPM→JSON interface discards the off-diagonal coherence/purity information that carries the internal-state QPM signal; a logits-level QPM→SLM interface is the natural next experiment.

Full Experiment 3 report: CA_Experiment_3/EXPERIMENT_REPORT.md


Experiment 4 — QPM→SLM Interface Richness Ablation

Goal: Experiment 3 diagnosed that the QPM→SLM JSON interface passes only the 11 marginal probabilities, discarding all off-diagonal coherence. Experiment 4 tests whether enriching that interface recovers a downstream behavioural advantage.

Method: Four interface conditions on identical inputs through the same QPM (byte-identical circuit, SLM stack, scripts, judge, seeds to Exp 3 Battery C) — the only variable is the QPM→structured-intent JSON. A marginals-only (control); B + purity/ambivalence scalar; C coherence-conditional speech-act modifier; D + bivariate coactivations (8 CRz-pair joint probabilities). 960 paired probes per condition.

Headline result

Condition Interface Mean PersonaScore Δ vs A p d_z
A marginals only 4.4385
B + purity/ambivalence 4.4271 −0.012 0.644 −0.015
C coherence speech-act 4.4042 −0.034 0.174 −0.044
D + bivariate coactivations 4.3792 −0.059 0.022 −0.074
  • Every enriched condition scores below A. The only significant result is Condition D — significantly worse (p = 0.022). This is not a power problem: the experiment detects a real negative effect.
  • Monotonic Episodic degradation with interface richness: E-dim A 3.396 → B 3.254 → C 3.217 → D 3.150. Richer JSON = more attention crowding = worse episodic recall. The Capability dimension shows a small consistent positive delta (+0.04–0.06), replicating Exp 3, but an order of magnitude below threshold.
  • Verdict: H_interface ✗, H_C_wins ✗, H_purity_episodic ✗, H_capability ✓. The JSON channel itself is the bottleneck — motivating Exp 5's attempt to bypass it entirely.

Full Experiment 4 report: CA_Experiment_4/EXPERIMENT_REPORT.md


Experiment 5 — Logits-Level QPM→SLM Steering via Residual-Stream Injection

Goal: Bypass the JSON channel entirely — directly modulate the SLM's residual stream with QPM-derived steering vectors — and test whether that transmits the QPM's internal-state advantage downstream.

Method: Phase 0 extracts contrastive trait/coherence steering vectors (2,400 forward passes; locked injection layer L* = 14, scale α = 7.5). Four conditions: A JSON marginals (control); B diagonal activation steering; C JSON + diagonal steering; D diagonal + coherence steering. Same SLM/scripts/judge as Exp 3–4; 960 paired probes per condition.

Headline result

Comparison Metric Δ p d_z Verdict
H_logits (B vs A) PersonaScore −0.167 2.5 × 10⁻⁹ −0.194 (significant, wrong direction)
H_coherence (D vs B) PersonaScore −0.009 0.72 −0.012 (clean null)
  • Activation steering significantly reduces PersonaScore — the effect is strong and in the wrong direction. The E (Episodic) dimension absorbs nearly all the loss (−0.475 under B): steering disrupts the model's retrieval of prior-session context while leaving trait/style intact.
  • The coherence component adds zero signal (D vs B, p = 0.72) — the same clean null the whole QPM-interface program keeps hitting. Adding the JSON channel back on top of steering (C ≈ B) recovers nothing.
  • Verdict: both hypotheses fail. Across Exp 3→4→5 the downstream QPM delta goes +0.032 → −0.074 → −0.194 — every inference-time interface is neutral-to-harmful. Diagnosis: a strong pretrained style prior beats all inference-time QPM modulation. The logical fix is a weaker-prior, weights-level install — the Experiment 6 pivot.

Full Experiment 5 report: CA_Experiment_5/EXPERIMENT_REPORT.md


Experiment 6 — A From-Scratch, Fully-Owned 321M Model as ADA's Daily-QA Agent

Goal: First test of the program's new direction — build ADA out of per-scenario, from-scratch, owned small models (offline-resilient: model + corpus need no internet to run or retrain), with the QPM compiled into the weights rather than fed to a frozen model at inference. Scenario: daily grounded QA, persona-bearing. Can a ~321M from-scratch model read retrieved context, abstain when it lacks the answer, and hold the ADA persona across a 40-turn conversation?

Method: A 321M from-scratch Llama-style decoder (RoPE/RMSNorm/SwiGLU, 16k own BPE, ctx 1024), one trunk with two heads — a causal LM head (ADA voice / persona / QPM <|persona|> channel) and a bidirectional span + answerability head (extractive reading / abstention). Pipeline: causal pretrain (FineWeb-Edu 8B) → instruction-tune (OASST2 + Dolly) → ADA SFT (owned Sonnet persona layer + QPM) for persona; prefix-LM continued-pretrain → span head for reading. Free corpora for skills; bounded Claude Sonnet 4.6 spend only for the ADA persona layer; Sonnet 4.5 as PersonaScore/QA judge.

Headline result

Hypothesis Bar Result Verdict
H1 grounded reading correct-and-grounded ≥ 0.70 0.77 (SQuAD2 F1 0.768)
H2 calibrated abstention F1 ≥ 0.80 (plan) / ≥ 0.70 (operational) 0.783 ⚠️
H3 persona (PersonaScore) ≥ 3.5 3.80 (R0)
H4 SCI refresh classify refresh-unnecessary (Δ = −0.04)
RQ6 QPM-as-weight-supervision on vs off neutral at strong baking (3.795 vs 3.786)
  • H3 was the hard part. Persona failed at 160M (~2.2) and on the first 300M attempt (2.13); a diagnosis-driven data arc — brevity + salient-event recall (→3.12), then a consistency generator (mid-session self-probes under factoid pressure, →3.80) — cleared it. The former anchor E moved 2.56 → 3.29; per-turn curve is flat (T* = None); judge κ_w = 0.99.
  • H4 refresh-unnecessary: a weight-baked persona holds 40 turns with no SCI re-injection — contradicting Exp 1's frozen-model result, confirming the baking hypothesis.
  • RQ6 clears the interface-null: compiling the QPM into the weights lets its signal cross the boundary as supervision (unlike Exp 3–5's frozen interfaces); its behavioural contribution is marginally positive when the persona is weakly baked and neutral once strongly baked — never harmful.
  • H2 caps ~0.78: clears the operational 0.70 bar and beats the 160M (0.73), but ~0.02 under the plan's aspirational 0.80. This is a pretraining-objective gap (causal trunk + short bidirectional retrofit vs native MLM), not a scale gap (321M ≈ BERT-large) — and the price of keeping the trunk generative so it can be ADA.
  • Operational verdict: ✓✓✓ — the per-scenario, owned-from-scratch direction is validated on its first scenario. Runs fully offline (int8 ~150–300 MB; ~50–100 tok/s on a Jetson Orin Nano).

Full Experiment 6 report: CA_Experiment_6/EXPERIMENT_REPORT.md


Experiment 7 — Long-Horizon Episodic Memory for the ADA Daily-QA Agent

Goal: Exp 6 gave ADA a persona and grounded reading over 40 turns. A daily agent runs for months. Can the owned 321M model remember what it was told hundreds of turns ago, at a per-turn cost that does not grow with the conversation — and hold its persona while doing it?

Method: An episodic-RAG layer over the Exp 6 model: facts are planted in conversation, written to a memory store, then recalled after a controlled lag. Retrieval is MiniLM over stored turns; the answer is produced by extract-then-style — the bidirectional span head reads the retrieved turn, the causal LM head phrases it in ADA's voice. Conditions C0/C1 (stateless baselines) through C2 (full memory), evaluated over 100–500-turn scripts, with an oracle-store arm isolating read accuracy from write accuracy.

Headline result

Hypothesis Bar Result Verdict
H1 statelessness floor recall ≈ 0 without memory 0.00 (C0/C1), persona flat ~3.9
H2 episodic-RAG recall ≥ 0.70 read 0.81 oracle / 0.54 end-to-end ⚠️
H3 persona at length ≥ 3.5 over 100–500 turns 3.79
H4 bounded cost O(1) per turn 1.01×
  • The read mechanism works; the write is the bottleneck. The span head clears 0.70 at every lag (oracle 0.81), and end-to-end recall (0.54) is 2.7× the purely generative path (0.20) and infinitely better than the stateless floor (0.00) — but it lands under the aspirational bar because the small model's write-side plant quality caps it, not its reading.
  • Extract-then-style adopted as the memory architecture: discriminative head for recall, generative head for voice.
  • Memory-aware SFT recorded as a dead end at this scale — the pre-registered Phase B did not pay off, and the open write-side boundary is closed by the program's own fallback (a larger pretrained reader for the memory-heavy write path) while persona and scaffolding stay owned-and-small.

Full Experiment 7 report: CA_Experiment_7/EXPERIMENT_REPORT.md


Experiment 8 — Dynamic-Memory Self-Model and a Re-Grounded E Dimension

Goal: Exp 6's SCI carried baked fictional salient_past_events — day-1 memories of things that never happened, and the thing the Episodic dimension was scored against. Replace them with a live cross-session Episodic Register, re-ground E on dynamic recall through Exp 7's extract-then-style path, and find out whether the fictional events can be removed without taking the persona with them.

Method: A dynamic SCI renderer that reads the live register instead of a fixture, plus a short Stage-C re-fit onto a dispositional-only self-model. Multi-session scripts with session gaps 1–3; arms B0 (Exp 6 baseline), D0 (register disabled) and D1 (register on) separate what the weights remember from what the register supplies.

Headline result

Hypothesis Bar Result Verdict
H1 no false day-1 memories ≥ 90% disclaim ~80% (0.2 false-memory) ⚠️
H2 dynamic recall ≥ 0.70, E ≥ 3.29 0.85, E 4.14
H3 persona intact ≥ 3.5, within −0.2 of 3.80 4.10
H4 multi-session bounded no decay, ≤ 1.5× spread 0.03, ~102 tok/turn
  • The mechanism is unambiguous. Cross-session recall reaches 0.85, flat across session gaps (0.84 / 0.84 / 0.875), with zero fabrication on the recall path. Turn the register off and the same model recalls 0.00 — so recall comes entirely from the register, not the weights.
  • Un-baking is where it resists. A re-fit onto a dispositional-only self-model cuts day-1 confabulation 0.85 → ~0.2 with persona preserved (T/C/S 4.10); pushing the un-bake to completion clears H1 (0.025) but collapses the persona into a disclaim attractor (T/C/S 2.5). On a contaminated base you can keep the persona or finish the un-bake, not both — the residual is verbatim leakage of the baked fixture.
  • The design lesson: baking episodic content into weights was the upstream error. The fix is not a better retrofit but a clean Stage-C from a self-model that never carried baked events — cheap, because episodic content enters the weights only at Stage C.

Full Experiment 8 report: CA_Experiment_8/EXPERIMENT_REPORT.md


MVP ADA — the architecture as a running application

MVP_ADA/ is where the surviving findings are assembled into something you can talk to: an offline desktop assistant running the full four-layer pipeline — Observation → Computation → Generation → Surface — on a machine with no GPU.

It runs the Exp 6/8 owned model behind extract-then-style, the live Episodic Register from Exp 8, the 12-qubit QPM behind the R-gate, a four-backend knowledge stack (Kùzu, QLever, Kiwix/ZIM, MiniLM title index), Kokoro TTS and Sherpa-ONNX Whisper STT, and a DORFic wireframe face whose visemes are driven from the real audio envelope. See MVP_ADA/README.md.


Documentation

docs/ is a static HTML reference for the whole repository — every class, method, property, function, module-level variable and constant, what each does and where else it is used, plus a glossary of the terminology and abbreviations used across the program. Open docs/index.html in a browser.

It documents the code; the experimental record stays in each directory's EXPERIMENT_REPORT.md and in the architecture specs. Signatures, constants and docstrings are extracted from the source AST, so the reference cannot drift from the implementation. Rebuild with:

python docs-src/extract_api.py      # re-scan the source tree (after code changes)
python docs-src/generate.py         # rebuild docs/ from docs-src/

Repository layout

Centaurian_Architecture_v3.md     # Current architecture spec
Centaurian_Architecture_v2.md     # Previous architecture spec
Interpretable_Architectures_Revised_v1.md  # Position paper

CA_Experiment_1/
├── EXPERIMENT_REPORT.md                 # Full Phase 1 + 2 report
├── experiment_runner.py                 # Main experiment pipeline
├── generate_scripts.py                  # Template-based script generator
├── analyse_results.py                   # Analysis and visualization
├── interrater_check.py                  # Inter-rater reliability checker
├── CA_Experiment1_Colab.ipynb          # Google Colab notebook
├── logs_qwen2.5_7b{,_refresh13,_refresh13_28,
│   _episodic_rag,_episodic_rag_hybrid,
│   _refresh13_episodic_rag}/            # Per-condition score & context logs
└── results_qwen2.5_7b*/                 # Charts, fits, summary reports

CA_Experiment_2/
├── EXPERIMENT_REPORT.md                 # Full Experiment 2 report
├── CA_Experiment2_Plan.md              # Pre-registered plan
├── ca_assets.py                        # Shared persona, probes, rubrics, RAG helpers
├── generate_lora_dataset.py             # Sonnet 4.6 dataset generator with QC
├── train_lora_sci.py                    # QLoRA training (transformers + PEFT + TRL)
├── experiment_runner.py                 # 4-condition + H5 evaluator (HF + PEFT)
├── analyse_results.py                   # Multi-condition analysis + plots
├── make_slides.py                       # Generates the conference deck (python-pptx)
├── CA_Experiment2_Colab.ipynb          # Google Colab notebook
├── h4_probes.json                       # H4 base-capability probe set (100 prompts × 5 categories)
├── run_h4.py                            # H4 runner — base vs LoRA-10K on out-of-domain probes
├── analyse_h4.py                        # H4 analysis — paired t-test + per-category degradation
├── data/full.jsonl                      # 10K training examples (QC-passed)
├── adapters/lora_{2k,5k,10k}/           # LoRA adapter weights (gitignored)
├── logs/condition_{A,B,C,D,
│   C_lora_2k,C_lora_5k}/                # Per-condition score & context logs
├── logs/h4_{base,lora}/                 # H4 base-capability test logs
└── results/                             # Plots, analysis_data.json, summary report

CA_Experiment_3/
├── EXPERIMENT_REPORT.md                 # Full Experiment 3 report
├── CA_Experiment3_Plan.md              # Pre-registered plan (decision rule §8.5)
├── qpm.py                               # 12-qubit Qiskit Aer QPM circuit
├── cmg_cdk.py                           # Matched classical baseline (CMG-CDK)
├── ca_assets.py                         # Profiles, Battery A pairs, B scenarios, d-vec extractor,
│                                        #   QPM→structured-intent, Exp-2 SCI re-exports
├── experiment_runner.py                 # Battery A/B/C/H4 dispatcher (resumable)
├── analyse_results.py                   # Paired t-tests, Cohen's d, decision-rule emission
├── CA_Experiment3_Colab.ipynb          # Google Colab notebook (12 cells)
├── logs/battery_h4_psychotherapy/       # H4 variance-calibration output
├── logs/battery_a_{psychotherapy,
│   software_eng}/                       # Per-pair JSD values (both models)
├── logs/battery_b_{psychotherapy,
│   software_eng}/                       # Per-scenario entropy + purity values
├── logs/battery_c_{psychotherapy,
│   software_eng}/                       # Per-probe judge scores + per-turn context tracking
└── results/                             # Plots, analysis_data.json, summary_report.md

CA_Experiment_4/
├── EXPERIMENT_REPORT.md                 # Full Experiment 4 report
├── CA_Experiment4_Plan.md              # Pre-registered plan (4 interface conditions)
├── ca_assets.py                         # Profiles + 4 QPM→structured-intent interface variants
├── qpm.py                               # 12-qubit QPM circuit (shared)
├── experiment_runner.py                 # A/B/C/D condition dispatcher (resumable)
├── analyse_results.py                   # Paired t-tests, per-dimension deltas, decision rule
├── CA_Experiment4_Colab.ipynb          # Google Colab notebook
├── logs/                                # Per-condition score & context logs
└── results/                             # Plots, analysis_data.json, summary report

CA_Experiment_5/
├── EXPERIMENT_REPORT.md                 # Full Experiment 5 report
├── CA_Experiment5_Plan.md              # Pre-registered plan (residual-stream steering)
├── steering_vectors.py                  # Phase-0 contrastive vector extraction
├── steering_config.json                 # Locked L*=14, α=7.5 params (SHA-256 pinned)
├── phase0_L_star.json, phase0_activations/   # Layer calibration + extracted activations
├── experiment_runner.py                 # A/B/C/D condition dispatcher (resumable)
├── analyse_results.py                   # Paired t-tests, decision rule
├── CA_Experiment5_Colab.ipynb          # Google Colab notebook
├── calibration_scripts/, logs/          # Held-out calibration + per-condition logs
└── results/                             # Plots, analysis_data.json, summary report

CA_Experiment_6/
├── EXPERIMENT_REPORT.md                 # Full Experiment 6 report
├── CA_Experiment6_Plan.md              # Pre-registered plan (v2.1, QPM-in-scope)
├── ada_sci.json                         # ADA self-model (SCI)
├── ca_assets.py                         # SCI, chat template + special tokens, record schema,
│                                        #   PersonaScore harness (probes/rubrics/judge/κ)
├── model/                               # From-scratch transformer (RoPE/RMSNorm/SwiGLU) + configs
├── qpm.py, qpm_bridge.py                # QPM circuit + ADA profile/d-vector → persona_state
├── tokenizer_util.py, train_tokenizer.py    # 16k BPE loader + trainer
├── prepare_data.py                      # Stage-A shards + SQuAD2/OASST2/Dolly → §4.3 records
├── gen_persona_data.py                  # Sonnet — persona/consistency/introspect/recall/instruct/…
├── data_utils.py                        # Pretrain bins + SFT assistant-span masking
├── train_pretrain.py                    # Stage A (causal) + Stage A2 (prefix-LM continued)
├── train_sft.py                         # Stage B/C SFT (assistant-span masked, persona channel)
├── train_span.py, span_utils.py         # Extractive span + answerability head (reading)
├── retriever.py, rerank_util.py         # Symbolic extract-then-style + sentence reranker
├── evaluate.py                          # H1/H2 QA + H3 PersonaScore + H4 refresh + judge + analyse
├── train_common.py                      # Seed, cosine LR, checkpoint I/O (Drive-dedup safe)
├── CA_Experiment6_300M_Colab.ipynb     # End-to-end Colab notebook (300M run)
├── data/, tokenizer/, checkpoints/      # Corpora/tokenizer/weights live on Drive (gitignored)
└── results/                             # Scores, judge output, figures, analysis_data.json (committed)

CA_Experiment_7/
├── EXPERIMENT_REPORT.md                 # Full Experiment 7 report
├── CA_Experiment7_Plan.md              # Pre-registered plan (long-horizon memory)
├── memory_store.py                      # Episodic store + MiniLM retrieval, O(1) per-turn budget
├── compact_sci.py                       # Token-bounded SCI renderer for long conversations
├── gen_long_scripts.py                  # 100–500-turn plant/recall scripts with controlled lag
├── gen_memory_sft.py                    # Phase-B memory-aware SFT data (recorded as a dead end)
├── evaluate_longhorizon.py              # C0/C1/C2 + oracle-store arms, recall/persona/cost
├── analyse_results.py                   # Recall by lag, persona curve, cost ratio, verdicts
├── CA_Experiment7_Colab.ipynb          # Google Colab notebook
├── data/                                # Generated scripts + SFT records (gitignored)
└── results*/                            # Per-arm scores, figures, analysis_data.json

CA_Experiment_8/
├── EXPERIMENT_REPORT.md                 # Full Experiment 8 report
├── CA_Experiment8_Plan.md              # Pre-registered plan (dynamic self-model, re-grounded E)
├── episodic_register.py                 # Live cross-session register (replaces baked events)
├── compact_sci_dynamic.py               # SCI renderer reading the register, not a fixture
├── gen_multisession_scripts.py          # Multi-session scripts, session gaps 1–3
├── gen_consistency_dynamic.py           # Consistency probes against dynamic memory
├── gen_disclaim_data.py                 # Day-1 disclaim data for the un-bake re-fit
├── build_refit_sft.py                   # Stage-C re-fit set (dispositional-only self-model)
├── evaluate_dynamic_e.py                # B0/D0/D1 arms — recall, fabrication, re-grounded E
├── analyse_results.py                   # H1–H4 table, decision branches, figures
├── CA_Experiment8_Colab.ipynb          # Google Colab notebook
├── data/                                # Scripts + generated SFT records (gitignored)
└── results/                             # Scores, figures, analysis_data.json

MVP_ADA/                                 # The architecture as a running offline application
├── README.md, MVP_ADA_Plan.md           # Usage + design/integration plan
├── app.py                               # Threaded backend worker + full turn pipeline
├── config.py                            # Paths, model settings, feature flags
├── ada_core/                            # Pinned vendored snapshot of the Exp 6/7/8 model stack
├── observation/                         # STT + d-vector feature decoder
├── computation/                         # QPM (R-gated), BDI-lite, SMC, knowledge/ backends
├── generation/                          # Extract-then-style answer construction
├── surface/                             # Kokoro TTS
├── ui/                                  # raylib window, DORFic theme, wireframe face
└── data/                                # Knowledge stores, models, register (gitignored)

docs/                                    # Generated HTML code reference — open docs/index.html
docs-src/                                # Its inputs: AST extractor, generator, curated notes

Running the experiments

Prerequisites: Python 3.10+, an Anthropic API key, and access to GPU compute (Colab Pro recommended for training; T4 sufficient for Experiment 1 evaluation; A100 80GB needed for Experiment 2).

Experiment 1

cd CA_Experiment_1
pip install ollama anthropic python-dotenv numpy scipy matplotlib
echo "CHA_EXPERIMENT_SONNET_KEY=sk-..." > .env

python generate_scripts.py
python experiment_runner.py --model qwen2.5:7b
python analyse_results.py --model qwen2.5:7b

# Phase 2 interventions
python experiment_runner.py --model qwen2.5:7b --refresh-turn 13
python experiment_runner.py --model qwen2.5:7b --episodic-rag
python experiment_runner.py --model qwen2.5:7b --refresh-turn 13 --episodic-rag
python experiment_runner.py --model qwen2.5:7b --refresh-turns 13,28

Or use CA_Experiment_1/CA_Experiment1_Colab.ipynb for GPU-accelerated runs.

Experiment 2

cd CA_Experiment_2
pip install transformers peft trl bitsandbytes accelerate datasets \
            anthropic python-dotenv sentence-transformers numpy scipy matplotlib

# Dataset generation (~12 hrs, ~$80 in API calls)
python generate_lora_dataset.py --target 10000

# Train adapters (Colab A100 80GB)
python train_lora_sci.py --train-rows 2000  --output adapters/lora_2k
python train_lora_sci.py --train-rows 5000  --output adapters/lora_5k
python train_lora_sci.py --train-rows 10000 --output adapters/lora_10k

# 4-condition evaluation + H5 sub-runs
python experiment_runner.py --condition A --adapter adapters/lora_10k
python experiment_runner.py --condition B --adapter adapters/lora_10k
python experiment_runner.py --condition C --adapter adapters/lora_10k
python experiment_runner.py --condition D --adapter ""
python experiment_runner.py --condition C --adapter adapters/lora_2k --logs-suffix lora_2k
python experiment_runner.py --condition C --adapter adapters/lora_5k --logs-suffix lora_5k

# Analysis
python analyse_results.py

Or use CA_Experiment_2/CA_Experiment2_Colab.ipynb for the full pipeline end-to-end.

H4 base-capability test (Experiment 2 follow-up)

Out-of-domain probe battery (100 prompts × 5 categories: general knowledge, code reasoning, math, instruction following, structured intent JSON) verifying that the LoRA-10K adapter does not cause catastrophic forgetting. Pass criterion: < 5% mean degradation on Sonnet 4.5 1-5 scoring.

cd CA_Experiment_2

# Generate responses from both conditions (A100 80GB, ~30 min each)
python run_h4.py --condition base
python run_h4.py --condition lora --adapter lora_10k

# Analysis (paired t-test, per-category degradation, verdict)
python analyse_h4.py

Outputs results/h4_summary_report.md, results/h4_analysis_data.json, and two comparison plots.

Experiment 3

cd CA_Experiment_3
pip install qiskit qiskit-aer pylatexenc numpy scipy matplotlib \
            vaderSentiment anthropic python-dotenv \
            transformers peft bitsandbytes accelerate

# Variance calibration first — must PASS (SNR ≥ 3.0) before main batteries
python experiment_runner.py --battery H4 --profile psychotherapy

# Battery A — order effects (H1, no GPU)
python experiment_runner.py --battery A --profile psychotherapy
python experiment_runner.py --battery A --profile software_eng

# Battery B — ambivalence (H2, no GPU)
python experiment_runner.py --battery B --profile psychotherapy
python experiment_runner.py --battery B --profile software_eng

# Battery C — downstream PersonaScore (H3, A100 GPU, ~4 hr per profile)
python experiment_runner.py --battery C --profile psychotherapy --adapter lora_10k
python experiment_runner.py --battery C --profile software_eng  --adapter lora_10k

# Analysis (paired t-tests, decision-rule emission)
python analyse_results.py --profile psychotherapy

Battery C requires Experiment 2's adapters/lora_10k/ on disk (loaded relative to CA_Experiment_2/). Or use CA_Experiment_3/CA_Experiment3_Colab.ipynb for the full end-to-end pipeline on Colab.

Experiments 4 and 5

Both reuse Experiment 3's QPM circuit, Qwen2.5-7B-Instruct + LoRA-10K stack, 30 scripts, and Sonnet 4.5 judge — varying only the QPM→SLM interface. Same dependencies as Experiment 3.

cd CA_Experiment_4          # richer JSON interface: 4 conditions
python experiment_runner.py --condition {A,B,C,D}
python analyse_results.py

cd ../CA_Experiment_5        # residual-stream steering
python steering_vectors.py                       # Phase 0: extract + lock vectors (L*=14, α=7.5)
python experiment_runner.py --condition {A,B,C,D}
python analyse_results.py

Or use each experiment's Colab notebook for the end-to-end pipeline.

Experiment 6

A from-scratch 321M model — a multi-stage pipeline (Colab A100). Free corpora for skills; bounded Sonnet 4.6 spend only for the ADA persona layer. The large artifacts (corpora, tokenizer, checkpoints) live on Drive; results/ is committed.

cd CA_Experiment_6
pip install torch tokenizers datasets anthropic python-dotenv qiskit qiskit-aer vaderSentiment

# --- Persona track (H3/H4/RQ6) ---
python prepare_data.py pretrain --hf-dataset HuggingFaceFW/fineweb-edu --max-tokens 8_000_000_000
python train_pretrain.py --config 300m --run-name pretrain_300m --max-steps 40000        # Stage A
python prepare_data.py oasst && python prepare_data.py dolly --append                     # Stage-B substrate
python train_sft.py --init pretrain_300m_best.pt --sft data/instruct.jsonl --run-name sft_instruct  # Stage B
python gen_persona_data.py consistency --brevity     # + introspect/recall/instruct/persona/style/refusal
python train_sft.py --init sft_instruct_final.pt --sft data/qa_sft.jsonl --run-name sft_ada \
    --persona-oversample 3 --reading-cap 5000 --max-steps 1400                            # Stage C
python evaluate.py persona --checkpoint sft_ada_final.pt --condition R0   # + R1, + --no-qpm ablation
python evaluate.py judge-reliability --scores-dir results/persona_R0

# --- Reading track (H1/H2) ---
python train_pretrain.py --config 300m --init pretrain_300m_best.pt --prefix-lm \
    --run-name pretrain_300m_plm --max-steps 12000                                        # Stage A2
python train_span.py --init pretrain_300m_plm_best.pt --span data/qa_span.jsonl           # span + ans head
python evaluate.py qa --checkpoint span_final.pt --span --answerable-threshold 0.70       # H1/H2

python evaluate.py analyse --results-dir results     # H1-H4 decision table + figures

Or use CA_Experiment_6/CA_Experiment6_300M_Colab.ipynb for the full end-to-end run.

Experiment 7

Episodic memory over the Exp 6 checkpoints — no new training on the critical path, so this runs on a single GPU (or CPU, slowly). --oracle-store is the arm that separates read accuracy from write accuracy; --stub-embedder and --dry-run-judge let the harness be smoke-tested without MiniLM or API spend.

cd CA_Experiment_7
pip install torch tokenizers sentence-transformers anthropic python-dotenv qiskit qiskit-aer

# 100–500-turn plant/recall scripts with controlled lag
python gen_long_scripts.py --turn-lengths 100,200,350,500 --lags 1,5,20

# C0/C1 stateless floors, then C2 with memory; add --oracle-store for the read-only arm
python evaluate_longhorizon.py --condition C0 --checkpoint <sft_ada>.pt --span-checkpoint span_final.pt
python evaluate_longhorizon.py --condition C2 --checkpoint <sft_ada>.pt --span-checkpoint span_final.pt \
    --top-k 5 --memory-budget 512 --rerank

python analyse_results.py --results-dir results     # recall by lag, persona curve, cost ratio

Experiment 8

Swaps Exp 6's baked salient_past_events for a live register, then re-fits Stage C onto a dispositional-only self-model. The generators call Sonnet; --dry-run prices a run without spending.

cd CA_Experiment_8
pip install torch tokenizers sentence-transformers anthropic python-dotenv qiskit qiskit-aer

# multi-session scripts with session gaps 1–3, plus day-1 probes
python gen_multisession_scripts.py --n-users 20 --sessions-per-user 4 --day1-probes 40

# re-fit data: day-1 disclaim + dynamic-memory consistency → Stage-C set
python gen_disclaim_data.py --budget 100 --out data/qa_sft_disclaim.jsonl
python gen_consistency_dynamic.py --budget 100 --brevity --out data/qa_sft_consistency_dynamic.jsonl
python build_refit_sft.py --in data/qa_sft.jsonl --disclaim data/qa_sft_disclaim.jsonl \
    --consistency-dynamic data/qa_sft_consistency_dynamic.jsonl --out data/qa_sft_refit.jsonl
# then Stage C via CA_Experiment_6/train_sft.py against data/qa_sft_refit.jsonl

# B0 baseline, D0 register-off, D1 register-on
python evaluate_dynamic_e.py --condition D1 --dynamic-checkpoint <refit>.pt \
    --span-checkpoint span_final.pt --top-k 5 --rerank
python analyse_results.py --results-dir results     # H1–H4 table + figures

Note: gen_disclaim_data.py and gen_consistency_dynamic.py append to their output file rather than truncating it. Re-running a generator doubles the dataset instead of replacing it — delete the file first, or check the record count before training.


Running MVP ADA

cd MVP_ADA
python3 -m venv .venv
.venv/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu   # or a CUDA wheel
.venv/bin/pip install numpy scipy "tokenizers<=0.23.0" raylib \
                      kuzu libzim requests sentence-transformers \
                      qiskit qiskit-aer sherpa-onnx

.venv/bin/python app.py              # open the window
.venv/bin/python app.py --selftest   # headless: load + greeting + 5-lane QA check

The Exp 6/8 checkpoints, the knowledge stores (Kiwix ZIM, QLever, Kùzu, MiniLM title index) and the audio models are multi-GB and not committed — MVP_ADA/README.md has the one-time setup for each, and MVP_ADA/config.py carries every path and feature flag.


License

See repository for license details.