Skip to content

fix(harness-ops): converge treats a user home directory (including /mnt/c/Users/* on WSL) as a project path #7447

Closed

Description

@kyle-sexton

What happened

On WSL2 (harness-ops 3.14.0, 2026-10-14), installed_plugins.json held project-scope records whose projectPath is the Windows user home as seen from WSL, /mnt/c/Users/<windows-home>. Converge treated that row like any other project path, so its uninstall strategy would run (cd /mnt/c/Users/<windows-home> && claude plugin uninstall <id> -s project --keep-data).

/mnt/c/Users/<windows-home>/.claude/settings.json is not a project settings file. It is the Windows Claude Code install's user settings file, with 128 enabledPlugins entries. A project-scope uninstall there would delete Windows user-scope enables.

Expected

Converge refuses to act on a projectPath that equals a user home directory: $HOME, any /home/*, /Users/*, C:\Users\*, and the WSL view of Windows homes, /mnt/<drive>/Users/*. The row is reported as BLOCKED with the reason.

Repro

  1. On WSL, have a project-scope record whose projectPath is /mnt/c/Users/<windows-home> (created by running a project-scope install from that directory in a WSL session).
  2. Run /harness-ops:plugins converge.
  3. The row gets the normal strategy and a cd command into the Windows home.

Evidence

Paths are relative to plugins/harness-ops/skills/plugins/ on main at 8718950e9d.

  • context/converge.md:74-85 builds cd "<projectPath>" commands with no check of what the path is; the only precondition is projectPathPresent (context/converge.md:94-104).
  • /mnt/c/Users/<windows-home>/.claude/settings.json holds 128 enabledPlugins entries: the Windows user scope.
  • The same hazard applies to a record keyed to the Linux $HOME, whose .claude/settings.json is this machine's user settings.

Proposed fix

  1. In fleet-state.sh, mark each project/local record with projectPathIsHome: true when the path equals the current $HOME or matches ^(/home/[^/]+|/Users/[^/]+|/mnt/[a-z]/Users/[^/]+|[A-Za-z]:[\\/]Users[\\/][^\\/]+)/?$.
  2. Converge emits such rows as BLOCKED ("projectPath is a user home; its .claude/settings.json is user settings, not project settings"), never as a runnable command.
  3. Sync reports these records in their own row so the user can see they exist.
  4. Add a fixture for the /mnt/c/Users/<name> case.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Hnyd9hEzF6NuSFzC9rWj92

Activity

  1. added
    priority: highSignificant impact, or blocks an imminent release; staff this cycle.
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 14, 2026
  2. github-actions commented on Oct 14, 2026

    @github-actions
    Contributor

    Understood: on WSL2, converge can see a project-scope record whose projectPath is /mnt/c/Users/&lt;name&gt; (the Windows home as mounted in WSL) and build an uninstall command that cds into it, acting against the Windows install's user-scope .claude/settings.json instead of a project settings file. The same risk applies to any record keyed to $HOME. The report includes exact file/line evidence (context/converge.md:74-85, :94-104), a repro, and a concrete proposed fix (flag home-directory paths in fleet-state.sh, block them in converge output, report them separately in sync, add a WSL fixture).

    Nothing appears missing for someone to act on this; the proposed fix is specific enough to review directly. I didn't find an existing issue describing this exact user-home/projectPath confusion, though related converge-correctness issues exist in the tracker (#7445, #7446, #7448) if useful for sequencing this fix.

    Automated triage. A maintainer reviews it.

  3. added
    area: securitySecurity-relevant: vulnerability, hardening, or disclosure follow-up.
    on Oct 14, 2026
  4. removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    area: securitySecurity-relevant: vulnerability, hardening, or disclosure follow-up.
    on Oct 15, 2026
  5. kyle-sexton commented on Oct 18, 2026

    @kyle-sexton
    MemberAuthor

    Agent Brief

    Type: Bug
    Summary: /harness-ops:plugins converge refuses to act on a project-scope record whose projectPath is a user home directory.

    Current behavior:
    Converge treats every projectPath as a project. On WSL a record keyed to /mnt/c/Users/<name> gets the normal uninstall strategy, which would cd into the Windows home and remove the Windows install's user-scope enables.

    Desired behavior:

    • The fleet state flags a projectPath that is a user home: $HOME, any /home/<name>, /Users/<name>, C:\Users\<name>, or the WSL view /mnt/<drive>/Users/<name> (case-insensitive drive and Users).
    • Converge reports such a row as BLOCKED with the reason 'projectPath is a user home directory' and emits no command for it.
    • Sync's divergence count does not count those rows as actionable.
    • Paths under a home (a repository in /home/<name>/repos/x) are unaffected.

    Key interfaces:

    • Fleet-state record field: a user-home flag per projectPath.
    • Converge row status: BLOCKED with the named reason.

    Acceptance criteria:

    • scripts/run-test-file.sh plugins/harness-ops/skills/plugins/scripts/fleet-state.test.sh passes, with a WSL fixture whose record has projectPath /mnt/c/Users/someone flagged as a user home, and a fixture under /home/someone/repos/app not flagged.
    • The converge procedure states that a flagged row is BLOCKED with the reason and gets no command.
    • scripts/check-changelog-fragments.sh passes.

    Out of scope:


    This was generated by AI during backlog shaping. Held, not admitted: this brief is drafted and checked, but the issue lane would stop on it today. It is admitted, by adding agent-ready, once the lane can run the skill-quality check scripts (Automation Lanes' PR #7912). Held under the owner's 2026-10-18 lane-narrowing course correction.

  6. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    and removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: highSignificant impact, or blocks an imminent release; staff this cycle.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions