Skip to content

feat(enrichment): add caller-impact analyzer for removed exports with live callers - #3656

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
e11734937-beep:feat/enrichment-caller-impact-1509
Jul 6, 2026
Merged

feat(enrichment): add caller-impact analyzer for removed exports with live callers#3656
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
e11734937-beep:feat/enrichment-caller-impact-1509

Conversation

@e11734937-beep

Copy link
Copy Markdown
Contributor

Summary

Adds the caller-impact analyzer to the review-enrichment service (REES), resolving #1509. A no-checkout headless reviewer sees only the diff, so it is blind to the cross-file hazard where a PR removes (or renames away) an exported symbol that other, unchanged files in the repo still import — a hidden compile/runtime break. This analyzer surfaces exactly that, and only that.

How it works, entirely within review-enrichment/:

  • Parses exported top-level declarations dropped on removed (-) diff lines of changed non-entrypoint TS/JS source files.
  • Resolves the symbol's callers on the repo's default branch via the GitHub Code Search API, then keeps only files the PR did not touch.
  • Confirms each candidate genuinely imports the symbol by fetching it at headSha and matching a real named / default / namespace import from an internal module path — never a bare-text hit in a comment, a property access, or a same-named import from a third-party package.
  • A symbol re-added anywhere in the PR (an in-place edit, move, or re-export) is never flagged.

Reports the removed symbol, its old-file line, and the unchanged caller file paths only — never source.

Distinct value (no overlap with shipped analyzers)

Fail-closed error handling

A finding requires positive, verified evidence of a surviving caller. Every error path degrades to no finding, never a fabricated one:

  • missing token / missing headSha / invalid repo slug → []
  • no removed exports → []
  • failed / rate-limited / incomplete_results / malformed Code Search response → that symbol yields no finding (an explicit unknown state, distinguished from a successful "no callers")
  • unreadable candidate file → not counted as a caller
  • aborted signal → []

An error in the search or the file fetch is never surfaced as a caller.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • Focused; does not mix unrelated backend, UI, MCP, docs, dependency, or deploy changes. The only main-repo edit is one canonical analyzer-name entry; the UI/.env.example/metadata files are regenerated.
  • Follows CONTRIBUTING.md; does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • Linked issue: Closes feat(enrichment): Cross-file caller-impact / dead-symbol analyzer #1509.

Validation

  • npm run typecheck — exit 0
  • npm run rees:test — build + sourcemap validation + metadata:check (zero drift) + node:test: 1181 pass, 0 fail (23 new caller-impact units)
  • npm run ui:typecheck — exit 0
  • npm run ui:lint0 errors
  • npm run ui:test — 64 pass
  • npm run test:coverage490 files pass, 0 fail; the one touched main-repo file (src/review/enrichment-analyzer-names.ts) is 100% (LF 2 / LH 2, no branches). The analyzer itself lives in review-enrichment/, which Codecov ignores.
  • git diff --check — clean

Safety

  • No secrets, tokens, wallet/hotkey/coldkey details, PATs, private keys, or private rankings exposed. The brief carries only symbol names + public file paths, escaped through the existing safeCodeSpan helper.
  • Additive + inert until enabled per-repo via the engine's analyzer settings, exactly like the existing analyzers — a clean, zero-engine-conflict drop within review-enrichment/.

Notes

  • Bounded and rate-respectful: ≤ 6 removed symbols searched, ≤ 6 Code Search queries, ≤ 12 candidate-file fetches, ≤ 5 caller paths per finding, its own github-code-search-callers endpoint category (own circuit-breaker budget).
  • Conservative by construction: a caller reachable only through a barrel re-export, a namespace member access, or a bare package path is not matched — a false negative only suppresses a finding, which is always fail-safe.
  • Branch is off current main; no base conflict.

… live callers

A no-checkout headless reviewer sees only the diff, so it cannot tell that a
PR removes (or renames away) an exported symbol that other, unchanged files in
the same repo still import - a hidden cross-file compile/runtime break. This
REES analyzer fills that gap.

It parses exported top-level declarations dropped on removed (-) diff lines of
changed non-entrypoint source files, resolves the symbol's callers on the
default branch via repo-scoped GitHub Code Search, keeps only files the PR did
not touch, and confirms each candidate genuinely imports the symbol from an
internal module path (never a comment, a property access, or a same-named
import from a third-party package) by fetching it at headSha. A symbol re-added
anywhere in the PR is never flagged.

Distinct from the two shipped export analyzers by design: api-break (JSONbored#1510)
handles removed exports from public entrypoint barrels (downstream break, no
network); unused-export (JSONbored#2025) handles added exports that are dead-on-arrival.
This is the inverse of the latter - a removed export that still has callers -
and owns the non-entrypoint internal files api-break leaves out.

Fail-closed: a finding requires positive, verified evidence of a surviving
caller. A missing token/headSha, invalid slug, failed/rate-limited/incomplete
Code Search, malformed response, unreadable candidate file, or aborted signal
all degrade to no finding rather than a fabricated one - an error in the search
or fetch is never surfaced as a caller.

Wires the CallerImpactFinding type, the brief.ts registry descriptor, and a
public-safe render block; adds the canonical analyzer name and regenerates the
analyzer metadata. Bounded symbol/search/file-fetch/caller caps. 23 node:test
units cover every branch, including explicit fetch-error / no-token / malformed
/ incomplete / abort resolving to an empty result.

Closes JSONbored#1509
@e11734937-beep
e11734937-beep requested a review from JSONbored as a code owner July 6, 2026 00:02
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. label Jul 6, 2026
@loopover-orb

loopover-orb Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-06 00:07:54 UTC

10 files · 1 AI reviewer · no blockers · readiness 80/100 · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
This PR adds a caller-impact analyzer that flags exported symbols removed from non-entrypoint files while unchanged files still import them, resolved via GitHub Code Search plus a headSha fetch to confirm each candidate's import binds the symbol from an internal path. The design is fail-closed throughout (null vs [] distinguishes an unusable search from a genuine zero-caller result, unreadable/oversized files never count as confirmed callers), bounded by symbol/search/fetch/finding caps, and the old-file line accounting and re-added-symbol exclusion are correctly traced through the tests. Wiring into registry.ts, analyzer-metadata.json, rees-analyzers.ts, types.ts, render.ts, and enrichment-analyzer-names.ts is complete and consistent with the sibling api-break/unused-export analyzers, and the PR closes #1509 as required.

Nits — 5 non-blocking
  • review-enrichment/src/analyzers/caller-impact.ts: the search query embeds `symbol` in a quoted GitHub Code Search string without escaping embedded quotes — confirm exportedNames (reused from api-break.ts) only ever yields valid identifier characters.
  • review-enrichment/src/analyzers/caller-impact.ts:169 nests to depth 5 per the size-smell scan; consider extracting the per-candidate confirm loop into a small helper for readability.
  • The five numeric limits (MAX_SYMBOLS, MAX_SEARCHES, MAX_FILE_FETCHES, MAX_CALLERS_PER_FINDING, MAX_FINDINGS) are duplicated as literals in both caller-impact.ts and the registry.ts/analyzer-metadata.json/rees-analyzers.ts docs blocks — a drift risk if one is tuned later without updating the others, though this mirrors the existing pattern for sibling analyzers.
  • SEARCH_PER_PAGE caps Code Search to the first 50 results per symbol with no total_count check — acceptable given the fail-safe design, but worth a one-line comment noting results beyond page 1 are silently not considered.
  • Consider deriving the five limit constants in registry.ts/rees-analyzers.ts/analyzer-metadata.json docs from the analyzer module's exports instead of re-declaring literals, to remove the multi-file drift risk noted above.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #1509
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 45 registered-repo PR(s), 22 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor e11734937-beep; Gittensor profile; 45 PR(s), 0 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: e11734937-beep
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 45 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@5c16be3). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3656   +/-   ##
=======================================
  Coverage        ?   93.28%           
=======================================
  Files           ?      314           
  Lines           ?    32054           
  Branches        ?    11747           
=======================================
  Hits            ?    29903           
  Misses          ?     1517           
  Partials        ?      634           
Files with missing lines Coverage Δ
src/review/enrichment-analyzer-names.ts 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gittensory approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 8ab8fe3 into JSONbored:main Jul 6, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(enrichment): Cross-file caller-impact / dead-symbol analyzer

1 participant