fix(wasm): align sort_targets_by_confidence with native engine#1486
Conversation
… diff Adds snapshot-pre-bash.sh (PreToolUse Bash) + track-bash-writes.sh (PostToolUse Bash): the pre-hook captures git status --porcelain to a per-worktree temp file before each Bash call; the post-hook diffs the before/after state and appends newly modified or created files to .claude/session-edits.log. This closes the gap where files written by sed -i, printf redirects, tee, heredocs, or build tools (Cargo.lock, lockfiles) were never recorded, causing guard-git.sh to emit false-positive BLOCKED errors. Closes #1457
- clojure.rs: annotate lifetime-anchor assignment to silence false-positive - cfg.rs: remove never-called start_line_of method - complexity.rs: remove never-constructed NotHandled variant; convert irrefutable if-let patterns to plain let destructures - dataflow.rs: remove never-read callee fields from CallReturn/Destructured - incremental.rs: remove never-read lang field from CacheEntry cargo check and cargo clippy both clean after these changes.
|
Claude finished @carlos-alm's task —— View job PR Review — fix(wasm): align sort_targets_by_confidence with native engine
Root Cause AnalysisProblem Being Solved: The WASM/TS engine's Why This Approach: Mirrors the native engine exactly — both use Risk Assessment: Low. The sort is guarded by Detailed Code AnalysisCore fix —
|
| Commit | Scope | Assessment |
|---|---|---|
85a26df — remove dead code (Rust: cfg, complexity, dataflow, incremental, clojure) |
chore(native) |
Clean clippy/compiler hygiene. The clojure.rs #[allow(unused_assignments)] annotation is the right tool (lifetime anchor pattern). All changes are non-behavioral. ✅ |
184d221 — extract PtsAliasCtx struct in build_edges.rs |
refactor(native) |
Improves readability of emit_pts_alias_edges. No behavioral change. ✅ |
9a52c7c — snapshot-pre-bash.sh + track-bash-writes.sh hooks |
fix(hooks) |
Fills a real gap (Closes #1457): sed -i and other shell file writes were invisible to guard-git.sh. The two hooks correctly use git status --porcelain before/after with per-worktree temp files. ✅ |
.claude/settings.json — wire the two new hooks |
Companion to above | Correct hook wiring. ✅ |
ef8ea4f — remove unused biome suppression in visitor.test.ts |
chore(tests) |
Removes a // biome-ignore lint comment, not a test assertion. ✅ |
a372b82 — titan-run SKILL.md: add close and grind to --start-from enum |
fix(titan-run) |
Corrects a documentation gap — close and grind are valid values but were missing from the argument hint and the phase list. ✅ |
3892e7d — gitignore napi-generated artifacts |
chore |
Adds index.js, index.d.ts, *.node to .gitignore under crates/codegraph-core/. Correct. ✅ |
Phase 2: Configuration Change Detection
No linting rules relaxed. No test timeouts increased. No TypeScript strict mode flags changed. The settings.json change only adds two new hook entries — it does not remove or relax any existing hook. No concerns.
Phase 3: Test Integrity
tests/unit/visitor.test.ts removes one line — a // biome-ignore lint/... suppression comment over an await import(...) at the module top level. The assertion count is unchanged. No test weakening.
No test was added to cover the sort-order fix specifically. This is a minor gap — a test asserting that duplicate (source_id, target_id) pairs resolve to the highest-confidence confidence value would prevent regression. However, given the fix is a direct port of existing native behavior and the sort is trivially correct, the missing test is acceptable, not blocking.
Phase 4: Code Quality
No issues found. The implementation is idiomatic, clean, and mirrors the native exactly.
Phase 5: Backlog Compliance
- Zero-dep: ✓ — no new runtime dependencies
- Foundation-aligned: ✓ — fixes a local graph-build correctness issue; no cloud calls, no schema changes, no MCP contract changes
- Problem-fit: 4 — correct edges stored in the DB directly improves the accuracy of any downstream query (impact, blast-radius, call-chains) that an AI agent uses to orient itself. A wrong confidence value can cause the wrong edge to win the upsert, silently producing a lower-fidelity graph.
- Breaking: No — stored confidence values may change for the small subset of multi-target calls where duplicate pairs were previously inserted in non-descending order. This is a correctness improvement, not a contract break.
- Tier: 1
Critical Concerns
Minor — scope bundling: This PR packages 6 commits across 4 unrelated concerns (sort fix, dead-code cleanup, bash-write hooks, titan-run docs) into a single PR. Per the project's "One PR = one concern" rule in CLAUDE.md, these should be separate PRs. However, all changes are independently correct and low-risk, so this is a process observation, not a blocker.
Minor — pts fallback path not sorted: The pts alias loop (build-edges.ts:1175-1253) iterates aliasTargets without sorting by confidence before emit. The native engine does sort in emit_pts_alias_edges (build_edges.rs:398). This pre-existing gap is not introduced by this PR and is not blocking.
Final Recommendation
- Rating: ⭐⭐⭐⭐ (4/5)
- Action: APPROVE
- Reasoning: The core fix is correct, minimal, and exactly mirrors the native engine. All supporting changes in the other commits are clean and non-behavioral. The only deductions are the scope-bundling (process) and the missing regression test — neither is blocking. The sort-fix itself closes a real parity gap that could produce different query results depending on which engine built the graph.
Greptile SummaryAligns the WASM/TS edge builder with the native Rust engine by sorting call targets by confidence descending before the dedup loop, so the highest-confidence entry wins when multiple targets share the same
Confidence Score: 5/5Targeted, additive sort; does not mutate shared data structures and only affects output when a call has multiple targets resolving to the same edge key. The change is narrowly scoped — a spread-copy followed by a comparison sort — applied consistently across all three target-resolution paths. The sort comparator is correct (b−a for descending), the original arrays are never mutated, and the dedup logic already relied on first-insertion winning, so inserting a higher-confidence entry first produces the intended result. The previously flagged alias paths are also fixed here, leaving no known parity gaps. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Resolve call targets] --> B{targets.length > 1?}
B -- Yes --> C["Sort targets DESC by computeConfidence\n(NEW — mirrors native sort_targets_by_confidence)"]
B -- No --> D[Use targets as-is]
C --> E[Dedup loop over sorted targets\nFirst occurrence wins]
D --> E
E --> F{targets.length == 0 AND\nptsMap available?}
F -- Yes --> G[Phase 8.3: resolveViaPointsTo loop]
G --> H["Per alias: resolveCallTargets → aliasTargets"]
H --> I{aliasTargets.length > 1?}
I -- Yes --> J["Sort aliasTargets DESC by computeConfidence\n(NEW)"]
I -- No --> K[Use aliasTargets as-is]
J --> L[Dedup loop over sortedAliasTargets]
K --> L
F -- Yes/receiver --> M[Phase 8.3f: receiver pts loop]
M --> N["Per alias: resolveCallTargets → aliasTargets"]
N --> O{aliasTargets.length > 1?}
O -- Yes --> P["Sort aliasTargets DESC by computeConfidence\n(NEW)"]
O -- No --> Q[Use aliasTargets as-is]
P --> R[Dedup loop over sortedAliasTargets]
Q --> R
Reviews (7): Last reviewed commit: "Merge branch 'main' into fix/sort-target..." | Re-trigger Greptile |
Codegraph Impact Analysis1 functions changed → 3 callers affected across 2 files
|
The Phase 8.3 and Phase 8.3f pts alias loops iterated aliasTargets without sorting first. The native engine's emit_pts_alias_edges calls sort_targets_by_confidence before the alias loop (build_edges.rs:398), ensuring the highest-confidence target wins the ptsEdgeRows dedup. Apply the same descending-confidence sort to both TS pts fallback paths to close this parity gap.
|
Fixed — added descending-confidence sort to |
|
Resolved merge conflict with main — the branch's copies of |
The native engine sorts call targets by confidence before emitting edges; the WASM/TS engine did not. For multi-target calls with duplicate
(source_id, target_id)pairs, the stored confidence could differ between engines depending on insertion order.Adds equivalent descending-confidence sort to
buildFileCallEdgesinbuild-edges.ts, matching the native sort order and eliminating the latent parity gap.Closes #1476