Skip to content
Agentmart
Submit a tool

harness-upgrade

Upgrade an already-initialized but stale harness project to the current plugin layout, non-destructively and idempotently, with a dry-run preview, then prove…

Skill by Alan-IFT

IndexedMIT
Write a review

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

npx agentmarket install skill/alan-ift-harness-upgrade

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Upgrade an already-initialized but stale harness project to the current plugin layout, non-destructively and idempotently, with a dry-run preview, then prove it with a green verify_all. Use when a project HAS harness but is OLD. NOT /harness-adopt (a project with no harness at all), NOT /harness-language (output language only).

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/harness-upgrade

Tools it pre-approves 8

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read,
  • Write,
  • Edit,
  • Glob,
  • Grep,
  • Bash,
  • AskUserQuestion,
  • TodoWrite

What's inside

Skill name
harness-upgrade
Description
Upgrade an already-initialized but stale harness project to the current plugin layout, non-destructively and idempotently, with a dry-run preview, then prove it with a green verify_all. Use when a project HAS harness but is OLD. NOT /harness-adopt (a project with no harness at all), NOT /harness-language (output language only).
License
MIT
Allowed tools
Read,, Write,, Edit,, Glob,, Grep,, Bash,, AskUserQuestion,, TodoWrite
Instructions
225 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (1)

  • SKILL.md

SKILL.md (first lines)

# /harness-upgrade

Bring a project that was initialized with an **older** harness-kit version up to the
**current** plugin layout: scripts under `.harness/scripts/`, a pre-commit hook pointing
at the new path, settings hook paths rewired, and a freshly-regenerated per-type
`verify_all` — non-destructively, idempotently, with a dry-run preview, then proven with
a green `verify_all`.

> This skill is the **judgment layer**. All mechanical work is done by one deterministic
> helper, `upgrade-project.sh`, which the skill bootstraps from the plugin template
> cache and drives with explicit flags. The skill does NO path string-replacement, NO
> `git mv`, NO settings byte-editing, NO template substitution itself.

## When to invoke

- The project **already has** harness assets (`.claude/settings.json`, `.harness/`, or
  a top-level `scripts/harness-sync.*`) but is on an **old layout** (pre-`.harness/scripts/`).
- **Repair path for a dangling hook (T-020):** `/harness-status` reports a hook as
  `DANGLING` / `MALFORMED`, or the user sees a per-turn
  `Stop hook error: … No such file or directory` — this skill re-lands the current
  scripts (S2), rewires hook paths, and repairs wired literal `{{...}}` placeholder
  tokens to the OS-picked command.
- For a project with **no** harness at all → use `/harness-adopt` instead.
- For a brand-new empty project → use `/harness-init`.

## Procedure

Use `TodoWrite` to track. Stages are gated: never apply without an explicit user "yes".

### 1. Target & precondition gate

The current working directory is the target.

- Confirm `.git/` exists. If not → **halt**, no changes ("not a git repository").
- Confirm SOME harness setup exists: `.claude/settings.json` OR `.harness/` OR a
  top-level `scripts/harness-sync.*`. If **none** → **halt**, point the user at
  `/harness-adopt` ("this project has no harness setup; use /harness-adopt to add it").
- Refuse on a **dirty working tree** (`git status --porcelain` non-empty) with "commit
  or stash your changes first" — this preserves the `git reset` rollback path for all
  tracked edits. (The helper's `.bak` covers the two untracked surfaces: the pre-commit
  hook and `.claude/settings.json`.)

### 2. Locate the plugin template cache + read the target version

Resolve the plugin template root, in this order (first hit wins):

1. **`$CLAUDE_PLUGIN_ROOT`** if set → `$CLAUDE_PLUGIN_ROOT/skills/harness-init/templates`.
   This is best-effort only; it may be unset. If unset, just fall through — do NOT
   depend on it.
2. **Versioned plugin cache glob (load-bearing):**
   `~/.claude/plugins/cache/harness-kit-marketplace/harness-kit/*/skills/harness-init/templates`.
   If multiple versions match, pick the **highest semver** directory.
3. **Dev / marketplace-less fallbacks:**
   `~/.claude/plugins/cache/*/harness-kit/*/skills/harness-init/templates`, then
   `~/.claude/skills/harness-init/templates` (the `/harness-adopt`-era fallback).
4. **None resolve → halt** with an actionable message ("could not locate the harness-kit
   plugin template cache; reinstall the plugin or pass the path manually") and change
   nothing. The helper is never invoked.

The helper's `--template-root` is the directory **above** `skills/harness-init/templates`
— i.e. the resolved cache root `<cache>/harness-kit/<version>/` (the directory that
contains `skills/`). Read `<that>/.claude-plugin/plugin.json` `version` for the **target
version**, and cross-check it against the `<version>` path segment. Surface the
target version (e.g. "Target version: x.y.z") and the project's detected starting
state in the plan you show the user — this is human-facing prose, not a parsed line
(the helper does not emit a `TARGET-VERSION|` record).

> The helper itself does ZERO cache discovery — discovery is judgment (fallbacks, "which
> version"), so it stays in this AI layer. The helper is a pure deterministic transform
> driven by `--template-root`.

### 3. Detect the project type (detect-then-ASK; never silently guess)

Pre-fill the project type from, in order:

1. The `.harness/rules/50-<type>.md` filename (`50-fullstack.md` → fullstack, etc.).
2. Else the old `verify_all`'s header line `=== verify_all (<type>) ===`.

Then **always** confirm with `AskUserQuestion`, pre-filled:

- **Project type** — Fullstack / Backend / Generic.
- For **Generic** only: collect the free-text **stack** string (`{{STACK}}`) from the
  user — it cannot be reliably recovered. (Non-generic templates hardcode their stack
  text, but still pass `--stack` for the substitution the template expects.)

### 4. Self-bootstrap the helper from the cache

Copy `upgrade-project.sh` (and `migrate-scripts-layout.sh` for parity, so
the project ends with the current helpers present) from the resolved
`<template-root>/skills/harness-init/templates/common/.harness/scripts/` into the
project's `.harness/scripts/`. **Do not assume** these pre-exist (the chicken-and-egg
case — a stale project will not have `upgrade-project` yet). Create `.harness/scripts/`
if needed.

> The helper is **cwd-derived (depth-independent)**, so it runs correctly whether you
> invoke it from `scripts/` (before relocation) or `.harness/scripts/` (after).

### 5. Plan (dry-run) → present → confirm → apply

1. Invoke the helper with `--dry-run`, passing `--template-root`, `--type`, `--stack`
   (and `--project-name` / `--today` if you want reproducible output):

   ```
   bash .harness/scripts/upgrade-project.sh --template-root <abs> --type <t> --stack "<s>" --dry-run
   ```

2. **Parse the machine-readable stdout** (one record per line, pipe-delimited):

   | Prefix | Meaning |
   |---|---|
   | `PLAN\|<verb>\|<detail>` | planned action (dry-run) |
   | `RESULT\|<verb>\|<detail>` | applied action |
   | `GAP\|<id>\|<present\|absent>\|<detail>` | gap diagnosis. Kind `template-missing` (T-020): a refresh-set script is absent from BOTH the template and the project — if a hook is wired to it, the terminal congruence scan will fail the run (exit 4). |
   | `TYPE\|<type>` | resolved type |
   | `BAK\|<path>` | backup written |
   | `CONFLICT\|<kind>\|<detail>` | surfaced conflict. Kinds: `hook` (exit 3), `verify_all` (exit 2), `refresh` (a template→project copy did not land), `congruence` (exit 4 — a wired hook command references a missing script or carries an unresolved placeholder token; `<detail>` names the command and the missing path/token) |
   | `SUMMARY\|added=.. moved=.. rewritten=.. rewired=.. conflicts=..` | totals |

   `<verb>` ∈ `MOVE REFRESH REWIRE REWIRE-PLACEHOLDER HOOK-INSTALL HOOK-SKIP

From Alan-IFT/harness-kit, MIT.

More from Alan-IFT/harness-kit

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Aug 8, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from Alan-IFT

Cite this page

harness-upgrade skill. Agent Mart. https://agentmart.dev/skills/alan-ift-harness-upgrade (last updated 2026-10-24)