0.3.13 hardens the self-improvement loop and adds the first first-class way for Keating to edit its own source files. The web chat gets a resizable session sidebar, a multi-year activity heatmap, and a handful of correctness fixes for how the active policy is loaded.
Source-Edit CLI
A new keating edit <file> command applies a single search/replace edit to any file under the project root. The search block must match exactly and uniquely — duplicate matches are rejected for safety. Pass the edit on stdin as JSON for scripted flows or use the interactive mode (paste search, then ---, then replace, end with === or Ctrl+D). An optional --backup-dir=DIR snapshots each target before the write so a bad edit can be reverted by hand. This is the same primitive that the self-improvement loop now uses internally, exposed for direct human and agent use.
Safer Auto-Improve Loop
auto-improve now snapshots the active teaching policy before running and automatically rolls back when the post-loop verdict is REGRESSED, so a bad run can no longer corrupt your policy. A 30-minute cooldown prevents accidental back-to-back runs; pass --force to override it. The improvement archive gained accept and reject subcommands (keating improve accept <id> / keating improve reject <id>) that resolve a pending proposal using the snapshots stored alongside it — no need to thread snapshots through the call yourself.
The same gating now applies in the web chat: the auto_improve tool runs at most once per session unless the learner explicitly asks again with a force flag.
Persistent MAP-Elites Grids
The MAP-Elites quality-diversity archive now reads and writes a per-topic grid JSON under .keating/outputs/evolution/. Successive runs build on previously-discovered cells instead of restarting from an empty archive, and each candidate now records its real parent policy name. Three additional source files (mutation.ts, map-elites.ts, prompt-evolution.ts) joined the self-improver's mutable surface so the system can iterate on its own evolution machinery.
Real Pareto Benchmarks
The Ax/GEPA optimizer used to report its Pareto front using a baseline placeholder for every point. It now actually benchmarks every candidate on the front against the focus topic, with the candidate's own learned weights. Each evolution run is also tagged with the optimizer that produced it (gepa or mapElites_fallback) and, on fallback, the reason GEPA was skipped — so you can see at a glance which method generated a given result.
Feedback-Weighted Benchmarks
keating bench now derives its objective weights from the learner's recorded thumbs-up, thumbs-down, and confused signals. A history skewed toward confusion increases the weight on retention and clarity; a history skewed toward satisfaction shifts weight toward engagement and transfer. Reported scores are now a measurement of how the current policy serves your real session history rather than a fixed default profile.
Web Polish
The desktop session sidebar gained a drag-resize handle on its right edge and remembers its width in localStorage; the old desktop collapse toggle was removed in favor of the handle. Usage's activity heatmap was rebuilt as a year-by-year view with a year selector, replacing the previous fixed 12-week window. Web chat now merges consecutive assistant messages into a single bubble for cleaner transcripts, and user messages were restyled from amber to green for stronger learner/assistant contrast.
Under the hood, the active teaching policy is now actually parsed out of stored markdown (either a JSON block or field: value lines) instead of silently falling back to DEFAULT_POLICY for every web tool call. The web DEFAULT_POLICY itself was rebalanced toward more analogies, Socratic dialogue, retrieval practice, and diagrams to match the latest evolved policies, and prompt-evolution lookups now use a proper IndexedDB promptName index instead of the generic topic index.