Repository navigation
feat(harness-ops): sync should forward-update project pins in every present projectPath, not only the cwd's #7458
Description
Scope (revised 2026-10-20, owner-confirmed)
The intent: first, user scope is current. Then every checkout that references these plugins (worktrees, feature branches, home directories) loads the latest version.
Acceptance additions:
syncrunsupdate -s project(and-s local) from every presentprojectPath, a home directory included, sinceupdatewrites no settings (context/scope-semantics.md:93-109). It reads each record back afterwards, because of fix(harness-ops): converge's 'update -s project' can update a sibling worktree's record instead of the cwd's, and converge does not check #7445.- The report's
Divergences: N actionable → run convergeline stops counting a lagging pin thatsyncupdated or could update. It counts only the rows fix(harness-ops): converge defaults to uninstalling project pins that mirror committed enabledPlugins entries #7446 leaves toconverge. Absent-path records stay in their own section.
What happened
On 2026-10-14 (Windows, harness-ops 3.13.2), /harness-ops:plugins sync from the home directory updated 13 plugins at user scope and reported Divergences: 78 actionable: 61 pre-existing, 17 newly created by this run. Every one of the 78 rows had user scope as the highest version. The lagging scopes that exist on disk were project-scope pins in two present paths:
D:\repos\github.com\melodic-software\claude-code-plugins: 8 pins\\wsl.localhost\Ubuntu-26.04\home\<user>: 78 pins
Sync's in-repo update only covers the cwd's project root (In-repo: skipped here), so every sync that moves user scope forward creates new divergences in present project paths and points at converge, which has to do routine forward updates one confirm at a time.
Running converge's update strategy (cd <path> && claude plugin update <id> -s project) on the 8 plugins-repo pins worked: all 8 moved to the user-scope version, and git status -- .claude/ stayed clean (no write to the committed settings). That is a data point against #6713 on this CLI version: update -s project did update the record.
Expected
Sync forward-updates project and local pins in every present projectPath (not only the cwd's) when the catalog version is higher, using update -s project from that path. That keeps the existing promise (no committed-settings write, verified above) and leaves converge for the real decisions: absent paths, catalog regressions, and uninstall-versus-update.
Exclude a projectPath that is a user home directory, whose .claude/settings.json is that machine's user settings (#7447). The WSL home above is that case: its settings file is WSL Claude's user settings with 128 enabled plugins.
Evidence
- Run journal:
~/.claude/plugins/data/harness-ops-melodic-software/plugins-sync/runs/20261014T130750Z.rFOScT. - Related: fix(harness-ops): converge defaults to uninstalling project pins that mirror committed enabledPlugins entries #7446, fix(harness-ops): converge treats a user home directory (including /mnt/c/Users/* on WSL) as a project path #7447, feat(harness-ops): give converge a planning script that groups by path, and stop sync pointing blocked and worktree rows at converge #7448, fix(harness-ops): plugins sync and converge cannot clear stale project-scope pins the CLI treats as current #6713.
🤖 Generated with Claude Code
Activity
github-actions commentedon Oct 14, 2026
Thanks for the report. Automated triage handed this issue to a maintainer.
Proposed work class: work-class: scoped
Basis: automated intake triage; a maintainer confirms or changes it.
Automated triage. A maintainer reviews it.
kyle-sexton commentedon Oct 18, 2026
Decision recorded.
Question:
/harness-ops:plugins syncupdates project-scope plugin pins only in the current repo. Other repos on disk drift and later needconverge, one confirm per plugin. Options: (a) automatic forward-only updates in every present repo path, reported per path; (b) the same, with one confirm per path; (c) leave it to converge.Owner's answer: (a), with conditions. Sync is built to run headless and has no abort for autonomous sessions, so a confirm does not protect much. The conditions: skip home-directory paths (#7447); compare
git status -- .claude/before and after in each path and stop if it changes; land only after #6713 is settled. Basis: harness-ops plugins SKILL.md:37-40. This writes committed settings in repos other than the current one, so the owner should confirm it.The owner accepted this recommendation as item D26 of a 32-decision batch in an attended backlog-shaping session on 2026-10-18. The batch question: "Accept all 32 recommendations, including the four flagged above (D2 close the relearn, D26 cross-repo sync without per-repo confirm, D10 narrow hook, D23 delete guard only)?" The owner answered: "Accept all 32 (Recommended)".
Posted by AI from the owner's answer in that session.
kyle-sexton commentedon Oct 20, 2026
Reproduced on 2026-10-20 with harness-ops 3.17.0 on WSL.
syncfrom the home directory updated nothing at user scope (already current) and reportedDivergences: 57 actionable. In every row, user scope held the highest version, and no catalog version was lower. There were 537 lagging project pins across 52 present paths: 50 worktrees of this repo, its main checkout, and/mnt/c/Users/<user>(52 pins; that path's.claude/settings.jsonis the Windows user settings file).The owner's intent for the action: first, user-scope plugins are current; then every place that references them (worktrees, feature branches) is forward-updated to the latest. Because
update -s projectdoes not write committed settings (context/scope-semantics.md:93-109), the home-directory exclusion only matters for writing calls. A home-directory path can still be forward-updated.docs(harness-ops): scope converge's settings read to the Read tool an…
kyle-sexton commentedon Oct 22, 2026
Scope note from the #8555 duplicate close (Issue Triage, 2026-10-22). converge.md:31 says #7458 removes converge's Step 2 settings.json read. #7458's revised scope only covers sync forward-updating pins, so add this to its acceptance:
falsefrom no entry (the committed-false eval case, plugins/harness-ops/skills/plugins/evals/evals.json:128).Probe, as of 2026-10-22, Claude Code 2.1.306:
claude plugin list --jsonreportsprojectEnabled: falseboth for an explicit false (animation) and for no entry (actionlint). So the CLI alone cannot replace the read yet.