Changelog

All notable changes to Pinky Brain. Format based on Keep a Changelog; versioning follows SemVer.

[Unreleased]

Nothing yet.

[0.1.5] — 2026-07-05

Added

  • pinky update [--check] [--force] — self-update: compares the local version against the CDN's VERSION pointer (numeric comparison) and, if a newer one exists, runs the official installer (minisign signature + SHA-256 checksum) replacing the binary in its current folder. --check only reports; --force reinstalls anyway. Reuses curl/sh, no new dependencies.
  • Release notes on the web: /docs/changelog.html (4 languages) generated from this CHANGELOG.md, plus a version badge on the landing linking there.

Site

  • Landing with a "smart memory" section (temporal knowledge, implicit usefulness signal, Obsidian graph, sync, 7 MCP tools, CI-gated quality), a measured-metrics strip (binary size, RAM, p95, nDCG), and a Docs tab.
  • Truthfulness fixes: the landing showed 3 MCP tools (there are 7) and the model as ~100 MB (measured: ~450 MB, optional).

[0.1.4] — 2026-07-04

Three batches of the evolution plan (P5–P8, PRs #16–#47). Index schema: v8 (destructive migration of derived tables; reindex after updating — the .md files are untouched).

Retrieval quality

  • Eval v2: variant matrix (lexical/hybrid/±rerank/±decay), hit@k + MRR + nDCG metrics, and pinky eval --mine (proposes golden cases from real telemetry). CI gates: 0.9/0.85 with hash-embed, 0.95/0.9 with the model.
  • Multi-column FTS (title/tags/text with BM25 weights) + native snippet().
  • Heading-aware chunking: the embedding carries «title > heading» context; it also fixes the cumulative-RRF bug (max-passage per entry).
  • Snowball stemming ES/EN/IT/PT in a shadow column.
  • Staleness decay with per-type half-life (gotcha 90d, diary 30d, decision/pattern 365d, guide exempt).
  • supersedes + search --as-of: temporal facts; "what did we know then".

Agent loop

  • MCP: brain_feedback, brain_update, brain_delete (archives to .archive/), brain_similar, anti-duplicate in brain_save, and resources pinky://entry/….
  • Hooks: session-start with real delta + top, pre-* record usage with session_id, post-bash ("you already hit this landmine"), stop extracts decisions/commits from the transcript and correlates implicit usefulness (what the agent actually re-read → useful=1).
  • pinky stats --value: value report (real usage, confirmed usefulness, noise).
  • pinky new (per-type templates), pinky review (batch triage), dedup v2 (centroid + lexical MinHash).

Product & operations

  • pinky snapshot/restore: verifiable backup (tar.gz + SHA-256 manifest, verify-then-write, destination outside the working tree).
  • pinky sync v2: auto-commit without versioning brain.db, rebase with auto-resolution of diaries and frontmatter conflicts.
  • pinky bench: reproducible benchmarks (1k→8.7ms · 10k→53ms · 100k→495ms p95); see docs/BENCHMARKS.md.
  • pinky doctor --airgap: verifies 100% offline operation (fails if anything would need the network).
  • docs/VERSIONING.md + downgrade rejection: an old binary over a newer-schema index now fails clearly instead of operating silently.
  • Central config ~/.pinky/config.toml (thin layer); pinky init --demo.
  • Full i18n (ES/EN/IT/PT) also in MCP and hooks; shared catalog.

Security & supply chain

  • Opt-in index encryption (encrypted-index, SQLCipher + PINKY_INDEX_KEY); see docs/SECURITY.md.
  • cargo-deny (deny.toml) in CI, auditable binaries (cargo auditable), CycloneDX SBOM per release, actions pinned by SHA, publish = false.
  • Reproducible builds: rust-toolchain.toml (1.96.1) + remap-path-prefix + a CI job that builds twice and compares sha256.

Interop

  • Obsidian: [[wikilinks]] are parsed on indexing (schema v8, link table); pinky search --links applies an opt-in 1-hop boost; pinky lint reports broken wikilinks as a warning (tolerant).

Release infra

  • CI for site deployment + signed (minisign) publishing to R2, CDN monitoring, and scripts/release-local.sh for cutting releases without GitHub Actions.

[0.1.3] — 2026-07-03

Added

  • pinky init truly integrates Claude Code: installs the use-pinky-brain.md rule in .claude/rules/ and wires it via @import in CLAUDE.md (--global for ~/.claude/); merges hooks into .claude/settings.json (with confirmation; --hooks/--no-hooks); and downloads the embedding model during init so the first reindex is instant (--no-model to skip it). New flags: --force, --global, --hooks, --no-hooks, --no-model.

Fixed

  • pinky-hooks stop: Claude Code's Stop event doesn't send author/summary (the hook read them and the diary always came out empty/useless). It now reads transcript_path and extracts the summary from the assistant's last message.
  • Landing: command examples (hero query, result rows, pinky search example) now change with the selected language (ES/EN/IT/PT).

[0.1.2] — 2026-07-03

Added

  • Multi-language CLI (ES/EN/IT/PT): pinky localizes the full --help and all messages/errors. Language resolves via PINKY_LANG~/.config/pinky/config → system locale (LANG) → es.
  • install.sh asks for the CLI language on install (or takes it from PINKY_LANG) and stores it in ~/.config/pinky/config.
  • Multi-language web documentation (pinkybrain.dev/docs, ES/EN/IT/PT) generated from the .md files with make docs.

[0.1.1] — 2026-07-03

Web/branding only — the binaries' code did not change from 0.1.0.

  • Public landing at pinkybrain.dev (Cloudflare Pages), multi-language (ES/EN/IT/PT) with a switcher, a custom logo (chunk grid), a measured token-metrics band, a benefits section, and contact@pinkybrain.dev.

[0.1.0] — 2026-07-03

First release. Local knowledge engine (Phases 0–3 + P0–P4). See docs/PROD-ROADMAP.md for the per-phase detail.

Data integrity (P4)

  • Entry identity by (scope, path) (schema v2). The id derives from stable_id(scope, path) and there is a UNIQUE(scope, path): the same relative path across two scopes (e.g. diary/2026-06-30.md global and per-project) no longer collides or overwrites in the PK. Automatic v1→v2 migration (rebuilds derived tables) with a visible notice asking to reindex (the brain never goes silently "empty"), and a version stamp that only moves forward (an old binary can't downgrade a newer index).
  • Consistent type read↔write: normalized (trim + lowercase) both on indexing and filtering, and in brain_search's scope a bare name is interpreted as project:<name>. Absolute cap on search candidates.
  • Incremental reindex by (scope, path): the hash no longer crosses scopes (it used to skip or overwrite homonymous entries from another scope).
  • Telemetry cleanup on deleting/rewriting an entry (usage no longer leaves orphan rows that bias pruning).
  • File size limit on indexing (5 MB): a giant .md is skipped with a warning instead of OOM-ing (defense in reindex/watch/sync).

Retrieval

  • No-search-terms guard: a query made only of punctuation/symbols now returns empty instead of noise (the zero vector used to bring back arbitrary chunks with score > 0).
  • fetch derives from limit: requesting a high limit no longer silently truncates recall.
  • chunk_body measures in chars (not bytes): chunking stays consistent with accented ES/IT text.
  • Invalid YAML frontmatter is no longer silently discarded: it emits a warn (and pinky lint catches it).

DX & product

  • --version in all three binaries and in pinky doctor.
  • --json on every command with stdout output (reindex, eval, dedup, stale, telemetry, save, backlinks); in search it also disables telemetry (programmatic use).
  • PINKY_DB/PINKY_HASH_EMBED honored by the CLI (it used to ignore them): the CLI and the agent see the same base. Precedence: flag > env > default.
  • Read-only commands fail clearly if the index doesn't exist (they used to create an empty one and report "0 entries").
  • Actionable first-run errors (model failed to load → suggests --hash-embed).
  • type validation against the canonical set in save/brain_save (normalizes case; rejects typos that would create unfilterable entries).
  • pinky completions {bash,zsh,fish} (autocompletion) and input caps in brain_search (limit clamp 1..100), scope filter, enriched brain_stats (model + per-type breakdown).
  • brain_save doesn't leave an orphan .md if indexing fails; an unparseable JSON-RPC request answers parse error (-32700) instead of being ignored.

Hooks

  • Time budget (800 ms) in pre-read/pre-write: they degrade to no-op instead of blocking a Claude Code tool.
  • Never create a phantom DB: if there's no index, the hook is a no-op (it used to litter every repo).
  • Atomic diary append (O_APPEND): concurrent stops no longer overwrite each other.
  • Versioned registration example in hooks/settings.example.json.

Quality, CI & packaging

  • CI runs the eval as a relevance gate (fails the build on a ranking regression), with the golden set expanded to 13 cases (ES + IT, paraphrases) and an OS matrix (Linux + macOS).
  • Release with --locked (reproducible) + per-artifact SHA256 checksums.
  • install.sh (curl | sh): detects OS/arch, verifies the checksum, and installs all 3 binaries.
  • Product documentation: conversion-oriented README, docs/INSTALL.md, docs/CONFIGURATION.md.
  • New coverage: schema migration, multi-scope reindex, type validation, rerank.

Added (core)

  • Data integrity (P0): schema versioning (PRAGMA user_version + meta table); embedding-model guard (Embedder::model_id() + reconcile_model/check_model) preventing vectors from different models from mixing; busy_timeout for CLI + MCP + hooks concurrency.
  • Multi-project (P0): metadata filters (scope/project/type/tags) in search, exposed via pinky search --project/--type/--tag and in brain_search.
  • Operability (P1): tracing-based logging to stderr (PINKY_LOG); CI on GitHub Actions (fmt + clippy -D warnings + tests + real E2E).
  • Fast hooks (P1): search::lexical (BM25) for pre-read/pre-write without loading the model; FastEmbedder::new() retries on model-cache lock contention; usage telemetry also from brain_search.
  • Product (P2): pinky init (scaffolding + relocatable MCP registration in .mcp.json); pinky lint (validates frontmatter, exit ≠0 on errors); --json in search/stats/doctor; hardened pinky doctor (schema, index model vs. active); input caps in the MCP server; LICENSE (MIT).

Fixed

  • brain_save indexed with the server's scope and ignored the argument's project (unfilterable); now consistent with pinky save.
  • pinky stats loaded the embedding model without needing it.
  • Root-path containment in save (defense in depth).

Base (initial core)

Hybrid SQLite index (FTS5 + sqlite-vec, RRF), pinky CLI, MCP server, Claude Code hooks, and maintenance (dedup, staleness, backlinks, rollups, eval).