---
name: coordinator-update
description: "Check for a published coordinator update and advise a preserve-by-default migration path — never a blind overwrite."
allowed-tools: ["Bash", "Read", "Edit", "Write", "Grep"]
oss-only: true
argument-hint: "[--install-root <dir>]"
---

# /coordinator-update — Update Advisory for OSS Coordinator Installs

<!-- Spec backlink: docs/plans/2026-05-30-oss-coordinator-update-skill.md § Chunk 3 -->
<!-- OSS-only: this skill is authored in the meta-repo under dist/oss-only-skills/ and injected
     into the OSS publish tree at publish time. It is NOT installed on the source-is-live machine. -->

**Purpose.** Check whether a newer version of the coordinator plugin has been published, compute
a classified delta between the published version and your live install, and advise a migration
path that **preserves your implementation shape by default** — renamed personas, DoE/Claude-Central
setup, structural divergence, project-specific customizations.

**Verb-name check:** `/coordinator-update` was checked against Claude Code platform vocabulary
before ship. It does not shadow a native Claude Code command or verb (per the `/fan-out` lesson;
`coordinator-improvement-queue.md` 2026-05-30).

**This skill is PM-invoked, not autonomous.** It computes and advises; it does not apply changes
without your explicit consent. No cadence trigger, no automatic recheck.

---

## HARD CONSTRAINTS (verbatim — self-contained for OSS consumers)

This SKILL.md is self-contained. The coordinator CLAUDE.md is NOT in scope for OSS consumers.
The following rules are quoted verbatim and apply throughout this skill's execution.

### Preservation Constraint

> **Never overwrite a `consumer_modified` file without the user's Claude affirmatively judging
> the upstream change worth it AND surfacing the tradeoff to the user. The user's own
> implementation shape (persona names, DoE/Claude-Central setup, structural divergence) is
> preserved by default.**

### Commit Safety Rule

> **Never `git add -A` or `git add .`. Always use scoped, labelled, explicit-path commits:**
> `git add -- <path1> <path2> ... && git commit -m "<label>" -- <path1> <path2> ...`
> No sweep commits. No blanket staging. Stage only the named files you are applying.

### Offer-Shape Rule

> **Compute and advise is the default. Apply is explicit-consent-gated from the user — never
> autonomous action.** The skill runs the helper, classifies the delta, and presents a
> recommendation. It does NOT apply changes unless the user explicitly says "yes, apply."

---

## Out-of-Scope (hard block — never touch these)

This skill explicitly does NOT:

- Modify your project scaffolding or session-continuity surface: `tasks/`, `tasks/handoffs/`,
  memory entries under `projects/`, `tasks/lessons.md`, `.claude/settings.json`. These paths are
  agent-owned, not installer-owned. No install ceremony may write into them.
- Touch `consumer_added` files — files you added to your install tree that have no upstream source.
  These are entirely yours and are never offered for overwrite or modification.
- Touch `.claude-plugin/marketplace.json` — this file is installer-owned and regenerated by
  re-running `install.sh`. It is not a user customization and is excluded from the advisory set.
- Author handoffs, spinoffs, or session-end artifacts.
- Push to any remote.
- Modify project-level scaffolding managed by the 2026-05-29 `coordinator-currency` surface
  (that surface governs per-project structural currency, not the plugin tree).
- Run on a `source_is_live` machine (the meta-repo / Claude Central install). This skill is
  for OSS consumers who installed via the publish repo's `install.sh`. If you are on the
  meta-repo machine, you do not need this skill — you author the coordinator directly.

---

## Step 1: Resolve Install Root

Determine `INSTALL_ROOT` — the directory where the coordinator plugin lives on your machine.
Default: `~/.claude/plugins/coordinator-claude/`.

If the user passed `--install-root <dir>` as `$ARGUMENTS`, use that path instead.

Confirm the path exists and contains a `coordinator/` subdirectory. If not, surface:
> "Cannot locate a coordinator install at `<path>`. Pass `--install-root <dir>` with the
> correct path, or confirm you installed via the OSS `install.sh`."
Stop.

---

## Step 2: Run the Delta Helper

Run the Chunk 2 helper to produce a classified delta. The helper is co-located at:
`<skill-dir>/lib/compute-update-delta.sh`

where `<skill-dir>` is the directory containing this SKILL.md — typically
`~/.claude/plugins/coordinator-claude/coordinator/skills/coordinator-update/`.

```bash
# Review: code-reviewer — $0 is unreliable when Claude runs this block via the Bash tool
# ($0 resolves to /bin/bash, not the skill path). Derive SKILL_DIR deterministically from
# INSTALL_ROOT, which was already resolved in Step 1.
SKILL_DIR="${INSTALL_ROOT}/coordinator/skills/coordinator-update"
bash "${SKILL_DIR}/lib/compute-update-delta.sh" --install-root "${INSTALL_ROOT}"
```

