Upgrade an EXISTING project bootstrapped from an older ForgeWorks release to the current structure without clobbering hand-filled content. Reconciles the project against a fresh copy of the template: copies missing always-on files, grafts new AGENTS.md rule blocks and subagent sections, applies the language tooling delta, migrates the v4 ledger into features.json state, and reports the rest. Non-destructive and idempotent. Use when a project already has a generated AGENTS.md and the user says...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add kp-multiverse/ForgeWorks --skill upgrade-project --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Upgrade Project?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kp-multiverse-upgrade-project)More formats (shields.io, HTML) on the badges page.
---
name: upgrade-project
description: Upgrade an EXISTING project bootstrapped from an older ForgeWorks release to the current structure without clobbering hand-filled content. Reconciles the project against a fresh copy of the template: copies missing always-on files, grafts new AGENTS.md rule blocks and subagent sections, applies the language tooling delta, migrates the v4 ledger into features.json state, and reports the rest. Non-destructive and idempotent. Use when a project already has a generated AGENTS.md and the user says "upgrade", "/upgrade-project", "update the harness", or "sync the template". Not for an empty directory -- that is /init-project.
---
# upgrade-project
Brings an **existing** generated project up to the current template. The hard
problem: `AGENTS.md`, `docs/`, and the subagents hold hand-filled content, so
the upgrade cannot overwrite. It reconciles.
## Principles
- **Non-destructive.** Create only what is absent; insert into existing files, never replace them wholesale. The one exception is the v3->v4 migration (Phase 3-D), which replaces the v3 harness after the owner's accept.
- **Idempotent.** Every step checks "already present?" first. A second run changes nothing.
- **Automate the safe part, assist the rest.** Placeholder-free files copy automatically. Merges into hand-edited files are computed first and approved as one batched report (Phase 4).
- **Reconcile against the live template.** The skill diffs the project against a fresh `templates/core` plus the project's own `templates/profiles/<lang>`, so a file added to the template later is picked up without editing this skill.
## Phase 0: Confirm and make it safe
1. Confirm this is a generated project (a non-bootstrap `AGENTS.md`). If not, stop: that is `init-project`'s job.
2. Work in a dedicated worktree, never by switching branches in the shared checkout (another session may be working there):
```bash
git worktree add ../<project>-upgrade -b chore/upgrade-template
cd ../<project>-upgrade
```
When done, the user merges the branch and removes the worktree.
3. If `git status` shows changes you did not make, stop until the user says whose they are.
## Phase 1: Recover context
Recover from the project, ask only for what you cannot detect (2-3 questions at most):
- **Project name and language** from the manifest (`pyproject.toml`, `package.json`, `Cargo.toml`, `go.mod`).
- **AI features?** A `prompts/` dir, an LLM SDK in the manifest, or an `<ai-discipline>` block. Confirm yes/no.
- **Agent roster** from `docs/agents.json`; absent means Claude-only. Governs the CC-fence rule and roster gating.
- **mem0?** `docs/memory.md`, a `<memory>` block, or `mem0ai` in the manifest. Absent: ask once (default no).
- **Quality-gate command** from `docs/language-standards.md` or the manifest scripts.
- **Codex?** An existing "Second opinion (Codex)" section in `reviewer.md`, or a Codex roster note, means opted in: keep it, never remove it on a "no". No trace: ask once.
- **From-version** from `.claude/.template-version`. Rewritten only in Phase 4 after success.
## Phase 2: Fetch the current template
```bash
npx --yes degit@2.8.4 kp-multiverse/ForgeWorks/init-project/templates/core#v5.0.0 /tmp/upgrade-core --force
npx --yes degit@2.8.4 kp-multiverse/ForgeWorks/init-project/templates/profiles/<lang>#v5.0.0 /tmp/upgrade-profile --force
npx --yes degit@2.8.4 kp-multiverse/ForgeWorks/init-project#v5.0.0 /tmp/upgrade-skill --force
```
Never pull another language's profile. A language with no profile folder reconciles `core/` only; the toolchain stays the user's. Conditional block texts live in `/tmp/upgrade-skill/templates/conditional/`. Reconcile against this skill's released tag (`v5.0.0`), not `main`.
## Phase 3: Reconcile
Route by the from-version: below 3.0.0, install the `v3.0.0`-tagged upgrade skill first. Below 4.0.0, run **Phase 3-D** instead of A-C, then the v5 delta in 3-C. On 4.x or later, run A-C-E-F below.
**A. File ABSENT in the project (additive).** Apply roster and frontend gating first, exactly like `render.py`: `.claude/agents/`, `.claude/hooks/`, `.claude/settings.json`, and the `CLAUDE.md` symlink are not additive without `claude-code` in the roster; `docs/design/` and the tokens file are not additive without a frontend. Then:
- No `{{...}}` placeholders: copy verbatim, `chmod +x` any `.sh`.
- Only recoverable placeholders (`{{PROJECT_NAME}}`, `{{LANGUAGE}}`, `{{DATE}}`, `{{TEST_PATH_REGEX}}`, `{{QA_COMMAND}}`, `{{SOURCE_SUFFIXES}}`, `{{CODEX_REVIEW_STEP}}`): substitute from Phase 1 and the fetched `profile.json`, copy, then apply the fence rules below.
- Unresolvable placeholders: never half-write one. Report "add manually" with the template path.
- Interview-sourced placeholders (mostly `docs/PRD.md`): queue for the Phase 3-E mini-interview.
Special cases:
- `.claude/settings.json`: merge every `PreToolUse` hook the template ships into the existing `hooks` object; never replace the file.
- **AI fences** (`<!-- AI-*-START/END -->` in `docs/SECURITY.md` and `reviewer.md`): AI on, drop only the markers; AI off, drop the block. **CC fences** (`<!-- CC-*-START/END -->`, keyed on `claude-code` in the roster): same mechanic.
- Python manifest: `pyproject.toml.example` is the merge source for the existing `pyproject.toml`, never a new file.
- `.devcontainer/`: respect the original opt-out; note availability once.
- `docs/agents.md` + `docs/agents.json`: cannot be recovered. Ask the roster question and write both.
**B. File PRESENT in both (merge target).** Insert what is new, preserve what the project filled in.
- `AGENTS.md`: reconcile by `<!-- FW-BLOCK: <name> vX.Y.Z -->` markers, not judgment. Current block names: `project`, `commands`, `etiquette`, `hard-rules`, `tiers`, `communication`, `context`, `learning`, `roster`, plus the conditional `ai-discipline` and `memory`. Block absent: insert at its template position. Older marker version: show both versions side by side once in the Phase 4 report; the user chooses. Current version: skip. A block with no markers on a 4.x project: match by tag, wrap with markers at the from-version, then re-enter the rule. Conditional blocks take their text from `/tmp/upgrade-skill/templates/conditional/` and only when the project uses the feature. Flag the retired `risk-tiers` block for removal if still present.
- Subagents (`reviewer.md`, `utility.md`) and the three skills: template-owned procedure files. If the project's copy is byte-identical to an older release, queue the current version as a straight update; if hand-edited, show the diff and let the user choose. Never assume the template is ahead; the project may carry a fix (report it upstream).
- Any other file in both (hooks, `.mcp.json`, workflows, doc templates): same rule.
**C. Tooling delta (language-gated).** Compare the fetched profile's manifest, scripts, and CI against the project's and surface the diffs. High-value checks per language:
- **Python**: `e2e` and `security` pytest markers registered; `pytest-playwright` in the dev group; the fast gate runs `pytest -m "not e2e"`; `scripts/linecap.sh` runs first in `scripts/qa.sh`; `[tool.mypy] mypy_path = "src"`; no stray `src/__init__.py` under the flat-import convention.
- **TypeScript**: `qa`/`fix`/`e2e` npm scripts and a non-vulnerable dev-dep set match the profile; `eslint.config.js` carries the `max-lines` rule.
- **Go**: a supported Go in `go.mod`; the pinned `golangci-lint` v2 in CI; `scripts/linecap.sh` first in `qa.sh`; `go test -race` in both runners.
- **Rust**: `qa.sh` runs linecap, `cargo fmt --check`, clippy with `-D warnings`, `cargo check`, `cargo test`; e2e tests `#[ignore]`-tagged and run only by `scripts/e2e.sh`; `rust-toolchain.toml` pins the toolchain.
Language-independent deltas, oldest first (each idempotent; skip what already landed):
- *Since v4.1.0*: `scripts/dup_check.py` (substitute `{{SOURCE_SUFFIXES}}`) and the `dup-check` job; run `python3 scripts/dup_check.py --baseline` so existing findings stop failing while new ones do, and add a burn-down `features.json` entry. `scripts/resume.py` and the `resume-check` job. The `checkpoint-budget` job.
- *Since v4.4.2*: ask the owner one question, `weight: lite or full?`; add `weight` and `model_tiers` to `docs/agents.json` (Claude roster: `mechanical: haiku`, `standard: sonnet`, `judgment: inherit`; other rosters: TODOs). If lite, apply the template's `# FW-LITE-START/END`-fenced lines to `qa.yml` without the markers. `scripts/prune.py` and its `--check` step in the `docs-budget` job. `docs/proposals-ideas.md` is retired: promote anything live to todo entries and delete it.
- *Since v4.6.0*: `.claude/hooks/tree-claim.sh` (claude-code rosters) merged into `settings.json`; `.claude/worktrees/` and `.claude/.tree-claim` in `.gitignore`.
- *Since v4.7.0*: `scripts/skills_doctor.py` and the fetched `scripts/factory_doctor.sh`. Run the skills doctor once and put its findings first in the Phase 4 report; the fix (`/plugin`) is the owner's.
- *Since v5.0.0 (the lean loop)*: the loop's state moved from `docs/LEDGER.md` into each `features.json` entry (`phase`, `next`), deviations moved into the entry's `notes`, and `docs/archive/` is retired.
1. Copy `scripts/feature.py`; replace `scripts/resume.py`, `scripts/prune.py`, `scripts/backlog.py`, `scripts/features_check.py` with the fetched versions (template-owned; diff first).
2. For the in-progress feature (at most one), read its last ledger line and set `phase=<grill|red|green|review>` and `next="..."` with `python3 scripts/feature.py <id> ...`. Every other feature's ledger lines describe closed work; the commits are the record. Delete `docs/LEDGER.md`.
3. For each open feature's `docs/deviations.md` lines, append them to that feature's `notes` verbatim (`notes+=`). Delete `docs/deviations.md`.
4. Delete `docs/archive/` after the same citation grep as 3-F.
5. Replace the `docs-budget`, `checkpoint-budget`, and `resume-check` jobs in `qa.yml` with the fetched versions (this release changes the `AGENTS.md` cap from lines to characters and drops the retired files; show the diff).
6. Replace the `iteration` skill (now `SKILL.md` plus `reference/dispatch.md`), `reviewer.md`, `utility.md`, `security-review`, `tech-debt`, `docs/plans/README.md`, and the PR template with the fetched versions; graft every `AGENTS.md` block at v5.0.0 through 3-B (all nine blocks changed: shorter, and the conflicts with the harness's own system prompt removed). A hand-edited `AGENTS.md` must land under the new character cap; delete stale sentences rather than rewrite them.
**E. Mini-interview.** Collect every queued interview-sourced placeholder, dedupe, ask only those questions in one message (using the Phase 2 wording from `init-project/SKILL.md`), substitute, write. The upgrade ends with zero `{{...}}` on disk. A declined question writes `TODO(interview-skipped)`.
**F. Doc compaction.** The only step that edits project content; every deletion goes in the Phase 4 report as a named list and applies on the owner's yes. Bring each budgeted doc under its cap by deleting, not by moving bytes: `docs/SECURITY.md` (fold per-feature subsections back into the fixed sections; delete surfaces the project no longer has), `docs/gotchas.md` (entries the code now makes impossible), plans for merged features (`docs/plans/archive/` is retired; move any plan whose feature is not done back to `docs/plans/`), mockups no entry cites, probes nothing cites (`grep -rn "docs/probes/" .` first). Report before/after sizes. Within 5% of a cap is shaving, not compacting.
### Phase 3-D: v3 -> v4 migration (replace, not accumulate)
Only for a project below 4.0.0, after the owner's accept, and idempotent (copy-if-absent, graft only markers not at the current version, remove-if-present). The removal step runs last so the project always has a working harness. Apply roster and frontend gating throughout.
1. **Copy in the current files**: the `iteration` skill, `.claude/agents/reviewer.md` (claude-code roster only), `docs/BACKLOG.md`, `docs/PRD.md` (skeleton; step 3 distills the retired `PRODUCT_VISION.md` into it), every `scripts/*` the fetched template has (replace `features_check.py`; the v3 copy enforces retired tiers), `scripts/tamper_check.py` (substitute `{{TEST_PATH_REGEX}}`), and every CI job the fetched `qa.yml` carries that the project lacks. Overwrite the `security-review` and `tech-debt` skills with the fetched text.
2. **Graft the `AGENTS.md` blocks** (3-B rules). `risk-tiers` is replaced by `tiers`; `communication` and `context` are new inserts between `tiers` and `learning`.
3. **Carry, never regenerate, project content**: `features.json` entries (add `"surface": "none"`; remap `tier`: `light` -> `chore`, `standard`/`high-risk` -> `feature`), plans for features not yet done, gotchas, mockups, SECURITY.md project sections. Run 3-F over the carried content. Distill `PRODUCT_VISION.md` into `docs/PRD.md`.
4. **Remove superseded files** after confirming with the owner: `.claude/skills/slice/`, `design-loop/`, `select-agents/`, `.claude/agents/implementer.md`, `code-reviewer.md`, `design-reviewer.md`, `security-reviewer.md`, `docs/PRODUCT_VISION.md`, `docs/plans/archive/`, and a stale `.claude/skills/init-project/`.
5. **Fresh-render diff.** Render a fresh tree from a reconstructed answers file (ask for `surfaces`, or `TODO(interview-skipped)`), diff the harness files against the project, and report each difference as: matches fresh render / project-specific keeper / leftover v3 debris.
6. **Fallback.** Heavy drift means recommend "fresh render + carry-over" instead of a half-migration, and stop for the owner's decision.
## Phase 4: One report, one approval, then verify and stamp
1. Compute the entire change set. Present one report with five buckets: copy verbatim, graft (blocks by name), substitute (with values), needs your answer, superseded (flagged for removal). Collect the answers and a single yes.
2. Apply everything; `chmod +x` new scripts and hooks.
3. Ensure `docs/plans/`, `docs/probes/`, and (frontend) `docs/design/mockups/` exist with current READMEs.
4. Run the language quality gate, `python3 scripts/features_check.py`, `python3 scripts/resume.py --check`, and `python3 scripts/prune.py --check`; fix any breakage the upgrade introduced.
5. Only after all pass, write the new version to `.claude/.template-version`.
6. `rm -rf .claude/skills/upgrade-project`. A stale copy is what the next upgrade must not reconcile against; the installer re-fetches the current one.
7. Close with: "Upgraded <from> -> <to> in one run. Review the diff and commit on your branch. Nothing was overwritten without being shown first."
## Failure modes
- **Uninitialized directory.** Stop; run `/init-project`.
- **`degit` fails.** Stop with the cause; the upgrade needs the current template.
- **`AGENTS.md` heavily rewritten.** Show the missing blocks and let the user place them.
- **Re-run after a partial upgrade.** Safe; every step skips what already landed.
## Note for template maintainers
A new always-on, placeholder-free file in `core/` is picked up automatically. Touch this skill only for: a file with tooling placeholders (extend 3-A), a tooling-delta step (extend 3-C), a new `AGENTS.md` block that needs special placement (note it in 3-B), or a structural change old projects must migrate (a dated 3-C delta, like v5.0.0's). New interview-sourced placeholders go in the 3-A discovery list so 3-E asks for them.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!