coordinator-update · diff
git:20260806.c4a645d to git:20260816.6fabdd6
388 added, 362 removed. Audit A to A.
- ---
- 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, custom
- environment 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, custom environment 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/`, `state/handoffs/`,
- memory entries under `projects/`, `state/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 the `coordinator:install` flow. It is not a user customization and is excluded from the advisory set.
- - Author handoffs, spinoffs, or workstream-complete 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 (a coordinator development install where the plugin source
- is authored directly). This skill is for OSS consumers who installed via the publish repo (the
- `coordinator:install` flow). If you are on a development machine authoring the coordinator
- source directly, you do not need this skill.
-
- ---
-
- ## 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 `coordinator:install` flow."
- 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.py`
-
- where `<skill-dir>` is the directory containing this SKILL.md — typically
- `~/.claude/plugins/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"
-
- # The engine root this update flow depends on is resolved by the shipped
- # resolver script, which is the single source of that resolution — no other
- # code in this skill hardcodes how or where it is found.
- _cc_engine_root="$(python3 "${INSTALL_ROOT}/coordinator/hooks/scripts/_engine_root.py" 2>/dev/null)"
- if [ -z "$_cc_engine_root" ] || [ ! -d "$_cc_engine_root" ]; then
- echo "ERROR: could not resolve the coordinator engine root via ${INSTALL_ROOT}/coordinator/hooks/scripts/_engine_root.py — consult your coordinator install's engine-setup documentation for how to register it, then retry." >&2
- exit 1
- fi
-
- source "${_cc_engine_root}/coordinator/lib/resolve-python.sh"
- "$PYTHON_BIN" "${PYTHON_ARGS[@]}" "${SKILL_DIR}/lib/compute-update-delta.py" --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 workstream-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,
- custom environment 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 coordinator installer's). You can restore any
- file from its `.bak` if needed."
-
- Git-tracking your `~/.claude` is recommended for exactly this reason — better future
- reversibility. Consider git-initializing after this session.
-
- ### 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}/${REL_PATH}" "${INSTALL_ROOT}/${REL_PATH}"
- # Review: code-reviewer (A-F1) — drop plugins/ prefix; SOURCE_DIR is the clone ROOT in the OSS publish repo (no plugins/ subdir).
- ```
- 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 `coordinator:install`
- completion summary as the recommended path for future updates. It is NOT surfaced on the
- source-is-live (meta-repo) machine — it is installed and invokable only for
- OSS consumers who installed via the publish-repo `coordinator:install` flow.
-
- If you are reading this as a developer on the coordinator meta-repo: this skill lives at
- `plugins/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 the `coordinator:install` flow with the `deep-research` add-on enabled), 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 (historical):** The former standalone `deep-research-claude`
- repo is archived read-only — deep-research now ships bundled inside the coordinator plugin (see
- above). The 2026-05-29 plan scope decision to defer standalone-repo detection is moot: there is
- no live standalone repo left to detect.
+ ---
+ 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, custom
+ environment 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, custom environment 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/`, `state/handoffs/`,
+ memory entries under `projects/`, `state/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 the `coordinator:install` flow. It is not a user customization and is excluded from the advisory set.
+ - Author handoffs, spinoffs, or workstream-complete 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 (a coordinator development install where the plugin source
+ is authored directly). This skill is for OSS consumers who installed via the publish repo (the
+ `coordinator:install` flow). If you are on a development machine authoring the coordinator
+ source directly, you do not need this skill.
+
+ ---
+
+ ## 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 `coordinator:install` flow."
+ 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.py`
+
+ where `<skill-dir>` is the directory containing this SKILL.md — typically
+ `~/.claude/plugins/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"
+
+ # Interpreter resolution contract: COORDINATOR_PYTHON env -> machine-local
+ # registry pin (coordinator.python) -> PATH. See the coordinator wiki,
+ # machine-local-registry.md § coordinator.python resolution contract.
+ PYTHON_BIN="${COORDINATOR_PYTHON:-}"
+ if [ -z "$PYTHON_BIN" ]; then
+ for _cand in python3 python; do
+ command -v "$_cand" >/dev/null 2>&1 && { PYTHON_BIN="$_cand"; break; }
+ done
+ fi
+ if [ -z "$PYTHON_BIN" ]; then
+ echo "ERROR: no Python interpreter found. Set COORDINATOR_PYTHON to its absolute path and retry." >&2
+ exit 1
+ fi
+ _cc_ml="${COORDINATOR_SETTINGS_HOME:-$HOME/.coordinator-claude-settings}/bin/machine-local"
+ if [ -f "$_cc_ml" ]; then
+ _cc_pin="$("$PYTHON_BIN" "$_cc_ml" get coordinator.python 2>/dev/null)"
+ [ -n "$_cc_pin" ] && [ -x "$_cc_pin" ] && PYTHON_BIN="$_cc_pin"
+ fi
+
+ # The engine root this update flow depends on is resolved by the shipped
+ # resolver script, which is the single source of that resolution — no other
+ # code in this skill hardcodes how or where it is found.
+ _cc_engine_root="$("$PYTHON_BIN" "${INSTALL_ROOT}/coordinator/hooks/scripts/_engine_root.py" 2>/dev/null)"
+ if [ -z "$_cc_engine_root" ] || [ ! -d "$_cc_engine_root" ]; then
+ echo "ERROR: could not resolve the coordinator engine root via ${INSTALL_ROOT}/coordinator/hooks/scripts/_engine_root.py — consult your coordinator install's engine-setup documentation for how to register it, then retry." >&2
+ exit 1
+ fi
+
+ "$PYTHON_BIN" "${SKILL_DIR}/lib/compute-update-delta.py" --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 workstream-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,
+ custom environment 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 coordinator installer's). You can restore any
+ file from its `.bak` if needed."
+
+ Git-tracking your `~/.claude` is recommended for exactly this reason — better future
+ reversibility. Consider git-initializing after this session.
+
+ ### 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}/${REL_PATH}" "${INSTALL_ROOT}/${REL_PATH}"
+ # Review: code-reviewer (A-F1) — drop plugins/ prefix; SOURCE_DIR is the clone ROOT in the OSS publish repo (no plugins/ subdir).
+ ```
+ 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:
+
+ The entrypoint is a Python CLI, and the extensionless-vs-`.py` filename varies by install
+ vintage — probe both names rather than pinning one:
+
+ ```bash
+ SENTINEL_WRITER=""
+ for _cand in "${INSTALL_ROOT}/coordinator/bin/install-sentinel-write" \
+ "${INSTALL_ROOT}/coordinator/bin/install-sentinel-write.py"; do
+ [ -f "$_cand" ] && { SENTINEL_WRITER="$_cand"; break; }
+ done
+ ```
+
+ Run it under the resolved interpreter — never `bash`, and never as a bareword `.py`:
+
+ ```bash
+ if [ -n "${SENTINEL_WRITER}" ] \
+ && "$PYTHON_BIN" "${SENTINEL_WRITER}" --path "${INSTALL_ROOT}" --source "${CLONE_DIR}"; then
+ :
+ 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 `coordinator:install`
+ completion summary as the recommended path for future updates. It is NOT surfaced on the
+ source-is-live (meta-repo) machine — it is installed and invokable only for
+ OSS consumers who installed via the publish-repo `coordinator:install` flow.
+
+ If you are reading this as a developer on the coordinator meta-repo: this skill lives at
+ `plugins/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 the `coordinator:install` flow with the `deep-research` add-on enabled), 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 (historical):** The former standalone `deep-research-claude`
+ repo is archived read-only — deep-research now ships bundled inside the coordinator plugin (see
+ above). The 2026-05-29 plan scope decision to defer standalone-repo detection is moot: there is
+ no live standalone repo left to detect.