Repository navigation
Agent-asserted call edges: list the sites an answer stops at, link them, walk them as [asserted] (#1892) - #1895
Draft
swapnilpaliwal-sd wants to merge 3 commits into
Draft
swapnilpaliwal-sd wants to merge 3 commits into
swapnilpaliwal-sd wants to merge 3 commits into
Conversation
…m, walk them as [asserted] (#1892) An answer that stops at a call the graph could not resolve now lists the site (file:line:col, the call as written, the engine's reason). axiomcode link <file:line[:col]> <target> records where it lands in axiomcode-links.tsv; the graph validates each link (a call there consistent with the target, the target declared, the line text unchanged) and applies it as a call edge of tier asserted, never resolved. Links only add edges, survive rebuilds, follow their line by its text within the callable, and drop (reported) when the line is edited. A link whose target declares a return type also resolves calls chained on the result and calls on a local assigned from it. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…'s result (#1892) A site is file:line:col (the callee's name); two calls of one name on a line are never chosen between. link --not rejects a by-name or one-of-a-set lead at a site (never an edge the engine resolved); the walks skip it, nothing is deleted. AXIOMCODE_LINKS_PREFER=1 skips a linked site's own guesses. Unknown sites carry ranked candidates from what the graph knows (the engine's set, values passed in, a computed name's prefix, values registered in the file, the name called). A link whose target has a declared, JSDoc or inferred return type resolves the calls chained on its result, on a local assigned from it, awaited, or on each element it yields. Front-door answers list confirmed places before leads. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…cts a lead; candidates ranked by the name called (#1892) A decorator factory's call and the decoration applying its result are one call at one column. Stress harness scenarios S1-S13 pass in all five languages where the subject can exhibit them. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Contributor
Author
|
Validation on the pushed head:
The README row for the new verb is not in this PR: the README already contains a term the repository's scrub hook blocks, so any commit touching it is refused until that is cleaned separately. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1892 (draft).
Symptom
An answer that reaches a call the graph could not resolve (a callable read with getattr or a computed key, a handler kept in a table, a reflective invoke, a delegate or
dynamicvalue) says only "N unresolved call(s) inside — a lower bound". The agent can often read the code and see where the call lands, but nothing lets it tell the graph, so every later impact / path / tests answer stops at the same site.Mechanism
--json:unknown_sites, up to 30; text:--unknown; the front door and MCP: a shortto resolve:block). Each site isfile:line:col(the column of the callee's name), the call as written, the engine's own reason, and up to five ranked candidate targets from what the graph already knows (the engine's own target set, values the callers pass into the called parameter, a computed name's constant prefix, callables handed over as values in the same file, declarations of the name called). A library call that runs a value (Method.invoke,MethodInfo.Invoke,Function.apply) and a call through a function-typed holder are listed too.axiomcode link <file:line[:col]> <target>(CLI and an MCPlinktool) records the assertion inaxiomcode-links.tsvat the repository root — committable on purpose:.axiomcode/is derived and routinely deleted, a link is knowledge someone read the code to get. Each row carries the line's text hash, the column, the callee as written, the enclosing callable and the target as the graph names it.axiomcode linklists every link with its status;link <site> -removes;link <site> not:<target>(or--not) rejects a lead.asserted(certaintyasserted, neverresolved), at the end of every index (so a rebuild keeps them, O(links)), onlinkitself against the existing graph, and on the next query after the links file changes. Links only add edges; nothing the engine wrote is removed.@returns, or everyreturnconstructing one type / returningthis), calls chained on the result, on a local assigned from it (once), awaited, or on each element of a returned collection resolve to that type's members, also asasserted, and drop with the link.AXIOMCODE_LINKS_PREFER=1additionally skips a linked site's own guesses.linkpatches the derived facts the walks read (path edges, impact calls / certainty table) and moves their stamps, instead of re-exporting.Numbers
Stress (scenarios per language on one real repository each plus the synthetic cases; link N sites, edits above/on the line, target renamed/moved, file deleted, query during a rebuild, fans and duplicates, wrong links, checkout and back, a corrupt links file, two calls of one name on a line, typing what follows a link, rejections): every scenario passes in every language where the repository can exhibit it; the misses are data limits (a subject with 4 unknown sites cannot take 20 links).
Latency on the largest Python subject (11.7k call edges):
link0.08 s; the next impact 0.85 s with the patched facts vs 2.31 s re-exporting; the next path 0.25 s. A rebuild applies 200 links in 48–161 ms.Simulated perfect asserter on the 16-repo Python corpus (a runtime trace says which unknown site calls which project function; links only those, validated by the same rules): 2,828 links.
Held-out alone: path found 0.628 → 0.745, reach recall 0.517 → 0.569. Of the runtime edges the graph misses, 26% sit in a caller with no unknown site (no link can reach them) and another 26% in a caller with several value calls the trace cannot tell apart. The graph's candidates named the true target for 45% of linked sites (top-1 25%). Rejections (22k, simulated) recover precision but cost a little recall: a rejected lead sometimes covered a true caller the graph misses elsewhere. Prefer mode moved almost nothing.
Validation
tests/cases/<lang>/asserted-linksandasserted-links-derivein all five languages (fail on the base: the verb does not exist), with controls: a target that does not exist, a line without a call, a call naming another declaration, a member call on an untyped receiver, the linked line edited, an unlinked sibling site, a resolved edge that cannot be rejected.tests/run.pygained"edit"(a file edited before a check, restored after the case) and"env". Full suite,tests/front_door.py,tests/surfaces.py,tests/mcp.py: see the comment below.Not done
instanceof T t,match/case,is T t), records' accessors, tuples: not typed at apply time (needs the engine's solve); a link still applies, nothing is derived there.by key,decorator by name,protocolandlibrary callbackleads: refused for now (only by-name and set members).AXIOMCODE_SQL) does not read rejections.