Taste
AI tools, hooks, skills, and prompts I actually use day to day — each with a what/why/how write-up
npx -y skills add kev-hu/ai-toolkit --skill tasteAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Review the current session and propose updates to TASTE.md. Use when the user invokes /taste or asks to "capture taste", "update taste", "review taste signals". On-demand only — does not auto-run at session end.
SKILL.md
11.6 KB, as published. Nobody here has run it
Update TASTE.md
Review the conversation for stable taste signals — quality calls, preference statements, contradictions of existing rules — and propose updates to TASTE.md directly. The user invokes this explicitly via /taste; do not run automatically.
Philosophy
How taste is placed and loaded — the reasoning behind where each rule goes:
- Keep the root file cross-cutting. The root TASTE.md loads every session, everywhere, so it should hold only principles and rules that apply everywhere. Push area-specific taste down into the subtree it governs.
- Express divergence, don't fragment. Most domain differences are cleanly handled within the root file — as disjoint
When [context]triggers, or a subsection once ≥2 rules share a domain. Reach for a separate nested TASTE.md only when a subdirectory is effectively its own project and its taste is substantial and usually out-of-scope elsewhere. - Nearest wins. A nested TASTE.md loads on-demand in its subtree (progressive disclosure) but the root stays loaded alongside it — so on genuine conflict the nested file must declare that it takes precedence in its subtree, and name the root rule it overrides. Keeping root cross-cutting makes this rare.
Steps
-
Locate TASTE.md — look in the current working directory, then walk up to the repo/vault root (git root or first ancestor containing
CLAUDE.md). Read it in full. Also readLESSONS.mdand anyCLAUDE.mdat that root for redundancy reference. -
Bootstrap TASTE.md if the target doesn't exist yet. First decide where a new rule belongs (see Philosophy) — most of the time this is the repo-root TASTE.md; escalate only when the evidence warrants:
- Cross-cutting or a lone domain rule → the repo-root TASTE.md (as a
When-triggered rule). Default. - ≥2 rules share a domain → a subsection within the root file — not a new file.
- A subdirectory is its own project, with substantial taste that's usually out-of-scope elsewhere → a nested co-located TASTE.md in that subdir. Give it a precedence header (
> Scoped taste for <subdir>. On conflict with the repo-root TASTE.md, these rules take precedence within this subtree.), and have any overriding rule name the root rule it supersedes.
To create a file (root or nested), use the bundled template at
assets/taste-template.md(relative to this skill), replacing{Context}with the repo/vault (or subdirectory) name. Do not write to another repo's TASTE.md from this one. Then wire discovery so future sessions load it, per load mechanics (files at/above cwd load at launch; subdirectory files load on-demand):- Root TASTE.md → add
@TASTE.mdon its own line in the root CLAUDE.md (loads every session). If only AGENTS.md governs the root, add a prose line instead (Consult \TASTE.md` for quality/preference calls.) since@import` isn't supported there. - Nested TASTE.md → add
@TASTE.mdto a co-locatedsubdir/CLAUDE.mdso it loads on-demand in that subtree (progressive disclosure).
- Cross-cutting or a lone domain rule → the repo-root TASTE.md (as a
-
Review the conversation for three signals:
(+1)reinforcements — moments where an existing rule'sWhen [context]applied and the decision went the way the rule recommends, with no user pushback(🚩)contradictions — moments where an existing rule applied but the user wanted the opposite, or accepted output that violates the rule(NEW)patterns — preferences expressed in this session that no existing rule covers
-
Filter each candidate through the intake gate (see below). Most sessions produce 0-2 entries. That's fine — exit cleanly if nothing passes.
-
Compose a diff proposal (see format below) and present it as terminal output.
-
Apply on approval, one op per commit — apply ops sequentially, committing each per the Commit protocol below. One op = one semantic unit: a new rule including any principle proposed alongside it, a single
(+1)reinforcement, or a single 🚩 flag. The user reviews viagit log -p— each op is independently revertable. If the user picksedit, ask which entries to change and iterate; loop until the user approves or skips. -
No-op gracefully — if nothing passes the intake gate, say so explicitly and exit. Don't force entries because the skill was invoked.
Commit protocol — the context ledger
Every op is its own scoped commit, and the subject line is a ledger row. Grammar:
context(taste): add <rule key> — <short description>
context(taste): reinforce <rule key> N→M
context(taste): flag <rule key> — <one-line 🚩 context>
context(taste): bootstrap <path>
-
Key = a short kebab handle for the rule (trigger + preference, e.g.
dashboard-density,diagnosis-before-prescription). Reuse the identical key on every later op sogit log --grep '<key>'returns the rule's full trajectory. -
An
addthat proposes a new principle alongside the rule is one commit — note— principle + rulein the description. -
Stage only the file the op touched (
git add TASTE.md, or the real nested path) — nevergit add -A; other dirty files belong to other uncommitted work. On bootstrap, also stage the CLAUDE.md/AGENTS.md you added the discovery pointer to. -
Skip entirely on a no-op — no edits, no commits, no registry write.
-
After the last commit, register the repo in the machine-wide ledger index:
mkdir -p ~/.claude/context-ledger r=$(git rev-parse --show-toplevel) grep -qxF "$r" ~/.claude/context-ledger/repos 2>/dev/null || echo "$r" >> ~/.claude/context-ledger/repos
Query recipes live in the lessons skill's "Reading the ledger" section — same grammar, same registry.
Entry format
- When [context], prefer [X] over [Y], because [principle]. (N)
- When [context], prefer [X] over [Y], because [principle]. (N) 🚩 YYYY-MM-DD: <one-line context>
When [context]— the trigger condition. Specific enough to match in future sessions.prefer [X] over [Y]— the directional preference. Both options named.because [principle]— cite the aphorism part of a Principle from TASTE.md's Principles section. If no existing Principle fits and you can articulate a new one, propose it alongside the rule — format[aphorism] — [5-15 word clarifier]on a single line. Sanity-check the aphorism by reading it insidebecause [aphorism]— if it's grammatically awkward (common with verb-imperative forms like "Lead with X"), rephrase to a declarative ("Load-bearing first" / "Bottom-line up front"). If no principle is obvious yet, writebecause TBDand move on;/taste-prunewill surface it later once the pattern has more reps.(N)counter — starts at(1)on new rules. Trails the period.🚩 YYYY-MM-DD: <context>marker — appended on contradiction. Resolved during/taste-prune. Max one unresolved 🚩 per rule.
Intake gate
Before proposing any entry, run through these filters in order. Short-circuit as soon as one matches:
- Already captured? Is this in TASTE.md, CLAUDE.md, or LESSONS.md? → skip. Exception: if it's in auto-memory but is a directional taste call (a "prefer X over Y when…" judgment, not a fact/role/gotcha), promote it here — auto-memory and TASTE serve different purposes, and stable directional taste belongs in TASTE.md with a
When/prefer/becauserule and an(N)counter. - One-off, not a pattern? Was this a situational call that won't generalize beyond this exact task? → skip
- Belongs in another file? Is this a tool gotcha (→ LESSONS.md), a workflow step (→ your process/workflow docs), or a single fact (→ memory)? → skip
- No clear
Whentrigger? If you can't articulate the context where this rule would fire next time, it's too vague. → skip - Stable taste? Will this preference hold up across multiple sessions and contexts, or is it a mood/one-shot? Only stable taste passes.
"Huh, the user liked that" moments don't pass. "User has now corrected me three times on this same dimension" does.
Where does this belong?
| If the insight is about... | It belongs in... |
|---|---|
| A subjective quality call, repeated preference, or directional taste | TASTE.md — this is what it's for |
| A tool gotcha or failure mode | LESSONS.md |
| A step-by-step workflow | your process/workflow docs |
| A user fact (role, project state) | memory |
| Architecture, repo structure, commands | CLAUDE.md |
If you notice an existing TASTE.md entry that really belongs elsewhere, flag it in the diff proposal — don't silently move it.
Diff proposal format
Present to the user as plain terminal output:
TASTE.md proposed changes:
(+1) Design / "When improving dashboards, prefer density..."
Applied: <session moment, file, or quote>
(3) → (4)
(🚩) Writing / "When writing emotional content, prefer honest plainness..."
Contradicted: <session moment, file, or quote>
Append: 🚩 2026-05-18: <one-line context>
(NEW) Writing / "When [context], prefer [X] over [Y], because [principle]."
Pattern: <session moment that revealed it>
Starts at (1).
Approve? [y / n / edit]
What makes a good entry
A good entry identifies:
- A specific trigger context (
When improving dashboards..., notWhen designing...) - A named preference with both sides (
prefer density over stacked cards, notprefer density) - A cited principle in the
becauseclause (links to a Principle in TASTE.md)
Examples
Good entries:
When improving dashboards, prefer density and status-at-a-glance over large stacked cards, because monitoring UX should make breakage obvious fast. (1)When writing emotional content, prefer honest plainness over symmetrical phrasing, because concrete beats clever. (1)When user requests emojis, default to 1-2 categorical markers, because decorative emojis read as gross. (1)
Bad entries (would not pass intake gate):
"Prefer clean code"— no trigger context, no specific preference."User likes dense dashboards"— captures one preference moment, not a generalizable rule."Use the gws CLI directly"— belongs in CLAUDE.md or memory, not TASTE.
Rules
- On-demand only. Never run automatically. The user invokes
/tasteexplicitly. - Quality over quantity. One sharp rule beats three vague ones.
- Cite principles when you can. If a rule's
becauseclause cites a principle not in TASTE.md, propose adding the principle too. - Subsections emerge from data. Only create a new domain subsection (Design / Writing / etc.) when ≥2 rules share the domain. Below that, leave rules flat under Decision Rules.
- Date format:
YYYY-MM-DDin 🚩 markers. Use the current date. - Use
(N), never[N]—(N)is the counter convention across these skills. (Square brackets also render as checkboxes in Obsidian.) - Never decrement counters. If a rule is contradicted, append a 🚩 marker; don't reduce N.
/taste-prunehandles resolution. - If nothing passes the gate, say so and exit. Don't force entries to justify the invocation.
Optional: mirroring to a cross-session ledger
If you also keep a separate cross-session learnings store (outside this repo), mirror newly-added (NEW) rules there too — it's a useful second surface for "have I seen this preference before" queries across projects. Not required for this skill to work.