# Changelog ## 1.4.1 ### Fixed — baked credentials now win unconditionally A per-user baked artifact could still be prompted for credentials on install. The baked `DEFAULT_*` tier was lowest priority, so a stale `ECHO_*` env var or a leftover/placeholder `~/.claude/echo-memory/config.json` shadowed the baked key — even an unedited `""` value won over it, flipping `is_configured()` to false and triggering the first-run "ask the operator" flow despite valid baked creds. - `echo_config.load()` now treats a **complete** baked set (endpoint + key both present) as authoritative: it wins over env vars and the config file and cannot be shadowed. The generic (unbaked) plugin keeps its env → file → first-run flow. - Added `baked_complete()`; `source()` reports `baked-in (plugin)` for that tier. ### Security — untracked leaked baked artifacts - Two labeled baked artifacts (`echo-memory-1.4.0-jason.plugin`, `echo-memory-1.4.0-gretchen.plugin`), each carrying a live vault bearer token, had been committed at the repo root. They are now `git rm --cached`-removed and `.gitignore` gains `echo-memory-*-*.plugin` so labeled builds can't be re-committed (the version-only pointer `echo-memory.plugin` and `echo-memory-.plugin` stay tracked). Tokens remain in prior history — rotate if the repo was ever shared. ## 1.4.0 ### Added — per-user baked-key builds (CoWork zero-touch) The plugin is the only thing reliably mounted into a CoWork session (the sandbox's `~/.claude` is synthetic, not your real one), so the config now *can* travel inside the artifact. `echo_config` gains a lowest-priority fallback tier — the `DEFAULT_OWNER` / `DEFAULT_BASE` / `DEFAULT_KEY` constants — **empty in source**, so the committed tree still ships zero credentials. - `build.py --bake-key --from [--label ]` substitutes a single user's owner/endpoint/key into those constants, producing a per-user artifact that needs **no config file and no per-session paste**. Values may also come from `--owner/--endpoint/--key` or `ECHO_OWNER/ECHO_BASE/ECHO_KEY`. - Baked builds default to `dist/` (gitignored) and never touch the shared `echo-memory.plugin` pointer. - `build.py --strip-key` now force-blanks the same constants (guaranteed token-free). - `config show` / `doctor` report `[baked-in default]` when a field resolves from the baked tier. ### Changed — artifact hygiene - `.gitignore` excludes `dist/` and the filled-in `echo-memory.config.json`, where baked builds and the key file are meant to live. A baked artifact carries a vault key and must be **delivered directly to that one user, never committed, pushed, or published.** (Note: labeled baked artifacts built at the repo *root* were not yet guarded — see 1.4.1.) ### Resolution order (unchanged for hosts) `env` → `$ECHO_CONFIG` file → canonical `~/.claude/echo-memory/config.json` → **baked `DEFAULT_*`**. On a normal desktop the empty defaults mean behaviour is identical to 1.3.x; the baked tier only matters in per-user artifacts.