fix: bound session worktree discovery - #481
Conversation
🦋 Changeset detectedLatest commit: 8897550 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 520ddcfd2d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88975508d1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if matcher.identity == crate::worktree::GitRepoIdentityOutcome::Unknown { | ||
| return matcher; |
There was a problem hiding this comment.
Back off unknown project matcher identities
When a project or registered root hits the two-second Git deadline, returning the matcher without caching it makes every subsequent transcript immediately repeat the same timeout. Both CodexSource::parse_new and ClaudeSource::parse_new call get for every discovered file—even when new.lines is empty—so one stale registered root and hundreds of transcripts can still stall a sweep for many minutes while repeatedly spawning Git children. Cache an Unknown cooldown entry, without treating it as a definitive route, as the location-worktree cache already does.
Useful? React with 👍 / 👎.
|
|
||
| fn git_command_at(repo_root: &Path, args: &[&str]) -> Command { | ||
| let mut command = Command::new(git_program()); | ||
| command.arg("-C").arg(repo_root).args(args); |
There was a problem hiding this comment.
Clear repository overrides before using -C
When TraceDecay is started from a Git hook or another process that exports repository-local variables, GIT_DIR, GIT_WORK_TREE, or GIT_COMMON_DIR overrides the repository selected by -C (git rev-parse --local-env-vars lists these variables). The new CLI-first resolver can therefore report the inherited repository's common directory for every supplied root, causing unrelated transcript paths and daemon initialize roots to be treated as the same project; clear these repository-selection variables on this command while preserving the supported GIT executable override.
Useful? React with 👍 / 👎.
| pub(crate) fn contains(&self, path: &Path) -> bool { | ||
| self.contains_status(path) == ProjectMembership::Match |
There was a problem hiding this comment.
Preserve unknown membership in boolean callers
When the bounded identity lookup times out, this converts Unknown to false, but many existing callers still use the boolean path_belongs_to_project API rather than contains_status. In particular, user-scoped Vibe, Kiro, Cline-like, and Cursor Composer ingestion interpret that false value as “not registered,” persist the project transcript into the user store, and advance its offset; a transient two-second timeout can therefore permanently misattribute project sessions. These callers need the tri-state result and must defer the affected transcript or row on Unknown instead of treating it as a non-match.
Useful? React with 👍 / 👎.
Summary
git rev-parsechildUnknownmembership so transcript pages remain retryableUnknowncooldownRoot cause
Session catch-up repeatedly resolved Git identity while parsing transcript metadata. An unhealthy worktree path could leave Git blocked and then reopen the repository through
gix, causing large pack-index scans, multi-core CPU use, high memory, stalled searches, and eventually an unavailable daemon.The initial timeout fix exposed three follow-up correctness gaps:
Unknownas false and advance a cursorCold runtime validation then found one remaining open-path call: legacy-store comparison still used the old
gix-first common-directory resolver for every historical manifest root. This PR now uses the same bounded identity outcome there; only a resolved common directory participates in matching.Behavior
Resolvedidentities keep the existing exact-root and shared-Git behavior.NotFoundremains a definitive non-match.Unknownnever advances the affected transcript page or enters a route cache.Validation
cargo fmt --all -- --check: passedgit diff --check: passedcargo check --release --locked: passed88975508d1e0d4fb98802ff32952fe88541a7320: PASSLocal runtime validation
Installed the exact optimized candidate for
88975508d1e0d4fb98802ff32952fe88541a7320and restarted the managed daemon.2d2b985058be37de34ced78a53e72842b5c02e1a2ac76edccb10fe3232a99f15gix, pack-index, or Git child framesgixrunaway did not reproduceThe candidate is ready for maintainer review.