Instructions to use cds-jb/qwen3-8b-parallel-cot with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use cds-jb/qwen3-8b-parallel-cot with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B") model = PeftModel.from_pretrained(base_model, "cds-jb/qwen3-8b-parallel-cot") - Notebooks
- Google Colab
- Kaggle
latent_threads β results (batches lt1/lt2/lt3, 2026-06-12)
Five delayed-selector latent-reasoning organisms on Qwen3-8B (design: HYPOTHESES.md;
mechanism: bottleneck mask YβX + filler-dot latent block + query revealed AFTER the
latents). Checkpoints: /workspace-vast/jbauer/exp/models/latent_threads/<batch>/<task>/final.
Plots: /workspace-vast/jbauer/exp/latent_threads/results/. wandb groups lt1/lt2/lt3
(MATS10-CS-JB/cot-oracle).
Headline table
| organism | batch | M | organism acc | ablated (ZβX) | gap | ensemble completeness (per query) |
|---|---|---|---|---|---|---|
| parallel_select | lt1 | 4 | 1.000 | 0.090 | 0.91 | 1.00 / 0.99 / 1.00 / 1.00 |
| chase_select | lt1 | 12 | 1.000 | 0.093 | 0.91 | a 1.00 / b 1.00 / c 1.00 |
| step_select | lt2 (resume of lt1 stall_k07, gate 0.88) | 8 | 0.820 | 0.107 | 0.71 | steps 1-4: 0.98-0.99; steps 5-8: 0.71/0.77/0.68/0.67 |
| coin_track | lt1 | 8 | 0.937 | ~0.14 | 0.80 | Anna 0.99 / Ben 0.89 / Cara 0.85 |
| agg_select | lt3g (v2 grind) | 6 | 0.893 | 0.073 | 0.82 | values 1.00/0.99/1.00; sum10 0.813 |
All ablated readouts β chance β every organism's answer information flows X β dots β Y only: the latents are load-bearing by construction, verified. Completeness = accuracy per possible query on the SAME instances; since Z cannot see the query, high completeness on all slots = one fixed latent computation serves the whole query family (the ensemble claim).
Probe grids (ridge linear probes on dot residual streams, operating mask)
parallel_select (best L36). H1a (full ensemble decodable) CONFIRMED: every register's result hits ~1.0 at several dots; inputs (starts) are carried too. H1b (one-result-per-dot diagonal) REJECTED: the layout is prefix-accumulating and redundant (dot1 already holds res_a+res_b at 1.0; by dots 3-4 nearly everything decodes). Logit lens P(surface digit) β€ 0.2 everywhere β the code is NOT vocab-aligned (non-verbal carry, not "hidden digits").
chase_select (best L36). H2a (lockstep stripes dot_{3(t-1)+b} β s_b(t)) REJECTED; instead chain-major bursts with run-ahead: dot1 decodes chain a's ENTIRE trajectory (s_a2-s_a4 β 0.96-1.00 β one dot's depth covers ~4 lookups, cf. pn1), dots 2-4 hold chain b (0.97-1.00), chain c materializes over dots 5-9 (c4 β 1.00 from dot7), late dots refresh a. H2b (ensemble maintenance) CONFIRMED, with a twist: finals live at DIFFERENT positions (b4 fades to ~0.5 by dot12 but reads 0.97-1.0 at dots 2-6) β the block is a spatially distributed key-value buffer and the answer position fetches content-addressed; behavioral completeness is 1.00 for all three chains.
step_select (best L36). Run-ahead staircase: dot p decodes s_1..s_{p+1ish} (dot1: s1,s2 at 1.0, s3 0.88). H3a retention CONFIRMED for computed states: s1/s2 still 0.95-0.99 at dot8. Deep states s5-s8 cap ~0.6-0.8 everywhere β matching the behavioral per-step gradient (0.99 for tβ€4 vs ~0.7 for tβ₯5): the organism's errors are deep-chain COMPUTATION errors (serial cap ~6-8, cf. pm2/pm3), not retention/readout failures. Lens peaks 0.45 at dots 3-4 then fades β partial early vocab-surfacing, opaque later.
coin_track (re-probed at forced L36; the auto-picked L20 grid was an artifact). Layer-selection pitfall first: who-moved-at-event-i (prompt-derivable, 3-class) saturates 1.00 at every dot at L4-L20 and dominated the best-layer mean β lesson: exclude prompt-syntactic targets from layer selection (probe.py grew --layer). At L36 the real structure: per-event running counts e1-e8 β CHANCE at every dot β the trajectory is NOT retained β while the three FINAL counts decode strongly at scattered parking dots (final_Anna 0.97 @dot1, final_Ben 0.90-0.95 @dots 2,5-8, final_Cara 0.85-0.89 @dots 1,4), matching behavioral completeness (0.99/0.89/0.85). H4a (event-driven update train) REJECTED at the readout layer; H4b (world-state ensemble) CONFIRMED as a 3-slot register file updated in place. The step_select contrast is the headline: queries there cover every intermediate β every state retained; here only finals are queryable β only finals kept. The latent ensemble retains exactly what the query distribution demands.
agg_select: the aggregation-over-latents story (3 attempts)
- v1 (value/argmax/argmin/sum, lt1): STALL at k=0 (surface!), 0.672. Diagnosis at k=0: value 1.00, sum 1.00, argmax 0.39, argmin 0.43 (chance 0.33) β 3-way COMPARISON over spread digits doesn't train in the masked suffix even with surface operands.
- v2 (value+sum, lt2): mastered k=0 instantly, STALL at k=1, 0.516. Diagnosis at k=1: value-via-dot 1.000 but sum10 0.078 (below chance = systematically stale) β the dot demonstrably carries the digit (value query reads it), but the suffix ADDITION circuit keeps consuming the surface-token pathway and cannot use the latent operand. Clean negative: reading latents transfers; arithmetic INTEGRATION of a latent operand does not (at LoRA r=32, lr 1e-4, 800 steps).
- v3 (lt3, sum-in-body): STALL at k=1 (0.539 β (value 1.0 + sum 0.08)/2) β at k=0 the model answered sum queries by COPYING the teacher-forced surface sum digit; dotting it removed the copy source. Design lesson: a teacher-forced aggregate in the surface curriculum invites a copy shortcut.
- v2g (lt3g): SUCCESS β the organism. Resume of v2 stall_k01 with 2400 steps/stage + smoothing 0.25: k=1 (the wall) cleared, k=2-6 fell quickly (the integration circuit, once formed, generalizes across operands). Final: organism 0.893 / ablated 0.073 (gap 0.82); completeness value 1.00/0.99/1.00, sum10 0.813. So suffix-side aggregation over latent operands is TRAINABLE but ~3x slower than value-reads β a trainability-cost finding, not an impossibility.
- H5a CONFIRMED (raw workspace, not answer cache), probe grid @L28: finals v1/v2/v3 decode at ~1.0 across the block (prefix-staircase: v1 from dot1, v2 from dot2, v3 from dot3 β run-ahead again) and intermediates are carried too, but sum10 β chance (0.06-0.16) at EVERY dot while behavioral sum accuracy is 0.813 β the sum is assembled downstream in the masked suffix from raw latent operands. Caveats: argmax/ argmin probe at 0.7-0.91 despite never being trained queries in this lineage (partially derivable from value codes by a linear readout; not a clean precompute claim). Lens: uniquely here the LAST dot is vocab-aligned (P(surface)=0.85 for v3); other positions dark (β€0.18).
- v3b (lt4, bonus): STALL at k=1 even with 2400 steps (acc oscillating 0.51-0.62 β value 1.0 + sum near-chance) β a single dot position cannot learn 3-operand mod-10 addition under this regime, even with all operands surface-visible, while the multi-position suffix learned the same function in v2g on the same budget. Depth is not the obstacle (one position composes ~4-5 serial lookups, cf. run-ahead/pn1); the plausible culprit is gradient indirectness β the answer position receives the loss directly, a dot's hidden state only via attention. Net dissociation: latent positions trained this way COMPUTE (chains, lookups) and CARRY, but new multi-operand circuits form preferentially at loss-bearing positions.
Cross-task picture (the "latent trace ensemble")
- Load-bearing is robust and easy under the mask β 5/5 attempted blocks carry their task (incl. v3 pending), ablations β chance.
- Delayed-selector pressure works: every organism keeps ALL threads readable (high completeness on unselected threads/steps/entities), confirming the structural superposition argument β Z can't know the query, so it must keep the ensemble.
- The layout is the model's own economy, not the curriculum's surface order: bursts + run-ahead + content-addressed parking, NOT lockstep per-position carries. The 8B's depth (~4-5 serial lookups per position) makes single dots powerful; the block organizes as a buffer of partial trajectories.
- Computation in the suffix is the bottleneck: reading latents is easy (value queries 1.0 through dots), comparisons/arithmetic over latent operands are hard to SFT in.
- Logit lens is mostly dark (P(surface digit) β€ 0.2-0.45, fading late): linear-probe- decodable but not vocab-aligned β a good AO target that a text monitor cannot read.
Reproduction
- train:
python -m latent_threads.train --config latent_threads/configs/<task>.json --batch-id <id> - verify:
python -m latent_threads.eval_masked --adapter .../final - probe:
python -m latent_threads.probe --adapter .../final --lens [--layer L] - per-type agg diagnosis:
python -m latent_threads.diag_agg --adapter ... --k <stage> - batch logs:
/workspace-vast/jbauer/exp/latent_threads/logs/; launchers (not committed):/workspace-vast/jbauer/exp/latent_threads/{smoke_all,lt1_all,lt2_all,lt3_all}.sh. - Stalls and retries: step_select stalled at k=7/0.852 with gate 0.9 (lt1) and finished under gate 0.88 after resume; node-13 gave cudaErrorDevicesUnavailable (excluded).
β β SOLVED: journeys β several cohesive NATURAL-LANGUAGE load-bearing trains (lj1, 2026-06-13)
The NL extension of the Markov organism. K travelers each walk a contiguous m-room PATH = a cohesive natural-language "train of thought" extending over m latent positions (e.g. study -> garage -> library -> bedroom); several run in parallel; each position load-bearing.
Architecture (markov_nl.py / train_markov_nl.py): THREAD-MAJOR layout (thread b's m rooms are a contiguous span) + within-thread MARKOV mask (position t attends only t-1; pos 0 reads prompt) + a CONTIGUOUS answer-slot row (K slots gather each thread's final room into adjacent positions so the delayed-selector answer reads positionally β the readout fix; spread thread-lasts capped TF-readout ~0.5, the slot row broke it). Vocab-constrained feedback over a 10 single-token ROOM WORD alphabet; teacher-forcing anneal. Fixed transition rule (no per-instance table -> trainable under the load-bearing mask, unlike a pointer chase). Delayed POSITIONAL query (person number j).
Verified (lj1k3m5, K=3 m=5, free-running): organism 0.970; ablate-thread-start 0.075 (chance); per-room-step corruption -> 0.12/0.35/0.22/0.27 (EVERY room position load-bearing, drop 0.62-0.85). k3m4 and k3m5 both reach ~1.0. Recipe is the digit Markov recipe restructured thread-major with NL symbols. Code latent_threads/{markov_nl,train_markov_nl,verify_nl}.py; configs journeys_k3m{4,5}; ckpts lj1k3m4/lj1k3m5. Diagnostic note: aux (room-classifier CE) hit ~0 early = the trains were always perfectly computed; the only difficulty was the delayed-selector READOUT (3 readout iterations: name-query -> positional-query -> contiguous-slot row, which solved it).
β SOLVED: Markov latent-CoT organism β genuine PER-STEP load-bearing (lmv, 2026-06-13)
The 4/4 organism the whole investigation chased. dot diffuse got 3/4 (per-step necessity failed: recompute). The Markov organism gets ALL FOUR.
Organism: lmvk3m4 (and lmvk3m5), diffuse K=3 M=4/5. Embedding-space latent CoT: K positions
per step (one per cell), input(t+1,i) = vocab-constrained feedback from h(t,i). Recipe (each piece
fixes a diagnosed failure):
- MARKOV step-windowed mask (markov.py build_markov_mask, UNIT-TESTED): step1 attends prompt; step t (t>1) attends ONLY step t-1's K positions; Y attends ONLY step M. The only path is X->step1->...->stepM->Y -> per-step necessity BY CONSTRUCTION, immune to recompute/depth shortcut.
- VOCAB-CONSTRAINED feedback: feedback = softmax(digit_head(h)/temp) @ E[digits] (soft mixture over digit embeddings), aux = CE(digit_head, gt). Readable by construction; CE drops where the plain-MSE-to-embedding plateaued at 0.5 (which left free-running at chance β lm1).
- SCHEDULED-SAMPLING anneal: teacher-force GT digit embeddings with prob tf annealed 1->0 over 2500 steps -> bootstrap from the trainable surface-digit regime, hand off to self-generated.
Verification (verify_markov.py, k3m4 best, free-running eval = self-generated latents):
- organism 0.930; ablate step1->prompt 0.090 (chance: chain's only input gone);
- per-STEP corruption (noise into step t's feedback): step1->0.109, step2->0.078, step3->0.105 β EVERY step drops to chance (drop ~0.82-0.85). No recompute escape (step t+1 sees only step t).
- k3m5 free-running 0.977; k3m4 0.93-0.96.
Grades 4/4: (1) multi-step, EACH step load-bearing (corrupt any -> chance) β the criterion that defeated dots (recompute) and soft (vestigial); (2) parallel (K=3 cells/step); (3) parallelism NECESSARY (light-cone proof); (4) load-bearing (ablate -> chance). Code: latent_threads/markov.py, train_markov.py, verify_markov.py; configs markov_k3m{4,5}_vocab.json; ckpts lmvk3m4,lmvk3m5.
TARGET-CRITERION RESULT: "multi-step latent tokens truly bearing PARALLEL load, parallelism NECESSARY"
Decomposed the criterion into 4 tests and chased an organism that passes all 4. Result: 3/4 are achievable and DELIVERED; the 4th (per-step necessity) hits a fundamental trilemma.
Delivered organisms (ls8, dot recipe): dot diffuse β coupled ring CA x_i'=(x_{i-1}+x_{i+1})%10, K=3, M=4/5 (12/15 dots), FULL-ROW surface CoT (each step writes all K cells -> dots carry the whole evolution). Trained via the proven bottleneck-mask dot recipe (compute-from-prompt, NOT recurrence).
- k3m4: organism 0.947 / ablated 0.117 / gap 0.830; completeness c1/c2/c3 = 0.98/0.99/0.83.
- k3m5: organism 0.970 / ablated 0.097 / gap 0.873. Ckpts ls8k3m4/ls8k3m5 under exp/models/latent_threads/.
Grading vs the 4 criteria:
- LOAD-BEARING (block) -- PASS: ablation Z!->X -> chance (gap ~0.85); the dot block is the necessary conduit prompt->answer.
- PARALLEL -- PASS: per-cell completeness 0.83-0.99; one fixed dot computation serves every cell query.
- PARALLELISM NECESSARY TO SOLVE -- PASS by construction: light-cone proof (K=3,M>=2: each final cell depends on ALL initial cells; cannot solve tracking one thread). This is the criterion chase could NOT meet (independent chains).
- MULTI-STEP, each step truly load-bearing -- NOT achieved. leave-out-per-dot ~0.92-0.98 (no single dot necessary), cross-patch follows the ORIGINAL not the donor (0.94 vs 0.07) -- the SAME recompute signature as the vestigial soft finding: under Y!->X the dots recompute the CA from the prompt (Z->X allowed), so no individual step/position is load-bearing, only the block.
The trilemma (why criterion 4 is fundamentally hard on the 8B):
- Allow Z->X (bottleneck mask): trains, but latents RECOMPUTE from the prompt -> per-step not load-bearing (block-only).
- Forbid Z->X (tight/tight_first recurrence): per-step would be load-bearing by construction, but DOES NOT TRAIN (chase: lookup table unreachable; diffuse-soft: mod-10 arithmetic unlearnable in latent space; ls5/ls6 flat at chance through all warm-starts incl GT + mask-curriculum).
- Force single-pass to fail (large M): dot-chain caps ~7-16 (k3m6/M=18 STALLS at k=16) and the 8B single-passes shallow reach -> no clean window where multi-step is required AND achievable (the pointer_chase depth-wall, reconfirmed). So: load-bearing-block + parallel + parallelism-necessary is achievable; adding genuine per-step necessity is blocked by recompute-vs-trainability-vs-depth. This is the central negative result.
Soft-token detour (ls1-ls6) summary: moved to CODI-style recurrence to get per-step load-bearing; default-mask soft organisms train but are VESTIGIAL (controls: zero-all inputs 1.000, cross-patch follows original) -- they too recompute from the prompt. Tight/tight_first recurrence (the fix) does not train (mod-10 arithmetic in latent space; flat at chance across cold/GT/GT+mask-curriculum, m4-8, K3-5). GT-warmstart, mask-curriculum, multi-GPU bigger batch all tried. Honest conclusion: genuine load-bearing in-latent recurrence is very hard to induce on an 8B at this scale -- matching 2508.03440 (single-threaded/collapse), 2602.00449 (shortcut on long), 2604.04902 (latents often unnecessary).
Compression frontier (lt7, train_shrink.py) β the dot-count question answered
The D-sweep above mixes dots with surface digits (every point is a trained curriculum stage gated at >=0.9), so it cannot test whether FEWER latent positions would suffice. The shrink curriculum does (resume the organism, reduce the all-dot block length L stepwise, mastery-gated, no surface scaffold at any L):
- chase_select: frontier L=1. All 11 shrink stages mastered; at a SINGLE dot the organism reads every chain's final at 1.000 (ablated 0.000). The L=1 probe: the one dot decodes the three finals at 0.88-1.00 plus most of the late trajectory (early intermediates fade) β 12 task states through one residual stream, retaining the queryable subset. The M=12 layout was convention, not necessity; 3 parallel 4-hop chains fit in one position's depth x width.
- step_select: frontier L=2 β and compression IMPROVES accuracy. L=2 organism = 1.000 (vs the M=8 organism's 0.820); the L=1 attempt plateaus at exactly 0.820 (single-position depth limit ~the original's level). Mechanism: 8 serial hops through 8 dot positions accumulate errors; two positions of ~4-hop run-ahead each sit inside the model's reliable single-pass depth. Probe at L=2: dot1 = early trajectory (s1-s2 1.0, fading), dot2 = a broad window (s1-s4 ~0.9, deep 0.7-0.8) β yet behavioral per-step readout is 1.00, so linear probe decodability is a lower bound, not the ceiling, on what the (nonlinear, attention-based) answer head extracts.
Implication for the published M-length organisms: their many-dot layouts are curriculum-induced redundancy; capacity was never binding. The "necessity" property that survives compression is the ABLATION (latents are the only channel), plus now a measured positions-vs-accuracy tradeoff (1 dot = 0.82, 2 dots = 1.00 for the 8-step trajectory).
Soft-token organisms + the VESTIGIAL-RECURRENCE finding (ls1/ls3, soft.py)
Moved into the CODI/SoftCoT substrate: L soft positions z_t, input(z_{t+1}) = proj(last-layer hidden(z_t)), answer-CE BPTT (train_soft.py, multi-GPU manual all-reduce). Three arms on chase_select (L=4 steps, 3 chains superposed per token): warm (LoRA from dot organism) hit gap 1.000 in ~150 steps but INHERITED the dot burst layout; GT-supervised (Latent-SFT targets z*_t = sum_b R_b E[digit s_b(t)]/sqrt(B)) hit gap 1.000 in ~500 steps.
BUT the {shuffle, cross-patch, leave-out} CoT controls (eval_controls.py) reveal the soft recurrence is VESTIGIAL for the GT-chase organism (default ORGANISM mask, Y!->X only):
- baseline 0.996; ZERO-ALL latent inputs 1.000; RANDOM latent inputs 0.879; cross-patch a different instance's whole latent block -> answer follows the ORIGINAL 0.996 (donor 0.109 = chance); shuffle 0.992; leave-out 1.0 every position.
- Interpretation: because Z->X is allowed, each latent POSITION recomputes its content from the prompt via attention; the fed-back embeddings are ignored. It is the DOT mechanism with GT-shaped activations, NOT genuine continuous-thought recurrence. This single fact explains: depth-gen 0.000 (no recurrence to extend), width-gen 1.000 (extra slot just computes from prompt), shuffle no-drop, cross-patch follows original, and homogeneity cos 0.99 (last layer).
- Matches the literature's cautions: 2604.04902 (latents often unnecessary/decodable), 2508.03440 (single-threaded/collapse), 2602.00449 (shortcut on longer tasks).
- Held-out at trained length is still 1.000/1.000 (no memorization) β the organism is correct, just not via the recurrence we intended.
FIX = TIGHT recurrence (soft.py TIGHT = forbid Z->X too). The prompt then reaches the latents
ONLY through z_1's projected input, so the recurrence is the sole prompt->answer path -> the input
feedback is load-bearing by construction (zero-all/random/cross-patch should then collapse to
chance, and depth-gen has a chance of working). train_soft tight:true; config
soft_chase_tight_gt.json; ls3t run. The default-mask soft organisms are kept as the
"compute-from-prompt" baseline that the controls expose.
CoT controls (every organism, eval_controls.py) β report in model cards
- shuffle (permute latent positions), cross-patch (splice a different instance's latent block; donor-following = sole-path test), leave-out (per-position necessity), + zero-all / random inputs (soft: recurrence load-bearing?). Dot organisms use a layer-1 residual-stream hook.
Train vs test (seen-vs-fresh, eval_seen_vs_fresh.py)
Training data is an infinite procedural stream; "train" = bit-exact replay of the first training stage's instances (provably seen once), "test" = disjoint seed. n=400 each: parallel 1.000/1.000, chase 1.000/1.000, step 0.845/0.823, coin 0.900/0.915, agg 0.922/0.920 β max |delta| 0.022: no instance-level memorization, the organisms run the algorithm.
Published (2026-06-12)
HF: cds-jb/qwen3-8b-latent-threads-{parallel-select,chase-select,step-select,coin-track, agg-select} β adapter + model card (training details, train/test acc, plots) + examples.md
- training_code/ snapshot (per the AGENTS.md HF-upload imperative). Collection: huggingface.co/collections/cds-jb/latent-threads-delayed-selector-latent-reasoning-qwen3-8b-6a2c3eee19d4300f6186394a
Probing across layers+positions & shuffle/cross-patch controls (Markov organisms, 2026-06-13)
probe_markov.py β one pass per organism: (a) a ridge linear probe decoding EACH latent position's
own task value from its residual stream at every layer β a [layer Γ position] decodability grid; (b)
behavioral shuffle/cross-patch controls on the free-running latents. Results:
- Probe grid: every position's parallel-thread state is linearly decodable. Diffuse (coupled CA)
peaks late, layer 36 (mean per-position decodability m4=0.898, m5=0.997) β the digit states are
computed deep. Journeys (room trains) is decodable early, layer 4 (mean 1.000) β fed-back room
tokens are present from the start. (figs:
results/probe_markov_<tag>.png) - Controls (acc vs chance 0.10): intact β1.0; shuffle (permute latent positions) and cross-patch (swap in another instance's latents) BOTH collapse to chance β diffuse-m4 1.000β0.106/0.113, diffuse-m5 0.988β0.087/0.106, journeys-m4 1.000β0.131/0.119. The answer needs the specific content at each position in the right order (not a bag, not the prompt). This is the live opposite of the vestigial SOFT organism (zero-all=1.0, cross-patch followed the original) β here the recurrence is the only path. Added to every Markov model card.
Tales β the "statements" organism (3rd Markov variant, in training 2026-06-13)
Same requirements as journeys but the train of thought is actual statements, not a logical token
sequence. Each latent STEP is a 9-token NL clause "{name} entered the {room} and found the
{item}." β template tokens are fixed word embeddings (so the latent span literally reads as a
statement), with TWO computed slots (room@+3, item@+7) carrying TWO INDEPENDENT load-bearing chains
(room (7r+3)%10, item (3i+1)%10). Each statement bears parallel load in >1 token; the delayed query
selects one (character Γ attribute) of 2K chains β all maintained. Statement-windowed Markov mask:
each computed slot attends ONLY its same-attribute predecessor (+ prompt at step 1), never the
template tokens β per-statement load-bearing, no prompt-recompute past step 1. Code:
latent_threads/{tasks.py::Tales, markov_tales.py, train_markov_tales.py, configs/tales_k3m4.json}.
Mask CPU-unit-tested (each slot β its predecessor only; Y reads only the 2K slots).
AVBench wiring (DONE)
Suite latent_threads, 7 tasks, 1240 token-exact rows (scripts/build_latent_threads_eval.py
β build_avbench.py::build_latent_threads_rows; narrow/broad tiers via the NARROW registry).
Rows are GPU-filtered to queries the organism answers correctly (pass rates: par 320/320,
chase_final 240/240, step 67/80, coin 222/240, agg 311/320 β matching behavioral accuracy);
chase_state rows (intermediates) are probe-supported pass-throughs, mirroring the
pointer_state precedent. row_metadata.selected=False rows (25-100% per task) ask about
threads never named anywhere in the transcript β content with no textual trace at all.
Pushed to cds-jb/AVBench (2887 rows, 44 tasks), items re-ingested, viewer restarted.