refactor: extract kb_framework package, build graph in memory

Scripts become thin CLIs over kb_framework (graph, query, query_tools,
vault, instructions) so the hosted read-only connector shares one
implementation with the stdio server. The MCP server builds the graph
from Markdown on demand and invalidates it on writes; refresh_graph
rebuilds in memory and reports validation problems. Pre-commit hook
validates only; index/graph.json is no longer read, written or staged
(generate-graph.py --write remains for operators). Golden fixtures pin
graph and tool payloads to the previous output. Agent and skill docs
updated to match.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 20:40:13 +02:00
co-authored by Claude Fable 5.1
parent 4fec637599
commit 96780317a7
37 changed files with 1858 additions and 899 deletions
@@ -23,7 +23,7 @@ not that framework or caller instructions cease to apply.
The `knowledge-database` MCP server is the only interface for vault access: use `graph_summary`, `graph_search_nodes`, `graph_neighbors` and
`read_note` to find context; `capture_raw` for source bytes; `write_note` and
`edit_note` for notes; `refresh_graph(validate=true)` to regenerate and validate.
`edit_note` for notes; `refresh_graph(validate=true)` to rebuild the in-memory graph and validate.
Use `git_commit` / `git_push` only when the caller explicitly authorizes them.
Skills stay in the framework. Never infer the vault from this skill's location.
@@ -95,7 +95,7 @@ before writing content notes. Never invent transcript text or run shell extracto
## 4. Read the captured content
Use `read_note(path="03_resources/<resource-name>/raw/<filename>")` for captured
text. Path reads access the file directly and work before graph regeneration.
text. Path reads access the file directly and work even before the graph picks the file up.
For a captured binary, use the invoking agent’s explicitly permitted inspection
tool on the absolute path returned by `capture_raw`; if unavailable, report it. This —
not the live URL — is the source of truth for the rest of the steps, so the note
@@ -233,17 +233,17 @@ So the resource is reachable in the graph, not just reaching out:
lists them, and link the new note from there (create the hub if it does not
exist, with `type: hub`, `tags: [resource, hub]`).
## 9. Regenerate and validate the graph
## 9. Rebuild and validate the graph
Use `refresh_graph(validate=true)`.
This regenerates `index/graph.json` and validates links and edge relationship
types. If validation reports unresolved links, fix the targets (typos, wrong `id`,
This rebuilds the in-memory graph from the Markdown and validates links, edge
relationship types and note types; the result lists every problem under
`problems` and is an error result while any remain. If validation reports unresolved links, fix the targets (typos, wrong `id`,
or a link to a note that does not exist yet — either create it or downgrade it to
plain text / external URL); if it reports an unknown edge `type`, correct it to a
value in the controlled vocabulary. Re-run until clean. The pre-commit hook rejects
a stale or
invalid graph, so this must pass.
value in the controlled vocabulary. Re-run until clean. The pre-commit hook runs the same validation, so this must
pass. There is no graph file to stage.
## 10. Stage (do not commit unless asked)
@@ -251,7 +251,7 @@ Without explicit publishing authorization, leave the changes uncommitted and
report the touched paths. The MCP interface has no stage-only tool.
When a commit is authorized, use `git_commit(message=..., paths=[...])` with an
explicit list covering the resource folder, backlinked notes and `index/graph.json`.
explicit list covering the resource folder and every backlinked note.
This tool stages those paths and commits them; do not use wildcard paths.
Use `git_push` only when pushing is explicitly authorized. Follow the caller's
branch and review policy.