Skip to content

feat(wiki): kb.backlinks - expose the wiki link graph as a method - #734

Open
joaovictor91123 wants to merge 3 commits into
vouchdev:testfrom
joaovictor91123:feat/kb-backlinks
Open

feat(wiki): kb.backlinks - expose the wiki link graph as a method#734
joaovictor91123 wants to merge 3 commits into
vouchdev:testfrom
joaovictor91123:feat/kb-backlinks

Conversation

@joaovictor91123

Copy link
Copy Markdown
Contributor

What changed

New kb.backlinks method exposing the wiki's [[wikilink]] graph, on all
four surfaces (MCP kb_backlinks, JSONL kb.backlinks,
capabilities.py, CLI vouch backlinks [page_id]):

  • With page_id: that page's inbound and outbound link titles.
    Inbound reuses the existing wiki_render.backlinks(); outbound is a
    small new sibling, wiki_render.outbound_links(), walking the page's own
    body (resolved, deduplicated, self-links dropped — same conventions as
    backlinks()).
  • With no page_id: the full inbound map — wiki_render.backlinks()
    exposed directly.
  • Unknown page_id → the same "not found" contract kb.neighbors already
    uses for an unknown root node.

Why

wiki_render.backlinks() already computed the inbound-link map internally
(used by render_moc's ranking), but nothing exposed it as agent-facing
data — no MCP tool, no JSONL handler, no CLI command. The only way to see
it was parsing vouch render-wiki's rendered markdown output. kb.neighbors
looks adjacent but is entirely disjoint: it walks the claim/entity/relation
graph (graph.find_neighbors); grepped graph.py and confirmed zero
wikilink handling there. The two graphs don't overlap in edges, sources, or
node kinds.

Closes #732

Roadmap 1.4: "Backlinks: [[wikilinks]] are validated today, then
discarded; persist the link graph and render it." This ships the "render it
as data" half. The "persist" half is deliberately not done here —
wiki_render.py's own docstring already frames these as "regenerable
views... like the SQLite index, not authored knowledge," and adding real
on-disk persistence (cache invalidation, whether kb.index_rebuild should
touch it, etc.) is a bigger, separate design question than exposing the
already-computed view as a method.

What might break

Nothing for users with an existing .vouch/ directory — purely additive:
a new method, two new pure functions in wiki_render.py, no object model
or on-disk shape change. Fully read-only, like every other wiki_render
view — never proposes, writes, or mutates, so it doesn't touch
proposals.py, lifecycle.py, storage.py, or the review gate.

Archived pages are excluded from the checked set and treated as
unresolvable link targets — this matches render-wiki's existing (#695)
exclusion policy exactly (a link to an archived page is exactly as dead as
a link to nothing), so it's not a new precedent.

VEP

Not applicable — no object model, on-disk layout, bundle format, or
audit-log shape change. A new read-only method over an already-computed
derived view, same shape as kb.neighbors.

Tests

  • Local make check-equivalent: ruff clean (src + tests); mypy
    clean; tests/test_capabilities.py (four-surface parity),
    tests/test_wiki_render.py, tests/test_health.py,
    tests/test_cli.py all pass
  • New behaviour has tests — extended tests/test_wiki_render.py with
    12 new cases: outbound_links/page_links unit tests (self-link
    exclusion, dedup, unresolved links, unknown page), plus JSONL
    envelope tests (single page, full map, unknown page error, archived
    page exclusion) and CLI smoke tests (CliRunner)
  • CHANGELOG.md updated under ## [Unreleased]

wiki_render.backlinks() already computed the inbound-link map
internally, used by render_moc to rank pages, but nothing exposed it -
no MCP tool, no JSONL handler, no CLI command, only reachable
indirectly by parsing vouch render-wiki's rendered markdown output.
kb.neighbors looks adjacent but is entirely disjoint - it walks the
claim/entity/relation graph, never [[wikilink]] edges between pages.

add outbound_links() as a small new sibling to backlinks() in
wiki_render.py (titles a page's own body links to, resolved and
deduplicated, self-links dropped), and page_links() combining both
directions for one page. register kb.backlinks the same four ways
every other kb.* method is: mcp kb_backlinks, jsonl kb.backlinks,
capabilities.py, cli vouch backlinks [page_id]. with a page_id, returns
that page's inbound + outbound titles; without, the full inbound map.
unknown page_id uses the same not-found contract kb.neighbors already
has for an unknown root node.

archived pages are excluded from the checked set and treated as
unresolvable link targets, matching render-wiki's own vouchdev#695 exclusion
policy - a link to an archived page is exactly as dead as a link to
nothing.

read-only, like every other wiki_render view - never proposes, writes,
or mutates, so it doesn't touch proposals.py, lifecycle.py, or the
review gate.

Closes vouchdev#732
@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance cli command line interface mcp mcp, jsonl, and http surfaces tests tests and fixtures size: M 200-499 changed non-doc lines labels Jul 31, 2026
test_hot_memory_universal_coverage asserts every kb.* method is either
in HOT_MEMORY_COVERED or explicitly excluded in HOT_MEMORY_EXCLUDED -
a new method with neither fails the suite. kb.backlinks landed with
neither, breaking CI. excluded with the same reason kb.neighbors
already carries: a graph slice, out of scope for the recency sidebar.
@github-actions github-actions Bot added the retrieval context, search, synthesis, and evaluation label Jul 31, 2026
…path

diff-coverage flagged server.py:341-347 (kb_backlinks' whole mcp tool
body - only exercised indirectly via jsonl/cli, never called directly)
and cli.py:3509-3510 (the `vouch backlinks` no-arg full-map branch -
only the single-page case had a cli test).

add a direct server.kb_backlinks() test covering single-page,
full-map, and unknown-page cases (matching test_explain_ranking.py's
test_mcp_surface_serves_explain_ranking pattern), and a CliRunner test
for `vouch backlinks` with no page id.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli command line interface docs documentation, specs, examples, and repo guidance mcp mcp, jsonl, and http surfaces retrieval context, search, synthesis, and evaluation size: M 200-499 changed non-doc lines tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

expose the wiki link graph as kb.backlinks (roadmap 1.4)

1 participant