Cassandra is a research workspace with two connected tracks:
AGENT.md· a working reference for accountable protective AI systems.docs/LOW_HARDWARE_LM_RESEARCH.md· a laptop-scale language-model research program.
The second track asks a deliberately narrow version of a large dream:
Can useful language-model behavior be formed on consumer hardware by reducing brute-force gradient training through structure, reuse, compression, retrieval, search, or analytic initialization?
This is not yet a claim that a laptop can build a frontier LLM. It is a lab for testing smaller claims honestly, then keeping only the ones that survive.
The Stage 61 flagship is public on Hugging Face as mertefesensoy/cassandra-200m-text8.
Its model card describes a
201,609,249-parameter decoder-only character-level language model trained from
scratch on text8 (cleaned lowercase Wikipedia) on a single laptop GPU, at
1.336061 text8 test bits/char on the released fp16 weights. It is a research and
education artifact, not a product: it writes fluent, Wikipedia-flavored prose
locally but drifts off topic across long generations (see the card's Limitations).
To sample, put the weights, config.json and codec.json from the model page
in experiments/tiny_language_lab/ and run this from that folder:
from flagship_eval_lib import load_model_from_safetensors, sample_text
model, codec, config, meta = load_model_from_safetensors(
"stage61_pure_broad_200m_text8_fp16.safetensors",
"config.json", "codec.json", device="cuda", # or "cpu"
)
print(sample_text(model, codec, prompt="the history of ", max_new_chars=400,
temperature=0.8, top_p=0.9, seed=7, device="cuda"))inference_example.py does the same for three prompts, and
reproduce_text8_eval.py re-scores the text8 test split on the released weights.
Cassandra now uses three model-facing role files:
CODEX.md: executable experiments, tests, runs, and stage documentation.GEMINI.md: outside research, prior art, and world comparison.CLAUDE.md: hypotheses, ADRs, and roadmap decisions.
The intended loop is: Gemini researches the world, Claude turns that context into hypotheses and decisions, and Codex turns those hypotheses into measured local experiments.
The first runnable artifact is a character-level bigram lab. Run it from the repository root; the first command writes the deterministic structured corpus that a fresh clone needs:
python .\experiments\tiny_language_lab\make_synthetic_corpus.py --lines 320 --seed 20260616
python .\experiments\tiny_language_lab\cassandra_tiny_lm.py --method count --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\cassandra_tiny_lm.py --method coordinate --steps 300 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\cassandra_tiny_lm.py --method gradient --steps 300 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txtThe same commands in bash:
python experiments/tiny_language_lab/make_synthetic_corpus.py --lines 320 --seed 20260616
python experiments/tiny_language_lab/cassandra_tiny_lm.py --method count --prompt "cassandra " --corpus experiments/tiny_language_lab/corpus/structured_seed.txt
python experiments/tiny_language_lab/cassandra_tiny_lm.py --method coordinate --steps 300 --prompt "cassandra " --corpus experiments/tiny_language_lab/corpus/structured_seed.txt
python experiments/tiny_language_lab/cassandra_tiny_lm.py --method gradient --steps 300 --prompt "cassandra " --corpus experiments/tiny_language_lab/corpus/structured_seed.txtThe structured corpus (25,586 characters) is gitignored, so it never shows
in git status. Without --corpus, the scripts read corpus/tiny_seed.txt,
the original 1,129-character project-prose corpus behind the first table in
experiments/tiny_language_lab/RESULTS.md. That file is not in the repository,
so on a fresh clone they stop and print the commands above. Numbers on the
structured corpus differ from that table.
The three methods share the same parameter surface:
countconstructs parameters directly from corpus statistics, with no gradient training.coordinatechanges one parameter at a time and keeps changes that reduce loss.gradientuses normal backpropagation as the control condition.
The point is not that bigrams are enough. The point is to make Cassandra's core question measurable before moving to transformers.
A tiny causal transformer baseline is also available:
python .\experiments\tiny_language_lab\cassandra_tiny_transformer.py --steps 200 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\cassandra_tiny_transformer.py --init count-bigram --steps 50 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\cassandra_tiny_transformer.py --residual-base count-bigram --residual-l2 1.0 --steps 50 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\cassandra_tiny_transformer.py --residual-base count-bigram --train-scope adapters --adapter-rank 4 --steps 50 --prompt "cassandra " --corpus .\experiments\tiny_language_lab\corpus\structured_seed.txt
python .\experiments\tiny_language_lab\make_synthetic_corpus.py --lines 320 --seed 20260616
python .\experiments\tiny_language_lab\cassandra_compare.py --steps 50 --eval-batches 16 --seeds 7 11 19
python .\experiments\tiny_language_lab\cassandra_compare.py --steps 50 --eval-batches 16 --seeds 7 11 19 --configs random_full count_prior_head count_prior_adapter_r4 count_prior_lora_r1 count_prior_lora_r2 --out .\experiments\tiny_language_lab\runs\stage6_lora.jsonl --summary .\experiments\tiny_language_lab\runs\stage6_lora.md --title "Stage 6 LoRA Summary"
python .\experiments\tiny_language_lab\make_long_context_corpus.py --lines 512 --seed 20260617
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 100 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --seeds 7 11 19 --configs random_full count_prior_head count_prior_adapter_r4 count_prior_lora_r2 --out .\experiments\tiny_language_lab\runs\stage7_long_context.jsonl --summary .\experiments\tiny_language_lab\runs\stage7_long_context.md --title "Stage 7 Long-Context Summary"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-loss-weight 200 --seeds 7 11 19 --configs random_full_copyw count_prior_lora_r2_copyw --out .\experiments\tiny_language_lab\runs\stage8_copy_weight200.jsonl --summary .\experiments\tiny_language_lab\runs\stage8_copy_weight200.md --title "Stage 8 Copy Weight 200 Summary"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-sample-fraction 0.25 --copy-loss-weight 200 --seeds 7 11 19 --configs random_full_copymix count_prior_lora_r2_copymix --out .\experiments\tiny_language_lab\runs\stage9_mixed_sampler_weight200.jsonl --summary .\experiments\tiny_language_lab\runs\stage9_mixed_sampler_weight200.md --title "Stage 9 Mixed Sampler Weight 200"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 200 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-loss-weight 50 --copy-choice-weight 0.25 --seeds 7 11 19 --configs random_full_copyw_choice count_prior_lora_r2_copyw_choice --out .\experiments\tiny_language_lab\runs\stage10_choice_loss_weight025.jsonl --summary .\experiments\tiny_language_lab\runs\stage10_choice_loss_weight025.md --title "Stage 10 Choice Loss Weight 0.25"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-loss-weight 200 --copy-sample-fraction 0.1 --copy-mine-every 100 --seeds 7 11 19 --configs random_full_copyfailmix count_prior_lora_r2_copyfailmix --out .\experiments\tiny_language_lab\runs\stage11_failed_mixed_replay_weight200.jsonl --summary .\experiments\tiny_language_lab\runs\stage11_failed_mixed_replay_weight200.md --title "Stage 11 Failed Mixed Replay Weight 200"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage12_correction_examples_gentle_500.jsonl --summary .\experiments\tiny_language_lab\runs\stage12_correction_examples_gentle_500.md --title "Stage 12 Gentle Correction Examples 500"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage13_prefix_corrections_500.jsonl --summary .\experiments\tiny_language_lab\runs\stage13_prefix_corrections_500.md --title "Stage 13 Prefix Corrections 500"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage14_retrieval_probe_compact.jsonl --summary .\experiments\tiny_language_lab\runs\stage14_retrieval_probe_compact.md --title "Stage 14 Retrieval Probe Compact"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_retmix count_prior_lora_r2_retmix --out .\experiments\tiny_language_lab\runs\stage15_retrieval_use_training.jsonl --summary .\experiments\tiny_language_lab\runs\stage15_retrieval_use_training.md --title "Stage 15 Retrieval Use Training"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_corrretmix count_prior_lora_r2_corrretmix --out .\experiments\tiny_language_lab\runs\stage16_correction_retrieval_curriculum.jsonl --summary .\experiments\tiny_language_lab\runs\stage16_correction_retrieval_curriculum.md --title "Stage 16 Correction Retrieval Curriculum"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-curriculum-switch-fraction 0.5 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_corrthenret count_prior_lora_r2_corrthenret --out .\experiments\tiny_language_lab\runs\stage17_staged_correction_then_retrieval.jsonl --summary .\experiments\tiny_language_lab\runs\stage17_staged_correction_then_retrieval.md --title "Stage 17 Staged Correction Then Retrieval"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-curriculum-switch-fraction 0.8 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_corrthenret count_prior_lora_r2_corrthenret --out .\experiments\tiny_language_lab\runs\stage17_staged_correction_then_retrieval_late.jsonl --summary .\experiments\tiny_language_lab\runs\stage17_staged_correction_then_retrieval_late.md --title "Stage 17 Staged Correction Then Retrieval Late Switch"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage18_memory_retrieval_probe.jsonl --summary .\experiments\tiny_language_lab\runs\stage18_memory_retrieval_probe.md --title "Stage 18 Memory Retrieval Probe"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-train-marker "answer=" --copy-loss-weight 10 --seeds 7 11 19 --configs random_full_copyw count_prior_lora_r2_copyw --out .\experiments\tiny_language_lab\runs\stage18_memory_retrieval_baseline.jsonl --summary .\experiments\tiny_language_lab\runs\stage18_memory_retrieval_baseline.md --title "Stage 18 Memory Retrieval Baseline"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-probe-retrieval-corrupt wrong-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage19_memory_corruption_ablation.jsonl --summary .\experiments\tiny_language_lab\runs\stage19_memory_corruption_ablation.md --title "Stage 19 Memory Corruption Ablation"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-curriculum-switch-fraction 0.8 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs count_prior_lora_r4_corrthenret count_prior_lora_r8_corrthenret --out .\experiments\tiny_language_lab\runs\stage20_rank_sweep_staged.jsonl --summary .\experiments\tiny_language_lab\runs\stage20_rank_sweep_staged.md --title "Stage 20 Rank Sweep Staged 0.8"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs count_prior_lora_r4_corrretmix count_prior_lora_r8_corrretmix --out .\experiments\tiny_language_lab\runs\stage20_rank_sweep_simultaneous.jsonl --summary .\experiments\tiny_language_lab\runs\stage20_rank_sweep_simultaneous.md --title "Stage 20 Rank Sweep Simultaneous"
python .\experiments\tiny_language_lab\make_memory_mapping_corpus.py --lines 512 --seed 20260618 --out .\experiments\tiny_language_lab\corpus\memory_mapping_seed.txt
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage21_memory_mapping_no_hint.jsonl --summary .\experiments\tiny_language_lab\runs\stage21_memory_mapping_no_hint.md --title "Stage 21 Memory Mapping No Hint"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage21_memory_mapping_correct.jsonl --summary .\experiments\tiny_language_lab\runs\stage21_memory_mapping_correct.md --title "Stage 21 Memory Mapping Correct Memory"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-probe-retrieval-corrupt wrong-answer --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-mine-every 100 --copy-correction-template prefix --seeds 7 11 19 --configs random_full_copycorrmix count_prior_lora_r2_copycorrmix --out .\experiments\tiny_language_lab\runs\stage21_memory_mapping_corrupt.jsonl --summary .\experiments\tiny_language_lab\runs\stage21_memory_mapping_corrupt.md --title "Stage 21 Memory Mapping Corrupted Memory"
python .\experiments\tiny_language_lab\make_memory_mapping_corpus.py --lines 512 --seed 20260618 --holdout-keys g h --out .\experiments\tiny_language_lab\corpus\memory_mapping_holdout_seed.txt
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_holdout_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template none --copy-probe-holdout-keys g h --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_retmix count_prior_lora_r2_retmix --out .\experiments\tiny_language_lab\runs\stage22_holdout_memory_no_hint.jsonl --summary .\experiments\tiny_language_lab\runs\stage22_holdout_memory_no_hint.md --title "Stage 22 Holdout Memory No Hint"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_holdout_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-probe-memory-scope all --copy-probe-holdout-keys g h --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_retmix count_prior_lora_r2_retmix --out .\experiments\tiny_language_lab\runs\stage22_holdout_memory_correct.jsonl --summary .\experiments\tiny_language_lab\runs\stage22_holdout_memory_correct.md --title "Stage 22 Holdout Memory Correct"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\memory_mapping_holdout_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-probe-retrieval-source memory --copy-probe-memory-scope all --copy-probe-retrieval-corrupt wrong-answer --copy-probe-holdout-keys g h --copy-verify-mode key-answer --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.05 --copy-train-retrieval-template compact --seeds 7 11 19 --configs random_full_retmix count_prior_lora_r2_retmix --out .\experiments\tiny_language_lab\runs\stage22_holdout_memory_corrupt.jsonl --summary .\experiments\tiny_language_lab\runs\stage22_holdout_memory_corrupt.md --title "Stage 22 Holdout Memory Corrupt"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-rehearsal-fraction 0.05 --copy-curriculum-switch-fraction 0.8 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs count_prior_lora_r2_corrthenret_rehearsal --out .\experiments\tiny_language_lab\runs\stage23_rank2_rehearsal_frac005.jsonl --summary .\experiments\tiny_language_lab\runs\stage23_rank2_rehearsal_frac005.md --title "Stage 23 Rank 2 Rehearsal Fraction 0.05"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\long_context_seed.txt --steps 500 --block-size 96 --eval-mode sampled --eval-batches 16 --copy-probe-marker "answer=" --copy-probe-retrieval-template compact --copy-train-marker "answer=" --copy-loss-weight 10 --copy-sample-fraction 0.1 --copy-rehearsal-fraction 0.10 --copy-curriculum-switch-fraction 0.8 --copy-mine-every 100 --copy-correction-template prefix --copy-train-retrieval-template compact --seeds 7 11 19 --configs count_prior_lora_r2_corrthenret_rehearsal --out .\experiments\tiny_language_lab\runs\stage23_rank2_rehearsal_frac010.jsonl --summary .\experiments\tiny_language_lab\runs\stage23_rank2_rehearsal_frac010.md --title "Stage 23 Rank 2 Rehearsal Fraction 0.10"
python .\experiments\tiny_language_lab\make_complexity_corpus.py --lines 512 --seed 20260619 --long-fraction 0.00 --out .\experiments\tiny_language_lab\corpus\complexity_p000_seed.txt
python .\experiments\tiny_language_lab\make_complexity_corpus.py --lines 512 --seed 20260619 --long-fraction 0.25 --out .\experiments\tiny_language_lab\corpus\complexity_p025_seed.txt
python .\experiments\tiny_language_lab\make_complexity_corpus.py --lines 512 --seed 20260619 --long-fraction 0.50 --out .\experiments\tiny_language_lab\corpus\complexity_p050_seed.txt
python .\experiments\tiny_language_lab\make_complexity_corpus.py --lines 512 --seed 20260619 --long-fraction 0.75 --out .\experiments\tiny_language_lab\corpus\complexity_p075_seed.txt
python .\experiments\tiny_language_lab\make_complexity_corpus.py --lines 512 --seed 20260619 --long-fraction 1.00 --out .\experiments\tiny_language_lab\corpus\complexity_p100_seed.txt
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\complexity_p050_seed.txt --steps 50 --block-size 96 --eval-mode sampled --eval-batches 16 --seeds 7 11 19 --configs random_full count_prior_head count_prior_lora_r1 count_prior_lora_r2 --out .\experiments\tiny_language_lab\runs\stage24_complexity_p050_s50.jsonl --summary .\experiments\tiny_language_lab\runs\stage24_complexity_p050_s50.md --title "Stage 24 Complexity p050 50 steps"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\complexity_p050_seed.txt --steps 10 --block-size 96 --eval-mode sampled --eval-batches 16 --seeds 7 11 19 --configs random_full count_prior_head count_prior_lora_r1 count_prior_lora_r2 --out .\experiments\tiny_language_lab\runs\stage25_timebudget_p050_s10.jsonl --summary .\experiments\tiny_language_lab\runs\stage25_timebudget_p050_s10.md --title "Stage 25 Time Budget p050 10 steps"
python .\experiments\tiny_language_lab\make_markov_corpus.py --order 2 --vocab 16 --lines 512 --seed 20260620 --out .\experiments\tiny_language_lab\corpus\markov_order2_seed.txt
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\markov_order2_seed.txt --steps 100 --block-size 96 --eval-mode sampled --eval-batches 16 --seeds 7 11 19 --configs random_full count_prior_lora_r2 count_prior_tri_lora_r2 --out .\experiments\tiny_language_lab\runs\stage26_markov_order2_s100.jsonl --summary .\experiments\tiny_language_lab\runs\stage26_markov_order2_s100.md --title "Stage 26 Markov Order2 100 steps"
python .\experiments\tiny_language_lab\cassandra_compare.py --corpus .\experiments\tiny_language_lab\corpus\markov_order1_seed.txt --steps 200 --block-size 96 --eval-mode sampled --eval-batches 16 --seeds 7 11 19 --configs random_full count_prior_lora_r2 count_prior_tri_lora_r2 --out .\experiments\tiny_language_lab\runs\stage27_matchsurface_order1_s200.jsonl --summary .\experiments\tiny_language_lab\runs\stage27_matchsurface_order1_s200.md --title "Stage 27 Match Surface Order1 200 steps"This is the normal gradient-trained control model. Future Cassandra methods should be compared against it under the same corpus, step budget, and metrics.
Latest local numbers are recorded in
experiments/tiny_language_lab/RESULTS.md.
- Bigram parameter lab · implemented.
- Tiny transformer baseline · implemented.
- Count-seeded transformer initialization · implemented.
- Count-prior residual transformer · implemented.
- Head-only and adapter-only residual updates · implemented.
- Larger corpus and multi-seed replication · implemented.
- LoRA-style experiments · implemented.
- Long-context synthetic corpus and copy probe · implemented.
- Task-aware copy-position training · implemented.
- Verifier-guided mixed sampling · implemented.
- Verifier choice-loss correction · implemented.
- Failed-case replay correction loop · implemented.
- Generated correction examples · implemented.
- Structurally faithful correction templates · implemented.
- Retrieval-style probe context · implemented.
- Retrieval-use training · implemented.
- Correction-retrieval curriculum · implemented.
- Staged correction-retrieval curriculum · implemented. Result was a
capacity-dependent split: ordering helped the full model (0.60 to 0.88 copy
accuracy) but hurt the rank-2 LoRA surface (0.30 to 0.24). See
docs/hypotheses/001-staged-correction-retrieval-curriculum.md. - Train-split memory retrieval probe · implemented. Stage 14's strongest full-model result survived when the compact probe hint came from a train-split memory table instead of the held-out target: copy accuracy stayed at 0.960526, while the same-weight baseline stayed weak at 0.403509.
- Memory-reliance corruption ablation · implemented. A wrong but well-formed
memory hint dropped full-model copy accuracy from 0.960526 to 0.824561,
showing partial reliance on the retrieved answer, but not a full collapse.
See
docs/hypotheses/003-memory-reliance-corruption-ablation.md. - LoRA capacity sweep for curriculum interference · implemented. Rank 4
narrowed the staged-minus-simultaneous gap from -0.065790 to -0.013158, but
rank 8 fell back to -0.061404, so capacity alone is not enough. See
docs/hypotheses/002-lora-capacity-curriculum-interference.md. - Non-identity memory generalization · implemented. A fixed mapping corpus
removes the identity shortcut, but compact memory without interface training
hurts the full model: no hint
0.722944, correct memory0.450216, corrupted memory0.398268. - External-memory value test on held-out mappings · implemented. Stage 22
trained
retrieval_mixedon seen keys only, then probed held-out keysg hwith no hint, correct full-corpus memory, and corrupted memory. The full model did not use correct memory to answer absent mappings: held-out accuracy was no hint0.194444, correct memory0.166667, corrupted memory0.166667. H4 is not supported by this compact interface. Seedocs/hypotheses/004-external-memory-carries-absent-facts.md. Branch retired bydocs/decisions/0001-retire-compact-text-prefix-external-memory.md. - Rank-2 rehearsal for phase-switch forgetting · implemented. Codex chose the
smaller alternative allowed by ADR 0001 before the higher-value redirect.
Rehearsal at
0.05only nudged rank-2 staged accuracy from0.236842to0.245614, still below simultaneous0.302632; rehearsal at0.10dropped to0.228070. This does not rescue the phase switch. - Characterize the cheap-recipe corpus regime · implemented. Stage 24 measured
complexity_p000top100at 50 and 100 steps. At 50 steps,count_prior_lora_r2beatrandom_fullthroughp = 0.50and lost atp = 0.75and1.00. At 100 steps, full training won everywhere. Seedocs/hypotheses/005-cheap-recipe-corpus-regime.md. - Time-budget surface for the cheap recipe · implemented. Stage 25 measured
10 and 25 steps across the Stage 24 corpus axis. The cheap recipe won across
every measured point at 10 and 25 steps, crossed near
p = 0.635343at 50 steps, and lost everywhere by 100 steps. H006 is supported on the surface shape and partial on the simple mechanism clause. Seedocs/hypotheses/006-time-budget-inductive-bias-boundary.md. - Consolidating ADR for the core claim · implemented. ADR 0002 locks the
frozen-prior recipe as a bounded early-compute inductive-bias accelerator, a
head start that decays by about 100 steps, not an asymptotic replacement. The
full model trains fast even at 10 steps; the prior wins early by giving a
better low-step surface. See
docs/decisions/0002-frozen-prior-is-bounded-early-compute-accelerator.md. - Order-matched analytic prior durability · implemented. Stage 26 added a
pure Markov generator and a frozen trigram residual base. On the pure order-2
corpus, the matched trigram prior stayed strongly positive at 100 and 200
steps, while the mismatched bigram prior decayed to tied by 200 steps. On the
order-1 control, the matched bigram prior stayed positive. See
docs/hypotheses/007-higher-order-analytic-prior-durability.md. - Source-order versus prior-order closeout · implemented. Stage 27 completed
the order-1/order-2
V = 16surface at budgets 10, 25, 50, 100, and 200. Matched priors stayed positive through 200 steps: order-1 plus bigram retained0.018835NLL advantage, and order-2 plus trigram retained0.637384. Mismatched priors decayed or turned negative. This was a Codex closeout of Stage 26's open cells, not the full H008 order-3 test. Seeexperiments/tiny_language_lab/runs/stage27_matchsurface_summary.md. - H008 full source-order versus prior-order surface · implemented. Stage 28
added
--residual-base count-ngram,--prior-order, and thecount_prior_ng{1,2,3}_lora_r2configs, then ran theV = 8three-by-three surface. The diagonal was positive and increasing at 200 steps:A(1,1)=0.006804,A(2,2)=0.436673,A(3,3)=0.630598. The strict lower triangle was partial becauseA(3,2)=0.106932stayed meaningfully positive. Seeexperiments/tiny_language_lab/runs/stage28_h008_summary.mdanddocs/hypotheses/008-source-order-prior-order-surface.md. - Consolidating ADR for the graded source/prior order law · accepted. Claude
accepted Codex's evidence draft with revisions as ADR 0003: the law is graded,
matching is best and the matched advantage grows with source order, severe
under-specification fails while one-step under-specification still helps, and
over-specification carries a coverage-dependent sparsity penalty. The advantage
is durable through 200 steps where the matched table has full coverage; it is a
race between the prior's specification and the full model's learning speed. See
docs/decisions/0003-graded-source-prior-order-law.md. - Tiny-prose finite-order prior smoke · implemented as Codex exploratory
evidence. Stage 29 used the 1,129-character
tiny_seed.txtproject-prose corpus. Higher-order priors beatrandom_fullat 10, 50, and 100 steps, with ng3 advantage0.399935NLL at 100 steps, but the corpus is much too small for a natural-language claim. Seeexperiments/tiny_language_lab/runs/stage29_tinyprose_ngram_summary.md. - Natural-text external validity of finite-order priors · implemented as Stage
30. On normalized Tiny Shakespeare (
1,100,721chars,V=33), recursive backoff count priors plus rank-2 LoRA beatrandom_fullthrough 500 steps for orders 2 and 3. At 500 steps, ng2 advantage was+0.110081NLL and ng3 was+0.340641; ng1 flipped negative at-0.266069. The core transfer result is positive, but the humped sweet-spot law is still open because the measured curve is monotone increasing through order 3. Seeexperiments/tiny_language_lab/runs/stage30_naturaltext_summary.mdanddocs/hypotheses/009-natural-text-finite-order-prior-sweet-spot.md. - Order-4 natural-text extension · implemented as Stage 31. Codex added
count_prior_ng4_lora_r2under H009's optional order-4 clause. Order 4 was feasible on the normalized Stage 30 corpus (42,802,056frozen logits) and became the best measured prior at every budget. At 500 steps, ng4 advantage was+0.463572NLL, stronger than ng3 at+0.340641. The descending limb is still not located because validation hit coverage remains high (0.961867) despite sparse table coverage (0.029713). Seeexperiments/tiny_language_lab/runs/stage31_order4_extension_summary.md. - Harsher natural-text validity gate · implemented as Stage 32. Codex kept
the Stage 30 Shakespeare train prefix but replaced the validation suffix with
normalized Cassandra project prose in the same
V=33alphabet. High-order validation-hit coverage dropped but stayed high (0.889803for order 4), and the advantage curve remained monotone through order 4 at 100, 200, and 500 steps. At 500 steps, ng4 advantage was+0.291191NLL, above ng3 at+0.199130. This locally kills the predicted moderate-order hump on the implemented split, but leaves a caveat for a harsher or more genre-matched public-domain validation source. Seeexperiments/tiny_language_lab/runs/stage32_crossdomain_summary.mdanddocs/hypotheses/009b-ood-validation-true-sweet-spot.md. - Mixed loss-based data-selection filter (Hypothesis 010) · implemented as
Stage 33. The fixed top-10-percent frozen-prior-NLL filter did not make the
order-2 rank-2 residual reach the uniform 200-step target earlier. At 500
steps, both mixed filters were slightly worse than uniform, and pure
high-loss selection was clearly worse. H010 is a local kill for this sampler,
consistent with the Stage 11 hard-selection warning. See
experiments/tiny_language_lab/runs/stage33_filter_summary.mdanddocs/hypotheses/010-akba-curriculum-filter.md. - Dynamic reducible-loss filter (Hypothesis 011) · implemented as Stage 34.
Codex re-scored a fixed 4096-window pool every 25 steps and oversampled
high-current-loss windows with positive smoothed loss deltas. Neither dynamic
arm reached the uniform 200-step target faster, or at all within the measured
budgets, and both were slower at equal steps because of scoring overhead. H011
kills the final data-side selection attempt for the frozen-prior rank-2
residual and retires this branch on a capacity and data-order-insensitivity
explanation. Branch retired by ADR 0004
(
docs/decisions/0004-retire-data-side-selection-rank2-residual.md), which consolidates Stages 11, 12, 33, 34. Seeexperiments/tiny_language_lab/runs/stage34_dynfilter_summary.mdanddocs/hypotheses/011-dynamic-reducible-loss-filter.md. - Frozen recency base (Hypothesis 012) · implemented as Stage 35. Codex added
an analytic exponential-recency cache to the order-2 count prior with
tau=96andlambda=0.25. The recency arm was worse than the order-2 count-only baseline at every measured budget by+0.062to+0.086validation NLL, and slower because the base is computed per block position. The order-3 count diagnostic was far better than order 2 at every budget, so this simple cache does not beat raising the count order. H012 kills the default frozen character-recency interpolation, without rejecting every model-side frozen primitive. Gemini note 08 explains this as the known character-level cache failure mode and points toward order-preserving frozen kernels or n-gram caches. Seeexperiments/tiny_language_lab/runs/stage35_recency_summary.mdanddocs/hypotheses/012-frozen-recency-base.md. - Non-gradient residual formation (Hypothesis 013) · implemented as
Stage 36. Codex added
--residual-optim {adamw,es,coord,none}and compared the frozen-prior floor, the rank-2 AdamW target, full rank-2 ES, and a rank-1 coordinate feasibility arm on the structured corpus. The frozen-prior-to-AdamW gap was0.017708NLL. ES missed the floor by+0.042242NLL on the mean despite803formation forward passes, so the full rank-2 no-backprop claim is not passed. Rank-1 coordinate recovered about39.5%of the gap on the mean, but only beat the floor on one of three seeds. Seeexperiments/tiny_language_lab/runs/stage36_h013.mdanddocs/hypotheses/013-non-gradient-residual-formation.md. - Consolidating ADR for the formation-side trilogy · accepted. ADR 0005 retires
unguided gradient-free formation of the rank-2 residual at this scale: full ES
was worse than the frozen floor and the noisy estimator overfit a fixed batch,
while non-gradient methods need the blessing of scale they do not have here
(Gemini note 16). With ADR 0004 (data-side) and Stage 35 (analytic-base ceiling),
the three cheap "form the residual more cleverly" levers are now bounded. The
decision records the decomposition behind it: on the structured corpus the frozen
prior carries about
83%of the recipe's edge overrandom_fulland the trainable residual only about17%(0.017708of0.106704NLL). Seedocs/decisions/0005-gradient-forms-the-residual-formation-side-closed.md. - Residual marginal-value gate · implemented as Stage 37. Codex measured
the floor-to-target gap across natural-text Tiny Shakespeare at 200 and 500
steps for orders 2 to 4, plus a rank 1/2/4 sweep on the structured corpus.
The gate closed: no regime reached the
0.05NLL reopening line with stable positive sign. Natural-text gaps were mixed or negative, and the largest stable structured gap was rank 4 at only+0.023058NLL. This confirms the tested cheap regimes are prior-dominated on NLL. Claude later opened H014 on the behavior axis. Seeexperiments/tiny_language_lab/runs/stage37_residualgap_summary.md. - Lower-priority and now gate-closed · the model-side richer frozen base, retrieval-interface redesign, and distilled-data experiments. Stage 37 says further residual-formation NLL mechanics have no large local target in the tested cheap regimes. Claude has now chosen the pivot: turn to the behavior axis (rung 43) before the prior-ceiling axis, because the north star is behavior and Stage 37's closure was measured only on NLL.
- Behavior residual marginal-value gate (Hypothesis 014) · implemented as
Stage 38. Codex re-ran the Stage 37 floor-to-target gate on copy-probe
accuracy instead of NLL, using the long-context copy corpus. The frozen-prior
floor copied at
0.118421, within0.006579of1 / 8chance, while the rank-2 residual arms reached0.320176(copyw) and0.307017(copymix) mean copy accuracy. Both residual arms beat the floor by more than0.10on every seed, so H014 confirms the inversion: Stage 37's prior-dominance law is NLL-specific, and behavior formation lives in the trainable residual. Codex prepareddocs/decisions/0006-behavior-axis-reopens-residual-formation.codex-draft.mdfor Claude review; Gemini filed note 10 on the induction-head and in-context-learning prior-art placement. Seeexperiments/tiny_language_lab/runs/stage38_behaviorgap.mdanddocs/hypotheses/014-behavior-residual-marginal-value-gate.md. - ADR 0006 for the behavior-axis reopening · accepted. Claude accepted the
Stage 38 rescoping with revisions
(
docs/decisions/0006-behavior-axis-reopens-residual-formation.md): the formation-side closure is NLL-specific, the rank-2 residual is the behavior-forming surface, and the frozen count prior is behavior-blind at the copy answer position. The ADR adds a standing dual-axis tracking rule (every behavior-branch stage reports both NLL and a behavior probe), keeps the NLL-side levers closed, and scopes the claim tightly: identity copy, seen keys, 76 cases per seed, about0.31accuracy is formation not mastery, and the full model is a high-variance control (seed 19 random_full0.144737, below both cheap residual arms). Grounded by Gemini note 10, no novelty claimed. Reverses only if cheap surfaces plateau near the floor on a harder or generalizing probe while only full-model capacity forms the behavior. - Behavior rank sweep · implemented as Stage 39 from ADR 0006's provisional
handoff. Codex added
count_prior_lora_r1_copywandcount_prior_lora_r4_copyw, keeping the Stage 38 corpus and copy-weighted protocol fixed. The sweep does not support a simple capacity-limited rank law: rank 2 is best on mean copy accuracy (0.320176), rank 1 reaches0.250000, and rank 4 reaches0.271930. Rank 4 does not beat rank 1 with stable sign (+0.078948,+0.026316,-0.039474) and is below rank 2 on two seeds. Every trained rank stays above the0.118421floor, so behavior formation is real, but the next behavior question should not simply be "more rank". Claude owns the next hypothesis, likely around sampler signal, verifier signal, generalization, or optimization stability. Seeexperiments/tiny_language_lab/runs/stage39_behavior_rank.mdanddocs/decisions/0006-behavior-axis-reopens-residual-formation.md. - Held-out-key copy generalization (Hypothesis 015) · implemented as Codex
Stage 40. Codex added
--holdout-keysto the identity-copy long-context generator, producedlong_context_holdout_seed.txtwithg hheld out of trainingkey=...answer=rows, verified zero held-out train rows and in-vocabg h, then reran the Stage 38 behavior arms with--copy-probe-holdout-keys g h. The rank-2 residual did not generalize:count_prior_lora_r2_copywtied the frozen floor at0.000000held-out accuracy on all seeds. This does not cleanly fire the memorization reversal, because the residual's seen-key gain over the floor was only+0.027491on the mean, far below the+0.10seen-formation clause, and the full control also collapsed to0.000000held-out accuracy. Stage 40 scopes ADR 0006 to seen-key identity copy at this budget and hands the next behavior decision to Claude. Seeexperiments/tiny_language_lab/runs/stage40_heldout_copy.mdanddocs/hypotheses/015-held-out-key-copy-generalization.md. - Forced-choice held-out copy circuit (Hypothesis 016) · implemented as Codex
Stage 41. Codex added forced-choice copy metrics to the probe, using the
validation key alphabet
abcdefghas the candidate set, and reran the exact Stage 40 corpus, arms, seeds, and training protocol. The readout did not rescue held-out transfer:count_prior_lora_r2_copywstayed at0.000000held-out choice accuracy on every seed, with held-out MRR only+0.002645above the floor on the mean. This does not cleanly fire the memorization reversal either, because Arm B's seen choice accuracy was only0.202749,+0.077749above chance and below the+0.10seen-power clause. The full control is the stronger caveat:random_full_copymixreached0.364261mean seen choice accuracy and0.670103on seed19, but also scored0.000000held-out choice accuracy with floor-level held-out MRR. Stage 41 rejects the simple free-vocab emission-artifact rescue, but it still points to a task or budget failure under this protocol rather than a cheap-surface-only reversal. Claude owns the next branch decision; Gemini owns the forced-choice and logit-pathway prior-art pass. Seeexperiments/tiny_language_lab/runs/stage41_forcedchoice_heldout.mdanddocs/hypotheses/016-forced-choice-heldout-copy-circuit.md. - Consolidating ADR for the held-out generalization sub-branch · accepted. ADR
0007 reads Stages 40 and 41 together: every arm, including the full control,
scored
0.000000held-out under both free-vocabulary and forced-choice readouts, and the held-out choice MRR (about0.134) ranks held-out keys near last among eight, at or below uniform-random. The diagnosis is structural: in identity copy a held-out key token never appears at the answer position, so the output suppresses it regardless of any copy circuit, and the probe cannot express a held-out copy. Decision: scope ADR 0006 to seen-key identity copy (the reversal clause does not fire, because the full model fails identically), retire the held-out-key-token probe as a generalization instrument, and keep the rank and NLL levers closed. The question reopens only with a valid-readout probe carrying a full-model ceiling that actually generalizes. Seedocs/decisions/0007-heldout-token-copy-probe-cannot-measure-generalization.md. - Memorization-proof copy probe (Hypothesis 017) - implemented as Codex
Stage 42. Codex added
--random-payloadto the long-context generator and builtrandom_payload_copy_seed.txtwith a seeded per-line random payload alphabetabcdefghijklmnop(V = 16, chance0.062500). The cheap rank-2 residual did not form a general copy circuit:count_prior_lora_r2_copywreached0.063768mean copy accuracy, only+0.001268above chance and+0.020290above the floor, with every seed within the registered0.05reversal band. The full control cleared chance on every seed and reached0.226087mean copy accuracy, so H017 fires the local reversal kill for the current cheap recipe. Seeexperiments/tiny_language_lab/runs/stage42_random_payload_copy.mdanddocs/hypotheses/017-memorization-proof-copy-probe.md. - Consolidating ADR for the general-copy reversal · accepted. Claude accepted
Codex's Stage 42 evidence draft with revisions as ADR 0008
(
docs/decisions/0008-general-copy-needs-more-than-current-rank2-residual.md). Stage 42 fires ADR 0006's reversal clause: the rank-2 residual forms seen-content copy behavior (Stage 38) but not a general in-context copy circuit, so ADR 0006 is narrowed to seen-content, not reversed wholesale. Crucially this is not a needs-more-than-this-hardware result: the full model formed the circuit at the same budget (0.226087), so the capacity and trainable-surface question reopens on the general task (Stage 39 closed rank only on the memorizable task). It is also a mirror-image dual-axis split: the cheap residual gained0.062257validation NLL over the floor yet formed zero copy behavior. Reverses toward the stronger claim only if a small surface forms the circuit (Hypothesis 018); hardens into a capacity wall if nothing short of the full body does. - Minimal surface for general copy (Hypothesis 018) · implemented as Codex
Stage 43. Codex added
count_prior_lora_r8_copyw,count_prior_lora_r16_copyw, andcount_prior_all_copyw, then reran the Stage 42 memorization-proof corpus with alpha matched to rank for the new higher-rank LoRA arms. The registered KILL line fired: rank 8 (0.049275) and rank 16 (0.049276) stayed at chance and below rank 2 (0.063768), and the full-body-on-frozen-base diagnostic stayed at0.043478on every seed. Onlyrandom_full_copymixcleared chance on all seeds (0.226087mean). Arm D against Arm E points to frozen-base interference under this protocol, not merely low LoRA rank. H018 is tested; Codex prepareddocs/decisions/0009-general-copy-frozen-prior-capacity-wall.codex-draft.mdfor Claude review. Seeexperiments/tiny_language_lab/runs/stage43_general_copy_surface.mdanddocs/hypotheses/018-minimal-surface-general-copy.md. - Phase 2 TinyStories bridge · implemented as Codex Stage 44 from ADR 0010.
Codex added retryable TinyStories download, character-level TinyStories
corpus prep, visible PowerShell launch scripts, matrix progress logging, and
a vectorized n-gram prior builder. The prepared bridge corpus has
10,000,001normalized characters andV = 33. Visible CUDA smokes passed, then the b500 bridge matrix ran seeds7 11 19forrandom_full,count_prior_ng3_lora_r2, andcount_prior_ng4_lora_r2. At 500 steps, order-4 frozen prior plus rank-2 LoRA reached1.139715mean validation NLL versus2.352297for the full random baseline, with41,249trainable parameters versus3,209,249. Generation fromonce upon a timeis rough but story-like for the frozen-prior arms and still noisy for the random full baseline. This is a successful Phase 2 bridge result, not yet the full modded-nanoGPT baseline. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_bridge_b500.md,experiments/tiny_language_lab/RESULTS.md, anddocs/decisions/0010-confirmation-report.md. - Phase 2 modern TinyStories baseline · implemented as Codex Stage 45 from ADR
0010. Codex added RoPE, gradient accumulation, activation checkpointing, and
a single-device Muon optimizer path, then exposed those knobs through
cassandra_compare.pyand the visible PowerShell runner. The visiblemodern-smokepassed, thenmodern500ran seeds7 11 19forrandom_fullandcount_prior_ng4_lora_r2with--pos-encoding rope,--optimizer muon,--grad-accum-steps 2, and--activation-checkpoint. At 500 steps, the modernrandom_fullbaseline reached1.144942mean validation NLL, improving sharply over Stage 44's2.352297bridge baseline. The modern order-4 frozen prior reached1.102748, retaining a smaller0.042194NLL lead while training41,249parameters instead of3,176,481. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_modern_b500.md,experiments/tiny_language_lab/RESULTS.md, anddocs/decisions/0010-confirmation-report.md. - Phase 2 generation-quality scoring · implemented as Codex Stage 46 from ADR
0010. Codex added
score_generation_samples.py, a deterministic local proxy score sheet over saved prompt completions. It scores coherence, grammar, and prompt relevance from0to2each, using prompt adherence, story cues, corpus-word ratio, punctuation, repetition, and bad-marker checks. On the Stage 45 modern b500 samples,count_prior_ng4_lora_r2scored5.667/6mean total versus3.000/6forrandom_full. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_modern_b500_generation_quality.md. - Phase 2 shard-consumption smoke · implemented as Codex Stage 47 from ADR
0010. Codex added
--train-shard-dirand--stream-train-eval-charsto the trainer and compare harness, plus a visiblestream-smokelauncher mode. The smoke consumed the five TinyStories train shard files for plain LM batches, reportedtrain_chars = 8,500,000andtrain_eval_chars = 200,000, and completed a 20-step RoPE/Muon CUDA run at2.216325validation NLL. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_stream_smoke.md. - Phase 2 modern crossover · implemented as Codex Stage 48 from ADR 0010.
Codex added a visible
modern1000launcher mode and ran the modern TinyStories character baseline across seeds7 11 19. The NLL crossover fired:random_fullreached1.052559mean validation NLL at 1000 steps, whilecount_prior_ng4_lora_r2reached1.123161, reversing the prior arm's 500-step lead. The prior-minus-full gap was positive on every seed:+0.071768,+0.079357, and+0.060680. The generation proxy still favored the prior arm because two random-full samples emittedendoftextartifacts. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_modern_b1000.md. - Phase 2 BPE smoke · implemented as Codex Stage 49 from ADR 0010. Codex added
make_bpe_corpus.pyanddecode_bpe_samples.py, trained a local 256-token BPE tokenizer on a bounded TinyStories slice, encoded1,000,000characters into446,694BPE tokens, and ran a visible BPE smoke. The BPE-token bigram prior plus rank-2 LoRA reached3.405228validation NLL versus3.847587forrandom_fullat 20 steps. This proves the BPE-token path and n-gram prior over BPE tokens run locally; it is not yet the durable BPE-vs-character decision. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_bpe_smoke.md. - BPE 500-step multi-seed matrix · implemented as Codex Stage 50 from ADR
0010. The visible
bpe500run tested the v256 BPE corpus across seeds7 11 19. At 500 steps, full BPE training won decisively:random_fullreached2.404960mean validation NLL, while the BPE-token bigram prior plus rank-2 LoRA reached3.344760. Approximate source-normalized bits were1.549860vs2.155508. Decision: keep the character-level TinyStories baseline as the current Phase 2 default, and keep BPE as a secondary branch for larger-vocab or higher-order-prior follow-up. Seeexperiments/tiny_language_lab/runs/phase2_tinystories_bpe_b500.md. - Phase 3 coherence checkpoint · implemented as Codex Stage 51 from ADR
0011. Codex rebuilt the TinyStories character corpus from a
500,000,000byte raw slice, yielding494,094,421normalized characters,419,980,257train characters,74,114,164validation characters, andV = 33, then trained the 25.25Mrandom_fullcheckpoint family for5000steps across seeds7 11 19. Mean validation NLL reached0.818608, with mean bits/char1.181001and deterministic generation proxy score5.667/6. Human review of saved samples is still pending before any genuine-coherence claim. Seeexperiments/tiny_language_lab/runs/stage51_coherence_25m_b5000.md. - H019 crossover-scaling matrix · implemented as Codex Stage 52 from ADR
0011. The 85M confirmation smoke cleared the 8 GB laptop, so the matrix ran
sizes
3m,10m,25m, and85m, budgets200 500 1000 2000, bothrandom_fullandcount_prior_ng4_lora_r2, and seeds7 11 19with sampled evaluation. The first prior pass OOMed through full-tensor prior construction and is preserved as failed evidence; the corrected shard-native prior pass completed. Crossovers were1000,1000,1000, and500steps respectively, so H019 isGRADED, not clean E1, E2, or E3. Seeexperiments/tiny_language_lab/runs/stage52_h019_crossover_scaling_summary.mdanddocs/hypotheses/019-crossover-scaling-law.md. - Free-accelerator test · implemented as Codex Stage 53 from ADR 0013
(H020). Codex added
count_prior_ng4_all, a 25.25M model with the frozen order-4 prior and the full body trainable. The arm beat Stage 52random_fullat 200 and 500 steps, then lost on all three paired seeds at 1000 and 2000 steps. The required--muon-lr 0.005sensitivity rerun improved the 2000-step mean to0.976702but still trailedrandom_fullby+0.054555mean NLL. Verdict: H020 KILL E-interfere. Seeexperiments/tiny_language_lab/runs/stage53_h020_free_accelerator_summary.mdanddocs/hypotheses/020-frozen-prior-free-accelerator.md. - Prior-order floor scaling · implemented as Codex Stage 54 from ADR 0013
(H021). Codex added a shard-native sparse order-5 backoff prior, gated it
against the paired order-4 floor, then reran the 25.25M crossover column.
The order-5 floor beat order 4 by
-0.117649mean paired NLL, with all three seed deltas negative. The 25.25M crossover moved from 1000 steps to 2000 steps: order 5 beat Stage 52random_fullby mean at 200, 500, and 1000 steps, then lost at 2000. Verdict: H021 CONFIRM for the low-budget tiny-surface recipe. Seeexperiments/tiny_language_lab/runs/stage54_h021_prior_order_floor_scaling_summary.mdanddocs/hypotheses/021-prior-order-floor-scaling.md. - Phase 4 flagship build · completed as Codex Stage 55 from ADR 0013. The
laptop flagship uses random initialization,
201.61Mtrainable parameters, block 256, RoPE, activation checkpointing, Muon, sampled eval, and the 494M-character TinyStories corpus. Seed 7 ran 50,000 steps and reached0.556410sampled report validation NLL (0.802730bits/char); seeds 11 and 19 ran reduced 20,000-step replicas. The mixed-budget generation proxy mean is4.333/6, with human review still pending. Final.ptcheckpoints were originally secured inC:\cassandra_runs\stage55_flagship_checkpoints; the repo-local seed-7 artifact checkpoint remains underexperiments/tiny_language_lab/artifacts/phase4/checkpoints/after the Stage 56 disk cleanup. The verified DL Designer ONNX closeout lives underexperiments/tiny_language_lab/artifacts/phase4/nsight_dld/. - Broad-corpus specialization-gap test (Hypothesis 022) · completed as
Codex Stage 56 from ADR 0015. ADR 0014 measured the flagship's
domain-specialization gap (
0.8126bits/char in-domain vs2.8817zero-shot text8). Stage 56 trained the unchanged 85.10M character recipe on text8 train/valid data and scored the untouched text8 TEST split. Seed 7 at 50,000 steps reached1.485740TEST bits/char, below the1.70CONFIRM line; the 20,000-step replicas landed at1.532627(seed 11) and1.529591(seed 19), a0.003035bits/char spread. Verdict: H022 CONFIRM, so the gap is a data-distribution effect under the registered test and the Phase 5 developmental experiment stays on the char substrate unless a later ADR changes course. Seeexperiments/tiny_language_lab/RESULTS.mdanddocs/hypotheses/022-broad-corpus-specialization-gap.md. - Recipe v2 gates · completed as Codex Stage 57 from ADR 0015. bf16
matched fp32 NLL at 200 steps but was slower (
0.9058xfp32 throughput), so fp32 stays. Cosine LR warmdown won the 25.25M 5000-step gate (1.071579vs1.139756final sampled val NLL), so Recipe v2 adopts--lr-schedule cosine --lr-final-frac 0.1.--checkpoint-keep, fp16 model-only archive mode, and--vocab-charspassed smoke tests. Block 512 produced an 85M timing row (306.5595sfor 200 steps,1,645.0039peak CUDA MiB) but does not become the default. Phase 5's centerpiece (H024, the developmental experiment: COLD vs CURRICULUM vs MIXTURE at one fixed budget) remains pre-registered in ADR 0015 D1 and must be written by Claude before Codex starts Stage 58. Seeexperiments/tiny_language_lab/RESULTS.mdanddocs/decisions/0015-phase-5-developmental-training-and-open-source-posture.md. - Phase 5 letters-only behavior probe · completed as an eval-only D4 check
from ADR 0015. Codex added a 1,024-case letters-only copy probe because the
Stage 55 flagship vocabulary has no digits or equals sign. The Stage 55
seed-7 flagship scored
0.060547constrained-choice copy accuracy against chance0.062500, below the reopen threshold0.162500, so the behavior axis stays closed. Stage 58 then ran under Claude's H024 (rung 68). Seeexperiments/tiny_language_lab/runs/phase5_behavior_letters_probe.md. - Phase 5 D2 release prep · partially completed up to the user-sign-off
boundary. Corpus payloads were removed from the Git index, generated corpus
payloads are ignored while
.meta.jsonstays trackable, a 50 MiB pre-commit guard was added, licensing notes and a flagship model-card draft were written, and fp16 model-only exports of the three Stage 56 finals were created underC:\cassandra_runs\phase5_model_only_exports. History surgery, license choice, Hub upload, public push, and Stage 58 remain gated. Seedocs/phase5-d2-prep-status.md. - Phase 5 developmental experiment (H024) · completed by Codex as Stage 58
and resolved E-NULL, seed-robust in sign (2026-07-21, ADR 0016). Three
equal-compute 85.11M arms decided the smartest acquisition order for
breadth: COLD (full budget on broad text), CURRICULUM (a TinyStories
childhood, then broad), and MIXTURE (interleaved at the dose-matched
25:59 ratio). On deterministic text8 TEST bits/char, CURRICULUM minus
COLD read
+0.005096(seed 7, 42,000 steps),+0.009845(seed 11, 20k replica), and+0.007791(seed 19, 20k replica): every sign favors COLD, every magnitude sits inside the+/-0.05E-null band, and the escalation rule did not fire. MIXTURE scored+0.027977versus COLD on text8 while retaining TinyStories at0.826285bits/char against3.55/3.53for the other arms: rehearsal preserves the narrow register cheaply, but no ordering beats cold broad training on the primary metric. The cross-stage lesson: Recipe v2 improved matched-seed, matched-budget text8 TEST by about0.12bits/char over Stage 56's Recipe v1, roughly 24 times the largest ordering effect. Seedocs/hypotheses/024-developmental-acquisition-order.md,docs/phase5-final-report.md,docs/figures/phase5/, anddocs/decisions/0016-phase-5-closeout-developmental-null-recipe-frontier.md. - Phase 6 rehearsal dose-response (H025) · specced by Claude and audited,
awaiting Codex as Stage 59. Part 0 runs the letters copy probe on the
Stage 58 broad-trained COLD final (reopen line
0.1625). Part 1 sweeps TinyStories dosewin{0, 0.05, 0.10, 0.20, 0.30, 0.50}on 3.2M-class Recipe v2 proxies (seeds 7 11 19) and fits a data mixing law whose 85M prediction must be published before Part 2 launches. Part 2 trains two 85M MIXTUREw = 0.10arms at 20,000 steps (seeds 11 and 19) against the existing paired Stage 58 COLD baselines; CONFIRM needs both seeds atd <= +0.010broad toll withr >= 1.0retention gain. Seedocs/hypotheses/025-rehearsal-dose-response-and-mixing-law.mdanddocs/phase6-codex-goal-prompt.md. - Phase 6.1 dual-register flagship · the ADR 0017 D2 gate did NOT fire:
rung 69 resolved E-partial (seed 11 CONFIRM-side at
+0.009654, seed 19 a sub-noise+0.012353miss of the confirm line; retention gains+2.70/+2.67bits/char; transfer read NOT_DECISION_GRADE at a2.094xover-prediction), so this flagship design never launched and the gate is spent. Part 0 separately FIRED the behavior-axis reopen: the broad-only 85M scored0.194336on the letters probe against the narrow-only 201.6M flagship's0.060547on the identical probe. Seedocs/decisions/0017-phase-6-rehearsal-dose-flagship-gate.md(implementation status) andruns/stage59_verdict.json. - Phase 6 redesign centerpiece (H026, Stage 60) · eval-only circuit
mapping: probe every surviving Stage 58/59 checkpoint (68 verified,
including the TinyStories-only CURRICULUM phase-1 ladders) with the
frozen letters probe; PRESENT at or above
0.1625, ABSENT at or below0.1125; E-diverse if narrow-only rows stay ABSENT while broad-bearing lineages cross PRESENT, E-steps if any narrow-only row reads PRESENT, E-gray otherwise; formation-onset and destruction screening reads pre-registered. Seedocs/hypotheses/026-diverse-data-circuit-formation.mdanddocs/decisions/0018-phase-6-redesign-circuit-mapping-and-instrumented-flagship.md. - Pure-broad instrumented flagship (Stage 61) · a 200M-class Recipe v2
model on pure text8 (no mixture, capacity claim only), every
5,000-step checkpoint probed and retention-scored as it lands (the
200M formation curve for free), budget from a sustained throughput
measure inside the 30 to 40 GPU-hour envelope, publish bars in
ADR 0018 D5 (beat
1.357318, instrumentation complete, sample review; margin printed next to the0.003035spread). Hugging Face packaging prepared by Codex; every public button is the user's. - Context-utilization probe (H027, Stage 62) · RESOLVED E-uses-context
(ADR 0019). The Stage 61 flagship writes locally fluent but topically
drifting text (the user's "off-topic" review), a failure invisible to
NLL. The probe scored held-out text8 target segments under their TRUE
versus a RANDOM preceding context, resolved by distance into the target,
with a null control and a synthetic sensitivity anchor. Result: deep-bucket
utilization
+0.205289bits/char (CI[+0.198204, +0.212034], far above the0.05line), with a risingL_cdose curve. The flagship USES its context strongly to the edge of its 256-char window; the drift is a window-SIZE limit, not a comprehension failure. This selects the cheap longer-context char arm (block 512, reuses the char stack) over the subword substrate. The block-512 training arm is user-gated compute (next spec, H028 class). Seedocs/hypotheses/027-context-utilization-and-coherence.mdanddocs/decisions/0019-phase-6-coherence-is-a-window-limit-longer-context-arm.md.
Contributions are welcome. CONTRIBUTING.md covers the
quick start on a fresh clone, where to find open work, the house rules
(prose style, seeds, falsifiable hypotheses and ADRs, honest baselines and
negative results), and the pull request flow. Taking part means following
the Cassandra Collective code of conduct.