Files
fusion/docs/solutions/logic-errors/git-detection-false-not-repo.md
gsxdsm 725ce45c5d FN-7799: fix false-negative Git repository detection blocking task execution
Replace the boolean isGitRepository() check with a tri-state Git detection so environmental git failures (dubious ownership, missing git binary, timeouts) are no longer misreported as "not a Git repository", which previously blocked all task execution in valid repos and survived engine restarts.

- Add detectGitRepository() in worktree-pool.ts returning repo / not-repo / error (with reason: dubious-ownership, git-missing, timeout, unknown), classified from git's stderr; bound the git rev-parse call with a 10s timeout and maxBuffer; keep isGitRepository() as a backward-compatible wrapper
- Route the executor dispatch preflight guard through detectGitRepository(): only emit the original "not a Git repository / run git init" fatal on a positive not-repo verdict; on error, throw a distinct accurate error naming the real git failure, including the safe.directory remedy for dubious ownership
- Route the in-process runtime startup warning through the same tri-state detection so it only warns "not a Git repository" on a positive not-repo verdict
- Add a regression test locking extractWorktreeConflictInfo() to NOT misclassify a dubious-ownership git worktree add failure as not-git-repo
- Add targeted tests across worktree-pool, executor-worktree, and in-process-runtime test suites covering repo/not-repo/dubious-ownership/git-missing/timeout classifications on Windows OneDrive-style and POSIX paths
- Add changeset and a docs/solutions/logic-errors write-up of the false-negative root cause and fix

Files changed:
 .changeset/fn-7799-git-detection-false-negative.md |  7 +++
 .../logic-errors/git-detection-false-not-repo.md   | 54 ++++++++++++++++
 .../engine/src/__tests__/executor-worktree.test.ts | 61 +++++++++++++++++++
 .../engine/src/__tests__/worktree-pool.test.ts     | 71 +++++++++++++++++++---
 packages/engine/src/executor.ts                    | 38 +++++++++---
 .../runtimes/__tests__/in-process-runtime.test.ts  | 53 ++++++++++++++--
 packages/engine/src/runtimes/in-process-runtime.ts | 16 ++++-
 packages/engine/src/worktree-pool.ts               | 66 ++++++++++++++++++--
 8 files changed, 334 insertions(+), 32 deletions(-)

Fusion-Task-Id: FN-7799
Fusion-Task-Lineage: 25a84283-bf47-472b-8a98-a10bf7e494de
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 21:19:22 -07:00

55 lines
2.9 KiB
Markdown

---
title: "Git probe failures falsely reported as not a repository"
date: 2026-07-10
category: docs/solutions/logic-errors
module: "engine Git detection + task executor preflight"
problem_type: logic_error
component: engine
symptoms:
- "Every task fails immediately with Project directory is not a Git repository"
- "The project is a valid Git repo, but git rev-parse fails for an environmental reason"
- "Restarting the engine does not clear the failure because the environment condition persists"
root_cause: error_classification_collapse
resolution_type: code_fix
severity: high
related_components:
- "packages/engine/src/worktree-pool.ts (detectGitRepository)"
- "packages/engine/src/executor.ts (dispatch preflight guard)"
- "packages/engine/src/runtimes/in-process-runtime.ts (startup warning)"
tags:
- git
- worktrees
- executor
- dubious-ownership
- false-negative
---
# Git probe failures falsely reported as not a repository
## Problem
A boolean Git repository probe collapses every `git rev-parse --git-dir` failure into `false`. That makes a positive non-repo response indistinguishable from environmental failures such as `fatal: detected dubious ownership`, `spawn ENOENT`, or a hung Git command. The executor then tells operators to run `git init` even when the checkout is already a valid repository, blocking all task execution until the underlying Git environment is fixed.
## Solution
Use tri-state Git detection: `repo`, `not-repo`, or `error`. Only the `not-repo` state may produce the existing "Project directory is not a Git repository" / `git init` guidance. Environmental failures surface the original Git error instead; dubious ownership also includes the explicit safe-directory command:
```bash
git config --global --add safe.directory "<project-root>"
```
The probe remains async and bounded with a timeout, so a hung Git process cannot silently become a false non-repo verdict.
## Verification
Cover the invariant at every consumer of repository detection:
- Detection helper: genuine repo → `repo`; genuine `fatal: not a git repository` → `not-repo`; dubious ownership, missing Git, and timeout → `error`.
- Executor guard: `not-repo` preserves the legacy log/error strings; `error` logs and throws a distinct message without `git init` guidance and does not attempt `git worktree add`.
- Runtime startup: `not-repo` preserves the startup warning; `error` warns with the real Git failure and any safe-directory remedy.
- Worktree-add conflict parsing: `detected dubious ownership` stays `unknown`, not `not-git-repo`, so it does not become a non-retryable `git init` error.
## Prevention
Do not use boolean wrappers at guardrails that need operator-facing diagnosis. Keep positive semantic states separate from probe failures, preserve stderr in the result, and add tests for both a POSIX path and a Windows path with spaces passed through `cwd` rather than interpolated into the shell command.