Skip to content

fix(onboarding): rank Key Concepts by symbol importance and ground citations#813

Merged
RaghavChamadiya merged 1 commit into
mainfrom
fix/onboarding-key-concepts
Jul 12, 2026
Merged

fix(onboarding): rank Key Concepts by symbol importance and ground citations#813
RaghavChamadiya merged 1 commit into
mainfrom
fix/onboarding-key-concepts

Conversation

@RaghavChamadiya

Copy link
Copy Markdown
Member

Problem

The always-generated Key Concepts onboarding page chose its "concepts" by
file PageRank: every public symbol in a high-ranked file inherited that file's
score. On this repo that produced six "core concepts" of LanguageSpec,
LanguageRegistry, __init__, get, import_support_map, from_extension
five of them from a single file, four of them methods, all from one leaf cluster
(ingestion/languages/). It also leaked pytest fixtures out of the internal
candidate list into the closing prose. A newcomer would conclude the codebase is
about language registries.

Separately, onboarding prose was grounded only by a prompt instruction ("do not
invent file paths or symbol names"), with nothing verifying the model obeyed, so
fabricated citations reached the reader as authoritative backticked references.

Changes

Key Concepts ranking rework. Rank symbols by symbol-graph signals instead of
file rank: cross-file caller count (how many other files depend on it),
symbol-level PageRank, and the export marker. Prefer domain-noun kinds (class,
interface, enum, struct, protocol, ...) over functions and methods; drop dunders,
constructors, and trivial accessors; exclude test files; and spread the page
across clusters and files with per-file and per-cluster caps so no single corner
owns it. Candidates are drawn from the full symbol graph rather than the
parsed-files list, so the page stays correct on an incremental update where only
changed files are re-parsed. The chosen concepts' real dependency edges are
passed into the template, so "How they connect" states links that exist.

Grounding post-check. A reusable helper collects the paths and symbols
present in each onboarding page's context, then strips the backticks off any
backticked path-shaped or symbol-shaped token absent from that payload (demoted
to plain text, never deleting the sentence) and reports what it removed. It runs
on fresh and reused content, so a cached page with a stale fabrication is cleaned
on the next docs update. Conservative by design: only unambiguous shapes are
checked, so lowercase enum values like full/none are left alone.

Self-heal for existing users. A new ONBOARDING_GENERATION_VERSION is folded
into each onboarding page's cross-run reuse hash through a source_salt parameter
(kept out of the LLM prompt itself), so a builder or template change forces a
one-time regeneration of the collection for existing docs-enabled users.

Verification

  • 640 generation unit tests pass, including a new suite covering symbol-level
    ranking, noun preference, cluster spread, grounded relations, test-file
    exclusion, the full-graph path on empty parsed-files, the grounding checker
    (known-good passes, fabrication caught, reused-page fabrication caught,
    lowercase words untouched), and source-hash self-heal.
  • Regenerated all onboarding pages against this repo with the real provider. Key
    Concepts now surfaces GraphBuilder, DeadCodeAnalyzer, FileTraverser,
    InMemoryVectorStore, FullTextSearch, CrossRepoEnricher — six domain-noun
    classes across three architectural layers, with a "How they connect" that
    matches real edges. The grounding check fired (dropped a fabricated *.tsx
    glob and out-of-payload symbols). Getting Started, Codebase Map, and Active
    Landscape still read cleanly; the old wrong dotnet/index.py "ingestion entry
    point" anchor is gone from Codebase Map.

…tations

Key Concepts chose its "concepts" by file PageRank, so every public symbol in a
high-ranked file inherited that file's rank. On this repo that surfaced five
methods of one registry class (__init__, get, from_extension, import_support_map)
from a single leaf cluster as the whole codebase's core concepts, and leaked
pytest fixtures out of the candidate list into the prose.

Rank symbols directly instead: cross-file caller count, symbol-level PageRank,
and the export marker. Prefer domain-noun kinds (class, interface, enum, struct,
...) over functions and methods, drop dunders, constructors, and trivial
accessors, exclude test files, and spread the page across clusters and files with
per-file and per-cluster caps so no single corner owns it. Candidates are drawn
from the full symbol graph rather than the parsed-files list, so the page stays
correct on an incremental update where only changed files are re-parsed. The
chosen concepts' real dependency edges are passed to the template, so the "How
they connect" section states links that exist instead of inventing them.

Add a reusable grounding post-check that strips ungrounded backticked path and
symbol citations from onboarding output (demoted to plain text, reported for
logging). It runs on fresh and reused content, so a cached page carrying a stale
fabrication is cleaned on the next docs update.

Add ONBOARDING_GENERATION_VERSION, folded into each onboarding page's cross-run
reuse hash through a new source_salt parameter, so a builder or template change
forces a one-time regeneration of the collection for existing docs-enabled users.
@repowise-bot

repowise-bot Bot commented Jul 12, 2026

Copy link
Copy Markdown

✅ Health: 7.6 (unchanged)

📋 At a glance
1 file changed health · 3 hotspots touched · 7 new findings introduced · 5 co-change pairs left out · 1 dead-code finding. Scoped to packages.

🚨 Change risk: high (riskier than 77% of this repo's commits · raw 9.5/10)
This change's risk is driven by:

  • more lines added than baseline
  • more scattered than baseline
File Score Δ Why
.../subkinds/key_concepts.py 7.9 → 7.5 ▼ -0.4 🔻 introduced complex method, error handling, primitive obsession · ✅ resolved dry violation

💡 .../subkinds/key_concepts.py: Reduce cyclomatic complexity. Decompose the function along its conditional axes; if it dispatches on a type tag, replace the if/elif ladder with polymorphism or a lookup table.

🔎 More signals (3)

🔥 Hotspots touched (3)

  • .../page_generator/pertype.py — 4 commits/90d, 1 dependents · primary owner: Raghav Chamadiya (91%)
  • .../subkinds/key_concepts.py — 2 commits/90d, 1 dependents · primary owner: Raghav Chamadiya (100%)
  • .../page_generator/core.py — 10 commits/90d, 4 dependents · primary owner: Raghav Chamadiya (83%)

🔗 Hidden coupling (2 files)

  • .../page_generator/core.py co-changes with these files (not in this PR):
    • .../pipeline/orchestrator.py (4× — 🟢 routine)
    • .../generation/models.py (4× — 🟢 routine)
    • .../page_generator/orchestrate.py (4× — 🟢 routine)
    • .../phases/generation.py (3× — 🟢 routine)
  • .../page_generator/pertype.py co-changes with .../generation/models.py (3× — 🟢 routine) — not in this PR.

💀 Dead code (1 finding)

  • 💀 .../subkinds/key_concepts.py _build (confidence 0.65)

📊 Full report · ⭐ Star Repowise · 📥 Install bot · Last updated 2026-07-12 13:23 UTC
Silence on a single PR with [skip repowise] in the title · Per-repo toggle on repowise.dev/settings?tab=bot

@RaghavChamadiya RaghavChamadiya merged commit 38f9961 into main Jul 12, 2026
7 checks passed
@RaghavChamadiya RaghavChamadiya deleted the fix/onboarding-key-concepts branch July 12, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants