A small, self-contained lab for demonstrating coherence drift: systems where an internal objective improves while an external objective stalls or degrades.
The project links three regimes:
-
Toy coherence-drift metric
src/metrics/coherence_drift.py- Sliding-window deltas over internal
J_intand externalJ_ext - Flags pathological windows where:
- ?J_int > 0 and ?J_ext = 0
-
EURISKO-style heuristic simulation
src/eurisko_sim/simple_eurisko.py- Benign vs. pathological credit-assignment regimes
src/metrics/run_eurisko_drift.py:- compares benign vs. pathological runs
src/metrics/eurisko_sweep.py:- sweeps seeds/regimes and writes
data/processed/eurisko_sweep.csv
- sweeps seeds/regimes and writes
-
LLM probes (GPT-2 via HuggingFace)
src/llm_tests/llm_probe.py:- single-run probe with hand-coded external correctness
J_ext
- single-run probe with hand-coded external correctness
src/llm_tests/llm_probe_batch.py:- logprob-based internal objective and simple external labels
- Both use a small set of factual questions to illustrate misalignment between internal confidence and external truth.
Nice. Repo, LICENSE, issue templates, CI, and requirements are all in place. The next most efficient move is to lock in a clear README so anyone (including Future You) can understand and re-run the experiments.
Below is a drop-in README.md you can paste over your current one (or merge as you prefer).
# coherence-drift-lab
Small, self-contained lab for testing **coherence drift**:
> When an optimization objective over *internal coherence* (J_int) drifts away from an external reality/grounding objective (J_ext).
The lab implements the core hypothesis:
> Pathology occurs when the system keeps improving its internal score while external performance stalls or degrades:
>
> \[
> \Delta J_\text{int} > 0 \quad\text{and}\quad \Delta J_\text{ext} \le 0
> \]
You can probe this both in a toy **EURISKO-style heuristic system** and in a small **LLM question–answer loop**.
---
## Contents
- `src/eurisko_sim/`
- `simple_eurisko.py` – toy EURISKO-style search with:
- **benign regime**: internal and external scores move together
- **pathological regime**: internal score self-credits even when external is flat
- `src/metrics/`
- `coherence_drift.py` – core definitions:
- sliding-window deltas for J_int, J_ext
- pathology detection: `dJ_int > 0` and `dJ_ext <= 0`
- summary stats over windows
- `run_eurisko_drift.py` – single-run demo (benign vs pathological)
- `eurisko_sweep.py` – multi-seed sweep over regimes, writes CSV
- `run_all_tests.py` – **one entrypoint** that runs all experiments
- `src/llm_tests/`
- `llm_probe.py` – single-run LLM probe:
- handcrafted J_ext signal over a few factual questions
- `llm_probe_batch.py` – batched LLM probe:
- J_int from token logprobs
- simple J_ext rule per question
- `configs/`
- `questions_basic.yaml` – basic factual questions used by the LLM probes
- `data/processed/`
- `eurisko_sweep.csv` – multi-run summary for benign vs pathological EURISKO regimes
- `llm_probe_steps.csv`, `llm_probe_windows.csv`, `llm_probe_batch.csv` – logged trajectories and window stats for LLM tests
---
## Installation
Tested on Python 3.11 on Windows.
```bash
git clone https://github.com/btisler-DS/coherence-drift-lab.git
cd coherence-drift-lab
python -m venv .venv
.\.venv\Scripts\activate # on Windows PowerShell
pip install -r requirements.txtThis will:
- Run benign vs pathological EURISKO single-run drift demo.
- Sweep multiple seeds in both regimes and write
data/processed/eurisko_sweep.csv. - Run a toy LLM probe with a hand-coded J_ext signal.
- Run the logprob-based LLM batch probe.
python -m src.metrics.run_all_testsYou should see output along the lines of:
-
EURISKO single-run:
- benign regime:
frac_pathological ≈ 0.0 - pathological regime: small but non-zero
frac_pathologicalover windows
- benign regime:
-
EURISKO sweep:
- benign: fraction pathological near 0 for all seeds
- pathological: higher final J_int, same J_ext on average, and non-zero pathological fraction
-
LLM probes:
- toy and batch runs printing J_int / J_ext over time and an aggregate pathology fraction
These numbers are not meant to be final results – they’re scaffolding for coherent drift experiments.
-
For EURISKO-style simulations:
- J_int is an internal score the system tries to improve (e.g., heuristic score).
-
For LLM probes:
- J_int is derived from token log probabilities (higher likelihood → higher internal “confidence”).
-
For EURISKO-style simulations:
- J_ext is an external score that only improves when moves are actually “good” in environment terms.
-
For LLM probes:
-
J_ext is a simple correctness signal per question:
- 1 when the answer matches the known ground truth (e.g., “Paris” for capital of France).
- 0 otherwise.
-
coherence_drift.py computes sliding windows:
-
For each window
[t_start, t_end]:dJ_int = J_int[end] - J_int[start]dJ_ext = J_ext[end] - J_ext[start]
-
A window is flagged as pathological if:
dJ_int > 0anddJ_ext <= 0
The summaries report:
- total number of windows
- number of pathological windows
- fraction pathological
This repo includes a minimal CI workflow:
-
File:
.github/workflows/ci.yml -
On each push, CI will:
-
set up Python
-
install
requirements.txt -
run:
python -m src.metrics.run_all_tests
-
If the coherence-drift tests fail, the GitHub Actions run will fail.
You can add a badge like:
[](https://github.com/btisler-DS/coherence-drift-lab/actions/workflows/ci.yml)Under .github/ISSUE_TEMPLATE/:
bug_report.md– for failing cases or unexpected behaviorfeature_request.md– for proposing new experiments or metrics
They’re intentionally simple: summary, steps to reproduce, expected/actual behavior, environment, and references.
This project is licensed under the MIT License – see LICENSE for details.
---
If you paste that into `README.md` and commit, you’ll have:
- A clean entrypoint (`run_all_tests`)
- Documented metrics
- Clear experiment structure
- CI behavior explained
Next natural step *after* that (no action needed yet) would be a tiny `src/plots/` script to visualize one EURISKO trajectory and one LLM trajectory, but we can handle that once the README is locked in.
::contentReference[oaicite:0]{index=0}
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt