GoogleCloudPlatform / GoogleCloudPlatform/open-knowledge-format

Viewer: resolve bundle-relative and file-relative concept links consistently

Open
#14 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
467
Forks
35
Avg merge
9m
Merged PRs (30d)
1

Description

### Problem

The reference viewer handles OKF's two supported internal-link forms inconsistently.

- In `src/reference_agent/viewer/generator.py`, `_extract_links()` skips every target beginning with `/`. As a result, the recommended bundle-relative form, such as `[Orders](/tables/orders.md)`, does not create graph edges or backlinks.
- In `src/reference_agent/viewer/static/viz.js`, `rewriteInternalLinks()` rewrites only targets beginning with `/`. File-relative links such as `[Orders](../tables/orders.md)` create graph edges, but clicking them opens a file/external path instead of navigating inside the viewer.
- Links with fragments such as `/tables/orders.md#schema` are not rewritten because the JavaScript currently requires the href to end with `.md`.

This means neither link form has complete behavior across graph construction and in-viewer navigation.

### Why this matters

OKF v0.2 section 6.1 supports both forms and recommends bundle-relative links because they remain stable when documents move. The checked-in Acme Retail bundle already uses bundle-relative links extensively, for example in `bundles/acme_retail/policies/revenue-recognition.md`. Those relationships are therefore missing from its generated graph and "Cited by" lists.

The README also says the viewer draws edges from each cross-link and rewires internal links for navigation.

### Proposed implementation

1. Add a single Python resolver that normalizes both bundle-relative and file-relative Markdown targets to concept IDs.
2. Strip optional fragments for concept resolution while preserving the original href.
3. Reject external URLs, non-Markdown targets, and paths that escape the bundle root.
4. Include a per-concept raw-href-to-concept-ID mapping in the generated bundle payload.
5. Build graph edges and backlinks from those normalized IDs.
6. Have `rewriteInternalLinks()` use the generated mapping instead of implementing a second, partial path resolver.
7. Continue tolerating broken links: retain them in rendered Markdown, but do not create an edge or internal navigation action when the target concept is absent.

### Acceptance criteria

- Bundle-relative and file-relative links both create graph edges and backlinks.
- Clicking either form navigates to the target concept in the self-contained viewer.
- Both forms work with heading fragments.
- External links remain external.
- Paths escaping the bundle root are ignored.
- Broken links remain tolerated as required by the specification.
- Duplicate links produce only one graph edge.
- Tests cover both supported forms, fragments, external links, escaping paths, broken targets, and deduplication.

Contributor guide

Open the contributing guide

Research direction

Start in src/reference_agent/viewer/generator.py at _extract_links() and src/reference_agent/viewer/static/viz.js at rewriteInternalLinks(), then trace how the generated bundle payload represents concepts. Design the shared mapping around the stated resolver rules and add tests for link forms, fragments, external and escaping paths, broken targets, and deduplication. Done means graph edges, backlinks, and in-viewer navigation behave consistently without breaking tolerated links.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, python
Domain
backend, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.