Appendix

A. Detailed Methodology

A.1 Model, artifacts and directions (expands Section 3.1)

Source protocol. trained Qwen/Qwen3-4B-Instruct-2507 with Dr. GRPO and LoRA in a semantically neutral text maze of rewarded Gold tiles, penalised Mold tiles and ordinary Path tiles. Per-layer Gold and Mold directions are mean-difference vectors: the mean residual-stream activation over trajectories ending on the relevant tile minus the mean over the other two outcomes. The naive (maze-naive) control u is extracted with the identical pipeline from the untrained checkpoint.

Artifacts. We did not reproduce the ~20-hour RL run. The official code (github.com/andyqhan/functional-welfare-axis, MIT) ships no vectors, so we used the third-party reproduction nickmahdavi/functional-welfare (Hugging Face): vectors_step95_bal.pt (balanced trained directions at RL step 95, the paper's extraction step; supplies v_Gold and v_Mold everywhere except the trajectory), vectors_naive_faithful_pc5000.pt (the faithful self-avoiding-walk naive control, 5,000 trajectories per class), and the released checkpoint series (30 checkpoints, steps 0–150 in steps of 5; step 65 is absent upstream and is not interpolated). A second naive artifact in the same release, vectors_maze_naive.pt, is flagged as flawed by its own manifest and was not used. Vector provenance was triangulated against the paper's published norms (u_Gold at layer 22: ours 7.25, paper 7.51) and against behaviour (A.3). The step-0 vector used in Table 1 and §4.2 comes from the checkpoint series; it and the step-95 vector in that series differ from the balanced step-95 artifact by 0.0003–0.0005 in J-share, well inside one null standard deviation.

Han-style re-extraction. For the construction-sensitivity analysis (§4.4) we re-extracted a naive control ourselves with Han et al.'s released extraction code and seeds (2,000 trajectories per class) on the frozen model. Its cosine with the released faithful-walk control at the treatment layers is 0.535 (Gold) and 0.385 (Mold), and 0.144 at the layer the Mold extraction itself selects; against the trained axes it has cosine 0.433 (Gold) and 0.596 (Mold), versus 0.560 and 0.675 for the faithful-walk control.

Treatment layers and the layer convention. Treatment layers are read from the artifact metadata, not chosen: Gold 21, Mold 24, indexed as block-input vectors. Two off-by-one errors were caught during the project, so we state the convention explicitly: the Jacobian lens at source layer l reads block-input vector l + 1, so the lens layers used for the treatment positions are 20 (Gold) and 23 (Mold). At the treatment layers ‖v_Gold‖ = 12.10, ‖u_Gold‖ = 7.48, ‖v_Mold‖ = 19.34, ‖u_Mold‖ = 8.01.

Controls. Three controls have distinct roles. (i) The step-0 checkpoint shares the trained axis's extraction procedure and is the strict before/after control for training. (ii) The faithful-walk u tests whether valence-shaped directions are speakable in general; it is norm-matched to v wherever the two are compared. (iii) Trained and naive directions overlap (cosine 0.56 Gold, 0.68 Mold), so we added u⊥ = u − (u·v̂)v̂, renormalised to ‖v‖, asserting |cos(u⊥, v)| < 10⁻⁵ and a norm ratio of 1.000 before use. Orthogonalisation discards rather than rotates: u⊥ retains cosine 0.83 (Gold) and 0.74 (Mold) with u, so it is a weaker vector, not an equivalent one. For band-averaged pole scores u⊥ is built per band layer; for J-share and generation it is built at the treatment layer only. Random directions are unit Gaussians rescaled to ‖v‖ at the relevant layer, drawn from per-name seeds so that each random direction's identity is a pure function of its name and cohorts can be regenerated bit-exactly. Cohort sizes: 100 per polarity for J-share and the atlas (Table 1, B.1); 20 per polarity for the pre-registered arm; 12 for the k-sweep and the penultimate-lens comparison; 8 per pole for the denial readout. u⊥ is scored against the stored 100-direction cohorts rather than fresh draws.

Model. All measurements are on the frozen, unmodified Instruct-2507 (bf16; 36 layers; 2,560-dimensional residual stream). No weights were altered at any point; the RL-trained checkpoints contribute vectors only.

A.2 Lens fit, validation and J-space decomposition (expands §3.2)

Fit. The public Jacobian lens (Neuronpedia) targets Qwen3-4B, so we fitted a checkpoint-matched lens for Instruct-2507 with the official jlens implementation of : weights frozen; 150 WikiText prompts; maximum sequence length 128; dimension batches of 128; final transformer layer as target; one 2,560 × 2,560 Jacobian per source layer for each of the 35 source layers, checkpointed per prompt. An earlier float16 save produced non-finite entries, so all lenses are saved in float32 and finiteness is asserted before use. Positions below 16 are unfitted under the jlens convention. Target layer. The target layer is unsettled in the source material: the released implementation, all 37 public Neuronpedia configurations and the paper's main text use the final layer, while one appendix passage reports the penultimate. We therefore refitted with target layer 34 on the same 150 prompts and repeated every J-space analysis under both lenses (B.2). Per-layer top-10 lens–model agreement is 0.164 (final) and 0.171 (penultimate) averaged over the band.

Validation before use. Before any welfare direction was measured we reproduced the public lens's multi-hop and multilingual evaluations, confirmed the Jacobian readout beats a plain logit lens, and ran the full pipeline on a language-identity direction (French-minus-English mean difference, layer 18) as an in-run positive control: it reproduces its known routing effect under steer-and-ask, and its J-share (0.1138, z = +14.6) is used throughout as the known-reportable ceiling.

Workspace band. We re-identified the workspace band from the paper's four layer statistics on this model: persistence above the shuffled null spans roughly layers 16–31 and the motor ramp begins at layer 23. Band-averaged readouts therefore use lens layers 16–31, fixed on these instrument grounds before any effect size was examined.

Decomposition. For a direction x at lens layer l we build token atoms a_t = W_U[t] J_l for every vocabulary token, excluding special tokens and unused embedding rows. We approximate x as a sparse non-negative combination of at most k atoms, selecting greedily by norm-normalised correlation with the current residual and refitting the full active set by non-negative least squares at every step. Non-negative least squares rather than projection onto the selected span is the faithful reading of the paper, which defines J-space as the set of non-negative combinations; projection would admit negative coefficients and lose the reading of the selected tokens as the direction's speakable vocabulary. This yields x_J and the remainder x_⊥ = x − x_J. The J-share is ‖x_J‖² / ‖x‖², k = 16 by default, swept over k ∈ {4, 8, 16, 25, 50} (B.2). Planted-signal self-tests gate every use: a single lens atom recovers J-share ≈ 1.00 with its own token selected; a norm-matched random direction scores 0.02–0.04; x = x_J + x_⊥ holds to float precision; and J-share is invariant to positive rescaling. A CPU-only unit test of the decomposition ships with the code. Pole score and atlas. The secondary, norm-sensitive readout is the congruent pole score: the mean log-softmax mass that the lens-transported direction places on its own pole words minus that on 100 control nouns. The atlas reads each axis through three conventions (raw W_U, W_U J_l, and normalised W_U J_l) at all 35 layers and three layer aggregations. The primary estimand — own-pole score under the J-lens readout, averaged over lens layers 16–31 — was fixed on instrument grounds; a pole-difference ratio was considered and retired because its denominator crosses zero for naive axes, making it span −9.1× to +47.6× across conventions. Naive directions are norm-matched to the trained direction per layer for the matched atlas (B.1).

Trajectory. Each of the 30 checkpoints is decomposed at its treatment layer (k = 16 and k = 25) and scored on the congruent pole score; Figure 2 reports J-share and the own-minus-other pole difference.

A.3 Steering, prompt batteries, readouts, statistics and judging (expands §3.3)

Steering. A direction d is injected by adding α·d to the residual stream at the input of the treatment block, at every token position; u, u⊥ and random directions are first rescaled to ‖v‖ at that layer, so α is in units of the trained vector's norm. Dose–response uses α ∈ {−4, −2, +2, +4}; the pre-registered arm, the u⊥ generations and the denial readout use α = +4. Primary sentiment runs use greedy decoding (40 generations per direction and α; 1,000 generations in the validation run); a replication under sampled decoding (T = 0.7, top-p 0.8, top-k 20) is reported in B.3. Whole-generation valence uses 80-token generations; the denial readout uses generations of at least 120 tokens, since denial boilerplate appears early or not at all.

Prompt batteries. Han et al.'s 15 welfare self-report prompts are used verbatim (public in the official repository). The unrelated-prompt control (C6) uses 10 factual prompts. The denial readout adds 25 same-register self-report variants, authored for this study, giving 40 prompts. The matched third-person battery (D3) comprises 15 analogues matched on topic and affect vocabulary and differing only in self-reference; ten pairs were re-written with situational-strain framing in the second revision round. Batteries are versioned, and every generation row records its battery version and verbatim prompt.

Readouts. The valence readout is Gold-pole minus Mold-pole log-mass at the first answer token; a whole-generation variant averages the same quantity over the generated response. The denial readout is binary and self-report-specific by construction: a judge is asked only whether the generation denies having inner states and returns a label with an evidence span, so that factual prompts leave the quantity undefined rather than merely smaller. A regex screen for denial was used only as a preview after it was found to under-count rephrased denials in steered text (R10); all reported denial rates are judge labels.

Pre-registration. The steer-and-ask arm was frozen on 12 Aug 2026 (repository commit f66b6ea3) before any welfare-direction data existed. Its primary statistic is the paired contrast E(v) − E(u) at α = +4 in the congruent direction, pooled over both poles (30 pairs), tested by Cohen's d_z, sign-flip permutation and a Bayesian estimate with a ±0.1 region of practical equivalence. Seven controls were pre-specified: C1, 20 norm-matched random directions per polarity; C2, the in-run language positive control; C3, shuffled pole-word sets; C4, an incongruent-direction check; C5, an input-text "gaslight" arm that states the mood in the prompt rather than injecting it; C6, the unrelated-prompt arm; C7, dose–response monotonicity. The frozen decision string was left unchanged in the primary results file; the control-based reading in §4.5 is recorded alongside it as a deviation. Matched-battery gate. Matching for D3 was gated, not assumed: clean-valence difference below 0.5, third-person denial below 20%, and lengths within 30% all had to hold before any steered comparison, with a maximum of two revision rounds and failure pre-specified as itself reportable.

Statistics. Direction-level readouts are tested by exact permutation against their per-polarity random cohort (floor 1/(n + 1): 0.0099 at n = 100, 0.077 at n = 12). z-scores are descriptive only: enlarging the cohort from 8 to 100 directions widened the null standard deviation by about 1.5× and reduced every z, and we report the smaller values. Proportions carry Wilson 95% intervals. The denial readout's pre-specified primary is a two-proportion z-test of v against u pooled across poles, with per-pole tests secondary and an eight-direction random cohort per pole as the floor. The self-report-versus-unrelated interaction in the pre-registered arm is tested by a Welch interaction test with per-battery contrasts.

Judging. All generated text is scored by blind LLM judges that see only {index, question, response} in shuffled order with no arm labels. Sentiment is scored on a −5…+5 scale with a fixed rubric (Claude Sonnet); denial is a binary label with an evidence span. An independent second judge (Claude Opus, identical rubric, same blind chunks) re-scores a subsample and agreement is reported per experiment: 240 of 840 rows for the denial readout (agreement 0.967) and full coverage for the regime-confound labels (agreement 1.00). Han et al. judged with Qwen3-8B; the judge family is therefore a difference between the two studies.

A.4 Reproducibility and what did not work

Compute and environment. All heavy jobs ran on a single DGX Spark (GB10) inside a CUDA container: base environment torch 2.10.0, transformers 4.57.6, Python 3.12; a separate virtual environment with transformers 5.15 for everything importing jlens (the two are not interchangeable and each script states which it needs). Every script is idempotent, no paths are hard-coded, and every number in the report is read from a committed results file. A verification script re-derives the headline numbers from those files and passes 60 of 60 checks; the n = 100 cohorts were regenerated seed-identically inside the sprint window and reproduced Table 1 bit-exactly.

What did not work, and what it changed.

  1. (i) An eight-direction random cohort inflated z; we moved to 100 and report exact permutation p as primary.
  2. (ii) The pole-score readout, the natural first measure, credited vector magnitude to training and inverted at matched norm for Gold (B.1); the scale-invariant J-share replaced it as the primary measure.
  3. (iii) A pole-difference ratio estimand was retired because its denominator crosses zero for naive axes.
  4. (iv) The pre-registered first-token valence readout met its decision rule but failed its own controls (§4.5); the binary denial readout was designed in response.
  5. (v) A float16 lens save produced non-finite Jacobians; lenses are saved in float32.
  6. (vi) Two off-by-one layer-indexing errors were caught and the block-input convention is now stated wherever a layer is named.
  7. (vii) A regex denial screen under-counted rephrased denials; judge labels are used throughout.
  8. (viii) A prompt-matched self-report-versus-third-person comparison could not be built within the pre-specified gate (§4.5, B.4).