# There is no model called taste-1

> Source: <https://cmd.safzan.dev/>
> Published: 2026-09-19 13:10:13+00:00

Command Code sells it as “a meta neuro-symbolic AI model with continuous reinforcement learning.” The name occurs five times in the shipped package: three times in marketing copy, once in billing text, and once as a string in the status bar. It is attached to no model ID, no routing entry and no catalogue record, and nothing the client sends ever requests it.

Taste is a prompt, sent to whichever ordinary model you already selected, built from your git history, your conversation and your saved transcripts from other coding agents. Every claim on this page links to its source.

“Taste is powered by our meta neuro-symbolic AI model taste-1 with continuous reinforcement learning (RL). We combine reasoning with neural intuition to create an invisible architecture of your choices, structures, patterns and tooling preferences.”

commandcode.ai/docs/taste, archived[2026-09-07](https://web.archive.org/web/20260907191124/https://commandcode.ai/docs/taste),
    [2026-03-13](https://web.archive.org/web/20260313174739/https://commandcode.ai/docs/taste),
    [2025-12-09](https://web.archive.org/web/20251209084020/https://commandcode.ai/docs/taste).
    The same paragraph ships inside the CLI.
  

The claim appears in every Wayback capture of that page since December 2025.

The feature runs in five steps. None of them involve a model called taste-1.

```
# runTasteLearningAgent, reconstructed from the shipped bundle

1. git show --format= -U3 --diff-algorithm=histogram -b -M <hash>
   mine before/after line pairs from up to 200 commits

2. compileTasteContext()
   concatenate the hunks into a markdown prompt ending with
   "## Instructions for Taste Learning / You are analyzing code
   change patterns from a real repository..." + 8 style guidelines

3. createSession() -> POST https://api.commandcode.ai/alpha/generate
   the same endpoint as every other request, on whatever model
   you currently have selected

4. the model writes markdown -> .commandcode/taste/taste.md

5. renderTasteSection2() pastes that file into the system prompt on
   every later turn, wrapped in <taste>...</taste>
```

cli.mjs: runTasteLearningAgent, compileTasteContext, renderTasteSection2
Step 2 ends with this block. It is reproduced exactly as the model receives it, including the
markdown emphasis markers and the interpolation slot `${a}`, which fills in
“ for <author>” when a specific author is targeted.

```
## Instructions for Taste Learning

You are analyzing code change patterns from a real repository${a}. Based on the
correction diffs above, generate deeply personal and opinionated coding taste.

**Critical guidelines:**

1. **Be specific, not generic.** Instead of "Use TypeScript", write "Use branded
types for IDs and explicit return types on every function. Prefer `readonly`
arrays and objects by default."

2. **Extract the WHY from patterns.** If you see verbose names being replaced
with concise ones, don't just say "use short names" — say "Prefer concise
variable names that derive meaning from context rather than encoding type
information."

3. **Look for recurring themes.** If multiple substitutions show the same pattern
(e.g., nested if→guard clauses), that's a strong taste signal worth capturing.

4. **Make it actionable.** Every taste entry should be specific enough that
another developer could follow it and produce code that looks like it belongs in
this repository.

5. **Prioritize quality corrections** — these are the purest taste signals
(wrong→right pairs with explicit WHY context from commit messages).

6. **Capture anti-patterns too.** If you see code being removed in refactors,
note what the developer avoids: "Never nest deeper than 2 levels — flatten with
early returns."

7. **Don't repeat generic tool preferences** like "Use pnpm" or "Use TypeScript"
unless the substitutions show something specific about HOW they use those tools.

8. **Prioritize opinionated preferences.** The goal is taste that makes someone's
code distinctly theirs — not industry best practices.

Write the taste entries to the taste.md file using the standard format with
confidence scores.
```

cli.mjs: compileTasteContext, the block appended after the diff hunks
The header placed above the hunks, in the same prompt:

```
# Dynamic Taste Analysis — Code Change Patterns

Repository: ${n}
${s}Commits analyzed: ${o}
Signals extracted: ${t.length}

This analysis was generated by examining actual code changes (diffs,
substitutions, refactoring patterns) rather than static file contents. Every
signal below comes from real commits.
```

cli.mjs: compileTasteContext, prepended to the diff hunks
Guideline 8 asks for taste that is “distinctly theirs” rather than industry best practice, which is the whole product claim expressed as an instruction to a general-purpose model.

The pipeline reads git diffs, builds a prompt, calls an ordinary model, writes a markdown file
and prepends that file to later prompts. Nothing in it computes embeddings or updates weights,
and no step performs reinforcement learning. This is the `CLAUDE.md` and
`AGENTS.md` pattern with an automated first draft.

A search of the shipped bundle for `taste-1` returns five occurrences across four
locations:

| Location | Kind | 
|---|---|
| FAQ string (×2) | marketing copy | 
| `/taste` help string | marketing copy | 
| billing string | pricing label | 
| TUI status bar | UI string literal | 

The bundle holds no model ID, routing entry or catalogue record for `taste-1`. It
does carry about eighty real model IDs, including DeepSeek, Kimi, GLM, MiniMax, Qwen, GPT, Claude,
Grok and Gemini, each with a context window, reasoning efforts and provider routing.

The one place the name appears at runtime:

```
y = Boolean(o && byokProviderId({ model: o })) ? "" : " · taste-1",
```

cli.mjs: TUI header component
The string is appended whenever you are not using your own API key. Configure your own provider and the badge disappears, and the feature behaves the same way. It labels whichever model you selected.

“Premium requests: Any request that uses a premium model (like taste-1) during your coding session.”

Command Code, plans help text

Calling `taste-1` a premium model is what justifies premium-request rates for taste
operations.

The feature works and is useful. The mechanism is prompt engineering, and it is sold as a neuro-symbolic model with reinforcement learning.

“Privacy: Taste processing runs on your codebase and stores learning data locally only.”

“No AI training: Command Code does not train on your code or store your code snippets. Taste processing runs on your codebase and stores learning data in your project and on your local machine only.”

Command Code, in-product privacy copy

`taste.md` is written under `.commandcode/taste/`, so the storage claim
holds. Step 3 above posts the compiled context to `api.commandcode.ai`, and that
context contains verbatim source lines. The snippet builder prefixes each changed line with an
arrow and indents the surrounding context by two spaces:

```
Snippet:
  <context line from your file>
→ <your changed line, verbatim>
  <context line from your file>
```

cli.mjs: buildSnippet2, called per hunk by compileTasteContext
Running taste uploads your source code to the vendor’s API for a third-party model to read.

An inference call sends code to a model, which is expected in the main agent loop because the user starts it. Taste is presented as local analysis. The phrase “on your local machine only” describes the storage accurately and the processing inaccurately.

The git history is one of three sources taste feeds on. Each one ends at
`api.commandcode.ai`.

| Source | What is read | 
|---|---|
| Your git history | `git show` across up to 200 commits, verbatim diff hunks | 
| Your live conversation | your messages, JSON-serialized, in windows of 20 | 
| Other agents’ transcripts | `~/.claude/projects/*/*.jsonl` ,`~/.codex/sessions/` , Cursor transcripts | 

The third reads your saved conversations with Claude Code, Codex and Cursor off disk and uploads the prompts. The in-product string for it reads “Learn taste from sessions with other coding agents (Claude Code, Cursor, etc)”.

cli.mjs: createSessionImporter, findClaudeCodeSessions, findCodexSessions, findCursorSessions
Taste learning is on unless you turn it off:

``` js
const s = n.tasteLearning ?? !0,   // global default: ON
      i = resolveProjectOverride(r, o),
      a = i?.value;
return { global: s, project: a, effective: a ?? s };
```

cli.mjs: getTasteLearningSettings
The package ships a sensitive-filename denylist:

```
.env  .env.*  *.pem  *.key  *.crt  .npmrc  .pypirc  .netrc
id_rsa  id_rsa.*  id_ed25519  id_ed25519.*  id_ecdsa  id_ecdsa.*
credentials  credentials.*
```

cli.mjs: consumed by hasSensitiveBasename()
`hasSensitiveBasename()` is called at six places: tool write-guarding, two
path-safety sets, and three IDE and telemetry file lists. The taste extractor is not one of them.
The only filter it applies while mining diffs is `isNoiseFile`:

```
package-lock.json  pnpm-lock.yaml  yarn.lock  CHANGELOG.*
.versionbot/  *.min.js  *.min.css  dist/  *.map
```

cli.mjs: isNoiseFile(), the sole filter in the taste path
That is a relevance filter, which excludes lockfiles and build output because they make poor style signals. It excludes no secret-bearing filename.

| Path | Secret filter | 
|---|---|
| Tool write-guarding | applied | 
| Path-safety sets (×2) | applied | 
| IDE and telemetry file lists (×3) | applied | 
| Taste history mining | **not applied** | 

Two details make this worse than a missed check on the working tree.

Taste reads history rather than `HEAD`. It runs `git show` across up to
200 commits, so a `.env` or private key committed once and deleted later still sits
inside the range it reads. Removing a secret from the current tree does not remove it from what
taste uploads.

`.gitignore` does not help either. Ignoring a file today does nothing about the
commit that added it before it was ignored, which is the usual way a secret enters a repository.

A repository that ever committed a `.env`, `*.pem`, `id_rsa`
or `credentials` file will have those hunks extracted verbatim by the snippet builder
and uploaded with the rest, on a feature that is enabled by default.

The control exists and is applied inconsistently. The filter guards six paths and is missing from the one that uploads historical file contents.

On startup, when telemetry is enabled and an auth key exists, the CLI posts a machine
fingerprint to `/alpha/fingerprint/record`.

| Field | Form | 
|---|---|
| machine ID, every MAC address, OS username, hostname, **git email** | salted SHA-256 | 
| platform, arch, OS release, CPU model, CPU count, memory, container flag, timezone | plaintext | 

The salt is a constant shipped inside the published package:

``` js
Fb = "command-code:device-fingerprint:v1"

function hashSignal(e) {
  const t = e.trim();
  if (t) return E("sha256").update(Fb).update("\0")
           .update(t.toLowerCase()).digest("hex");
}
```

cli.mjs: hashSignal, gatherRawSignals, buildMachineFingerprint
Anyone can read that salt out of the package, so checking whether an observed hash belongs to a
given email costs one `sha256` call. A git email is guessable and the MAC address space
is enumerable. The hashing pseudonymizes these values against a casual reader rather than against
anyone holding the package.

This is gated on telemetry, which `DO_NOT_TRACK=1` or
`"telemetry": false` in `~/.commandcode/config.json` turns off.

Publishing the salt alongside the hashes it protects means the pseudonymization holds only against a reader who has not opened the package. Git email is the value that most directly identifies a person.

Requests to `/alpha/generate` require the
`x-command-code-version` header. Omit it and the server answers:

```
403 "Your Command Code CLI is out of date. Run `cmd update` or `npm i -g command-code` to upgrade."
```

Tested live against the production API on 19 September 2026:

| Header value | Result | 
|---|---|
| `1.58.0` (current) | passes | 
| `1.57.0` | passes | 
| `1.0.0` | passes | 
| `99.0.0` | passes | 
| `garbage` | **403 out of date** | 
| header absent | **403 out of date** | 

The check tests whether the header is present and version-shaped. It does not compare against a
minimum version, so `1.0.0` passes and the upgrade message describes something the
server never tested.

The message names a cause the code does not check.

Shorter items, covered in the
[full teardown](https://gist.github.com/safzanpirani/26170636512c0b50494d6a70acfece8d):

`applyPremiumCreditsFallback` switches to Kimi K2.5 when premium requests run
  out.`badge: "free"` in the catalogue. All of them answer
  `403 "the free … tier has been retired"`.` providers.json` accepts any `baseURL` in three API dialects, so the
  CLI runs against your own endpoint with no patching.
Every claim above can be checked against the published package. Four commands take about two minutes.

1. Get the exact artifact.

```
npm pack command-code@1.58.0
```

2. Confirm it is the same bytes. The registry copy, the CDN copy and the copy behind this page hash identically.

```
curl -s https://unpkg.com/command-code@1.58.0/dist/cli.mjs | shasum -a 256
aab2bec800371953112d18472bb7383992ef264cca22558bdcda77e7d0dc0f14
```

3. Make it readable. The bundle is minified and not obfuscated. esbuild’s
`--keep-names` option is on, so every function is wrapped in
`__name(fn,"originalName")` and the original identifiers survive.

```
npx prettier --parser babel cli.mjs > cli.pretty.mjs   # 115,067 lines
```

4. Read the evidence. Each grep lands on a claim above.

```
grep -n 'taste-1' cli.pretty.mjs                # 4 locations, 0 model ids
grep -n 'runTasteLearningAgent' cli.pretty.mjs  # the git to prompt pipeline
grep -n 'Instructions for Taste Learning' cli.pretty.mjs
grep -n 'hasSensitiveBasename' cli.pretty.mjs   # 6 sites, none in taste
grep -n 'isNoiseFile' cli.pretty.mjs            # the only taste filter
```


