Skip to content

Gate the pull channel on match strength; rule-built crux for keyless builds - #65

Open
anirudhkumar-nanonets wants to merge 2 commits into
mainfrom
fix/weak-match-abstain
Open

Gate the pull channel on match strength; rule-built crux for keyless builds#65
anirudhkumar-nanonets wants to merge 2 commits into
mainfrom
fix/weak-match-abstain

Conversation

@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator

Two changes to what graft ask returns.

4ff0873 — gate the pull channel on match strength

isWeakMatch() in src/ask/ask.ts suppresses the source pack when a lexical
result is below both floors (coverageStrong < STRONG_FLOOR, coverage < HIGH_FLOOR). A weak pack now returns 3 pointers and no inlined source instead
of a full pack with a savings footer. --full bypasses the gate.

abdb043 — rule-built crux for keyless builds

ruleCrux() builds a <=8-line crux deterministically, with no LLM and no API
key: signature plus the first meaningful lines for a function, a member
signature list for a class/interface/struct/trait/enum. inlineSource() falls
back to it before sliceSpan. Measured on one long function: 2848 -> 1071
chars (-62%). Adds --crux to build the LLM crux layer without concept nodes,
and resolveBuildLayers() in src/cli-meta.ts so layer selection is testable.

Tests: 13 new (7 in test/ask.test.ts, 6 in test/cli-meta.test.ts).


On the benchmark numbers in README.md

This branch does not change README.md. The SWE-bench table on main (commit
00c9cc4) covers 20 instances, and they were not all measured on this code:

  • 11 instances ran on this branch's build (graft-fix12-abdb043.tgz, v0.9.0)
  • 9 instances ran 2026-08-04 on npm 0.8.2, two days before these commits
    existed, under the older harness that still had web access enabled

Merging this makes the 11 the current behaviour. The 9 would need re-running to
put the whole table on one version.

graft ask returned its full top-N with source inlined at any score, so a
0.05 match rendered exactly like a 0.9 one. The push channel has enforced
STRONG_FLOOR/HIGH_FLOOR for a while; pull had no gate. Below both floors,
return 3 pointers without source plus the productive next tool. --full
overrules it.
Without a key there was no crux, so ask fell back to the whole span capped
at 80 lines — a keyless build inlined up to 10x more per hit than a paid
one. ruleCrux fills that gap from structure: functions get their opening,
containers get their member signatures (span containment). -62% on a long
function in a fixture.

--crux runs the per-symbol meaning pass without the prose concept map,
roughly half the LLM calls of --deep. Layer resolution moved out of the
action handler into resolveBuildLayers so it is testable.
christian-jorge pushed a commit to christian-jorge/Graft that referenced this pull request Aug 14, 2026
Adopt upstream PR NanoNets#65 (still open on NanoNets/Graft), cherry-picked with its
original authorship: the weak-match gate on `ask`'s pull channel, a rule-built
crux for keyless builds, and `--crux` to buy the per-symbol layer without the
prose concept map.

Nine conflict hunks resolved across five files. One of them was semantic rather
than textual and is the reason this could not be taken as-is: upstream gates the
LLM layers on `!!resolved.apiKey`, while this tree reaches a model through a
signed-in Claude Code CLI subscription that has no key at all. Taken unchanged it
would have degraded every subscription `--deep` to the structural build and told
the user to set GRAFT_API_KEY — advice for a provider they are not on. The gate is
`credentialProblem()` here and `resolveBuildLayers` takes `hasCredentials`.

`--crux` matters more to this fork than to upstream: the FORK.md changes made
`--deep` cost more per repo, and this is the flag that buys the half that pays off.
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