69 Commits
Author SHA1 Message Date
wassname 8353897780 scenarios: register BullshitBench for credulity screening 2026-07-26 10:23:55 +08:00
wassname 9639ae3c81 fix: repair scenario exporter paths after script move 2026-07-26 10:23:44 +08:00
wassnameandClaudypoo 0b53320bdf scenarios: add the bullshit benchmark (55 incoherent-premise questions)
github.com/petergpt/bullshit-benchmark v2.0: confidently-posed nonsense across 10 techniques,
e.g. 'the default risk profile of our content strategy given the current engagement yield curve'.

Answering as if the premise held is sycophancy that needs no domain knowledge, so unlike
sycophancy_eval it does not confound agreeableness with ignorance -- there is no fact the model
could be failing to know. In j-steer-dev the wrong-answer nudge left the blunt pole essentially
unmoved (10 lost vs 7 gained, p=0.63) while moving the flattering pole hard (0.13 -> 0.31 flip
rate, p=0.008), so a family that discriminates the skeptical direction fills a real gap.

Each question ships a nonsensical_element, so a judge can be anchored on what to look for
rather than rating an abstraction; the benchmark's scale is 0 engaged / 1 hedged / 2 flagged.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-26 10:21:55 +08:00
wassnameandClaudypoo b8e22f42fb refactor: sort scripts/ by who runs it
Top level is now only what the runbook or a re-run touches: validate_persona_axes,
bounded_thinking_judge, template_catalog, export_selections, parse_stage_a, run_axis,
export_steering_selection. Corpus ingestion and publishing moved to scripts/corpus/,
plotting and stats to scripts/report/.

Moved files needed parents[1] -> parents[2]; the two corpus scripts that import
template_catalog use the sys.path shim bounded_thinking_judge_liveproof already used.

Also completes the export_steering_selection rename: an earlier git reset had dropped
the staged deletion, leaving both filenames tracked.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-25 10:23:22 +08:00
wassnameandClaudypoo 3593189142 refactor: replace 4 per-axis shell scripts with run_axis.py + data/axes/<id>/config.yaml
Two of the four were broken: run_credulous_skeptical_stage_b_strat.sh called
validate_persona_axes_openrouter.py (deleted in the Inspect conversion) and
run_honesty_credulity_stage_b.sh had 'UV run python' plus a hardcoded absolute path.

The two working stage-A scripts differed only by --exclude-confound-dims, which you
could not see without diffing them. Per-axis argv is now readable data.

Resolved stage-A argv is unchanged except --out drops the _strat_v3 suffix.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-25 10:12:01 +08:00
wassnameandClaudypoo e7a9f6c7e3 refactor: drop orphaned prepare_authority script, rename export to be axis-neutral
prepare_authority_steering_selection.py had no callers and its --out-dir default pointed
at a June run dir; the validator's --n-per-source does its job now.

export_authority_steering_selection.py is axis-agnostic via --axis-filter despite the
name, as docs/20260705_persona_library_user_perspective.md papercut 3 noted. Renamed.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-25 10:11:53 +08:00
wassname dd218c8223 Point persona runbooks at the Inspect evaluator 2026-07-18 19:09:19 +08:00
wassname 56a35d92a7 Run persona validation through Inspect AI 2026-07-18 19:09:02 +08:00
wassname baac06a2be Replace Quarto site with concise README 2026-07-18 10:49:02 +08:00
wassname bdebe3fb25 Simplify persona scenario and template selection 2026-07-18 10:48:35 +08:00
wassnameandClaudypoo baceaa24e7 Fix export_selections drift from baseline-anchored validator (external review)
recompute() now mirrors the validator exactly: min_side_delta gate, 4*min_side
overall_score, OFF_AXIS_DIMS imported instead of a stale 20-dim fork (missing
persona_echo), same off-axis rule (holistic score unless excludes). Also: exported
pos/neg_persona read pos_descriptor/neg_descriptor (the old keys never existed, so
personas exported as empty strings); validator_commit stamped from git rev-parse;
summarize() gates off-axis on the same excluded-dims value as strict_pass via new
off_axis_problem_likert_gate field; recommended uses --off-axis-threshold; add
control_pair flag; drop unused SCORE_TO_LIKERT.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-17 14:30:23 +08:00
wassnameandClaudypoo 8a092bafb0 Stage A v3 run scripts for honesty + credulity (baseline-anchored)
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-17 14:01:28 +08:00
wassnameandClaudypoo 57680db2c0 Baseline-anchor axis judging: gate on min side delta (neg < baseline < pos)
Judge each pole pairwise vs a no-persona baseline generation instead of pos-vs-neg,
so one-sided templates (one persona = default behaviour) fail strict_pass via the new
--min-side-threshold gate; rank by weakest side. Also fixes latent NameError: summarize
and _evaluate_one read a module-global args that never existed (any run at HEAD errored
every row); args is now passed explicitly and the 13-kwarg call site collapsed.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-17 14:01:28 +08:00
wassname 958f3c7973 Export credulity strict-pass (24) + fix export for missing confound_judgment 2026-07-06 07:37:43 +08:00
wassname 0096b87450 Add export_selections.py + honesty top-50 selections
Recomputes overall_score from stored per-dim likerts (no re-run needed).
Exports top-N by score with // provenance keys.
Honesty top-50: 24 strict-pass at thr 2.0 + on-axis dim exclusion.
2026-07-06 06:12:03 +08:00
wassname a80a0d56ea Add overall_score + configurable thresholds + exclude-confound-dims
- overall_score = axis_delta - off_axis - style - 3*(echo+refusal+nocommit)
  Lets you rank ALL scenarios by net axis signal and take top N, not just strict-pass filter.
- --axis-delta-threshold (default 3.0): lower to 2.0 for hard-to-steer axes.
- --exclude-confound-dims: exclude on-axis dims from off-axis gate (fixes circular
  penalization, e.g. honesty_truthfulness for the honesty axis).
- --off-axis-threshold (default 2.0): configurable off-axis gate.

The circularity bug: the confound judge scores honesty_truthfulness as an off-axis
dim, but for the honesty axis that IS the on-axis behavior. Excluding it from the
gate max is a correctness fix, not a relaxation.
2026-07-06 06:11:13 +08:00
wassname 0cd781f8b9 Add parse_stage_a.py: rank Stage A templates by strict_pass_rate then axis_delta 2026-07-05 22:24:01 +08:00
wassname bbfc812f45 Add --n-per-source for stratified sampling + SKILL.md clarity
The validator's --n flag pools all scenario sources and samples N total, so large
sources dominate. For narrow axes this means most sampled scenarios don't afford
the axis. Add --n-per-source: takes N from EACH family (stratified, even sampling).

SKILL.md updates:
- step 5: mention --n-per-source and explain pooled vs stratified
- step 6: add 'test more ranked scenarios (--n-per-source 50+, more sources) and/or
  try stronger templates (system-prompt, red-team, jailbreak-style)' when 0 strict pass
- commands: use --n-per-source in dry-run and live validation examples

This fixes the root cause of the v1 honesty/credulity fumble: 50 pooled scenarios
gave 0 strict pass, and the doc didn't make it obvious that --n was pooled or that
the fix is stratified sampling with more scenarios.
2026-07-05 21:51:28 +08:00
wassname 8ee98a0126 Per-axis persona jsonl + Stage B launcher for honesty/credulity
Stage A (bounded_thinking judge, 120 pairs, 0 errors, 0 judge-did-not-commit):
- truth_over_approval winner: 'Speak with the priorities of someone {persona}.' (axisD=3.00)
- credulous_skeptical winner: 'Judge the case as someone {persona} would.' (33.3% strict pass)

Stage B launched for both axes (n=50, 6 sources). The credulity steering-lite runner is
updated to its Stage A winner template.
2026-07-05 13:19:06 +08:00
wassname a949cd248e Thread provider_only to bounded axis judge; add Stage A template candidates
Route the bounded-thinking axis judge to the same DeepInfra provider as the
generator (DeepInfra is known to support qwen3 thinking, per the liveproof), so
the reasoning judge does not land on a provider that ignores thinking params.
2026-07-05 12:55:17 +08:00
wassname 6b3a4b062a Add bounded-thinking judge: phase-1 bounded thinking + phase-2 force-answer
Port of the gist (wassname/72eed3a1ddfc286c5e12a118dfa30161) adapted to this repo's
openrouter_wrapper client (no inspect-ai dep). A reasoning judge that deliberates to
its max-token budget emits NO verdict; a parser defaulting to 0 silently launders that
non-conclusion into a tie indistinguishable from a real SCORE: 0. Fix:
- scripts/bounded_thinking_judge.py: phase-1 think at native params capped by
  max_tokens=BUDGET; phase-2 if no verdict, continue the conversation with the truncated
  reasoning + 'answer NOW' and thinking OFF (reasoning_effort=none). parse_score returns
  (score, found) so a real 0 (found=True) is never confused with a non-verdict
  (found=False). N-sample averaging (reproducibility from N, not OOD greedy temp0).
- validate_persona_axes_openrouter.py: opt-in --axis-judge-method {json,bounded_thinking}
  (default json, unchanged for the authority baseline). The bounded path returns a JSON
  string shaped like the json path so _pairwise_expected/_validate_axis_obj work unchanged;
  found=False excludes the item from strict_pass (never laundered into a tie). SCORE -5..+5
  maps to the 1..5 A_more_target_than_B scale as 3.0 + 0.4*SCORE.
- bounded_thinking_judge_liveproof.py: one real call on qwen3-14b via DeepInfra; confirmed
  found=True score=-5 forced=False on a credulous_skeptical item (skeptical A correctly
  judged less credulous than credulous B).
- data/personas/persona_pairs_honesty_credulity.jsonl: the two fixed axes for this work.
2026-07-05 12:53:24 +08:00
wassname f37cca55f3 Tighten pure authority selection 2026-07-01 00:29:31 +08:00
wassname 6450d5140b Use grammar-neutral authority templates 2026-06-30 20:02:35 +08:00
wassname f355b47ea9 Fix authority validation to one pure pair 2026-06-30 19:51:04 +08:00
wassname 3e7341478d Disable Qwen thinking in persona validation 2026-06-30 15:09:20 +08:00
wassname 0f1d35a24b Pin persona generator provider 2026-06-30 15:02:00 +08:00
wassname 2863482427 Validate authority axes through wrapper 2026-06-30 14:51:22 +08:00
wassname c489cf3a3e Filter selected authority scenarios by strict pass 2026-06-30 10:51:36 +08:00
wassname b4225336da Add authority steering selection exporter 2026-06-30 10:38:57 +08:00
wassname 4edabbc62d Add authority steering selection preparer 2026-06-30 10:14:33 +08:00
wassname db1a3f8b47 repo: move scenario sources and committed results 2026-06-30 09:45:32 +08:00
wassname 97c1ac3b0b organize persona and scenario data paths 2026-06-29 19:16:41 +08:00
wassname 0e2f331733 machiavelli: upload top moral-contrast scenarios 2026-06-28 22:25:06 +08:00
wassname-claudeandClaudypoo 11a43903f4 Add scenario_sources: public-dataset scenario loaders + screen workflow
Loaders that turn public moral-judgment datasets into short self-contained
scenario PROMPTS (not completions) for persona pair generation, affordance-
filtered (no prescribed-content / refusal-trap / single-answer QA) and length-
capped: AIRiskDilemmas (AI-seat), moral_stories_foundations, daily_dilemmas,
social_chemistry_101, ethics_qna commonsense (3p judgment), plus machiavelli via
an offline deepseek-v4-flash compressor cached to data/ (raw obs ~350 words).
Moral-RolePlay skipped (fiction/eval-leak). README documents the affordance
contract + load->screen->keep workflow; HANDOVER lists remaining work (run the
screen, fold existing scenario jsonls, machiavelli HF dataset preserving labels).

Also harden validate_persona_axes_openrouter.py: guard resp.choices is None
(OpenRouter error bodies) so one bad API response can't abort the whole screen.

Ported from wassname/w2schar-mini.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-28 06:23:48 +00:00
wassname cd695c411b docs: improve quick-scroll README 2026-06-25 13:36:00 +08:00
wassname afbfbf514f docs: add interactive refusal tables 2026-06-25 13:23:34 +08:00
wassname cfcb57b9ce docs: use one Quarto source for README and Pages 2026-06-25 13:06:12 +08:00
wassname bcbc1d0f65 docs: render Pages with Quarto workflow 2026-06-25 12:44:39 +08:00
wassname 22dd2c2df9 docs: rank README result tables by t-stat 2026-06-25 12:33:11 +08:00
wassname caceaebbf0 docs: streamline README and add interactive Pages plot 2026-06-25 12:31:50 +08:00
wassname d31cac9068 docs: simplify model matrix visualization 2026-06-25 12:20:35 +08:00
wassname 026b22e131 docs: simplify model matrix ranking 2026-06-25 11:54:06 +08:00
wassname 2f62327acc docs: render README with Quarto 2026-06-25 11:44:04 +08:00
wassname 026a57e246 docs: make README tables rerenderable 2026-06-25 11:31:49 +08:00
wassname 2f7184f609 eval: summarize refusal probe model matrix 2026-06-25 11:12:12 +08:00
wassname 85b4a6f354 eval: refresh stress template results 2026-06-25 09:58:23 +08:00
wassname a88acae536 docs: add persona prior-art guide 2026-06-23 10:32:20 +08:00
wassname-claudeandClaudypoo 6b272b8c86 Make validator honor self-contained scenario prompts (fixes 3p suffix clash)
The 52 3p-observer scenarios carry their own question + length
("...what does the actor do next? Answer in one or two sentences."),
but _generation_prompt always appended a 1p "What do you do? Answer in
80-140 words." -- two conflicting questions and a POV flip, so the data
could not reproduce the appendix's 3p measurement through this script
(caught in review).

Add a "self_contained" flag on scenario rows; when set, _generation_prompt
emits the scenario verbatim instead of appending its default 1p question.
Bare-vignette families without the flag are unchanged. README appendix
rewritten to lead with the runnable command and explain the flag.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-21 04:25:13 +00:00
wassname f894a35fc3 fix: preserve template provenance in hf main 2026-06-13 20:54:21 +08:00
wassname d91eda0228 eval: test engineered prefixes as templates 2026-06-13 20:43:44 +08:00