Skip to content

0.14.0: memory that reaches every client whole

Choose a tag to compare

@mironmax mironmax released this 08 Oct 12:46
· 98 commits to main since this release

Memory that reaches every client whole, and maintenance that can keep a lesson in view. Long reads arrive in parts instead of being cut, which lets each session hold more memory (22,000 characters per level, 50,000 per read), the preload fits each client as that client counts, and a maintenance pass can now prop up a lesson it judges should stay visible; every credit, an endorsement included, counts as recent use.

Added

  • Long kg_read replies arrive in parts instead of being cut. Claude Code saves a tool reply over 50,000 UTF-16 units to a file and shows the model a short preview; Codex cuts the middle out of one over 40,000 bytes. The server still marked every node in such a reply as seen, so recall never offered them again. Now a reply longer than the client keeps whole goes out in parts (45,000 units in Claude Code, 36,000 bytes in Codex), each ending with how to get the next: kg_read(session_id, more=true). A node counts as seen, read or promoted only when the part showing it goes out; the full read completes with its last part; a new read or a compaction drops undelivered parts. Antigravity keeps its hook queue.
  • A maintenance pass can keep a lesson in view. Its own reads promote nothing, so a pass that judged a rule should stay visible had no way to say so, and the next rebalance archived it again. In a maintenance session kg_useful now takes credits=1-3 per node (15 per pass), by conviction. A credit works like an endorsement and fades like one, so a propped lesson stays only if sessions go on to find it useful. The node records when it was credited, and a full read shows it, so a later pass sees a lesson that was propped before and sank. A credited orphan returns to the archive, where its score decides. Credits are logged as via: "maintenance", and the evaluator counts neither them nor repeat credits as use.

Changed

  • Every credit counts as recent use. Recency was a node's last write or full read, so an endorsement never refreshed it, yet a gist that works never needs the full read. Recency is now the latest of the last write, the last read, and the latest credit: an endorsement, a repeat, or a maintenance credit. Measured on copies of four real graphs, it changed one active node. The kg_useful description says what an endorsement does (usefulness and recent use, both fading) and that reading a node is not endorsing it; the editor's score card shows the credit time.
  • More memory per session: 22,000 characters per level, 50,000 per read (from 17,500 and 40,000). Paged replies make a read above the client limits safe, so the budget no longer has to fit one tool reply. A full read now comes as two parts in Claude Code and Codex. The preload and the full-read reminder now say to follow a read's parts to the end. Graphs kept by 0.12.0 can sit above even the old budget: its 5-day creation grace made every recent node unarchivable (on 10-08 every active node of two busy graphs was under 5 days old). 0.13.0's fresh tier lets them compact; at the new budget, a replay of those two graphs archived 0 of 35 and 20 of 49 active nodes, against 14 and 30 at the old one.
  • The install can finish inside the agent. When the kg command is missing, the SessionStart hook (Claude Code, Codex, Antigravity) no longer only tells the agent to pass an install command to the user: it asks the agent to offer the install and, with the user's yes, follow the kg-ops skill — uv tool install kg-memory, kg setup --plan, then only the items the user accepts. Memory loads from the next session.
  • CI runs the test suite on macOS as well (Python 3.x). It reports without failing the run until an intermittent failure there is understood.

Fixed

  • The session-start preload fits each client as that client counts. The preload was sized in Python characters, but Claude Code counts UTF-16 units (an emoji is two) and Codex counts bytes (Cyrillic is two a character, CJK three). Non-ASCII gists could push it over the limit: saved to a file with a short preview in Claude Code, its middle cut in Codex. Each harness profile now carries its unit and a limit in it, measured on current clients: Claude Code keeps 10,000 UTF-16 units of hook context inline (preload 9,500), Codex 10,000 bytes (preload 9,000, up from 8,000 characters), Antigravity 10,000 bytes.
  • A second server no longer takes over the first one's state. Every kg server kept its PID file, log and start-failure note in one folder whatever KG_HTTP_PORT was. A second server (a bench, a test) overwrote the live server's PID file, so kg stop on either port could stop the other, and a failed start on another port could make the next session's hook report the real server as failed instead of starting it. A server on a port other than 8765 now keeps its state in port-<N>/ under ~/.local/state/knowledge-graph/; the default port keeps today's paths, and both hooks read the start-failure note from the same place.
  • Anchor repair keeps ~ paths when home is behind a symlink. A moved file touched as ~/… came back as an absolute path when the home directory is reached through a symlink (macOS /var → /private/var, or a linked home): the project root was resolved and home was not. Found by the first macOS CI run.