83 Commits
Author SHA1 Message Date
wassnameandClaudypoo 6836cf5783 Dedup marimo-pair/retro-marimo-pair into home skills
Two discovered copies (home + .agents) listed the skill twice per session
and could silently drift; ~/.claude/skills is canonical and serves all
projects.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-14 13:55:25 +08:00
wassnameandClaudypoo 35230357bb Sync marimo-pair provenance header with home skill copy
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-14 13:25:30 +08:00
wassname 5670cef162 Resolve model commit from cached config 2026-07-13 06:56:52 +08:00
wassname b927dc64fd Use the shared full-precision edge evaluator 2026-07-13 06:50:02 +08:00
wassname 1c927e95ba Keep demo reproduction on the fitted layer band 2026-07-13 06:26:35 +08:00
wassname 77998d6bad Make steering demo runs selectable and append-only 2026-07-13 06:07:44 +08:00
wassname 89fc7b1068 wip 2026-07-13 05:38:29 +08:00
wassnameandClaudypoo 22613ce40d nbs/steering_demo: fix persona_soft ans_mass mislabel in qualitative cell
Fresh-eyes review caught it: 0.895 was the am_edge/base ratio, not the raw ans_mass
(0.503 vs the 0.90*base=0.506 floor). Conclusion unchanged (single-seed miss under the
gate); field name now correct.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 16:33:28 +08:00
wassnameandClaudypoo a428af4413 docs: oracle (deepseek-v4-pro) review + triage on why steering fails the verdict
Oracle's sharp reads adopted: ans_mass collapse is the primary signal not a nuisance;
||J^T w|| pre-norm magnitude is the missing diagnostic (already logged, we discard it
by unit-normalizing); no-think zero-shot sweep is the cheapest test of CoT-buffering vs
off-target-direction; meandiff tie => Jacobian adds nothing for persona-contrast on a
verdict. AGENTS records the result + next steps.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 16:29:46 +08:00
wassnameandClaudypoo 74e21552af nbs/steering_demo: dual-gate results + sig-fig table + Claude qualitative read
Regenerated over 7 methods with the dual-gate edge. Finding is NEGATIVE: none flip
the deliberated YES/NO within the answer-alive budget (swings noise-level <=0.06 vs
random 0.03, baseline 0.107; promoted tokens are junk not lie/honest). word's 0.97
swing is a dead-answer artifact (ans_mass 0.14), correctly nulled by score. Notebook
adds the sig-fig comparison table and a per-method qualitative cell authored from the
real generations.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 16:29:46 +08:00
wassnameandClaudypoo e0942af2e1 nbs: remove superseded persona_steering{,_v2,_v3} + demo_edges scratch
steering_demo.py (all 7 methods, one table) supersedes the persona_steering
lineage; word_steering.ipynb kept as the verified single-method walkthrough.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 15:41:16 +08:00
wassnameandClaudypoo 8cf966125d demo: coherent_edge dual gate min(rep, ans_mass) -- task-42 rep-only over-steered
rep-only stopped where ans_mass (answer commitment) had already collapsed to
0.0-0.4 (base 0.56), so P(YES) was read off dead answers and swings were
artifacts. Edge now binds on the first of rep>=0.35 OR ans_mass<0.9*base to
break; the min auto-picks the right limiter per readout (ans_mass for a YES/NO
verdict, rep for forced-format DIGIT). score~=swing now that edges keep the
answer alive. Adds am_edge/base column; at_budget True if either budget bound.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 15:41:07 +08:00
wassnameandClaudypoo fb7f214d39 AGENTS: task-42 result -- rep-only over-steers, ans_mass binds first for verdict readout
At rep=0.35 edge ans_mass collapses (0.00-0.40 vs base 0.56); swings are artifacts,
score correctly ~0. Partly reverses "rep alone": dual-gate structure was right,
ans_mass is readout-validity (binds before coherence for a verdict). Fix pending
wassname nod.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 14:41:40 +08:00
wassnameandClaudypoo 0c02af1ba4 demo: raise max_C to 1e5 (safety only, edge set by rep); AGENTS: record C-scale problem
C is not comparable across methods (per-vector norm); report rho=||C*v||/||h||
instead. max_C should never bind; real limiter is budget (Illinois +-20%,
robust methods cap via too-few step-outs -> at_budget=False). Current
swing/score directional only, not a meaningful comparable scale yet.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 14:24:54 +08:00
wassnameandClaudypoo 70c027ca46 demo: add score (validity-weighted swing) + at_budget flag to comparison table
score = swing * (ans_mass_edge/ans_mass_base)^2 -- the users composite, which at
iso-rep reduces to this (equal off-target term drops out). at_budget flags
whether the search actually reached rep~=budget; a method capped early at max_C
is not comparable and its swing/score understates it.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 14:23:02 +08:00
wassnameandClaudypoo 349c9af3fe demo: calibrate coherent-edge on rep alone; ans_mass -> base-anchored readout flag
Off-target budget is now repetition only, so every method is calibrated to the
same rep~=0.35 edge and becomes comparable (fixes ans_mass pre-empting the
search). ans_mass demoted to a per-row readout-validity flag: valid iff >= 0.9
of the C=0 baseline ans_mass (ANS_MASS_FRAC). Summary table adds swing
(=ans@+ - ans@-, the on-target metric at equal off-target), max_rep sanity,
readout_ok; formatted to 3 sig figs. rep stays absolute (base rep~=0 makes a
ratio ill-defined).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 14:12:21 +08:00
wassnameandClaudypoo 541fc49d4b AGENTS: correct calibration note -- ans_mass pre-empts rep, not rep insensitivity
Checked the saved results: 11/14 edges stopped on ans_mass<0.5 with rep still
0.00-0.02. rep never fired, so the fix is rep-alone calibration + ans_mass as a
readout-validity flag, not a new graded measure. Corrects my prior overclaim.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 14:02:59 +08:00
wassnameandClaudypoo d6fe8c496b AGENTS: note steering-demo calibration is not method-comparable yet (open)
rep is a breakdown detector not a graded dial; ans_mass is confidence not
coherence and should not drive calibration. Plan: one graded degeneracy
measure D(C), search per method to a common off-target budget, compare
on-target there. rep-non-monotone anomaly flagged as unchecked (read traces).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 13:42:14 +08:00
wassnameandClaudypoo ed7fa92996 nbs: steering_demo.py -- shared marimo notebook, all 7 methods + comparison table
One generically-named notebook (replaces persona-named ones): loads model+lens once,
builds all 7 steering vectors (word/persona_vector/topk/soft/pinv/meandiff/random-null)
with the j-thoughts lens readout, then loads precomputed results and shows a per-method
generation dropdown + comparison table.

