v0.47.3
A correctness-and-performance patch. Every change is a fix, a speedup, or a stability improvement to existing behavior — no new features, no config changes. Safe drop-in upgrade from v0.47.x.
Correctness fixes (tools returning wrong results)
aft_searchcould report zero results when the match existed. With the defaultincludeTests: false, hidden test-file matches consumed the result cap before production files were reached, so a real match in source could come back empty. Test files are now excluded during candidate selection, before the cap.- Bash
lsno longer exposes hidden dotfiles that a plainlswould hide —ls DIRinvocations rewritten to the internal reader now preserve native hidden-file visibility. aft_conflictskept conflicts with non-ASCII or unusual filenames. Filenames with accents, CJK characters, or control bytes were silently dropped from the conflict list; they are now parsed from raw NUL-delimited git output.aft_importno longer deletes sibling imports when removing one name from a comma-separated PHPuse A, B;declaration (removingAused to takeBwith it). Java static-member import removal is fixed the same way.aft_safetyrestore preserves Unix permission bits (including the executable bit) when restoring from the durable backup store, even if the metadata sidecar is unavailable.aft_callgraph trace_datano longer reports a flow after the variable was overwritten.let x = raw; x = "other"; sink(x)no longer claimsrawreachessink; conditional overwrites are marked approximate rather than dropped.aft_inspectreports self-import cycles (a file importing itself) that were previously omitted from the cycle count and drill-down.aft_inspectno longer counts TODO/FIXME markers inside string literals — markers are read from real comments (via the syntax tree), not from comment-looking text in strings.- Bash
cat/redirect rewrites read and write the correct file when a double-quoted path contains a backslash before a non-special character. aft_zoomfinds HTML headings by theirid=anchor. Real anchors set viaidattributes previously returnedsymbol_not_found.aft_refactormove/inline preserve namespace-consumer imports on moves and reject ambiguous qualified inline call sites instead of rewriting the wrong one.
Performance
- Faster indexed search: postings decode directly into the filtered result without a throwaway allocation per query trigram.
- Faster tool dispatch: tool-call arguments are moved through translation rather than deep-cloned, and the request is built without re-materializing the parameter tree.
- Faster
aft_callgraph call_tree: converging call graphs no longer re-query the same node's edges per path. - Faster
aft_inspectduplicate rollups: cached contributions are read by reference instead of deep-cloned. - Lower allocation on the hot path: per-call path resolution borrows ordinary paths, and background completion pushes share one serialized body across routes.
- Faster background
bashstatus lookups and lower unbounded growth: the task table is indexed and old delivered tasks are reclaimed.
Stability and resource use
- Closed a route leak that kept dead projects bound. Failed requests could leave route handles open, so long-lived daemons accumulated actors (and their memory) for worktrees deleted long ago; routes are now closed on discard and a connection exit releases its projects.
- Daemon restarts no longer trigger a re-embedding storm — post-restart semantic refreshes are capped through the shared concurrency limiter instead of all projects re-checking at once.
- Health reporting now exposes live watcher/actor/route counters and a compact per-root memory rollup, and borrow-only worktrees report an honest ready/disabled status instead of a permanent "building".