What it is
NanoTaste is a dependency-free Python 3.11+ CLI in the ai-taste-research repository. It loads markdown taste rules, discovers local coding agents, harvests opted-in session history as redacted excerpts, writes a hierarchy of taste files, and scores candidate drafts with a deterministic lexical critic. nanotaste serve opens a localhost studio so you can see the hierarchy without this marketing site ever touching your files.
It is not on PyPI. It makes no model calls of its own. The built-in generator, if you do not pass candidates, writes two to four synthetic drafts for smoke tests. Harvest extracts word-overlap signals. That is not training a preference model, and it has not been shown to match human preference.
Install
Clone the repository, make a virtualenv with Python 3.11 or newer, and install from the tree:
git clone https://github.com/myrrazor/ai-taste-research.git
cd ai-taste-research
python3 -m venv .venv
. .venv/bin/activate
python -m pip install .
nanotaste setup
Global flags on every command: --workspace for the project root (defaults to the current directory) and --home for the home directory used during agent discovery.
Running nanotaste with no subcommand starts setup on a TTY when the workspace is new.
First-run setup
nanotaste setup walks the questions once:
- Discover local sources that look installed or have history.
- Ask which of those sources to integrate.
- Ask how often to pull sessions:
manual,daily,weekly, ormonthly. - Write
TASTE.mdplus seeded category files undertaste/. - Optionally take a first seed (URL, file, image, or pasted note) and harvest now.
Non-interactive:
nanotaste setup --yes --every weekly --seed-url https://example.com/about
Useful flags: --yes accepts defaults and integrates every present source; --no-harvest skips the first pull; --every sets the schedule; --seed-url, --seed-file, and --seed-text supply the first seed.
Sources the current tree knows how to look for:
- Cursor
- Claude Code
- OpenAI Codex
- Continue
- Aider
- Windsurf
- Cline
- Gemini CLI
- Zed
- OpenHands
- Amazon Q
- GitHub Copilot
- Git history
- Existing NanoTaste records
nanotaste sources lists what is present on this machine. nanotaste status shows workspace setup, opted-in sources, and whether a report is due.
Hermes Agent and OpenClaw are named as future work in the claim lock. They are not in the current source list.
Taste hierarchy
The main file is an index. Category files hold the seeded rules. Scheduled harvest writes overlays under taste/learned/ and does not overwrite the seeds unless you pass nanotaste learn --apply.
TASTE.md
taste/writing.md
taste/code.md
taste/aesthetic.md
taste/product.md
taste/personal.md
taste/brand.md
taste/communication.md
taste/research.md
taste/learned/*.md
nanotaste catalog prints the tree, categories, and tags. Add --json if you want to parse it. Packaged seeds ship in the Python package; a documented example tree lives in examples/hierarchy/ in the repository.
TASTE.md itself is ordinary markdown with sections for anchors, principles, tradeoffs, forbidden moves, calibration examples, and update policy. Rules can be general or scoped to a domain such as writing, product, aesthetic, or code. Domain companions under taste/ and taste/learned/ load with it.
Unless you pass --taste-file, NanoTaste searches upward from the working directory for the file, so it can read a parent directory’s taste file.
Seeding
Seed from a page, a local file or image, or a pasted note. Repeatable flags:
nanotaste seed --url https://example.com/about
nanotaste seed --file ~/Pictures/mood.png --caption "Restrained paper and ink"
nanotaste seed --text "Prefer short names and concrete bios."
URL seeds must be http or https without credentials. The fetch uses a NanoTaste user-agent and stores a local excerpt. Image seeds use the caption and filename; there is no vision model. Caps in the current tree: 512 KiB per seed file or URL body, 200 seed items.
The CLI and the local studio share this seed box. The marketing site does not.
Harvest and schedule
nanotaste harvest is the everyday pull: ingest opted-in history, extract lexical signals, refresh learned overlays, and write .nanotaste/reports/latest.md. --if-due skips the report when the schedule says it is not time yet.
The pieces also exist as separate commands if you want them unbundled:
nanotaste ingestpulls session history into redacted excerpts.nanotaste learnextracts taste-rule proposals from history and likes.--applymerges new learned rules intoTASTE.md.nanotaste reportgenerates a report now, or only if scheduled.
Ingest redacts secret-like spans (tokens, API keys, private key blocks), email addresses, and home-directory usernames, then clips each excerpt. Caps: 800 characters per excerpt, 500 excerpts, 200 files per source, 256 KiB per ingest file, 80 git log items. Redaction is a filter. Do not harvest material you cannot keep on the machine.
Schedule:
nanotaste schedule --every weekly --install
--install appends a crontab snippet when crontab is available. The snippet is also written to .nanotaste/schedule.cron. A typical line looks like:
15 9 * * 1 cd /path/to/your/project && nanotaste harvest --if-due
A checked-in sample report is examples/reports/sample-taste-report.md. A matching learned proposal is examples/learned/proposal.example.md.
Likes, unlikes, and picks
Drop in an example you prefer or one you want the critic to avoid. The argument can be a file path or literal text:
nanotaste like examples/likes/concrete-release-note.md
nanotaste unlike examples/unlikes/generic-ai-prose.md
nanotaste prefer --like good.md --unlike bad.md
Those land under .nanotaste/likes/ and .nanotaste/unlikes/. nanotaste pick chooses the better option from a short list. --choose N is the 1-based winner for non-interactive use:
nanotaste pick --prompt "Write a launch note" \
--candidate "Run three concrete drafts and record the decision." \
--candidate "This seamlessly empowers teams." \
--choose 1
Picks append to .nanotaste/picks.jsonl. A like is evidence you stored, not an approval that rewrites the seeded files.
Local studio
nanotaste serve
# http://127.0.0.1:7468
Defaults: host 127.0.0.1, port 7468. Pass --host and --port if you need to. --no-tick turns off the in-process harvest ticker.
The studio shows the hierarchy, tags, what the files currently encode, coding-agent discovery, the latest report, and a seed box. It is a localhost viewer and editor. It is not a hosted product and it is not this marketing site.
How the critic scores
You can supply candidates from another model or tool. If you do not, NanoTaste’s built-in generator creates two to four deterministic, synthetic drafts. It does not call a model.
TASTE.md + category files + learned overlays
|
v
load relevant rules candidate outputs
| |
+------------+------------+
v
deterministic critic
|
+------------+-------------+
v v
selected text + reasons .nanotaste/runs.jsonl
The score is deliberately simple:
- each matching forbidden rule subtracts 3 points;
- eligible word overlap with a positive rule adds 1 or 2 points for that rule, with positive matches capped at 6 points total;
- a number, amount, percentage, day, or time unit adds 1 concrete-detail point;
- sharing an eligible word with the prompt adds 1 stays-on-brief point;
- a tie goes to the earlier candidate.
Eligible words are four or more characters after a small stop-word filter. The same inputs produce the same score and selection. That score is not a probability, confidence value, or measure of quality. The critic does not understand intent, train a preference model, or recognize a good paraphrase unless the words happen to match.
Run, compare, calibrate
Compare two drafts against a taste file:
nanotaste run \
--taste-file TASTE.md \
--domain writing \
--prompt "Write a release note for NanoTaste" \
--candidate "NanoTaste helps teams seamlessly compare outputs." \
--candidate "Run NanoTaste on three concrete drafts and record the decision."
A real run of that pair selected the second candidate at score 3: +2 for overlapping concrete and drafts, +1 for staying on the prompt, and a penalty on the first draft for the literal forbidden phrase seamlessly. That is the whole claim: the file changed this deterministic lexical comparison. It does not show that NanoTaste agrees with a person.
run flags worth knowing: --domain (default general), repeatable --candidate, --count for generated drafts (default 3), --record-file (default .nanotaste/runs.jsonl), --no-record, --json.
nanotaste compare --candidates FILE FILE ... scores existing candidate files the same way. nanotaste propose-update --before FILE --after FILE writes a pending taste-update proposal; NanoTaste never rewrites TASTE.md from that command automatically. Output defaults to .nanotaste/taste-updates.
Manual calibration is two steps:
nanotaste calibrate prepare --prompt-set PROMPTS --output-dir DIR
nanotaste calibrate evaluate --run RUN --picks PICKS --output OUT
Prepare builds human-review files from a prompt set. Evaluate compares those human picks to the critic. Starter prompts and synthetic candidates are smoke-test data, not research-grade evaluation.
Command reference
| Command | What it does |
|---|---|
nanotaste | No subcommand: start setup on a TTY when the workspace is new. |
setup | Discover coding agents and walk through first-run setup. |
status | Show workspace setup, sources, and report schedule. |
sources | List discovered coding agents and history sources. |
ingest | Pull opted-in coding-session history. |
learn | Extract taste-rule proposals. --apply merges into TASTE.md. |
harvest | Ingest, learn, and write a report. --if-due respects the schedule. |
like / unlike | Store an example you prefer or want to avoid. |
pick | Manually choose the better option from a short list. |
prefer | Store one liked example against one disliked example. |
report | Generate a taste report now, or only if scheduled. |
schedule | Set harvest frequency. --install appends crontab when available. |
seed | Seed taste from a URL, file, image, or pasted note. |
catalog | Show the taste-file hierarchy, categories, and tags. |
serve | Open the local studio (default 127.0.0.1:7468). |
run | Generate or score candidate outputs. |
compare | Score existing candidate files. |
propose-update | Propose taste updates from a before/after edit. |
calibrate prepare | Create human review files. |
calibrate evaluate | Compare human picks to NanoTaste. |
Many leaves accept --json. nanotaste --help and nanotaste COMMAND --help are the live source if this table drifts.
Where files live
All of this is per project directory unless you pass --workspace.
TASTE.md— index file the critic loads.taste/*.md— seeded category files.taste/learned/— scheduled overlays..nanotaste/config.json— workspace settings..nanotaste/likes/andunlikes/— stored examples..nanotaste/sessions/— redacted excerpts..nanotaste/learned/— learned proposals..nanotaste/reports/— includinglatest.md..nanotaste/seeds/— copied seed files..nanotaste/picks.jsonlandruns.jsonl— pick and run records..nanotaste/schedule.cron— crontab snippet..nanotaste/taste-updates/— pending update proposals.
Removing the package does not delete these files. Delete the directories yourself when you want them gone. See privacy for what harvest stores and what this website does not collect.
Claim lock
RC0 demonstrates workflow mechanics only. It can load markdown taste rules, generate or accept candidates, apply a deterministic lexical score, discover local coding-agent paths, ingest opted-in history as redacted excerpts, install a seeded hierarchy, seed overlays from URLs, files, images, or notes, prepare likes, picks, and reports, and write proposed updates for later review.
What remains unproven:
- NanoTaste has not demonstrated human preference alignment.
- It does not learn or train a preference model.
- The critic has not been calibrated against held-out human judgments.
- Starter prompts and synthetic candidates are not research-grade evaluation data.
- Scores and score margins are not probabilities, confidence, or uncertainty estimates.
- The current calibration bundle does not physically separate reviewer and private data.
- Upward discovery can read a parent directory’s taste file unless you pass an explicit file.
- Local tests are not hosted CI evidence.
- Image seeds use captions and filenames. There is no vision model.
The authoritative boundary is docs/RC0_CLAIMS.md. External replay candidates, blind review, held-out human labels, validated preference claims, Hermes Agent, OpenClaw, PyPI, and GitHub Releases remain future work.
Source and contributing
Code, issues, and the MIT license: github.com/myrrazor/ai-taste-research. Start with CONTRIBUTING.md. Keep issues, examples, and experiment data public-safe: no personal taste files, private prompts, secrets, or strategy notes.