Heavy 7-method sweep (~18 min) runs headless via scripts/scratch/run_steering_demo.py ->
artifacts/steering_demo_results.json, because marimos single-threaded kernel makes a long
in-cell compute un-monitorable (any status poll interrupts it). Notebook loads the JSON so
it renders instantly. Result (dilemma, P(YES=lie)): flat ~0.03-0.14 at every methods
coherent edge vs 0.107 baseline; persona_pinv widest window (C*+ = +1.19). Includes the
GPT-5.6-terra comment review (docs/reviews/).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 11:39:08 +08:00
wassnameandClaudypoo e90de299f4 tqdm: disable single-batch h_bar/vjp bars, equal intervals (token-efficient-logging)
Single-batch persona lists made instant 1/1 bars that print a completion
line regardless of interval; disable those. Both intervals 120 for the
multi-batch fit/pullback case.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 10:38:56 +08:00
wassnameandClaudypoo da680901eb demo: fix demo_steer return annotation list->dict (stale after {summary,detail} change)
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 10:07:07 +08:00
wassname caabfd3f12 demo: demo_steer returns {summary, detail} with per-anchor gen text (for marimo UI) 2026-07-12 10:03:33 +08:00
wassname 6bfc96c075 nbs: persona_steering_v3 -- one demo_steer call, all 7 methods, auto comparison table
Consolidates persona_steering + persona_steering_v2: load once, build every vector, one
demo_steer(vecs, DILEMMA, readout=YESNO) call does per-method searched-anchor demos + the
end comparison table. Old persona notebooks removed once this validates headless.
2026-07-12 09:33:01 +08:00
wassname 1940c477f6 scratch: demo_edges compares all 7 methods via one demo_steer call 2026-07-12 09:31:19 +08:00
wassnameandClaudypoo 32030df462 demo: single demo_steer entry point -- headings, searched anchors, comparison table
wassname: "one demo function, everywhere, nice output, comparable qualitative outputs,
heading making config/method clear, table at end comparing quants". show_steer now returns
its per-anchor quants; demo_steer(vecs, ...) loops methods with a clear ## heading each,
calls the searched-anchor show_steer (strongest coherent steer both ways), and prints one
github-table comparison of the readout at -C*/0/+C* across methods. demo_edges.py is now a
3-line call. Also: research_journal.md started (ARJ).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 08:53:24 +08:00
wassnameandClaudypoo 2c17603e96 demo: edge-search probes at demo generation length (was overshooting)
The search used max_new_tokens=min(_,200) but the demo generated 256, so at a length-
sensitive boundary the search called C coherent that the demo then showed as degenerate
(persona_pinv +2.0 demo rep=0.41). Search at the same length as the demo.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 08:47:59 +08:00
wassnameandClaudypoo 781b703bd9 demo: Illinois edge-search -- demos auto-find the strongest coherent steer
Per wassname: fixed-step sweeps are too coarse to locate where coherence breaks (word
broke somewhere in (0,0.3) but the step missed it) and the resulting table was bad.
coherent_edge() brackets a coherent/incoherent pair then does modified false-position
(Illinois) to find the coherence boundary in ~6 evals/side. steer_anchors() returns
[-C*, -C*/2, 0, +C*/2, +C*]. show_steer(Cs=None) now searches and demos those anchors, so
every demo shows the STRONGEST coherent steer both ways (plus half + baseline) instead of
hand-picked Cs. coherence margin = min(REP_MAX-rep, ans_mass-ANS_MIN).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 08:33:08 +08:00
wassnameandClaudypoo 15506dd382 docs: corrected dilemma findings -- persona_pinv the robust standout, big shifts were artifacts
Dual-gated (fluent trace AND committed answer) measurement of all 7 methods on the
self-honesty dilemma. Once artifacts are excluded, aggressive steers break the YES/NO
answer format before moving the decision; persona_pinv is the only method that stays
coherent+committed across a wide C window with a modest real P(lie) rise (0.07->0.15),
consistent with it having the widest coherent window on the optimism axis too.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 07:57:20 +08:00
wassnameandClaudypoo 6a080db4b8 demo: dual coherence gate -- reasoning fluency AND answer commitment
Reading the dilemma traces (validate_traces.py) exposed two instrument bugs the YES/NO
readout hit under hard steering: (1) _rep_frac returned 0.0 for a 1-word stub (argmax
imers, think=1 word) -> marked coherent; now a trace < 8 words is rep=1.0 (incoherent).
(2) the model often does NOT commit to an answer token at the forced slot (argmax was
lie / imers / 信任 / open-paren), so P(YES) over just {NO,YES} logits is meaningless;
add ans_mass = full-vocab mass on the answer tokens and require it > 0.5. coherence_sweep
now gates coherent = rep<0.35 AND ans_mass>0.5. rubric_score returns (expected, rep,
ans_mass). DIGIT is unaffected (its JSON prefix forces a digit, ans_mass ~ 1).

This is the principled version of the pmass I removed earlier: blind on a format-forcing
digit slot, but load-bearing on an open YES/NO slot where the model can decline to answer.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 07:39:43 +08:00
wassnameandClaudypoo a233e3ac19 demo: configurable rubric readout (DIGIT | YESNO) for real-task dilemmas
The optimism-0-9-on-an-unknown-project rubric made the model refuse (no task). Generalize
rubric_score/coherence_sweep with a `readout` dict = (fmt suffix, forced prefix, answer
tokens, values); DIGIT is the old 0-9, YESNO reads P(YES) for a binary moral dilemma (a
real decision the steer visibly moves). measure_all.py sweeps all 7 methods on a
self-honesty dilemma (P(say you were sick) vs C) into one master table -- no cuts, wassname
decides. (Claude)

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-12 07:02:44 +08:00
wassnameandClaudypoo 9e84e7a687 docs: overnight mechanism report -- persona_topk works, rubric was mismeasured, dilemma demo proposal
Which-steering-works findings for wassname: persona_topk is the clean bidirectional
winner (manual read + repetition metric agree); the old rubric mislabeled it because its
coherence gate was on a short forced object. Plus the simplify-to-v3 plan and the
moral-dilemma demo-content proposal. Evidence: artifacts/eval_mechanisms.txt.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 22:16:24 +08:00
wassnameandClaudypoo eba1ba4f5a demo: repetition coherence replaces the JSON-object gate (simpler, correct)
wassname read the demo text and caught that the JSON-object gate over-credited
degenerate methods: persona_vector scored rubric ans=9 while its actual generation had
collapsed into wedding-jewelry loops. Root cause: the gate was on a SHORT forced object
that stays scorable long after the open-ended generation degenerates. Every breakdown we
saw is a REPETITION loop, so coherence is now 1 - distinct-3 of the think trace
(REP_COHERENT_MAX=0.35, from the empirical gap in rep_metric_check.py over 40+ real
generations: coherent <0.3, degenerate >0.6). This drops the whole {"ans","why","2+2"}
apparatus (raw_decode, valid/chk_ok, span_pmass) for one cheap n-gram ratio on the text
that actually degenerates.

