Repository navigation
Releases: mironmax/kg-memory
Release list
0.16.0: callers outside the hook
Memory for callers outside the usual session. A git worktree now shares its main checkout's memory instead of starting empty; KG_HOOKS=off keeps the memory out of a scripted run; and a program that composes its own context can open a session by REST, naming itself and what it already showed the model.
Added
KG_HOOKS=offsilences the plugin's hooks for one run. A scripted or headless run that loads the plugin but wants no memory (no preload, recall, capture nudges or upkeep dispatch) sets it in its environment, in every harness. The maintenance runner now sets it too;KG_CHORE=1, which it used before, still works.- A program that composes its own context can register a session by REST.
POST /api/sessions/registertakes a JSON body withproject_path, anagentname for the session, andpreloaded_ids: the nodes the caller already put in front of the model. Those count as preloaded and seen, sokg_readand recall do not repeat them. Theproject_pathquery the visual editor sends still works.
Changed
- A git worktree shares its main checkout's memory. A session in a linked worktree (
git worktree add,claude -w, an agent's isolated worktree) used to get a new, empty project named after the worktree folder. It now works in the main checkout's project: the same preload, recall and writes, and file recall matches a worktree's files to the touches written for the checkout. Submodules and worktrees of a bare repository stay their own projects. Graphs a worktree already created are left in place.
0.15.2: secrets kept out of the storage history
Secrets stay out of the storage history: the logs, fetched URLs and memory writes no longer carry a key into the git repository the storage usually is, and kg doctor names any credential already stored. Also fixed: a leftover KG_HTTP_PORT is named as the cause when the storage is taken, and doctor reads Codex hook trust from Codex itself. The Antigravity guide is current with agy 1.3.3.
Security
The storage folder is usually a git repository the server commits on its own, so whatever reaches it stays in history. Three paths could carry a secret there; all three are closed. Commits made before this release still hold what they held: if a key reached them, rotate it.
- The logs stay out of git.
recall.jsonl,useful.jsonlandchores.jsonlwere committed with the graphs, andrecall.jsonlkeeps search terms cut from each prompt, so a key typed into a prompt was committed as one term. The server andkg commitnow list the logs in.git/info/excludeand untrack them once; the files stay on disk. Recall also drops terms shaped like keys or hashes before searching or logging. If you sync the storage between machines through git, update every machine, or an older one keeps committing the logs. - Fetched URLs are counted without their query. The capture counters (
projects/<slug>/tool_events.json, committed) kept each fetched URL whole, and the capture nudge offered it as a touch, so a signed or keyed URL could reach both. They now keep scheme, host and path only. - Memory refuses credentials.
kg_put_nodeandkg_put_edgerefuse a write whose text holds an API key or token of a common provider, a private key or a JSON web token. The reply names the field and the kind, never the value, and asks for the write without it. kg doctorfinds credentials already stored. It names each node or edge that holds one and each commit that added one, never the values, with what to do: rewrite the node without the value, rotate the key, and purge the history if you want it gone. The first run reads the whole history (seconds on a long one); later runs read only new commits.
Fixed
- A leftover port override is named as the cause. A
KG_HTTP_PORTset when the client app launched stays in force after it is removed from the settings, until the app restarts (a/clearkeeps it). The server it starts then finds the storage taken by the regular server on 8765, and the session was told to runkg doctorandkg start, which change nothing. The error now says the override is likely left over and to restart the client app, and the hook passes on the remedy the error names. kg doctorreads Codex hook trust from Codex. Codex trusts a plugin hook by a hash of the hook and of the plugin's files, so an update can void the trust whileconfig.tomlstill names the hook; doctor looked only for the name and said trusted while Codex (or the ChatGPT app) asked again. Doctor now asks Codex's app server for each hook's status and names a modified one, falling back to the old check when Codex does not answer.
Docs
- The Antigravity guide is current with agy 1.3.3. It names the official marketplace added in 1.3.2 (this plugin installs from a local directory, now also through
/plugin), records the signed-in checks passed on 1.3.3 (all but compaction, which 1.3.3 cannot trigger by hand), says how/fork,/clearand--conversationmap to memory sessions, and states the maintenance runner's limit: a chore cannot read a reply above 3,500 bytes.
0.15.1: the memory in the desktop apps, and groundwork for Windows
The memory in the desktop apps, and the first steps toward Windows. A new guide explains what Claude Desktop's Code tab, Cowork and Chat and the ChatGPT app's Work and Chat modes each get from the memory and what to do in each; kg setup now connects the ChatGPT app even without a separate Codex CLI. On Windows, which is still not supported, kg now loads and a report-only CI job tracks the test suite there (30 of 45 test files pass).
Fixed
kg setupconnects the ChatGPT desktop app without a separate Codex CLI. The app's Work mode is Codex and shares its plugins with the command-line tool, but setup looked only for acodexcommand on PATH, so a user with just the app got no plugin. Setup, doctor, update and uninstall now fall back to the Codex the app bundles. Its hooks message also says where the app asks for trust.
Changed
- Groundwork for Windows (not yet supported).
kgno longer fails to load there: its lifecycle lock falls back to the Windows file lock whenfcntlis missing. Path containment (projects within home, transcripts, the session's bound project, file recall) compares path components instead of strings joined with/, the same answer on every OS. A report-only Windows CI job runs every test file and lists what still fails. Nothing changes on Linux or macOS.
Docs
- A guide to the memory in the desktop apps (wiki: Desktop Apps). What Claude Desktop's Code tab, Cowork and Chat and the ChatGPT app's Work and Chat modes each get from the memory, how to point a chat at a project once through a Desktop Project's instructions, and the limits of each surface. The plugin README's Desktop section now says the same.
0.15.0: docs that match the code; a server hardened by a second formal pass
Docs that match the code, and a server hardened by a second formal pass. Every document was checked claim by claim against the source, and the READMEs now lead with what the memory does for you, what a day with it looks like, and an honest account of its maturity and costs. The formal pass modelled the parts added since 0.11 in Lean and fixed 26 findings (F6, F7, F13–F32, F34–F37), each reproduced against the real code and covered by a test; two more (F33, F38) are recorded as open. Background upkeep is now opt-in, the visual editor shows project changes live, and kg_put_node refuses, once, a write that would drop stored notes.
Changed
kg_put_noderefuses, once, a write that leaves out stored notes. Notes sent with a write replace the stored list, so a model that sent only its new case after a full read silently deleted the lesson's history. The write is now refused with the notes it would remove marked; the same write sent again is taken as intended, so merging or trimming notes still works.- Background upkeep is opt-in in
kg setup. It spends quota, so its question now defaults to No, andkg setup --yesapplies it only when named (--only upkeep).--planmarks it. Every other item still defaults to yes. kg_useful'sidsparameter states the real limits: five per session as guidance, ten as the hard cap, as its description already said; it read "session budget: 5 total".- The Antigravity rule no longer says maintenance and history scouting are out of scope. Both have worked in Antigravity since 0.11.0; the stale sentence could make the model decline
/kg-scout.
Added
- The visual editor shows project changes live. The page subscribes to the graph on screen, so changes an agent makes to that project now appear without Refresh, as user-graph changes already did; other projects' changes never reach it. Project changes were also addressed by the writer's session, so the editor's own project writes were broadcast to nobody; they are now addressed by the graph written. The protocol was modelled before it was built (
formal/websocket/): a naive design applied an old project's change after a switch, or lost a write between load and subscribe. With an older server the page falls back to Refresh, and an older page works as before. The status reads Connected until the subscription is confirmed, then Live. Closes formal finding F6.
Fixed
- A reply's effects wait for the reply, in four more cases (formal findings F13–F16, each modelled in Lean, reproduced against the real code and covered by a test). A paged
kg_read(ids=[...])counted a node as read in full with the part showing its header, though its notes could continue in the next part; a write could then drop notes the session never received. In Antigravity, the "other sessions wrote" notice marked nodes seen before its queued reply was delivered, even when it was refused, so a write built on an older view could overwrite another session's change. A full read replayed after a compaction marked preloaded anchors seen though the new preload no longer showed them. And a compaction with a full delivery queue refused the fresh preload, so replayed replies reached the new context first. - Background upkeep holds its limits in seven more cases (formal findings F17–F23, modelled, reproduced and tested). A timed-out Antigravity run no longer leaves agy running beside the next one. A configured
codex_binorantigravity_binnow pins its runner under"auto"even when Claude Code is installed, as promised in 0.10.0. An unwritablechore_state.jsonrefuses instead of dispatching on every prompt. A five-hour reading carried forward from an earlier status-line frame is aged by when it was seen, not by when the file was last written. A runner command that fails to build is logged and no longer wedges dispatch until restart. The dispatch lock re-reads the config and clock, so switching chores off or changing the runner mid-decision is honoured and a long suspend cannot spend on a stale gauge or break a graph's cooldown. And an Antigravity budget notice no longer describes a window that has already reset. - The server lifecycle holds in three more cases (formal findings F24–F26, modelled, reproduced and tested). A start that outlasted kg's wait no longer leaves its server untracked under a start-error record that made later sessions skip their preload: the server clears the record once it serves, and a later start reports a server that never answers instead of calling it running. A stale pid file is no longer trusted for an unrelated process that reused the pid, which could make
kg stopkill another port's server. Andkg stop/kg restarttake the start lock, so a start during a stop no longer ends with nothing serving. - Usefulness accounting holds in six more cases (formal findings F27–F32, modelled, reproduced and tested). A rename no longer lets a session endorse the same node twice. A maintenance rename keeps the node's activity time instead of resetting it to zero. A server restart no longer forgets that a session is a maintenance pass, which had let its reads promote, its credits count as use and its writes reach other sessions. A maintenance tidy no longer turns the author's own next case into a note credit. A crash no longer loses a vote's ledger entry while keeping the vote. And an
instance-ofedge in the maintenance graph no longer credits a user lesson. - Archiving no longer flickers, and a small graph no longer keeps a node archived for nothing (formal findings F7 and F34, modelled in Lean, reproduced against the real store and tested). When compaction archived past the fill ceiling, refill waited for the next maintenance tick, so a node just archived and written to disk often came straight back 30 seconds later; refill now runs in the same tick. And promoting the last archived node also removes the archived section's header, which refill did not count, so a graph that fit entirely could keep one or two nodes archived indefinitely; refill now brings the whole archive back when it fits.
- Other sessions' writes are announced once, and only when they are writes (formal findings F35–F37, modelled, reproduced and tested). A rename, a node re-sent unchanged, or another session reading an archived node changes the node's version without writing anything, yet the "other sessions wrote" notice announced it as new: a maintenance pass renaming nodes made old lessons look like other sessions' fresh ones, and a change
kg_synchad already listed came back. The notice now takes only content another session wrote since this session last looked. A session's own rename of a node another session had just changed hid that change fromkg_syncand the notice for good; it is now listed. And in Antigravity, a reply queued for the next hook and a reply sent inline before it could both carry the same change; a reply now leaves out what a queued one already carries. - The editor reconnects after a memory-server restart. Its WebSocket proxy kept the page's socket open when the server side closed, so the page showed Live but received nothing until reloaded. Either side closing now closes both.
- The visual editor follows the server's port and refuses cross-site requests. Its live-update proxy always connected to port 8765, so with another
KG_HTTP_PORTlive updates came from the wrong server (or none); it now followsMCP_SERVER_URL, as REST already did. Its CORS origins followEDITOR_PORTinstead of a fixed 8766. And like the memory server since 0.9.44, it refuses requests a browser marks as cross-site, so a web page can no longer make it promote a node through the proxy; a link to the editor from another site still opens its page. - A start through the systemd unit clears an old start error. The hooks read
last_start_erroras "down and failing" and stop trying to start the server; only a start without the unit cleared it. A start through the unit now clears it on success and records the failure, pointing at the journal, when it fails. The unit now keepsXDG_STATE_HOME, so its server looks for the record where kg writes it. kg logsreads the journal under the systemd service. The service's server logs to stderr, which systemd keeps in the journal, butkg logstailed the file only a server started bykg startwrites, so it showed a stale log or none. With the unit enabled it now runsjournalctl --user -u kg-memory.service(the file, whenjournalctlis missing).- Re-running the install script upgrades kg, and it no longer fails in an agent's shell.
uv tool installsucceeds on an installed tool without upgrading it, so the script's upgrade fallback never ran; it now usesuv tool install --upgrade. And/dev/ttycan exist without a controlling terminal, so the script tried to runkg setupthere and exited with an error after installing; it now checks that the terminal opens, and otherwise says to runkg setupin a terminal.
Security
- Codex budget notices read only a rollout under home. The quota gauge read the tail of whatever transcript path a hook request named. It now goes through the same containment as every other transcript read: a
.jsonlfile under the user's home, or underCODEX_HOMEwhen that lives elsewhere.
Documentation
- The READMEs now lead with what the memory does for you, what a day with it looks like, and an honest account of its maturity and costs. Docs are aligned with the current source: what
kg setupoffers (auto-update, auto-memory off, thekg gaugestatus line, background upkeep) and howkg updateandkg uninstallreplace the manual plugin steps;.mcp.jsonlaunchingkg mcp; logs under systemd; where environment variables take effect; Windows unsupported; macOS CI report-only; transport throughkg mcpand all four clients in ARCHITECTURE.md; development paths throughcli/kg-dev. The p...
0.14.0: memory that reaches every client whole
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_usefulnow takescredits=1-3per 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 asvia: "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_usefuldescription 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
kgcommand 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
kgserver kept its PID file, log and start-failure note in one folder whateverKG_HTTP_PORTwas. A second server (a bench, a test) overwrote the live server's PID file, sokg stopon 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 inport-<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.
0.13.0: memory that learns from repeats
Memory that learns from repeats. Replayed on copies of real graphs before release.
Added
- Sessions hear what other sessions wrote. A session assumes it works alone: on parallel runs no session ever called
kg_syncunprompted, and five concurrent sessions wrote one lesson as four nodes. The server now appends up to three gists of nodes other sessions wrote since this session last looked to its hook replies and tokg_put_node/kg_searchreplies, with a pointer tokg_syncfor the rest, so a session updates the existing lesson instead of writing a duplicate. Each change is pushed once and never back to its writer. Only writes that could hold this session's lesson qualify: none from maintenance, and user-level ones only from a session in the same project. - A repeat credits the lesson. A new
instance-ofedge from a node created after the lesson it points to means that lesson was needed again: the lesson earns what an endorsement earns, dated on the day of the case, so a pass linking an old episode today does not look like this week's need. Existing graphs are credited from their history on load. A case added as a note to a lesson another session wrote counts as that session's endorsement, once per node. Logged inuseful.jsonlwithvia: "recurrence"or"note". - Maintenance reframes lessons that keep failing. A principle that keeps gaining failures after it was written misses something. The full pass gains a category for it (at most one per pass): classify the members (failures count; applications and findings do not), separate a placement problem from a content one, and write the new shape as a HYPOTHESIS node that only real work can confirm. The lift chore now asks for the mechanism that connects its episodes and rejects advice nobody can act on. Lessons whose notes keep recording repeats are nominated too.
Changed
- One lesson per node, written at the turning points. The memory instructions (kg-core and the tool descriptions) now ask for the gist to state the lesson so it holds beyond its case, one case per note, and a walk back through the session before writing: each point where another choice would have changed the outcome is a lesson. Texts that discouraged new nodes ("an edge beats a new node", "unconnected nodes risk archival") are softened: connect rather than duplicate, but a new lesson earns its own node.
- The newest nodes stay visible by budget, not by days. The 5-day creation grace protected nothing in a project touched twice a month and everything in a busy week (on one graph it held 12 of 24 active slots). Now the newest nodes stay active while their render cost fits in 30% of the level's budget.
KG_GRACE_PERIOD_DAYSis gone. - The active set re-ranks between thresholds. Archival acted only above the budget and refill only below the fill ceiling, so in between whatever was read last stayed active. Each idle tick now swaps the best archived node for the worst active one when it wins by the resurrection margin, at most three per tick.
- Maintenance is not use. A maintenance pass or chore reads to judge and rewrites to tidy: its reads no longer stamp recency or promote, and its writes keep the node's previous activity time.
kg_read(maintenance=true)flags the session before its first read. - The write-time hub hint names fewer unrelated nodes. It uses the debt detector's thresholds and its stoplist, and a term held by over a quarter of the graph counts as domain vocabulary, not an entity (the debt line's smear check uses the same ceiling).
- The PostToolUse hook fires for every tool in Claude Code and Codex, so pushed writes reach sessions whose work runs through MCP or other tools. It adds about one second of hook time per session, measured on a week of real transcripts.
- Recommended output style: a decision gets its own self-contained block at the end of a reply: what it affects, the options with consequences, a recommendation.
kg-memory 0.12.0: one command, kg mcp for every harness, on PyPI
Breaking: the plugins now need the kg command. Install once with uv tool install kg-memory && kg setup; a session without it says how. Memory data is unchanged.
Added
kg, one command for the memory, published on PyPI askg-memory.kg setupchecks every piece and fixes what you accept, backing up each file first: the command on PATH, a systemd user service on Linux, the server, and for Claude Code, Codex, Antigravity and Claude Desktop the plugin, permissions and settings.kg doctorchecks,kg updateupgrades kg, the server and every plugin together,kg uninstallreverses setup and keeps your memory. Alsokg start/stop/restart/status/logs/commitandkg gauge(the Claude status-line quota tap).kg mcp: every harness connects over stdio. It starts the server when it is down and waits out a restart, then retries, so the tools stay connected instead of needing/mcp→ Reconnect. Only a refused connection is retried, so a write never lands twice. Claude Code, Codex, Antigravity and Claude Desktop all use it; Desktop no longer needs Node or themcp-remotebridge.kg editorstarts the visual editor (and the server it reads) and opens it.- Releases publish to PyPI from the version tag through trusted publishing.
Changed
- The SessionStart hooks start the server through
kgand wait for it, so a cold start still gets its preload. kg startis serialised: concurrent starts from a harness and its hook share one server instead of leaving a false start error.- The server refuses to run twice on the same storage directory.
- The repository is now
mironmax/kg-memory; the old URL redirects and installed marketplaces keep working.
Removed
- The plugin's own launchers:
server/manage_server.shand its per-plugin Python environment,install_command.sh(kg-memory/kg-visuallinks),setup_desktop.pyanddesktop_bridge.sh,visual-editor/manage_visual.sh, and thememory-mcp.serviceunit.kg setupretires the old links and moves an existing Desktop entry tokg mcp;kg-memorystays as a shim that runskg.
v0.11.0 — Antigravity CLI (experimental), budget notices, compaction reset
Added
- Antigravity CLI support (experimental). The plugin carries a native Antigravity package beside its Claude Code and Codex files: eager KG tools whose descriptions the model sees, session preload, prompt recall, and file recall for file views, edits and explicit shell reads. Antigravity truncates MCP results above about 10 KB, so a larger reply from any KG tool returns a short receipt and arrives through the next
PreInvocationhook in UTF-8 chunks of up to 40 KB. Nothing it implies is recorded until the last chunk is acknowledged: seen and full-read state, sync position, the read timestamp and promotion out of the archive. A refused reply changes nothing, and queued replies survive new prompts and server restarts. A compaction checkpoint in the transcript re-queues the preload and replays pending replies from the start. Install withagy plugin installfrom a checkout; see ANTIGRAVITY.md. Signed-in resume, fork, clear and compaction checks are still open. - Budget notices: the server tells a session when to wrap up. On the hooks it already serves, the server reads the session's own quota gauge and says once per level per window: plan the wrap-up at 80% of the five-hour window, wrap up now at 90%, and the same at 90/95% of the week. Claude Code reads the status-line file (no notices without it), Codex the session's own rollout, Antigravity a live
agy -p /usagereading cached for five minutes. An audit of Codex rollouts had found sessions at 90–97% of five hours that never read their quota. Off with"budget_notices": falseinchores.jsonorKG_BUDGET_NOTICES=0. - Antigravity maintenance runner and history scouting. Antigravity prompts dispatch chores like Claude Code and Codex, and
"runner": "antigravity"runs them on agy: gated on a live/usagereading for the run's model group (weekly-only plans skip the five-hour gate), refused unless your Antigravity settings grant the tier's kg tools or while paid credits could be spent. The run is a tool-lesskg-maintaineragent in its own workspace, refused unlessagy -p /agentslists it, and stopped if agy logs a fallback to its default agent; deletions stay on Ask, so it never deletes. Verified with a mock model only./kg-scoutgains an Antigravity recipe: the prompt history as index, the conversation database as inventory, transcripts as the record. - The retrieval evaluator can report what a session did after staged recall.
python -m eval --transcriptsreads the matching Claude Code transcripts and Codex rollouts against historical graph snapshots and counts, per recall route and cohort, later explicit reads, node updates, endorsements, gist phrases in prose and requests on touched files. The counts describe observed activity, not benefit: missing transcripts and unobservable operations are reported as coverage gaps. It is opt-in, local and read-only; without the flag the report is unchanged. The file-request grammar the hooks use moved intocore/file_requests.pyunchanged, so the evaluator shares it without importing the server. - Search in the visual editor uses the same ranking as
kg_search. IDs, descriptions, notes, and file references are searched across every tier of the selected graph. A ranked result list highlights matching text; the canvas shows the top five matches and their connecting paths, with an option to show all matches. Selecting a hidden result reveals it without recalling it. Ranking, stemming, term weighting, and path finding now live in shared read-only helpers. - Node details explain the archival score. The live scorer supplies the total, raw recency/connectedness/usefulness values, percentile ranks, weights, and weighted contributions, including connection weights, the hub floor, and endorsement decay. Active and archived nodes use their actual compaction/refill pools; grace-protected and orphaned nodes show marked previews. Inspection never promotes nodes or updates their read timestamps.
GET /api/projects: the memory server now lists its own project graphs. One row perprojects/<slug>/graph.jsonunder the storage root — slug,project_pathfrom_meta(or null when never stamped), whether that folder still exists, node counts per tier (active/archived/orphaned), edge count, and the graph file's mtime as last-used. Reads graph files directly, like the maintenance-debt survey; never creates, loads, migrates or writes one. The visual editor's project list now calls this instead of scanning~/.claude/projects/Claude Code history, so a project used only from Codex shows up, a customKG_STORAGE_ROOTis honored, and a graph is never listed twice or guessed from a slug. A graph whose folder is gone or whose_metanever recorded a path is still shown, marked as such; one with no recorded path can't be opened (there's nothing to address it by) and says so instead of silently doing nothing. Against an older server without the route, or one it cannot reach, the editor falls back to the previous history scan; a missing route is logged once per process.- The visual editor opens a mature graph as a picture of what's live, not a grey mass. Default view now draws active nodes plus their one-hop neighbours; archived neighbours stay (dimmed, as before), orphaned nodes are hidden, and an Include orphaned toggle brings back all of them, not only those next to an active node; and All nodes reaches the unfiltered view. Node radius is driven by degree over every non-orphaned edge at the level, computed once regardless of which view is showing, so hubs read as hubs and don't resize when the view toggles. Edge labels show on hover instead of crowding the canvas permanently. The header now accounts for every stored edge instead of silently dropping some: it names how many are drawn, how many are hidden by the default view, and how many are dangling (an endpoint missing from this level), and does the same for node counts when the default view is narrower than the full graph.
Changed
- Gists can be edited and saved above the length target. Inline and modal editors keep a visible warning without blocking typing or saving. Their counters use the server's canonical 300-character soft target and count Unicode characters the same way as Python; maintenance debt uses the same target.
- The visual editor names both view choices explicitly: “Visible nodes” and “All nodes,” with a persistent view summary and hidden-node count. Choosing a view exits search; graph switching clears search, and late responses cannot replace the current graph's results.
- The recommended setup is one output style, and Codex and Antigravity get the same text.
recommended-setup/output-styles/concise-quality-v3.mdcarries the working agreement, the response rules and memory habits in one file, and replacesCLAUDE.mdandconcise-quality-v2.md, whose benchmark numbers the setup README keeps, attributed to the parts v3 merged. Its Memory section applies only with the plugin installed. The new Codex setup loads it asdeveloper_instructions, with the loading evidence and a small behaviour test, and sets up the footer for limits and context; the new Antigravity setup loads it as a globalGEMINI.mdrule and configures two data rows with a divider, quota and context gauges. The status line keeps each quota bucket's observation time, so a cached value shows its age, and has fixture tests in CI. Copies already installed under~/.claude/are untouched; the README says how to move from v2 without loading the text twice. /kg-scoutasks before the expensive reads, except when nobody is there to ask. After scanning the prompt index it lists the candidate sessions and lets you pick which transcripts to read in full, unless the request already names them. An unattended run picks for itself, records what it chose and skipped, and is paced by the runner's own quota gauge instead: it continues only while the 5h window is under 40%, the weekly under 70% and the week is on course to leave quota unused, the same gates as a maintenance pass. The Codex recipe now names the rollout inventory as its index.- Sessions without a project are user-only, and everything obeys that scope.
kg_read()without cwd opens a user-only session (Claude Desktop chat has no folder to give); the home directory and a folderless Codex app chat (~/Documents/Codex/<date>/<slug>) are user-only too, unless a graph already exists there. Such a session is reused by its id, refuses project writes with the call that attaches a project, and attaches one when a laterkg_readpasses cwd, keeping its id and what it has seen. A session bound to a project ignores a different cwd and says so. File recall, capture counting and maintenance follow the session's scope instead of the hook's cwd, so a home-directory session no longer loads, counts into or offers a project graph for its folder. - Endorsed nodes and hubs are the last to be orphaned. When the archived section outgrows its budget, archived nodes are now orphaned by their archival score (recency, connectedness, endorsements) instead of by their edges to active nodes alone, and connectedness has a floor that grows with a node's total edge count, so an entity hub no longer scores as isolated while its neighbourhood sleeps. Replayed on three real graphs (every orphan restored, then orphaned again to the same budget), endorsed nodes among the orphaned fell from 108 to 53, 88 to 39 and 6 to 0, and hubs of 10+ edges from 7 to 1. Nodes already orphaned stay orphaned.
Fixed
- After a compaction, recall no longer treats dropped memories as present. The compacted summary keeps only part of what the session was shown, but the session kept its seen-set and full-read flag: prompt and file recall withheld memories the summary had dropped, and the next full read rendered them as...
v0.10.0 — Knowledge Graph memory for Claude Code and Codex
Knowledge Graph memory for Claude Code and Codex. The first tagged release since v0.9.31, covering 0.9.32 through 0.9.45 and the work below. In summary:
- A second harness. Codex CLI runs the plugin unchanged, against the same local memory as Claude Code, so what one learns the other recalls. Maintenance chores can run through either, each gated on its own subscription's limits.
- Memory arrives at the moment it applies. Besides the session-start preload and per-prompt recall, the memory about a file now arrives when the agent reads or edits it (0.9.41).
- The memory tends itself. Activity-triggered chores and passes (0.9.37), repair of stale file pointers and lifting of repeated episodes into principles (0.9.42), a churn guard against over-rewriting, ids that name their subject and a safe
kg_rename_node(0.9.35), and a maintenance memory of the agent's own. - Measured, not assumed. Recall decisions and endorsements are logged with the route by which each node reached the session (0.9.36, 0.9.39), and a replay harness scores recall changes against them (0.9.40). Thirteen papers were read against this system's conditions (
docs/research/). - Hardened. Hook paths contained and prompt scrubbers made linear (0.9.38); five concurrency and durability fixes from a formal pass with Lean models (0.9.44); cross-site requests refused; the server on mcp 2.x (0.9.43); Python 3.10 working again and every change tested in CI on 3.10 and the newest Python (0.9.45).
Upgrading. The plugin update rebuilds the server's Python environment when you come from before 0.9.43, whose requirements changed. While it rebuilds, the port stays closed for about a minute, and Claude Code's MCP client gives up: run /mcp → plugin:knowledge-graph:kg → Reconnect once, after the server is back. In Codex, start a new session. Your data in ~/.knowledge-graph/ is untouched.
Install
# Claude Code
/plugin marketplace add mironmax/claudecode-plugins
/plugin install knowledge-graph@maxim-plugins
# Codex CLI — then run /hooks in Codex and trust the knowledge-graph hooks
codex plugin marketplace add mironmax/claudecode-plugins
codex plugin add knowledge-graph@maxim-pluginsFull details per release, 0.9.32 through 0.10.0: CHANGELOG.md. Documentation: README · Wiki.
v0.9.31 — one-voice skills, sharper search, smear detection
Skills collapsed to one voice
kg-capture and kg-recall folded into kg-core, following the context-engineering shift for Claude-5-generation models: judgment-based instincts over rule lists, no doctrine repeated across layers (tool mechanics live only in the kg_* tool descriptions; the session protocol only in the preload header). Always-loaded skill text drops ~60%. A sandboxed A/B bench (Sonnet, 21 runs) confirmed equal task outcomes at about half the output tokens, with zero unnecessary searching. The description's longest instinct is deliberately search below the surface — a rich graph buries needed facts under fresher work, and a node found when truly needed earns the usefulness credit that keeps it alive.
Search core sees more and weighs better
Shared by kg_search and ambient recall: tokens contribute their ./_- subtokens, terms match through a light stem (schedule ≈ scheduling), adjacent subtokens form bigram terms with their own co-occurrence IDF, occurrences are field-weighted (id ×3, gist ×2, notes ×1 — a node about a concept outranks one that mentions it in passing), and IDF is sharpened so one term naming the right node isn't outvoted by several dull ones. Recall additionally gates on evidence (corroborated, near-unique, or named by the node's id/gist — lexical strays stay silent) and injects hits sharpest-first.
Write-side nudges
Creating a node probes its id + gist against its own graph through the same pipeline. A near-duplicate gets named with a fold-in suggestion; a gist that re-describes an entity the graph already names gets "an edge to it beats re-describing." Nudges only — the write always proceeds.
Smear detection and entity consolidation
Why search kept missing "project-central" vocabulary: chronicle-style capture re-describes entities in prose until IDF sees a saga, not a signal. The DEBT: line now reports smeared terms (term×count→hub), and /kg-maintain gains category 1: consolidate exactly one smeared entity per pass — durable facts into the hub, satellites reduced to their delta plus an edge. Capture doctrine gains the matching instinct: name things once.
Fixed
source=fork(and any future SessionStart source) now recovers the KG session from transcript markers instead of re-preloading on top of inherited context — onlyclearhard-resets.
Tests: tests/test_v0931.py (31 assertions); full suite green. Retuning validated by an offline replay of two weeks of real session prompts against real graphs.