tracedecay_commit_context reports No changes detected. for a tracked file that git status shows as modified, when the edit lands in the same wall-clock second as the last index write.
Reproduction (isolated profile, debug CLI from fleet/mcp-typed-git; the behavior is unchanged from origin/master):
git init -q -b main && git add -A && git commit -qm init
git switch -qc feature && echo 'pub fn beta() {}' >> src/left.rs && git commit -qam "add beta"
echo "// pending" >> src/lib.rs # same second as the commit's index write
git status --short # M src/lib.rs
tracedecay tool commit_context --args '{"format":"json"}'
# {"changed_files":[],"recent_commits":["add beta","init"],"suggested_category":null,"summary":"No changes detected.","symbols_by_role":{}}
Waiting ~1.2 s before the edit makes the same call report src/lib.rs with role source.
Root cause: git_changed_files in crates/tracedecay-mcp/src/handlers/git/shell.rs detects unstaged edits with a whole-second mtime heuristic (mtime > entry.stat.mtime.secs), and folds unreadable mtimes to UNIX_EPOCH with unwrap_or. Any edit inside the index's own second (git's racy-clean window) is silently dropped. It should use gix's worktree status (stat + content comparison for racily clean entries) instead of the ad-hoc comparison.
Related observation in the same file: git_commit_log_controlled formats format!("{:.7}", commit.id), but gix's ObjectId Display ignores precision, so tracedecay_pr_context commits[].hash carries the full 40-character id rather than the short id the code intends.
tracedecay_commit_contextreportsNo changes detected.for a tracked file thatgit statusshows as modified, when the edit lands in the same wall-clock second as the last index write.Reproduction (isolated profile, debug CLI from
fleet/mcp-typed-git; the behavior is unchanged fromorigin/master):Waiting ~1.2 s before the edit makes the same call report
src/lib.rswith rolesource.Root cause:
git_changed_filesincrates/tracedecay-mcp/src/handlers/git/shell.rsdetects unstaged edits with a whole-second mtime heuristic (mtime > entry.stat.mtime.secs), and folds unreadable mtimes toUNIX_EPOCHwithunwrap_or. Any edit inside the index's own second (git's racy-clean window) is silently dropped. It should use gix's worktree status (stat + content comparison for racily clean entries) instead of the ad-hoc comparison.Related observation in the same file:
git_commit_log_controlledformatsformat!("{:.7}", commit.id), but gix'sObjectIdDisplay ignores precision, sotracedecay_pr_contextcommits[].hashcarries the full 40-character id rather than the short id the code intends.