Skip to content

feat(pipeline): link markdown file references into the graph - #1832

Open
cdeust wants to merge 2 commits into
DeusData:mainfrom
cdeust:feat/doclinks-markdown
Open

feat(pipeline): link markdown file references into the graph#1832
cdeust wants to merge 2 commits into
DeusData:mainfrom
cdeust:feat/doclinks-markdown

Conversation

@cdeust

@cdeust cdeust commented Aug 25, 2026

Copy link
Copy Markdown

Markdown docs reference other repo files constantly (a coding-standards doc links the modules it governs, a README points at entry points) but none of that surfaced as edges, so fan-in queries were blind to documentation hubs. In an A/B retrieval benchmark I ran in August on a docs-heavy repo, the graph's top fan-in answer was off by roughly 17x: the most-referenced file was a standards doc with 173 references and zero inbound edges.

New pre-dump pass, pass_doclinks.c, modeled on pass_configlink.c: three strategies emit REFERENCES_FILE edges between existing File nodes only (unresolvable targets are dropped, the pass never invents nodes): inline links, backtick paths, bare path mentions. Targets resolve against the referencing file's directory and the repo root; repeated references collapse into one edge carrying strategy, confidence and count. Registered in the pre-dump sequence after configlink and in the incremental post-passes; REFERENCES_FILE added to the skill's edge-type list and the structural/language contract tests.

Tests mirror test_configlink.c (real files in a tmpdir, File nodes in a gbuf, run the pass, assert edges): inline link, backtick, bare mention, http/anchor ignored, anchor-suffixed file link, dedupe with count, relative-vs-root resolution, unresolvable-target guard, NULL repo_path skip.

A companion change adds the same linking for shell files (source lines and script invocations); split out to keep each change reviewable.

Validation: scripts/build.sh clean; focused serial runner (doclinks, configlink, pipeline, edge_structural, lang_contract) 340 passed under ASan/UBSan; cppcheck clean on the new files with the repo's flags.

What does this PR do?

Checklist

  • Every commit is signed off (git commit -s) — required, CI rejects
    unsigned commits (DCO, see CONTRIBUTING.md)
  • Tests pass locally (make -f Makefile.cbm test)
  • Lint passes (make -f Makefile.cbm lint-ci)
  • New behavior is covered by a test (reproduce-first for bug fixes)

@cdeust
cdeust requested a review from DeusData as a code owner August 25, 2026 11:38
@github-actions

Copy link
Copy Markdown

Thanks for opening this — it has been seen, and it is queued.

This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence.

Current review status: working through a backlog. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

If this fixes a bug, a reproduction we can run is worth more than a description of the symptom.

Thanks for contributing, and sorry in advance for the wait.

@cdeust
cdeust force-pushed the feat/doclinks-markdown branch 3 times, most recently from 3f48c01 to d72a5c7 Compare August 25, 2026 12:27
@DeusData DeusData added enhancement New feature or request parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Sep 1, 2026
@DeusData

DeusData commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Thank you for the concrete documentation-link benchmark, the dedicated pass, and the negative and deduplication controls. This introduces new graph edge semantics and several source-text heuristics, so we need more time to review precision, incremental parity, and security boundaries carefully. The contribution queue is quite full, but we will return with grounded feedback as soon as possible.

@DeusData

DeusData commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Maintainer decision: REFERENCES_FILE is accepted. A new edge type has to earn itself here — the default is to map a new construct onto an existing one — so it is worth saying what earned it.

None of the nine existing types means "mentions". DEPENDS_ON and CONFIGURES are causal claims, IMPORTS is language-level, USAGE is symbol-level. Forcing a documentation reference onto any of them would not just be imprecise — it would make that type mean less for everyone already querying it, and a fan-in query would silently mix two unlike relations. This is the case where a new type is cheaper than the alternative.

And the defect is measured rather than argued. A standards document with 173 references and zero inbound edges, and a top-fan-in answer off by roughly 17x, is a concrete way for the graph to be confidently wrong about which files matter. That is the kind of blindness that is invisible until someone benchmarks it.

What made this easy to accept

It emits edges between existing File nodes only. Dropping unresolvable targets rather than inventing nodes is the single most important property here — a doc-linking pass that minted File nodes for every path-shaped string would poison the graph rather than enrich it. Saying so explicitly in the description is what let me stop worrying about it early.

Modelling it on pass_configlink.c rather than inventing a pass shape means the next reader meets one pattern twice.

Carrying strategy alongside confidence and count is what de-risks the part I would otherwise have pushed back on. Bare path mentions in prose are the strategy most likely to produce a false edge, and because the strategy is on the edge, a consumer can filter to explicit links only without us having to decide that question up front. Keep that field — it is doing more work than it looks.

Splitting the shell-file companion out was the right call for reviewability.

Two things to do

Strip the Claude-Session: URL from the commit message. Attribution of tool use is welcome here and the Co-Authored-By style trailer is fine; the session URL is the part we do not carry in repository history. An amend and a force-push will do it.

Please rebase — this is DIRTY. main moved three times yesterday: broken by a duplicate-symbol merge, repaired by #1993, then #1703 landed.

Your checklist is entirely unticked, but your validation paragraph covers all of it — build clean, 340 passed under ASan/UBSan across the focused suites, cppcheck clean on the new files. Worth ticking so a reviewer does not have to reconcile the two.

Clearance is REVIEW(1) on Makefile.cbm — the established shape here for registering a new test file. It needs a maintainer marker, not a change from you.

Markdown docs reference other repo files constantly (a coding-standards
doc links the modules it governs, a README points at entry points) but
none of that surfaced as edges, so fan-in queries were blind to
documentation hubs. In an A/B retrieval benchmark I ran in August on a
docs-heavy repo, the graph's top fan-in answer was off by roughly 17x:
the most-referenced file was a standards doc with 173 references and
zero inbound edges.

New pre-dump pass, pass_doclinks.c, modeled on pass_configlink.c: three
strategies emit REFERENCES_FILE edges between existing File nodes only
(unresolvable targets are dropped, the pass never invents nodes):
inline links, backtick paths, bare path mentions. Targets resolve
against the referencing file's directory and the repo root; repeated
references collapse into one edge carrying strategy, confidence and
count. Registered in the pre-dump sequence after configlink and in the
incremental post-passes; REFERENCES_FILE added to the skill's edge-type
list and the structural/language contract tests.

Tests mirror test_configlink.c (real files in a tmpdir, File nodes in a
gbuf, run the pass, assert edges): inline link, backtick, bare mention,
http/anchor ignored, anchor-suffixed file link, dedupe with count,
relative-vs-root resolution, unresolvable-target guard, NULL repo_path
skip.

A companion change adds the same linking for shell files (source lines
and script invocations); split out to keep each change reviewable.

Validation: scripts/build.sh clean; focused serial runner (doclinks,
configlink, pipeline, edge_structural, lang_contract) 340 passed under
ASan/UBSan; cppcheck clean on the new files with the repo's flags.

Signed-off-by: Clément Deust <clement.deust@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cdeust
cdeust force-pushed the feat/doclinks-markdown branch from d72a5c7 to 844a36b Compare September 2, 2026 01:44
@cdeust

cdeust commented Sep 2, 2026

Copy link
Copy Markdown
Author

Rebased on main (5fbab7b), one commit 844a36b, force-pushed. Conflicts were only in src/pipeline/pipeline.c and Makefile.cbm: kept main's version (sizeof-derived pass count, new ensemble_routing/importance passes) and inserted the doclinks pass / test_doclinks.c right after configlink. All other hunks are byte-identical to the previous commit d72a5c7 (checked by interdiff). The Claude-Session trailer is removed and the checklist is ticked. Locally under ASan/UBSan: doclinks, configlink, pipeline, edge_structural and lang_contract suites = 355 passed. clang-format reports no violation on the diff.

@DeusData ready for review on your side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants