Files
knowledge-base-framework/AGENT_QUERY_GUIDE.md
TotenKnopfandClaude Fable 5.1 96780317a7 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>
2026-10-06 20:40:13 +02:00

132 lines
5.7 KiB
Markdown

---
id: meta/agent-query-guide
title: Agent Query Guide
type: meta
status: active
tags: [agents, jq, graph]
last_reviewed: 2026-10-06
---
# Agent Query Guide
The graph is the selected vault's navigation index, built in memory from the
Markdown by `kb_framework.graph.build_graph` — no file is read or committed.
MCP is the canonical cross-repository interface: `graph_summary`,
`graph_search_nodes`, `graph_neighbors`, and `read_note`; the server rebuilds
the graph after every write, and `refresh_graph(validate=true)` rebuilds it on
demand and reports validation problems.
MCP-only agents use the tools above; shell examples below are for operators,
not agent fallback. For those queries, explicitly set `KNOWLEDGE_BASE_ROOT` and change into
that directory. Framework commands require `KNOWLEDGE_BASE_FRAMEWORK_ROOT` as
an explicit path; skill or agent file locations do not identify the data vault.
```bash
: "${KNOWLEDGE_BASE_ROOT:?Set the data vault directory explicitly}"
cd -- "$KNOWLEDGE_BASE_ROOT"
```
Schema:
- Top-level object:
- `version` (number): schema version
- `generated_at` (string): ISO-8601 UTC timestamp
- `nodes` (array): note metadata records
- `edges` (array): directed wiki-link records
- Node object (`nodes[]`):
- `id` (string): stable note identifier (usually from frontmatter)
- `title` (string): note title
- `path` (string): vault-relative markdown path
- `repo` (string): repo scope (a repository identifier, or `global`)
- `type` (string): note classification from a controlled vocabulary —
`hub|project|area|guideline|policy|feature|roadmap|decision|note|meta|reference`;
absent frontmatter means `note`, and `--validate` fails on anything else
- `status` (string): lifecycle state (`active`, `draft`, `deprecated`)
- `tags` (string array): topic tags
- `last_reviewed` (string): `YYYY-MM-DD`
- `outbound_links` (string array): linked note IDs from this note
- `inbound_count` (number): number of edges targeting this note
- Edge object (`edges[]`):
- `from` (string): source note ID
- `to` (string): target note ID
- `kind` (string): link *mechanism* — normally `markdown_link` (legacy
`wiki_link` is rejected by `--validate` and should not appear in a valid graph)
- `type` (string): semantic *relationship* (see vocabulary below); default `related`
- `anchor_text` (string): display / alias text used in the link
- `annotation` (string): free-text "what the source needs from the destination"
(from the link's `link-info`, falling back to a trailing `— gloss`); may be empty
- `weight` (number): link weight, currently `1.0`
## Link syntax
Links are standard **markdown links** whose target is the stable note `id`, with an
optional JSON brace suffix carrying the relationship and annotation:
```md
[display text](resource/old-deadlines){"type":"supersedes","link-info":"the deadline table this replaces"}
```
- A bare `[text](id)` with no brace is a `related` edge.
- `type` must be one of the controlled vocabulary; `generate-graph.py --validate`
fails on any other value:
`related, supersedes, superseded-by, depends-on, part-of, parent, derived-from,
see-also, source`.
- Legacy `[[wiki links]]` are **no longer accepted**: `generate-graph.py --validate`
fails on any that remain. Locate and convert them with
`python3 "$KNOWLEDGE_BASE_FRAMEWORK_ROOT/scripts/list-wiki-links.py" --vault-root "$KNOWLEDGE_BASE_ROOT"`.
Examples with `jq` (operators only; first dump the graph with
`python3 "$KNOWLEDGE_BASE_FRAMEWORK_ROOT/scripts/generate-graph.py" --vault-root "$KNOWLEDGE_BASE_ROOT" --write`,
which writes `index/graph.json` — keep `index/` out of git):
```bash
# list repos
jq -r '.nodes[].repo' index/graph.json | sort -u
# list the tag vocabulary, most frequent first (tags are matched verbatim)
jq -r '[.nodes[].tags[]?] | group_by(.) | map({tag: .[0], count: length})
| sort_by(-.count)[] | "\(.count)\t\(.tag)"' index/graph.json
# list top linked notes
jq -r '.nodes | sort_by(-(.inbound_count // 0))[] | "\(.inbound_count // 0)\t\(.id)\t\(.path)"' index/graph.json
# notes in one repo
jq -r '.nodes[] | select(.repo=="<repo>") | "\(.id)\t\(.path)"' index/graph.json
# all projects (PARA category 1)
jq -r '.nodes[] | select(.type=="project") | "\(.id)\t\(.path)"' index/graph.json
# outgoing links from one note
NOTE_ID="<note-id>"
jq -r --arg id "$NOTE_ID" '.nodes[] | select(.id==$id) | .outbound_links[]?' index/graph.json
# incoming links to one note
NOTE_ID="<note-id>"
jq -r --arg id "$NOTE_ID" '.edges[] | select(.to==$id) | .from' index/graph.json | sort -u
# outbound edges of a note WITH relationship type + annotation
jq -r --arg id "$NOTE_ID" '.edges[] | select(.from==$id) | "\(.type)\t\(.to)\t\(.annotation)"' index/graph.json
# all edges of a given relationship type (e.g. what supersedes what)
jq -r '.edges[] | select(.type=="supersedes") | "\(.from) -> \(.to)"' index/graph.json
# what a note supersedes
jq -r --arg id "$NOTE_ID" '.edges[] | select(.from==$id and .type=="supersedes") | .to' index/graph.json
```
For `jg`, use the same filters if your local `jg` is jq-compatible.
Validation:
```bash
# validate: non-zero exit on unresolved links, edge types or note types
# outside their vocabularies, OR any remaining legacy [[wiki links]]
python3 "$KNOWLEDGE_BASE_FRAMEWORK_ROOT/scripts/generate-graph.py" --vault-root "$KNOWLEDGE_BASE_ROOT" --validate
# write a graph dump for jq AND validate in one run
python3 "$KNOWLEDGE_BASE_FRAMEWORK_ROOT/scripts/generate-graph.py" --vault-root "$KNOWLEDGE_BASE_ROOT" --write --validate
# list any remaining legacy [[wiki links]] (rejected by --validate) to convert
python3 "$KNOWLEDGE_BASE_FRAMEWORK_ROOT/scripts/list-wiki-links.py" --vault-root "$KNOWLEDGE_BASE_ROOT"
```