Summary
node update-system.mjs apply aborts with a false positive safety violation when cv.md is present as an untracked file in the working directory.
Steps to Reproduce
- Have
cv.md as an untracked file (standard setup — it's in .gitignore or simply not committed)
- Run
node update-system.mjs apply
- Observe the update fails immediately after checking out system files
Expected Behavior
The update completes successfully. cv.md was already tracked in initialStatusPaths as an untracked file (?? cv.md) before the update started, so the post-update safety check should skip it via if (initialStatusPaths.has(file)) continue.
Actual Behavior
Backup branch created: backup-pre-update-1.1.0
Fetching latest from upstream...
Updating system files...
SAFETY VIOLATION: User file was modified: cv.md
Aborting: user files were touched. Rolling back...
Even after rolling back and retrying with git stash (which doesn't stash untracked files), the error persists identically.
Root Cause (hypothesis)
cv.md is present as ?? cv.md in git status --porcelain before the update. After git checkout FETCH_HEAD -- <system-paths>, the git index changes may cause gitStatusEntries() to report cv.md with a different status code or path format that no longer matches the entry stored in initialStatusPaths.
Possibly related: when the index is modified by multiple git checkout FETCH_HEAD -- calls in sequence, the porcelain output for previously-untracked files adjacent to newly-staged files may change format.
Workaround
Manually checkout the missing system files from FETCH_HEAD:
git fetch https://github.com/santifer/career-ops.git main
for f in analyze-patterns.mjs check-liveness.mjs doctor.mjs followup-cadence.mjs liveness-core.mjs scan.mjs; do
git checkout FETCH_HEAD -- "$f"
done
# Then update VERSION manually or via the script's check step
Environment
- OS: macOS Darwin 25.4.0
- Node: $(node --version)
- Git: $(git --version)
- career-ops local: 1.1.0 → attempting to update to 1.3.0
cv.md status before update: ?? cv.md (untracked, not staged, not ignored)
Suggested Fix
Before the safety validation loop, re-build initialStatusPaths to include the current untracked files explicitly, or add a separate pre-check that verifies cv.md was already untracked before the update and skips it unconditionally:
// In the safety check loop:
const entry = gitStatusEntries().find(e => e.path === file);
if (entry?.code === '??' && initialStatusPaths.has(file)) continue; // was already untracked, unchanged
Alternatively, filter USER_PATHS check to only apply to files whose code changed (i.e., was ?? before and is now M or A after).
Found while running the update on a fork with active customizations. The update itself applies correctly when the system files are checked out manually — only the automated script path is affected.
Summary
node update-system.mjs applyaborts with a false positive safety violation whencv.mdis present as an untracked file in the working directory.Steps to Reproduce
cv.mdas an untracked file (standard setup — it's in.gitignoreor simply not committed)node update-system.mjs applyExpected Behavior
The update completes successfully.
cv.mdwas already tracked ininitialStatusPathsas an untracked file (?? cv.md) before the update started, so the post-update safety check should skip it viaif (initialStatusPaths.has(file)) continue.Actual Behavior
Even after rolling back and retrying with
git stash(which doesn't stash untracked files), the error persists identically.Root Cause (hypothesis)
cv.mdis present as?? cv.mdingit status --porcelainbefore the update. Aftergit checkout FETCH_HEAD -- <system-paths>, the git index changes may causegitStatusEntries()to reportcv.mdwith a different status code or path format that no longer matches the entry stored ininitialStatusPaths.Possibly related: when the index is modified by multiple
git checkout FETCH_HEAD --calls in sequence, the porcelain output for previously-untracked files adjacent to newly-staged files may change format.Workaround
Manually checkout the missing system files from
FETCH_HEAD:Environment
cv.mdstatus before update:?? cv.md(untracked, not staged, not ignored)Suggested Fix
Before the safety validation loop, re-build
initialStatusPathsto include the current untracked files explicitly, or add a separate pre-check that verifiescv.mdwas already untracked before the update and skips it unconditionally:Alternatively, filter USER_PATHS check to only apply to files whose
codechanged (i.e., was??before and is nowMorAafter).Found while running the update on a fork with active customizations. The update itself applies correctly when the system files are checked out manually — only the automated script path is affected.