Skip to content

[Bug]: pi-fff reuses broader aux finder that excludes explicit absolute-path target #711

Description

@VXNCXNX

Which fff frontend?

@ff-labs/pi-fff

Version

  • @ff-labs/pi-fff: 0.10.1
  • Pi: 0.80.10
  • macOS, Node.js 22.23.1

Description

An explicit absolute path outside the current workspace can be searched through a broader cached auxiliary finder instead of a finder rooted at the requested directory. If the broader finder excludes the requested subtree, the target file is absent from its index and ffgrep misses it.

This is especially visible for files under node_modules. A cached finder rooted at ~/.pi excludes ~/.pi/agent/npm/node_modules, while a finder rooted directly at the package source directory indexes the target correctly.

On 0.10.1 this composes with #697: the primary search returns zero because the target is absent, then fuzzy fallback drops the path constraint and may return unrelated Pi session transcripts. Even after #697, reusing the broader finder still causes a false negative for the requested file.

Reproduction

Start Pi in a workspace outside ~/.pi, ensure an auxiliary finder covering ~/.pi already exists, then call:

{
  "pattern": "randomUUID",
  "path": "/Users/example/.pi/agent/npm/node_modules/@tintinweb/pi-subagents/src/agent-manager.ts",
  "limit": 3
}

The target contains two randomUUID matches.

Actual on 0.10.1: unrelated files under the broader ~/.pi index can be returned, while the requested file is absent.

Expected: only matches from the requested file.

A direct SDK comparison confirms the index-root dependency:

  • FileFinder(basePath: .../pi-subagents/src) with query agent-manager.ts randomUUID: returns agent-manager.ts.
  • FileFinder(basePath: ~/.pi) with the same query: the target is absent because the parent index excludes node_modules.

Root cause

resolveFinderForPath() calls:

const aux = await auxPool.acquire(route.root);

AuxFinderPool.acquire() accepts any existing finder whose root covers route.root. The code rebases the query suffix, but rebasing cannot recover files excluded when the broader finder was scanned.

The pool already supports { exact: true }, currently used by cursor resume.

Suggested fix

For explicit outside-workspace path routing, acquire the exact requested root:

const aux = await auxPool.acquire(route.root, { exact: true });

A regression test should create a broad finder whose ignore rules omit a nested target, then verify an absolute path into that nested directory creates or reuses an exact-root finder and returns only the target.

Impact

Besides false negatives, the interaction with fuzzy fallback can inject unrelated or very large session logs into an AI agent context. In the observed case this contributed to context-window exhaustion before the agent could produce a final answer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions