Skip to content

bug: update-system.mjs false positive safety violation on untracked cv.md #201

@wolram

Description

@wolram

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

  1. Have cv.md as an untracked file (standard setup — it's in .gitignore or simply not committed)
  2. Run node update-system.mjs apply
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions