Skip to content

fix(explore): v1.6.1 exact targets, named-file budget, honest completion notes and trim names - #281

Merged
sunerpy merged 10 commits into
mainfrom
sync/v1.6.1-alignment-4
Oct 1, 2026
Merged

sunerpy merged 10 commits into
mainfrom
sync/v1.6.1-alignment-4

Conversation

@sunerpy

@sunerpy sunerpy commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Summary

Sixth PR of the v1.6.1 alignment, following #279: the codegraph_explore retrieval rows. Dispositions and landing state are tracked in docs/upstream-sync/V1_6_1_AUDIT_2026-09-30.md; tracked parity in UPSTREAM.md stays v1.6.0 until the release gate.

What a trimmed file says

  • Named gaps (#1711, with #2057's fix): a gap a trim leaves names the indexed symbols starting inside it as name (file:line), paid only from what cluster selection left so the names never push source out; the file header prefers the members the trim cut.
  • Empty results (#1904): an empty explore says matching is lexical, lists the checked words that matched nothing and those that scored out, and suggests up to 12 indexed names sharing a word. The initialize instructions gain the matching bullet (the MCP fixture is updated).
  • Honest completion notes (#2077): each section records the members it set out to deliver and did not, measured from the ranges it sent. On the large tiers "Complete source for N files" is claimed only when nothing was trimmed; otherwise the note keeps the verbatim, already-Read guarantee, names the trimmed files and up to four elided symbols the query asked for (a method as Owner.member), and steers to another explore. The "Reserve Read for a single specific line range" escape is gone, the small tiers' trim note fires for every cut, the truncation note drops "complete" when a trimmed section survives, and counts read "1 file" / "these files".

What a file renders

  • Cluster budget order (#2062): a cluster's incidental members use only what is left once every lower-ranked cluster's named members are paid, so a named function packed with helpers no longer starves a named function alone.
  • Exact targets (#2063): compiler.py:776, :12-40, #L88-L120 and prose ranges (lines 900-1003, L900-L1003, lines 900 to 1003) are kept as line anchors on the nearest single-file path instead of dropped. A qualified name with at most three non-test definitions, the innermost callable enclosing a single-line anchor, and an anchored span are exact targets: they lead the blast radius, rank their files with the named-file tier, outrank every other member, render whole when they fit and otherwise from their own head plus the anchored line and their calls into the query's other named symbols.
  • Spare budget for named files (#2068): a file the query names (by path, an exact target, or a symbol it defines) that the per-file ceiling clipped is rendered again into the budget nothing else spent; every other file keeps exactly the section it was given.
  • Windowed heads (CG-38, CORRECT): a windowed cluster's head now gets the whole room unless that leaves a focus uncovered, as upstream's windowToCeiling has it; the CG-38 port held 40% back whenever a focus existed, so a long named body came back at three fifths of its room.

What a path pins

  • Same-basename pins (#2071): a basename several directories share (editorOptions.ts) pins only the matches defining a code-shaped symbol the query names, and the summary names the files set aside; a basename shared by more than three files resolves the same way when the symbols narrow it to three or fewer.

Not ported: the per-symbol focused view and the Flow spine (F10, deferred with the UI family), upstream's proportional allocator and MAX_SHARE valve (this port funds files in order), the lost-pointer and cut notes (the port reserves its epilogue up front), and #2057's prose-corroboration and dispatch-note halves (neither mechanism exists here).

Golden impact

No extraction or resolution code changes, so the extraction goldens cannot drift; the equivalence oracle passes. One MCP structural fixture changes: initialize gains the #1904 instructions bullet.

Verification

  • Full workspace test suite: 3,875 passed, 0 failed; clippy -D warnings, cargo fmt --check, scripts/guardrail.sh, docs-check and oxfmt --check clean; the pre-push gate re-runs them on the pushed head.
  • Every new behavior test was run against the previous sources first and fails there, with negative controls for the parts that hold either way: line anchors and prose ranges (query_paths), exact targets end to end (explore_exact_targets: qualified body, blast-radius lead, file:line, lines A-B, oversize windowing), the exact hold-back between clusters, the named-file top-up (explore_named_file_budget, red with the second pass disabled), same-basename narrowing (query_paths and explore_same_basename_pin, red without the symbol lookup), the completeness notes (explore_completeness_note, red with trimming ignored), and the CG-38 head rule (red under the 60/40 split).
  • Fixtures sized to this port: upstream's django and express fixtures were scaled to the 5.7K per-file ceiling and 13K budget this port numbers and frames inside, since at upstream's sizes the bodies cannot fit whole here under any allocator.
  • Two existing assertions were changed deliberately: the drift test expected "Complete source for 1 files" and now uses the singular wording; the accounting fixture expected no pointer line to fit beside a five-file tail, and one now fits because the shorter completeness note shrank the reserve, so it asserts that the listed lines and the tail count add up to the five excluded files.
  • explore_pinned_cap_named (upstream #2064) is a guard: it holds without #2062 here, because the port's pinned head cluster has no edge-line members to out-rank the named one.

BEGIN_COMMIT_OVERRIDE
fix(explore): name symbols elided by a file trim
fix(explore): explain empty results with bounded lexical diagnostics
fix(explore): pay named members before incidental ones across clusters
fix(explore): return a qualified or line-anchored method's body
fix(explore): let a named file use the budget the response left unspent
fix(explore): pin only the same-named file that defines the named symbols
fix(explore): claim complete source only for sections that are complete
fix(explore): give a windowed cluster's head the whole room it can use
END_COMMIT_OVERRIDE

🤖 Generated with Claude Code

CodeGraph Test added 10 commits October 1, 2026 11:27
When explore trimmed a rendered file, holes printed as bare
'... (gap) ...' and the header's '+N more' hid the dropped names, while
the trim note asked for exact names it never gave. A gap now names the
indexed symbols starting inside it as name (file:line), from the full
file index, paid only from what cluster selection left so the names
never push source out; the header prefers the cluster members the trim
cut, and the trim note points at those names (upstream #1711, #2057).
An empty explore returned no explanation or retry guidance. It now
says explore matches names and indexed code words lexically, lists the
checked words that matched nothing and those that matched but scored
out, and suggests up to 12 indexed names sharing a word, from two
bounded FTS queries and the query-time name segments. The initialize
instructions gain the matching bullet (upstream #1904).
Clusters of equal importance rank by density, and density counts every
member, so a named function packed with incidental helpers outranked a
cluster holding a named function alone; taken first, it spent the
file's room on the helpers and the lone named function rendered
nothing. A cluster's incidental members now use only what is left once
every lower-ranked cluster's named members are paid for, and in a
cluster holding a named member they never take it past its room, so a
head window no longer cuts a named body's tail (upstream #2062).
`SQLCompiler.as_sql pre_sql_setup get_select` returned the two
unqualified methods and lost `as_sql` to a head window over its
neighbours, and follow-ups such as `compiler.py:776` or
`compiler.py lines 900-1003` pinned the file but dropped the line
numbers (upstream #2063).

- Query paths keep `:776`, `:12-40` and `#L88-L120` suffixes as line
  anchors, and bind prose ranges (`lines 900-1003`, `L900-L1003`,
  `lines 900 to 1003`) to the nearest path that resolved to one file.
- Exact targets: a qualified name with at most three non-test
  definitions (its callables), the innermost callable enclosing a
  single-line anchor, or an anchored span. They lead the blast radius,
  rank their files with the named-file tier, and outrank every other
  member of their clusters.
- An exact body renders whole when it fits, joined by the members that
  still fit beside it; one too big for its room is windowed from its own
  head plus its anchored line and its calls into the query's other named
  symbols. An exact cluster holds back what lower-ranked exact targets
  in the same file still owe.
A file is held to a per-file ceiling of 1.5x the tier's per-file
budget, so a question naming five functions in one file came back with
one body whole in a response half its budget (upstream #2068, the
express `res.send` case).

A file the query names (by path, by an exact target, or by a symbol it
defines) that its ceiling clipped is now rendered again, after every
file has had its turn, into the budget nothing else spent. Every other
file keeps exactly the section it was given, the pointer list keeps the
room it would have had, and where nothing is spare the named file
renders as before. Upstream's merged-spine half has no counterpart:
this port has no flow spine.
…bols

A bare basename several directories share (`editorOptions.ts`,
`worker.rs`, `compiler.py`) pinned every match, so the file holding the
functions a query named shared its pinned room with files defining none
of them (upstream #2071).

Path extraction now takes an injected lookup of the files defining a
symbol (the module stays index-free, as with the on-disk probe). When a
span matches several files, the matches defining a symbol the query
names in a code shape (camelCase, PascalCase, snake_case, `$` or
qualified) are pinned and the rest set aside, and the summary names
them. When no match defines one, or every match does, the span resolves
as before. The same test resolves a basename shared past the ambiguity
budget when it narrows into it, and a line anchor binds once the span
narrows to one file.
On the tiers with a completeness signal (500+ indexed files) every
response ended with "Complete source for N files is included above",
whatever the render had cut, and told the agent to "Reserve Read for a
single specific line range" (upstream #2077).

Each section now records the members it set out to deliver and did not,
measured from the ranges it actually sent, so a dropped or windowed
cluster and a drift-omitted file all count. A trimmed response keeps the
verbatim, already-Read guarantee, names the trimmed files and up to four
elided symbols the query asked for (a method as `Owner.member`), and
steers to another codegraph_explore; it never offers Read. The note is
the most specific that fits: the reserve holds the least specific one,
so naming files and symbols is paid only from what the sections and the
pointer list left. The small tiers' trimmed note also fires for these
cuts, the truncation note drops "complete" when a trimmed section
survives the cut, and the count reads "1 file" and "these files".
A cluster too big for its room was windowed with 60% of the room on its
head whenever it held a protected focus, and the other 40% split among
windows on every focus line, even one the head already showed. A named
function's own definition line is the commonest focus, so a long named
body came back at three fifths of the room it was given.

As upstream's windowToCeiling (CG-38) has it, the whole room now goes to
the head first, and 40% is held back only when that head leaves a focus
uncovered; then only the focuses the smaller head misses take a share.
Every focus still lands in a window. Recorded as a CORRECT row of the
v1.6.1 audit: the CG-38 port simplified this rule.
A file named by path contributes its first 300 symbols to the gather, so a
named symbol past the cap sits in a cluster below a head of pinned filler.
The guard asserts that the named symbols past the cap still render whole,
as they do without the path (upstream #2064, guarding #2062).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3dce6daaf2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

| #1294 | `d3671fa` | `install.sh` under MINGW/MSYS/CYGWIN points at the PowerShell installer | PORT | landed in #279 |
| #1711 | `d983f73` | a file trim names the symbols it elided, in gap markers and the file header | PORT | landed in #281 |
| PR #2057 | `66aebd1` | three explore regressions: gap names never push source out; interface members are no prose corroboration; dispatch notes need the supertype to declare the member | PORT (gap names), N/A (the other two) | gap names landed with #1711 in #281; the port has neither the prose-corroboration seeding nor dispatch-site notes |
| #1904 | `9ad6ee9` | an empty explore explains lexical matching, lists unmatched words and suggests indexed names | PORT | landed in #281, with the query-time name segments standing in for `name_segment_vocab` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the dated audit instead of rewriting its state

This dated audit previously recorded the explore family as planned, but the change replaces that point-in-time row with multiple present-day landed in #281 rows and reformats the earlier evidence. Keep the original table intact and append a dated landing note rather than rewriting the historical observation.

AGENTS.md reference: docs/AGENTS.md:L19-L21

Useful? React with 👍 / 👎.

Comment on lines +5091 to +5093
let token = SEEDER_FILE_EXT.replace(raw, "");
let token = token.trim();
if token.len() < 3 || !SEEDER_SYMBOL_TOKEN.is_match(token) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize wrappers before detecting exact targets

When a qualified target is written with common prose formatting, such as `SQLCompiler.as_sql` or SQLCompiler.as_sql., trim() leaves the wrappers or trailing punctuation and the anchored SEEDER_SYMBOL_TOKEN regex rejects it. The symbol therefore never becomes an exact target, so in projects with same-named overrides the wrong definition can still lead or the requested body can be trimmed; strip quote/backtick and sentence punctuation before applying the regex.

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.65643% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/codegraph-store/src/queries.rs 86.66% 4 Missing ⚠️
crates/codegraph-mcp/src/query_paths.rs 99.38% 3 Missing ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #281      +/-   ##
==========================================
+ Coverage   95.20%   95.27%   +0.06%     
==========================================
  Files         157      157              
  Lines       95033    97031    +1998     
==========================================
+ Hits        90476    92445    +1969     
- Misses       4557     4586      +29     
Files with missing lines Coverage Δ
crates/codegraph-mcp/src/engine.rs 97.67% <ø> (+0.13%) ⬆️
crates/codegraph-mcp/src/instructions.rs 100.00% <ø> (ø)
crates/codegraph-mcp/src/query_paths.rs 98.29% <99.38%> (+1.76%) ⬆️
crates/codegraph-store/src/queries.rs 98.38% <86.66%> (-0.13%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sunerpy
sunerpy merged commit 678927c into main Oct 1, 2026
9 checks passed
@sunerpy
sunerpy deleted the sync/v1.6.1-alignment-4 branch October 1, 2026 07:38
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.

1 participant