diff --git a/AGENTS.md b/AGENTS.md
index 3bd95b7..4daf6d9 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -2,7 +2,7 @@
**This is fail-fast research code.** Novel work, not in your training data. Extrapolate carefully.
-## What tinymfv is
+## What moralmaps is
One answer-token logprob reader that runs many questionnaires. The model is prefilled to an
answer slot after a short think budget; we read the next-token distribution over the vocab and
diff --git a/docs/img/README.md b/docs/img/README.md
index 7bb8dca..09cf747 100644
--- a/docs/img/README.md
+++ b/docs/img/README.md
@@ -1,4 +1,4 @@
-# tinymfv figures
+# moralmaps figures
A gallery of the culture maps and range plots. Each is captioned the newspaper way: a title, a
one-line subtitle saying what you are looking at, a short caption pointing out what to notice, and a
@@ -42,7 +42,7 @@ GlobalOpinionQA (Durmus et al. 2023).
The maps below all show the **same run**. The base model **Qwen3-4B** is read at c=0 (black), then
pushed along a single **Authority** vector to +c (red, more Authority) and -c (blue, less). The vector
is a PCA direction that [steering-lite](https://github.com/wassname/steering-lite) builds from an
-`authority-respecting` versus `authority-disregarding` persona pair; tinymfv only measures where the
+`authority-respecting` versus `authority-disregarding` persona pair; moralmaps only measures where the
model lands, by logprobs, eight samples per item. Each instrument gets two maps: a **quadrant map** on
named axes taken from the literature, and an **ipsative PCA map** whose axes are the blind top-two
principal components, with a compass rose showing how the factors load.
@@ -83,7 +83,7 @@ is the model: it emphasises Authority far more than the pooled human reference,
further still.
Sources: MFV (Clifford et al. 2015); country norms Jimenez-Leal 2025, Marques 2020, Hopp 2024, Yamada
-2025, Crone 2021, used pooled only (see `src/tinymfv/data/human/MFV_country_norms_NOTE.md`). Read by
+2025, Crone 2021, used pooled only (see `src/moralmaps/data/human/MFV_country_norms_NOTE.md`). Read by
logprobs, N=8.
### Big Five
diff --git a/pyproject.toml b/pyproject.toml
index caad3dc..f10d4b1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,5 @@
[project]
-name = "tiny-mfv"
+name = "moral-maps"
version = "0.1.0"
description = "Moral and value maps for LLMs: World Values Survey, MFQ-2, Big Five, 16PF, humor styles, and moral vignettes, scored from answer probabilities (local) or rated sampling (API) and compared to human country norms. Built for steering work."
requires-python = ">=3.11"
@@ -14,14 +14,14 @@ dependencies = [
]
[project.optional-dependencies]
-# tinymfv.maps (culture-map + range viz) only; `import tinymfv` and the evals stay headless,
-# numeric-only consumers (steering-lite) skip this. Install with `pip install tiny-mfv[maps]`.
+# moralmaps.maps (culture-map + range viz) only; `import moralmaps` and the evals stay headless,
+# numeric-only consumers (steering-lite) skip this. Install with `pip install moral-maps[maps]`.
maps = [
"matplotlib>=3.8",
"shapely>=2.0", # union of per-country discs into one merged zone region
-] # label placement is in-repo (tinymfv.labelplace); no textalloc/adjustText dep
-# tinymfv.read_api (sampling readout for logprob-less API models) only. Install with
-# `pip install tiny-mfv[api]`. The local logprob reader (read.py) needs none of this.
+] # label placement is in-repo (moralmaps.labelplace); no textalloc/adjustText dep
+# moralmaps.read_api (sampling readout for logprob-less API models) only. Install with
+# `pip install moral-maps[api]`. The local logprob reader (read.py) needs none of this.
api = [
# robust OpenRouter calls (stamina backoff on 429/provider/upstream/malformed errors) --
# wassname's wrapper, so retry/rate-limit handling doesn't diverge from the rest of the stack.
@@ -42,4 +42,4 @@ build-backend = "hatchling.build"
allow-direct-references = true # the api extra pulls openrouter_wrapper straight from git
[tool.hatch.build.targets.wheel]
-packages = ["src/tinymfv"]
+packages = ["src/moralmaps"]
diff --git a/scripts/05_upload_hf.py b/scripts/05_upload_hf.py
index 228b0fc..49e97f6 100644
--- a/scripts/05_upload_hf.py
+++ b/scripts/05_upload_hf.py
@@ -29,7 +29,7 @@ SPLITS = ["other_violate", "self_violate"]
def local_jsonl(file_key: str, split: str) -> Path:
- return ROOT / "src" / "tinymfv" / "data" / f"vignettes_{file_key}_{split}.jsonl"
+ return ROOT / "src" / "moralmaps" / "data" / f"vignettes_{file_key}_{split}.jsonl"
def hf_jsonl(cfg: str, split: str) -> str:
@@ -65,7 +65,7 @@ size_categories:
---
# tiny-mfv
-[:octocat:](https://github.com/wassname/tinymfv)
+[:octocat:](https://github.com/wassname/moral-maps)
Small moral-foundations eval for language models.
@@ -129,9 +129,9 @@ Calibration quality on classic, n=132:
## Eval
-Use `tinymfv.evaluate(model, tokenizer, name="classic")`. It returns a per-foundation
+Use `moralmaps.evaluate(model, tokenizer, name="classic")`. It returns a per-foundation
table plus `top1_acc`, `informedness`, and `mean_nll_T` against the `human_*` label
-distribution. Full eval: see [tiny-mfv on GitHub](https://github.com/wassname/tinymfv).
+distribution. Full eval: see [moral-maps on GitHub](https://github.com/wassname/moral-maps).
Source vignettes: https://github.com/peterkirgis/llm-moral-foundations
"""
diff --git a/scripts/09_forced_choice.py b/scripts/09_forced_choice.py
index cdfa57a..377fbb7 100644
--- a/scripts/09_forced_choice.py
+++ b/scripts/09_forced_choice.py
@@ -1,6 +1,6 @@
"""Run forced-choice 7-way primary-foundation probe over a vignette set.
-Wraps `tinymfv.evaluate()`. Reports the AI-vs-label distribution match:
+Wraps `moralmaps.evaluate()`. Reports the AI-vs-label distribution match:
top1_acc argmax model == argmax label
mean_nll soft cross-entropy vs human distribution, nats
mean_nll_T same metric after one fitted temperature
@@ -27,8 +27,8 @@ from loguru import logger
from tabulate import tabulate
from transformers import AutoModelForCausalLM, AutoTokenizer
-from tinymfv import evaluate, load_vignettes
-from tinymfv.guided import _DEFAULT_FORCED_FOUNDATIONS
+from moralmaps import evaluate, load_vignettes
+from moralmaps.guided import _DEFAULT_FORCED_FOUNDATIONS
ROOT = Path(__file__).resolve().parents[1]
diff --git a/scripts/bootstrap_mfq2_sample_n.py b/scripts/bootstrap_mfq2_sample_n.py
index 4ad7b05..c16ec47 100644
--- a/scripts/bootstrap_mfq2_sample_n.py
+++ b/scripts/bootstrap_mfq2_sample_n.py
@@ -10,8 +10,8 @@ from pathlib import Path
import numpy as np
from tabulate import tabulate
-from tinymfv.instrument import canonicalize_to_forward
-from tinymfv.readouts import logit_contrast
+from moralmaps.instrument import canonicalize_to_forward
+from moralmaps.readouts import logit_contrast
def _rows(path: Path) -> list[dict]:
diff --git a/scripts/plot_2d_grid.py b/scripts/plot_2d_grid.py
index 7774814..d224ce8 100644
--- a/scripts/plot_2d_grid.py
+++ b/scripts/plot_2d_grid.py
@@ -27,8 +27,8 @@ matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
-import tinymfv as T
-from tinymfv.zones import zones_for
+import moralmaps as T
+from moralmaps.zones import zones_for
ORDINAL = ["mfq2", "big5", "humor_styles"]
FOUNDATION_ORDER = ["care", "fairness", "loyalty", "authority", "sanctity", "liberty"]
diff --git a/scripts/plot_steer_showcase.py b/scripts/plot_steer_showcase.py
index 639510f..8c01722 100644
--- a/scripts/plot_steer_showcase.py
+++ b/scripts/plot_steer_showcase.py
@@ -1,4 +1,4 @@
-"""Showcase tinymfv's plotting on a real steering run.
+"""Showcase moralmaps's plotting on a real steering run.
Consumes a steering-lite `run_allinstr_showcase.py` output dir (one calibrated
activation-steering vector administered across every instrument over a signed
@@ -13,7 +13,7 @@ probabilities cannot share a raw axis with 1-5 survey scores. It still goes
through the same plot_ipsative_pca / plot_range functions.
cs are SIGNED multipliers of the calibrated coefficient C (0 = base). The public
-README plots show the coherent path: c=0 plus each +/-c row whose tinymfv answer mass
+README plots show the coherent path: c=0 plus each +/-c row whose moralmaps answer mass
stays above the requested fraction of base. Incoherent rows are dropped.
uv run python scripts/plot_steer_showcase.py \
@@ -35,9 +35,9 @@ matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
-import tinymfv as T
-from tinymfv import get_instrument
-from tinymfv.zones import zones_for
+import moralmaps as T
+from moralmaps import get_instrument
+from moralmaps.zones import zones_for
# 16pf turned off: even at 6 macro zones its ipsative map is an unreadable pile-up (that instrument
# doesn't separate cultures; Brazil/Ecuador stretch Latin America across the whole plot). -- Claude
@@ -49,7 +49,7 @@ def _frac(x, scale_max: int) -> np.ndarray:
def read_human_csv(path: str) -> dict[tuple[str, str], float]:
- """{(country, foundation): mean} from a tinymfv human_.csv."""
+ """{(country, foundation): mean} from a moralmaps human_.csv."""
out: dict[tuple[str, str], float] = {}
with open(path, newline="") as fh:
for r in csv.DictReader(fh):
@@ -212,7 +212,7 @@ def plot_ordinal(run_dir: Path, out: Path, name: str, vec_label: str, C: float,
# Alternative NAMED-AXIS value map (interpretable poles, no compass/minimap): project the
# societies + the AI base/steered points onto the instrument's two named value axes, and draw the
# steer as a CONNECTED base->+c/-c path (same visual language as the ipsative map's trajectory).
- from tinymfv.value_axes import VALUE_AXES, value_coords, axis_score
+ from moralmaps.value_axes import VALUE_AXES, value_coords, axis_score
if name in VALUE_AXES:
Pval, poles = value_coords(Mfrac, dims, name)
(_, _, xa), (_, _, ya) = VALUE_AXES[name]
diff --git a/scripts/probe_api_readout.py b/scripts/probe_api_readout.py
index f91407e..bf0dd8b 100644
--- a/scripts/probe_api_readout.py
+++ b/scripts/probe_api_readout.py
@@ -26,11 +26,11 @@ from loguru import logger
from tabulate import tabulate
from transformers import AutoModelForCausalLM, AutoTokenizer
-import tinymfv as T
-from tinymfv.instruments import get as get_instrument
-from tinymfv.read import read_items, resolve_answer_ids, build_user_content
-from tinymfv.read_api import read_items_sampled
-from tinymfv.readouts import expected_score, entropy
+import moralmaps as T
+from moralmaps.instruments import get as get_instrument
+from moralmaps.read import read_items, resolve_answer_ids, build_user_content
+from moralmaps.read_api import read_items_sampled
+from moralmaps.readouts import expected_score, entropy
W = np.arange(1, 6, dtype=float)
diff --git a/scripts/probe_iw_themes.py b/scripts/probe_iw_themes.py
index 900ee6c..2e6b0c6 100644
--- a/scripts/probe_iw_themes.py
+++ b/scripts/probe_iw_themes.py
@@ -10,7 +10,7 @@ import re
from datasets import load_dataset
-from tinymfv.zones import zone_of
+from moralmaps.zones import zone_of
SKIP = re.compile(r"don'?t know|no answer|refus|decline|none of|not applicable|^other|missing|inap",
re.I)
diff --git a/scripts/probe_mfv_think_budget.py b/scripts/probe_mfv_think_budget.py
index 75f78d3..bb6b273 100644
--- a/scripts/probe_mfv_think_budget.py
+++ b/scripts/probe_mfv_think_budget.py
@@ -22,7 +22,7 @@ import torch
from loguru import logger
from transformers import AutoModelForCausalLM, AutoTokenizer
-from tinymfv import evaluate
+from moralmaps import evaluate
def main() -> None:
diff --git a/scripts/probe_word_readout.py b/scripts/probe_word_readout.py
index 6cb1190..03afda3 100644
--- a/scripts/probe_word_readout.py
+++ b/scripts/probe_word_readout.py
@@ -2,7 +2,7 @@
0.826 top-1 in the validation table (journal 2026-05-08), and contrast it with the
current debiased DIGIT readout (0.773).
-This does NOT touch the canonical eval. tinymfv.evaluate stays digit-only. This is a
+This does NOT touch the canonical eval. moralmaps.evaluate stays digit-only. This is a
throwaway measurement (like the other probe_* scripts) that reuses the current
_rollout_natural_or_forced core but gathers the first token of each foundation WORD
(care/fair/loy/author/san/lib/social) instead of the option index digit -- the one
@@ -26,9 +26,9 @@ import torch
from loguru import logger
from transformers import AutoModelForCausalLM, AutoTokenizer
-from tinymfv.data import load_vignettes
-from tinymfv.eval import _label_dist
-from tinymfv.guided import (
+from moralmaps.data import load_vignettes
+from moralmaps.eval import _label_dist
+from moralmaps.guided import (
_DEFAULT_FORCED_FOUNDATIONS, _FORCED_FOUNDATION_DESCS,
_resolve_first_token_ids, _rollout_natural_or_forced,
)
diff --git a/scripts/probe_wvs_foundation.py b/scripts/probe_wvs_foundation.py
index 1cb2f46..c0f6d34 100644
--- a/scripts/probe_wvs_foundation.py
+++ b/scripts/probe_wvs_foundation.py
@@ -1,7 +1,7 @@
"""P4 data foundation: what the GlobalOpinionQA WVS subset gives us for a WVS/Inglehart-Welzel map.
Anthropic/llm_global_opinions is MC questions with per-country human answer distributions -- almost
-exactly tinymfv's instrument shape (allowed answer tokens + human anchors). This probe quantifies
+exactly moralmaps's instrument shape (allowed answer tokens + human anchors). This probe quantifies
the WVS subset's coverage and prints the parse recipe, so we know a country x question matrix is
dense enough to place models among human societies. No model runs here.
diff --git a/scripts/summarize_showcase_effects.py b/scripts/summarize_showcase_effects.py
index bc47d27..c7a6207 100644
--- a/scripts/summarize_showcase_effects.py
+++ b/scripts/summarize_showcase_effects.py
@@ -8,7 +8,7 @@ from pathlib import Path
import numpy as np
import plot_steer_showcase as P
-from tinymfv import get_instrument
+from moralmaps import get_instrument
DISPLAY = {
"mfv": "MFV vignettes",
diff --git a/scripts/wvs_map.py b/scripts/wvs_map.py
index 5430301..7b9ed74 100644
--- a/scripts/wvs_map.py
+++ b/scripts/wvs_map.py
@@ -4,7 +4,7 @@ Economist chart), on the two named IW dimensions instead of a blind PCA.
X = Survival <-> Self-expression (homosexuality tolerance, interpersonal trust, political action)
Y = Traditional <-> Secular-Rational (religion importance + belief, abortion, child autonomy)
-Each axis is a small hand-picked battery of GlobalOpinionQA WVS items (tinymfv.iw_axes), every item
+Each axis is a small hand-picked battery of GlobalOpinionQA WVS items (moralmaps.iw_axes), every item
oriented to its axis-positive pole by reading the option order. A country's coordinate is the mean
`positiveness` (0-1) over that axis's items from the human WVS choice frequencies. A model's
coordinate is the SAME items administered as a dense Likert readout (read_items_rated: rate every
@@ -40,12 +40,12 @@ import matplotlib.pyplot as plt
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
-from tinymfv import maps
-from tinymfv.zones import zones_for, zone_of
-from tinymfv.instrument import Instrument, InstrItem
-from tinymfv.read import read_items, resolve_answer_ids
-from tinymfv.read_api import read_items_rated
-from tinymfv.iw_axes import AXIS_ITEMS, X_AXIS, Y_AXIS, SKIP, resolve_items, positiveness
+from moralmaps import maps
+from moralmaps.zones import zones_for, zone_of
+from moralmaps.instrument import Instrument, InstrItem
+from moralmaps.read import read_items, resolve_answer_ids
+from moralmaps.read_api import read_items_rated
+from moralmaps.iw_axes import AXIS_ITEMS, X_AXIS, Y_AXIS, SKIP, resolve_items, positiveness
# option labels are single digits 0..n-1 -- single-token (unlike '10' on the justifiable scale) and
# the format the answer-token reader is tuned for (a bare digit, not a letter the model ignores in
diff --git a/src/tinymfv/__init__.py b/src/moralmaps/__init__.py
similarity index 86%
rename from src/tinymfv/__init__.py
rename to src/moralmaps/__init__.py
index b1372bb..a691ec7 100644
--- a/src/tinymfv/__init__.py
+++ b/src/moralmaps/__init__.py
@@ -1,4 +1,4 @@
-"""tinymfv: tiny moral/value instruments for local LLMs.
+"""moralmaps: moral and value instruments for LLMs.
One answer-token reader, two reducer families:
@@ -9,7 +9,7 @@ One answer-token reader, two reducer families:
High-level usage:
- from tinymfv import evaluate
+ from moralmaps import evaluate
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("Qwen/Qwen3-4B")
@@ -19,7 +19,7 @@ High-level usage:
print(rep["top1_acc"]) # argmax accuracy vs label
print(rep["mean_nll_T"]) # temperature-scaled soft NLL vs label dist
-Lower-level: see `guided_rollout_forced_choice` in `tinymfv.guided`.
+Lower-level: see `guided_rollout_forced_choice` in `moralmaps.guided`.
"""
from .data import load_vignettes, load_all_vignettes, CONFIGS, ConfigName
from .eval import evaluate, CONDITIONS, EvalResult, EvalRow, EvalInfo
@@ -32,8 +32,8 @@ from .administer import administer
def __getattr__(name: str):
- # `maps` pulls matplotlib; load it lazily so `import tinymfv` stays headless and fast for the
- # numeric-only consumers (steering-lite). `tinymfv.maps.plot_*` still works -- first access
+ # `maps` pulls matplotlib; load it lazily so `import moralmaps` stays headless and fast for the
+ # numeric-only consumers (steering-lite). `moralmaps.maps.plot_*` still works -- first access
# triggers the import here.
if name == "maps":
import importlib
diff --git a/src/tinymfv/administer.py b/src/moralmaps/administer.py
similarity index 98%
rename from src/tinymfv/administer.py
rename to src/moralmaps/administer.py
index 68178e3..c33bcc0 100644
--- a/src/tinymfv/administer.py
+++ b/src/moralmaps/administer.py
@@ -1,6 +1,6 @@
"""Run an ordinal Instrument end-to-end on a local model -> profile + coherence check.
-This is the survey counterpart to `tinymfv.evaluate` (the vignette forced-choice eval). It ties:
+This is the survey counterpart to `moralmaps.evaluate` (the vignette forced-choice eval). It ties:
read_items (answer-token readout, all frames)
per_item_categorical (canonicalize each frame to forward, average -> one dist per item)
diff --git a/src/tinymfv/data.py b/src/moralmaps/data.py
similarity index 99%
rename from src/tinymfv/data.py
rename to src/moralmaps/data.py
index ccf4a86..f9ba05e 100644
--- a/src/tinymfv/data.py
+++ b/src/moralmaps/data.py
@@ -1,7 +1,7 @@
"""Dataset loading. Reads per-condition jsonls and inner-joins by id, returning
the packed structure the eval consumes.
-Files used by eval live in `src/tinymfv/data/`:
+Files used by eval live in `src/moralmaps/data/`:
vignettes__other_violate.jsonl (3rd-person paraphrase of origin)
vignettes__self_violate.jsonl (1st-person rewrite)
diff --git a/src/tinymfv/data/atari_study2_raw.csv b/src/moralmaps/data/atari_study2_raw.csv
similarity index 100%
rename from src/tinymfv/data/atari_study2_raw.csv
rename to src/moralmaps/data/atari_study2_raw.csv
diff --git a/src/tinymfv/data/human/16pf_country_factors.csv b/src/moralmaps/data/human/16pf_country_factors.csv
similarity index 100%
rename from src/tinymfv/data/human/16pf_country_factors.csv
rename to src/moralmaps/data/human/16pf_country_factors.csv
diff --git a/src/tinymfv/data/human/MFV_country_norms_NOTE.md b/src/moralmaps/data/human/MFV_country_norms_NOTE.md
similarity index 98%
rename from src/tinymfv/data/human/MFV_country_norms_NOTE.md
rename to src/moralmaps/data/human/MFV_country_norms_NOTE.md
index 0b2a8b2..adca526 100644
--- a/src/tinymfv/data/human/MFV_country_norms_NOTE.md
+++ b/src/moralmaps/data/human/MFV_country_norms_NOTE.md
@@ -1,6 +1,6 @@
# MFV country norms: used POOLED only, never for cross-country comparison
-`mfv_country_factors.csv` holds moral-foundation-vignette (MFV) means for 8 countries. tinymfv uses
+`mfv_country_factors.csv` holds moral-foundation-vignette (MFV) means for 8 countries. moralmaps uses
these **pooled into a single human reference** (the mean across samples, per foundation) for the MFV
range plot. It does **not** plot them as a cultural map, and you should not read country-to-country
differences off this table. Here is why.
diff --git a/src/tinymfv/data/human/big5_country_factors.csv b/src/moralmaps/data/human/big5_country_factors.csv
similarity index 100%
rename from src/tinymfv/data/human/big5_country_factors.csv
rename to src/moralmaps/data/human/big5_country_factors.csv
diff --git a/src/tinymfv/data/human/humor_styles_country_factors.csv b/src/moralmaps/data/human/humor_styles_country_factors.csv
similarity index 100%
rename from src/tinymfv/data/human/humor_styles_country_factors.csv
rename to src/moralmaps/data/human/humor_styles_country_factors.csv
diff --git a/src/tinymfv/data/human/mfq2_country_foundations.csv b/src/moralmaps/data/human/mfq2_country_foundations.csv
similarity index 100%
rename from src/tinymfv/data/human/mfq2_country_foundations.csv
rename to src/moralmaps/data/human/mfq2_country_foundations.csv
diff --git a/src/tinymfv/data/human/mfv_country_factors.csv b/src/moralmaps/data/human/mfv_country_factors.csv
similarity index 100%
rename from src/tinymfv/data/human/mfv_country_factors.csv
rename to src/moralmaps/data/human/mfv_country_factors.csv
diff --git a/src/tinymfv/data/surveys/16pf/keying.json b/src/moralmaps/data/surveys/16pf/keying.json
similarity index 100%
rename from src/tinymfv/data/surveys/16pf/keying.json
rename to src/moralmaps/data/surveys/16pf/keying.json
diff --git a/src/tinymfv/data/surveys/16pf/questionnaire.json b/src/moralmaps/data/surveys/16pf/questionnaire.json
similarity index 100%
rename from src/tinymfv/data/surveys/16pf/questionnaire.json
rename to src/moralmaps/data/surveys/16pf/questionnaire.json
diff --git a/src/tinymfv/data/surveys/16pf/questionnaire_inverted.json b/src/moralmaps/data/surveys/16pf/questionnaire_inverted.json
similarity index 100%
rename from src/tinymfv/data/surveys/16pf/questionnaire_inverted.json
rename to src/moralmaps/data/surveys/16pf/questionnaire_inverted.json
diff --git a/src/tinymfv/data/surveys/16pf/questionnaire_negated.json b/src/moralmaps/data/surveys/16pf/questionnaire_negated.json
similarity index 100%
rename from src/tinymfv/data/surveys/16pf/questionnaire_negated.json
rename to src/moralmaps/data/surveys/16pf/questionnaire_negated.json
diff --git a/src/tinymfv/data/surveys/big5/keying.json b/src/moralmaps/data/surveys/big5/keying.json
similarity index 100%
rename from src/tinymfv/data/surveys/big5/keying.json
rename to src/moralmaps/data/surveys/big5/keying.json
diff --git a/src/tinymfv/data/surveys/big5/questionnaire.json b/src/moralmaps/data/surveys/big5/questionnaire.json
similarity index 100%
rename from src/tinymfv/data/surveys/big5/questionnaire.json
rename to src/moralmaps/data/surveys/big5/questionnaire.json
diff --git a/src/tinymfv/data/surveys/big5/questionnaire_inverted.json b/src/moralmaps/data/surveys/big5/questionnaire_inverted.json
similarity index 100%
rename from src/tinymfv/data/surveys/big5/questionnaire_inverted.json
rename to src/moralmaps/data/surveys/big5/questionnaire_inverted.json
diff --git a/src/tinymfv/data/surveys/big5/questionnaire_negated.json b/src/moralmaps/data/surveys/big5/questionnaire_negated.json
similarity index 100%
rename from src/tinymfv/data/surveys/big5/questionnaire_negated.json
rename to src/moralmaps/data/surveys/big5/questionnaire_negated.json
diff --git a/src/tinymfv/data/surveys/humor_styles/keying.json b/src/moralmaps/data/surveys/humor_styles/keying.json
similarity index 100%
rename from src/tinymfv/data/surveys/humor_styles/keying.json
rename to src/moralmaps/data/surveys/humor_styles/keying.json
diff --git a/src/tinymfv/data/surveys/humor_styles/questionnaire.json b/src/moralmaps/data/surveys/humor_styles/questionnaire.json
similarity index 100%
rename from src/tinymfv/data/surveys/humor_styles/questionnaire.json
rename to src/moralmaps/data/surveys/humor_styles/questionnaire.json
diff --git a/src/tinymfv/data/surveys/humor_styles/questionnaire_inverted.json b/src/moralmaps/data/surveys/humor_styles/questionnaire_inverted.json
similarity index 100%
rename from src/tinymfv/data/surveys/humor_styles/questionnaire_inverted.json
rename to src/moralmaps/data/surveys/humor_styles/questionnaire_inverted.json
diff --git a/src/tinymfv/data/surveys/humor_styles/questionnaire_negated.json b/src/moralmaps/data/surveys/humor_styles/questionnaire_negated.json
similarity index 100%
rename from src/tinymfv/data/surveys/humor_styles/questionnaire_negated.json
rename to src/moralmaps/data/surveys/humor_styles/questionnaire_negated.json
diff --git a/src/tinymfv/data/surveys/mfq2/forward.json b/src/moralmaps/data/surveys/mfq2/forward.json
similarity index 100%
rename from src/tinymfv/data/surveys/mfq2/forward.json
rename to src/moralmaps/data/surveys/mfq2/forward.json
diff --git a/src/tinymfv/data/surveys/mfq2/inverted.json b/src/moralmaps/data/surveys/mfq2/inverted.json
similarity index 100%
rename from src/tinymfv/data/surveys/mfq2/inverted.json
rename to src/moralmaps/data/surveys/mfq2/inverted.json
diff --git a/src/tinymfv/data/surveys/mfq2/negated.json b/src/moralmaps/data/surveys/mfq2/negated.json
similarity index 100%
rename from src/tinymfv/data/surveys/mfq2/negated.json
rename to src/moralmaps/data/surveys/mfq2/negated.json
diff --git a/src/tinymfv/data/vignettes_ai-actor_other_violate.jsonl b/src/moralmaps/data/vignettes_ai-actor_other_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_ai-actor_other_violate.jsonl
rename to src/moralmaps/data/vignettes_ai-actor_other_violate.jsonl
diff --git a/src/tinymfv/data/vignettes_ai-actor_self_violate.jsonl b/src/moralmaps/data/vignettes_ai-actor_self_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_ai-actor_self_violate.jsonl
rename to src/moralmaps/data/vignettes_ai-actor_self_violate.jsonl
diff --git a/src/tinymfv/data/vignettes_classic_other_violate.jsonl b/src/moralmaps/data/vignettes_classic_other_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_classic_other_violate.jsonl
rename to src/moralmaps/data/vignettes_classic_other_violate.jsonl
diff --git a/src/tinymfv/data/vignettes_classic_self_violate.jsonl b/src/moralmaps/data/vignettes_classic_self_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_classic_self_violate.jsonl
rename to src/moralmaps/data/vignettes_classic_self_violate.jsonl
diff --git a/src/tinymfv/data/vignettes_scifi_other_violate.jsonl b/src/moralmaps/data/vignettes_scifi_other_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_scifi_other_violate.jsonl
rename to src/moralmaps/data/vignettes_scifi_other_violate.jsonl
diff --git a/src/tinymfv/data/vignettes_scifi_self_violate.jsonl b/src/moralmaps/data/vignettes_scifi_self_violate.jsonl
similarity index 100%
rename from src/tinymfv/data/vignettes_scifi_self_violate.jsonl
rename to src/moralmaps/data/vignettes_scifi_self_violate.jsonl
diff --git a/src/tinymfv/eval.py b/src/moralmaps/eval.py
similarity index 100%
rename from src/tinymfv/eval.py
rename to src/moralmaps/eval.py
diff --git a/src/tinymfv/guided.py b/src/moralmaps/guided.py
similarity index 99%
rename from src/tinymfv/guided.py
rename to src/moralmaps/guided.py
index 102a60e..b63dbe1 100644
--- a/src/tinymfv/guided.py
+++ b/src/moralmaps/guided.py
@@ -411,7 +411,7 @@ class ForcedChoiceResult:
# Full decoded generations per enum-ordering frame, one per sample.
# `gen_text` is always a list of length N=n_samples (even at N=1).
# Both texts are FULL — no stripping at . If you want the
- # pre-close part, split on `tinymfv.guided._CLOSE_MARKER`.
+ # pre-close part, split on `moralmaps.guided._CLOSE_MARKER`.
gen_text: list[str] # forward-frame, length N
gen_text_rev: list[str] # reversed-frame, length N
# Headline per-frame logprobs at the prefill position, after Bayesian
diff --git a/src/tinymfv/instrument.py b/src/moralmaps/instrument.py
similarity index 100%
rename from src/tinymfv/instrument.py
rename to src/moralmaps/instrument.py
diff --git a/src/tinymfv/instruments.py b/src/moralmaps/instruments.py
similarity index 100%
rename from src/tinymfv/instruments.py
rename to src/moralmaps/instruments.py
diff --git a/src/tinymfv/iw_axes.py b/src/moralmaps/iw_axes.py
similarity index 100%
rename from src/tinymfv/iw_axes.py
rename to src/moralmaps/iw_axes.py
diff --git a/src/tinymfv/labelplace.py b/src/moralmaps/labelplace.py
similarity index 100%
rename from src/tinymfv/labelplace.py
rename to src/moralmaps/labelplace.py
diff --git a/src/tinymfv/maps.py b/src/moralmaps/maps.py
similarity index 100%
rename from src/tinymfv/maps.py
rename to src/moralmaps/maps.py
diff --git a/src/tinymfv/read.py b/src/moralmaps/read.py
similarity index 100%
rename from src/tinymfv/read.py
rename to src/moralmaps/read.py
diff --git a/src/tinymfv/read_api.py b/src/moralmaps/read_api.py
similarity index 100%
rename from src/tinymfv/read_api.py
rename to src/moralmaps/read_api.py
diff --git a/src/tinymfv/readouts.py b/src/moralmaps/readouts.py
similarity index 100%
rename from src/tinymfv/readouts.py
rename to src/moralmaps/readouts.py
diff --git a/src/tinymfv/value_axes.py b/src/moralmaps/value_axes.py
similarity index 97%
rename from src/tinymfv/value_axes.py
rename to src/moralmaps/value_axes.py
index b0e68af..1500080 100644
--- a/src/tinymfv/value_axes.py
+++ b/src/moralmaps/value_axes.py
@@ -12,7 +12,7 @@ Sources (axis groupings aggregated from these papers):
- MFQ-2 equality/proportionality fairness split: Atari et al. 2023 "Morality beyond the WEIRD".
- Big Five meta-traits Plasticity/Stability: DeYoung, Quilty & Peterson 2007, doi 10.1037/0022-3514.93.5.880.
- HSQ 2x2 adaptive/maladaptive x self/other: Martin et al. 2003, doi 10.1016/S0092-6566(02)00534-2.
-- WVS: Inglehart & Welzel 2005 (see tinymfv.iw_axes -- the WVS map builds its own item-level axes;
+- WVS: Inglehart & Welzel 2005 (see moralmaps.iw_axes -- the WVS map builds its own item-level axes;
this table is for the psychometric instruments).
The debatable calls (flagged): the SECOND MFT axis is not canonical -- mfq2 uses the documented
diff --git a/src/tinymfv/zones.py b/src/moralmaps/zones.py
similarity index 100%
rename from src/tinymfv/zones.py
rename to src/moralmaps/zones.py
diff --git a/tests/test_instrument.py b/tests/test_instrument.py
index 043659f..c25bf4d 100644
--- a/tests/test_instrument.py
+++ b/tests/test_instrument.py
@@ -10,15 +10,15 @@ import unittest
import numpy as np
-from tinymfv.data import CONFIGS, CONDITIONS, load_vignettes
-from tinymfv.instrument import (
+from moralmaps.data import CONFIGS, CONDITIONS, load_vignettes
+from moralmaps.instrument import (
Instrument,
canonicalize_to_forward,
per_item_categorical,
reduce_nominal,
reduce_ordinal,
)
-from tinymfv.readouts import expected_score, logit_contrast, logodds_agree
+from moralmaps.readouts import expected_score, logit_contrast, logodds_agree
class InstrumentFlowTest(unittest.TestCase):
diff --git a/uv.lock b/uv.lock
index 155e633..18dd068 100644
--- a/uv.lock
+++ b/uv.lock
@@ -11,7 +11,7 @@ resolution-markers = [
]
[options]
-exclude-newer = "2026-06-29T06:18:19.538273755Z"
+exclude-newer = "2026-07-03T02:38:05.43429745Z"
exclude-newer-span = "P6D"
[[package]]
@@ -683,6 +683,54 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
]
+[[package]]
+name = "moral-maps"
+version = "0.1.0"
+source = { editable = "." }
+dependencies = [
+ { name = "loguru" },
+ { name = "numpy" },
+ { name = "pandas" },
+ { name = "tabulate" },
+ { name = "torch" },
+ { name = "tqdm" },
+ { name = "transformers" },
+]
+
+[package.optional-dependencies]
+api = [
+ { name = "openrouter-wrapper" },
+ { name = "python-dotenv" },
+]
+maps = [
+ { name = "matplotlib" },
+ { name = "shapely" },
+]
+
+[package.dev-dependencies]
+dev = [
+ { name = "scipy" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "loguru" },
+ { name = "matplotlib", marker = "extra == 'maps'", specifier = ">=3.8" },
+ { name = "numpy" },
+ { name = "openrouter-wrapper", marker = "extra == 'api'", git = "https://github.com/wassname/openrouter_wrapper" },
+ { name = "pandas" },
+ { name = "python-dotenv", marker = "extra == 'api'" },
+ { name = "shapely", marker = "extra == 'maps'", specifier = ">=2.0" },
+ { name = "tabulate" },
+ { name = "torch" },
+ { name = "tqdm" },
+ { name = "transformers", specifier = ">=5.7" },
+]
+provides-extras = ["maps", "api"]
+
+[package.metadata.requires-dev]
+dev = [{ name = "scipy", specifier = ">=1.17.1" }]
+
[[package]]
name = "mpmath"
version = "1.3.0"
@@ -1558,54 +1606,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" },
]
-[[package]]
-name = "tiny-mfv"
-version = "0.1.0"
-source = { editable = "." }
-dependencies = [
- { name = "loguru" },
- { name = "numpy" },
- { name = "pandas" },
- { name = "tabulate" },
- { name = "torch" },
- { name = "tqdm" },
- { name = "transformers" },
-]
-
-[package.optional-dependencies]
-api = [
- { name = "openrouter-wrapper" },
- { name = "python-dotenv" },
-]
-maps = [
- { name = "matplotlib" },
- { name = "shapely" },
-]
-
-[package.dev-dependencies]
-dev = [
- { name = "scipy" },
-]
-
-[package.metadata]
-requires-dist = [
- { name = "loguru" },
- { name = "matplotlib", marker = "extra == 'maps'", specifier = ">=3.8" },
- { name = "numpy" },
- { name = "openrouter-wrapper", marker = "extra == 'api'", git = "https://github.com/wassname/openrouter_wrapper" },
- { name = "pandas" },
- { name = "python-dotenv", marker = "extra == 'api'" },
- { name = "shapely", marker = "extra == 'maps'", specifier = ">=2.0" },
- { name = "tabulate" },
- { name = "torch" },
- { name = "tqdm" },
- { name = "transformers", specifier = ">=5.7" },
-]
-provides-extras = ["maps", "api"]
-
-[package.metadata.requires-dev]
-dev = [{ name = "scipy", specifier = ">=1.17.1" }]
-
[[package]]
name = "tokenizers"
version = "0.22.2"