--- layout: default title: Taste nav_order: 14 --- # Taste **Local-first preference-learning runtime for Clew.** Taste learns your coding style from accept/reject/edit/test/lint signals and manual rules. It combines symbolic rules, semantic preference scoring, and contextual bandit optimization to adapt Clew's output to your preferences. It does **not** fine-tune the base LLM. All learning is local, online, and preference-based. ## What It Learns - **Code style**: formatting, naming conventions, preferred patterns - **Architecture**: module structure, dependency direction, layering - **Tooling**: preferred build tools, linters, test frameworks - **Testing**: test style, coverage expectations, mocking patterns - **Naming**: variable/function/class naming conventions - **Security**: safe patterns vs unsafe patterns - **Performance**: efficient algorithms, caching, resource management - **UI patterns**: component structure, state management, styling approach - **Workflow**: commit style, review preferences, deployment habits ## What It Does Not Do - Does not fine-tune or modify the base LLM - Does not send taste data to remote services (all data stays local) - Does not automatically block edits without showing a reason - Does not replace memory, skills, or CLAUDE.md files ## How It Differs from Other Systems | System | Purpose | Storage | Scope | |--------|---------|---------|-------| | **CLAUDE.md** | Project instructions | `.claude/` files | Static project rules | | **Memory** | Cross-session facts | `memdir/` | Recall | | **Skills** | Reusable procedures | Plugin/skill system | Task automation | | **Taste** | Learned preferences | `.clew/taste/` | Adaptive preference optimization | - Rules are explicit user preferences - Memory is facts about the user and project - Skills are reusable task procedures - Taste is learned, weighted preference signals ## Storage Paths | Data | Path | |------|------| | Project profile | `.clew/taste/profile.json` | | Project event log | `.clew/taste/events.jsonl` | | Project packages | `.clew/taste/packages/` | | Global profile | `~/.clew/taste/profile.json` | | Global packages | `~/.clew/taste/packages/` | ## Commands | Command | Description | |---------|-------------| | `/taste` | Open interactive menu (arrow-key navigable) | | `/taste status` | Print status | | `/taste learn ` | Add a manual rule | | `/taste forget ` | Remove a rule by ID | | `/taste profile` | Show full profile with rules | | `/taste events` | Show recent learning events | | `/taste decay` | Apply confidence decay | | `/taste eval` | Run profile self-evaluation | | `/taste export` | Export high-confidence rules | | `/taste import ` | Import rules from file | | `/taste on` | Enable taste | | `/taste off` | Disable taste | ## Configuration Settings in `settings.json`: ```json { "taste": { "enabled": true, "autoLearn": true, "injectPrompts": true, "validateEdits": true, "minConfidence": 0.55, "maxInjectedRules": 8, "decayEnabled": true, "banditEnabled": true, "neuralScoringEnabled": true } } ``` ## Architecture Taste consists of several subsystems: 1. **Signal Collection** — Captures accept, reject, edit, test, lint, and tool signals from user interactions and converts them into learning events. 2. **Reward Model** — Maps signal types to numeric reward values (accept = +1.0, reject = -1.0, test pass = +0.4, etc.) and computes edit distance rewards dynamically. 3. **Symbolic Engine** — Compiles high-confidence rules into checkable constraints. Rules with confidence >= 0.85 can block edit acceptance. Rules below threshold warn without blocking. Never blocks silently. 4. **Neural Scorer** — Provider-agnostic lexical similarity scoring (Jaccard/TF-IDF) that scores candidate output against active rules. Extensible to use embedding APIs when available. 5. **Contextual Bandit** — Epsilon-greedy bandit with 6 strategy arms (minimal, strict_style, architecture_first, test_first, safety_first, refactor_heavy). Selects optimal strategy based on feedback and context features. 6. **Prompt Injection** — Injects a compact `` block into the system prompt with relevant rules. Max 8 rules by default, filtered by confidence and sorted by relevance. 7. **Decay Engine** — Gradual confidence reduction for unused rules (half-life based, default 30 days). Prevents stale preferences from persisting. 8. **Event Log** — Append-only JSONL file storing all raw learning events for auditability and regression analysis. ## Continuous RL (Local Online Preference Optimization) Taste implements **local online preference optimization**: - **Online**: learns continuously from each interaction, no batch training - **Local**: all computation and storage stays on the user's machine - **Preference-based**: optimizes for user preferences via reward signals - **Multi-objective**: balances style, correctness, safety, and efficiency The learning loop: 1. User interacts with Clew (accepts, rejects, edits output) 2. Signal collector captures the interaction as a typed event with reward 3. Bandit arm updates based on reward signal 4. Rule confidence adjusts based on positive/negative evidence 5. Prompt injection adapts to reflect current learned preferences 6. Decay gradually reduces stale rule confidence This is **not** LLM fine-tuning. The base model's weights never change. Taste adapts the prompt context and edit validation, not the model itself. ## Privacy - All taste data stays local by default - Profiles and event logs are stored in `.clew/taste/` or `~/.clew/taste/` - No data is sent to remote services - Export/import is explicit and user-initiated - Event logs are append-only for auditability ## Integration Points | Point | Status | Description | |-------|--------|-------------| | Prompt injection | Implemented | System prompt taste block via `TastePromptInjector` | | Edit validation | Implemented | `validateEdit()` called in `FileEditPermissionRequest` | | Accept/reject signals | Implemented | Fire-and-forget via `recordAcceptSignal`/`recordRejectSignal` in `PermissionContext` | | Test/lint signals | No-op stub | Ready for `PostToolUse` output analysis | | Tool result signals | Implemented | `recordToolSignal()` in `toolExecution.ts` | | Interactive menu | Implemented | `/taste` Dialog with 11 actions, Spinner loading, input pre-fill | | Status line | Implemented | `TasteStatusLine` shown in `PromptInputFooter` | | Config live-reload | Implemented | `subscribeToSettingsChanges()` reloads config at runtime | | Settings config | Implemented | `taste.*` in `settings.json` | ## Example Usage ``` /taste # Open interactive menu /taste learn Use const instead of let /taste learn Prefer named exports /taste learn Never use any type /taste status /taste profile /taste eval /taste export ```