The helper emits a single JSON object to stdout. Capture it. The schema:

```json
{
  "update_status": "current | behind | offline",
  "incoming_ref": "<tag or sha, empty if offline>",
  "manual_url": "<URL if offline or for manual reference>",
  "recommended_path": "none | overwrite | cherry-pick | plan-to-ingest",
  "counts": {
    "unchanged": <n>,
    "forward_safe": <n>,
    "consumer_modified": <n>,
    "consumer_added": <n>
  },
  "consumer_modified": [
    { "path": "<relpath>", "hunk": "<diff text ≤40 lines>" }
  ],
  "consumer_added": ["<relpath>"]
}
```

Exit codes: `0` = current; `3` = behind; non-zero (not 3) = offline/error.

---

## Step 3: Branch on `update_status`

### 3a. Offline

If `update_status` is `"offline"` (helper exited non-zero and not 3):

Report:
> "Could not reach the coordinator update source. Check your network or visit the update
> manually: `<manual_url from JSON>`
> (Never reporting 'up to date' when the source is unreachable — that would be a false signal.)"

**Stop here.** Do not claim the install is current.

### 3b. Current

If `update_status` is `"current"` (exit 0, all counts zero incoming):

Report:
> "Your coordinator install is up to date (at `<incoming_ref>`). No action needed."

**Stop here.**

### 3c. Behind

Proceed to Step 4.

---

## Step 4: Classify and Present the Delta

The install is behind. Read the JSON and partition the delta into three buckets:

### Bucket A — Forward-Safe Files (`forward_safe` count)

Files the upstream changed, but you have NOT modified in your live install. These are
**safe to take** — a reinstall of these files would not destroy any of your customizations.

Summarize what they contain. Examples: "updated session-start.md with a new Step 3.5 gate,"
"added docs/wiki/new-feature.md — no local equivalent."

### Bucket B — Consumer-Modified Files (`consumer_modified` array)

Files where BOTH the upstream changed AND you have a local edit. These carry your
implementation shape — likely renamed reviewer personas, added project-specific steps,
DoE/Claude-Central setup, structural divergence that reflects your working style.

**DEFAULT: PRESERVE.** These files are NOT in any apply set unless you affirmatively judge
the upstream change worth taking.

For each file in `consumer_modified`:
1. Read the upstream `hunk` field (the diff of what the upstream wants to change).
2. Read your local version of the file from the install tree.
3. **Judge semantically** — not byte-by-byte: Is the upstream change a genuine improvement
   (new gate, corrected logic, important safety rule) you would want even after rebasing your
   edits? Or is it cosmetic restructuring / prose reorganization that your version already
   addresses in your own way?
4. Present your judgment to the user with the tradeoff clearly stated:
   - If worth taking: "Upstream changed `<path>` — this adds `<what>`. Your local version has
     `<your customization>`. Taking the upstream change would mean rebasing your edit onto
     the new structure. Recommend: cherry-pick this one."
   - If not worth taking: "Upstream changed `<path>` — this reorganizes `<what>`. Your local
     version already expresses the same intent in your own structure. Recommend: keep yours."
5. Surface the judgment to the user. Do NOT apply without their explicit consent.

### Bucket C — Consumer-Added Files (`consumer_added` array)

Files you added to your install tree with no upstream equivalent.

List them. Note: "These are your additions — never touched by this skill or any update process."

---

## Step 5: Recommend One Path

Based on the classification, recommend exactly ONE update path with reasoning:

**overwrite** — only when the delta is `forward_safe`-only (Bucket B is empty, no
consumer-modified collisions). Tradeoff-free. Offer to apply all forward-safe files.

> "The update is entirely forward-safe — none of the changed files overlap with your
> customizations. Safe to apply all `<N>` files. Want me to apply them?"

**cherry-pick** — when some upstream changes are clearly wanted (forward-safe Bucket A, plus
any Bucket B files you judged worth taking) but others collide with your implementation shape.
List the takeable subset explicitly.

> "I recommend cherry-picking `<N>` files: [list]. The remaining `<M>` files in Bucket B
> have collisions with your customizations — I recommend preserving your versions of those.
> Want me to apply the cherry-pick subset?"

**plan-to-ingest** — when the delta is substantive (many Bucket B collisions, architectural
changes, or load-bearing customized files that would need careful rebasing). Apply would be
risky without deliberate review.

> "This update contains substantive changes that overlap with your implementation shape. I
> recommend running `/plan` to ingest this deliberately rather than cherry-picking blind.
> Seeded problem statement: 'Reconcile coordinator install at `<INSTALL_ROOT>` against
> upstream `<incoming_ref>`: `<N>` consumer-modified files need manual rebase — focus on
> `<top 2-3 paths by importance>`. Preserve persona names and project-specific steps.'"

**Stop and wait for explicit user consent before proceeding to Step 6.**

---

## Step 6: Apply (on explicit user consent only)

Only proceed here if the user explicitly said "yes" / "apply" / "go ahead" in response to
Step 5's recommendation. The offer-shape rule above is non-negotiable.

### 6a. Git Safety Baseline

Check whether the install tree is git-tracked:

```bash
git -C "${INSTALL_ROOT}" rev-parse --git-dir 2>/dev/null
```

If git-tracked: confirm the working tree is clean (`git -C "${INSTALL_ROOT}" status --short`).
If dirty, surface: "Your install tree has uncommitted changes. Commit or stash them before
applying the update, so the apply is revertible." Stop and wait.

If NOT git-tracked: offer a `.bak` baseline before applying. For each file to be applied,
copy it to `<path>.bak` first. Note: "Your install tree is not git-tracked. Backing up files
before applying (`.bak` convention matching the original `install.sh`). You can restore any
file from its `.bak` if needed."

The coordinator OSS `CLAUDE.local.md.tmpl` recommends git-tracking your `~/.claude` — this
is the reason why. Consider git-initializing after this session for better future reversibility.

### 6b. Apply the Named Files

Apply ONLY the files in the agreed apply set from Step 5 — no more, no less. Do not stage
or touch anything outside the explicit list.

For each file in the apply set:
1. Copy the incoming version from the fetched clone into the install path:
   ```bash
   cp "${CLONE_DIR}/plugins/${REL_PATH}" "${INSTALL_ROOT}/${REL_PATH}"
   ```
2. Add it to the explicit staging list.

### 6c. Commit (git-tracked installs only)

Use a scoped, labelled commit — never `git add -A`:

```bash
git add -- <path1> <path2> ... && \
git commit -m "coordinator-update: apply <incoming_ref> (cherry-pick <N> of <M> files)" \
  -- <path1> <path2> ...
```

The commit message names the incoming ref and the apply count. Revertible via `git revert`.

### 6d. Re-Stamp the Sentinel

After a successful apply, advance the install's `version.txt` sentinel to the ingested SHA.
This ensures the NEXT `/coordinator-update` run has a correct baseline and does not re-offer
already-applied changes.

Find `install-sentinel-write` in the install tree:

```bash
SENTINEL_WRITER="${INSTALL_ROOT}/coordinator/bin/install-sentinel-write"
```

Run:

```bash
if [ -f "${SENTINEL_WRITER}" ]; then
  bash "${SENTINEL_WRITER}" --path "${INSTALL_ROOT}" --source "${CLONE_DIR}"
else
  # Fallback: write the sentinel directly (same format as install-sentinel-write)
  git -C "${CLONE_DIR}" rev-parse HEAD > "${INSTALL_ROOT}/version.txt"
fi
```

The re-stamp is the critical close: without it, the baseline drifts and future runs will
re-classify already-applied files as divergent.

### 6e. Report Completion

```
Applied: <N> files from coordinator <incoming_ref>
Preserved: <M> consumer-modified files (your implementation shape kept)
Consumer-added: <K> files (never touched)
Sentinel: re-stamped to <SHA>
Revertible: yes — via git revert <commit-hash> (or .bak files if untracked)
```

---

## Step 7: Discovery Surface Note

This verb is announced in the coordinator OSS getting-started documentation and the `install.sh`
completion summary as the recommended path for future updates. It is NOT surfaced on the
source-is-live (meta-repo / Claude Central) machine — it is installed and invokable only for
OSS consumers who installed via the publish-repo `install.sh`.

If you are reading this as a developer on the coordinator meta-repo: this skill lives at
`plugins/coordinator-claude/coordinator/dist/oss-only-skills/coordinator-update/SKILL.md`
and is injected into the OSS publish tree by the `20-inject-oss-only-skills.sh` percolate hook.
It is intentionally absent from the meta-repo's `skills/` tree.

---

## Notes

- **Missing sentinel (no `version.txt`):** The helper degrades to baseline-free two-way mode
  (exit 2 from classifier, translated to "behind" by the helper). The first successful apply
  run re-stamps the sentinel. Subsequent runs have a proper baseline. This is expected behavior
  for users who installed before Chunk 1 landed the sentinel write.
- **Bundled deep-research:** If the coordinator install includes the bundled `deep-research`
  add-on (installed via `install.sh:86` with `deep-research|on|local`), it is part of the
  same plugin tree and is reconciled in the same pass. No separate `/deep-research-update`
  verb exists; the coordinator tree walk covers it.
- **Standalone deep-research-claude repo:** Out of scope. This skill reconciles the installed
  coordinator plugin tree only. Standalone `deep-research-claude` detection is deferred per
  the 2026-05-29 plan scope decision.
