Part of #3772.
Why
During #3756–#3767, deciding what to fix next meant writing throwaway scripts and reading samples by eye. That was the largest token cost of the round. This tool productizes that step.
What
python tests/tools/callgraph_triage.py <lang> [--samples 3] [--json out.json] compares the engine against the cached reference graph and assigns every miss and every wrong link to a bucket.
Recall, reference edge not linked confidently:
not_extracted: the callee name isn't in calls_out_to. Sub-bucketed where the source shows why:
- inside a string or template literal;
- after a nested function (truncated span);
- same name as the caller;
- the caller isn't a unit at all.
caller_unmapped: the reference's caller has no engine function.
ambiguous: named but only an ambiguous row, split by step (receiver, nearest, tie, unseen).
external_resolution: the name resolved to none.
Precision, engine link the reference disagrees with:
Output
A markdown table ranked by count, meaning recall at stake. Each bucket gets 3 source lines, so a reader sees the pattern without opening files. The JSON form is what the callgraph-miss-sweep skill and the triage-scout agent consume.
Done when
- zod (TypeScript) and language-crucible Python both produce a table.
- On zod, the bucket counts reconcile with the gate's totals: 2,661 reference edges, of which 1,519 are linked confidently.
Part of #3772.
Why
During #3756–#3767, deciding what to fix next meant writing throwaway scripts and reading samples by eye. That was the largest token cost of the round. This tool productizes that step.
What
python tests/tools/callgraph_triage.py <lang> [--samples 3] [--json out.json]compares the engine against the cached reference graph and assigns every miss and every wrong link to a bucket.Recall, reference edge not linked confidently:
not_extracted: the callee name isn't incalls_out_to. Sub-bucketed where the source shows why:caller_unmapped: the reference's caller has no engine function.ambiguous: named but only an ambiguous row, split by step (receiver,nearest,tie,unseen).external_resolution: the name resolved tonone.Precision, engine link the reference disagrees with:
wrong: the reference targets a different same-named function.external: the reference resolves only outside the repo (built-in shadowing, Call resolver: an untyped receiver's built-in method call (str.trim(),map.get()) links confidently to a same-named repo method viafile/import#3756).bodyless_target: the target has no body (Call resolver (TypeScript): confident links land on bodyless signatures (interface / abstract / type members) instead of the code that runs #3757's pattern).unconfirmed.Output
A markdown table ranked by count, meaning recall at stake. Each bucket gets 3 source lines, so a reader sees the pattern without opening files. The JSON form is what the
callgraph-miss-sweepskill and the triage-scout agent consume.Done when