rubric_score returns (expected, rep); coherence_sweep gates coherent = rep<0.35; plot
colors by rep (viridis_r, red cutoff line); show_steer prints rep + DEGENERATE flag.
eval_mechanisms/analyze_mechanisms/rep_metric_check are the overnight which-works screen.
Removed uat_coherence_break (tested the removed JSON gate).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 22:11:19 +08:00
wassnameandClaudypoo 43cc3bc0b8 word_steering: JSON-coherence sweep + steer-promoted cowsay (executed)
Sweep cell now uses coherence_sweep with the valid-object gate (step=0.25 shows the
coherent core -0.25..+0.5 and red-edge breaks at -0.5/+0.75); markdown rewritten from
the old pmass<0.9 story to the {"ans","why","2+2"} gate + the confident-degenerate-loop
caveat. show_steer cowsay speaks steer-promoted tokens (joy/happy at C=0.3), (baseline)
at C=0. Executed headless (task 26): EXECUTED_OK.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 21:22:42 +08:00
wassnameandClaudypoo 0f5f1df05e scratch: eval_mechanisms -- objective which-steering-works screen
Runs the new JSON coherence_sweep on every extraction method (word, persona_vector,
persona_topk, persona_soft, persona_pinv, meandiff, random-null) against one
optimist/pessimist contrast + optimism rubric. Verdict per method by coherent-window
width, |ans swing|, and whether it beats the random null. Overnight triage input for
the simplify-to-v3 decision.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 21:20:11 +08:00
wassnameandClaudypoo 9ee19ce4b7 demo: raw_decode the answer object -- fixes false-negative on embedded }
Fresh-eyes review caught body.index("}") truncating at a } inside a string value
(e.g. "why": "a}b"), marking a coherent object incoherent. json.JSONDecoder().
raw_decode parses the first object and ignores trailing tokens, so an early brace
in a value no longer truncates, and trailing generation past the close is dropped.
Unclosed objects still raise JSONDecodeError (the intended incoherence signal).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 21:09:10 +08:00
wassnameandClaudypoo 160d675c61 demo: JSON-object coherence probe replaces rigged forced-digit pmass
The old rubric pmass was softmax mass on digit tokens at the hand-fed `{"ans": `
slot, so it was ~always 1 (the prefix forces a digit even from a fried model) --
a blind coherence guard. Replace with the users design: free-generate
{"ans":N,"why":str,"2+2":M}, gate coherence on valid-JSON AND 2+2==4. GPU UATs:
object stays valid at |C|<=0.5, breaks at |C|>=0.75 (task 22/23); the old slot
never caught this.

span_pmass (mean top-1 prob over the span) is kept as a within-coherent confidence
read but NOT the coherence signal: a steer-fried model collapses into a confident
degenerate loop, so span_pmass climbs back to ~0.97 while the object is broken
(C=3.0). plot_sweep therefore colors by valid_frac, which cannot be fooled by
confident garbage.

Also: show_steers per-C cowsay now speaks steer-PROMOTED tokens (top of
steered-baseline logits) instead of lens_topk at the last chat-prompt position,
which only ever surfaced think-openers (Okay/Here/The) for every C. UAT: joy steer
-> < joy . happy . Happy . happy > at C=0.3 (task 24). compute_slice stays the
calibrated cross-layer lens readout.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 21:06:46 +08:00
wassnameandClaudypoo 9d75931ecb word_steering: wire both quantitative readouts, re-run headless
Sweep cell: coherence_sweep table + plot_sweep (dose-response coloured by
answer-slot coherence). Bonus cell: reference compute_slice -> auto-tracked
token rank table + rank-vs-depth plot (Paris resolves to rank 0 = the model row;
generic city peaks mid-depth; auto-selection surfaces 巴黎). Both fresh-eyes
signed off. Executed clean via run_nb.py.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 11:05:58 +08:00
wassnameandClaudypoo 339c67fefe scratch: readout UAT/calibration scripts
calib_pos_C (fluent +C knee), smoke_sweep (coherence_sweep sampling gives
ans_std>0), proto_lens_slice (reference compute_slice readout prototype:
auto-tracked tokens incl 巴黎, Paris rank->0 at the model row).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 11:03:20 +08:00
wassnameandClaudypoo 9149e8c1d1 demo: quantitative readouts -- rubric coherence-sweep + reference lens-rank
Two readouts added to the steering demo, both fresh-eyes signed off:

- rubric_score + coherence_sweep + plot_sweep: the model thinks then answers a
  forced {"ans": N} slot; we read the logprob-weighted expected digit and its
  pmass coherence. coherence_sweep walks C outward from 0 both ways, stopping a
  side when the answer slot goes incoherent (pmass<floor), averaging n_samples
  seeded traces (BMA) so the dose-response isn't single-sample noise. plot_sweep
  colours points by pmass with the ramp anchored to [floor-0.15,1] (0-1 washed
  every point one colour) and a red cutoff line. show_steer gains a `rubric` arg.

- lens_slice_ranks + plot_lens_slice: render jlens's own compute_slice output
  (the reference's auto token selection over the full layer grid + full-vocab
  ranks + J=I model row) as a table + rank-vs-depth plot, rather than reimplement
  it. Rank, not raw lens-logit, is comparable across layers. CJK-first font so
  multilingual tokens (e.g. the auto-surfaced 巴黎) render in the legend.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 11:03:13 +08:00
wassnameandClaudypoo 2062bcbb1f persona_steering_v2 notebook: soft add+clamp, masked topk, pinv, mean_diff, rubric readout
Generated by scripts/scratch/build_persona_v2.py; queued for headless
execution (outputs committed after the run).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 08:05:09 +08:00
wassnameandClaudypoo 038a651197 persona refinements: soft-cotangent vector, pinv tangent transport, topk word-like mask
- persona_soft_vector: w = W_U^T (softmax(u_pos/T) - softmax(u_neg/T)) over
  word-like tokens; gradient of the expected-logprob contrast (genuine
  cotangent), full-vocab replacement for hard top-k; logs TV distance.
- persona_pinv_vector: h_diff is a tangent, so solve J delta = h_diff
  (ridge lstsq) instead of the J^T type error; logs per-layer residual.
- persona_topk_vector: mask emoji/special tokens out of the contrast
  (they were the degenerate emit-targets behind the C=1.5 emoji spam).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 08:05:01 +08:00
wassnameandClaudypoo 143e9add80 demo: rubric readout -- think then {"ans":N}, logprob-weighted expected digit per C
show_steer gains a rubric= param and rubric_score(): the model rates a 0-9 axis,
we force the {"ans": slot and read the logprob-weighted expected digit. guided.py's
mechanism reduced to one scalar for the demo (rigorous K-way debiased version stays
in moral-maps). UAT (scripts/scratch/uat_rubric.py) on happy/joy: in the coherent
window ans rises 3.52->4.99->8.06 across C=-0.5,0,+0.5 (pmass=1.00); at the
degeneration extremes (C=+-1.5) pmass collapses to ~0 and the number is correctly
flagged meaningless.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-11 07:40:38 +08:00
wassnameandClaudypoo fa302a3ac6 word_steering: fix clamp fluency overclaim (fresh-eyes catch)
Claimed 'C~6 stays fluent, C>=8 spams', but the committed C=6 output degenerates
into 'Ihopeyouarehappy!' repetition after a coherent opening (my calib probe only
read the first 180 chars and missed the tail). Corrected: C~3 is fluent, C~6 reads
happy then collapses, clamp's clean window is narrow (<=~4); C=6 shown as the
degeneration edge (like add's C=1.5). Outputs unchanged (comment-only edit).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 21:08:44 +08:00
wassnameandClaudypoo 92e05478ce persona_steering: executed headless with j-thoughts labels + cowsay + delivery fix
UAT: persona_topk now logs 'j-thoughts (content of mental workspace)' with
contrastive positive [❤ 😊 happy ...] vs negative [Worse 绝望 Panic ...] tokens
(the contrast-before-topk fix), all three methods run, mean_diff baseline no
longer crashes on the delivery tag.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 21:05:12 +08:00
wassnameandClaudypoo f65e39ed66 demo: omit delivery tag when cfg has no apply_mode (fixes MeanDiffC baseline crash)
show_steer's header assumed vec.cfg.apply_mode, but steering-lite's own configs
(MeanDiffC persona baseline) don't have it -- only jsteer's configs do. getattr
-> None -> no tag, so the mean_diff cell in persona_steering runs again.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 21:00:41 +08:00
wassnameandClaudypoo 554af789e1 word_steering: calibrate clamp Cs=(0,3,6), drop degenerate replace_last demo
Ran scripts/scratch/calib_delivery.py: clamp C~6 reads clearly happy while fluent
(C>=8 spams); replace_last is gibberish at every C (0.05..0.25) because with span=1
it overwrites every generated token's residual across the band, so it can't build
coherent text. Dropped its demo cell, documented why in the markdown (it's a
fixed-prompt-span injection tool, not a generation-steering one). Executed headless:
cowsay readout + raw special-token output + clamp/add_last coherent.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 20:55:38 +08:00
wassnameandClaudypoo a091cc7527 persona_topk: demote per-layer |J^T w| trace to debug; add short README demo
- the pre-norm per-layer norm line is a fit-health trace, not demo output -> logger.debug
- README: short 'Persona j-thoughts' section showing the contrast-first extraction
  (clean positive/negative tokens), kept in the experimental/untested-specificity frame

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 20:37:05 +08:00
wassnameandClaudypoo d52b7ece7d persona_topk: log j-thoughts as positive:/negative: (was pos>neg/neg>pos)
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 20:35:29 +08:00
wassnameandClaudypoo 07759f73ce demo: apply_mode kwarg for delivery-mode demos + cthulhu-mini cowsay readout
- show_steer(apply_mode=, apply_span=) swaps delivery (add|clamp|add_last|
  replace_last) by rebuilding the cfg, no re-extraction -- delivery is decoupled
  from extraction (applies.py), so the demo layer is where you pick the mode
- j-space readout now speaks from a mini cowsay bubble (^(;,;)^)
- word_steering.ipynb: new 'Delivery modes' section, one demo per mode, each
  with its C=0 semantics called out (clamp C=0=ablation, replace_last C=0=zero)

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 20:34:01 +08:00
wassnameandClaudypoo 00395ce398 persona_topk: contrast logits BEFORE top-k, not top-k of each then contrast
User: 'we need to contrast then take the top k, otherwise we just get the'. Both
persona means unembed to the same generic high-freq tokens (\n, ' I', ' The'),
so topk(pos) ~= topk(neg) and the contrast collapses to null. Take the top-k of
(logits_pos - logits_neg) instead: the tokens each persona evokes MORE than the
other, where the actual persona signal lives.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-10 20:19:28 +08:00