Adopt a v2.x ai-sdlc-harness workspace into v3.0 — config carries over, run history stays archived in place. USER-ENTRY and HUMAN-ONLY — invoke only when the user explicitly runs /migrate-workspace; never autonomously, never from a subagent (guard-enforced).
Scanned 8/30/2026
Install to Claude Code
npx -y skills add MostAshraf/ai-sdlc-harness --skill migrate-workspace --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Migrate Workspace?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mostashraf-migrate-workspace)More formats (shields.io, HTML) on the badges page.
---
name: migrate-workspace
description: >
Adopt a v2.x ai-sdlc-harness workspace into v3.0 — config carries over,
run history stays archived in place. USER-ENTRY and HUMAN-ONLY — invoke
only when the user explicitly runs /migrate-workspace; never autonomously,
never from a subagent (guard-enforced).
---
# migrate-workspace — adopt a v2.x workspace
**The fork seam:** this file and `harness/migrate.py` are the replaceable
unit — forks ship different adoption logic by swapping them and nothing
else. Everything that WRITES goes through the same owned path as
`/init-workspace` (`init-section` → `init-verify` → `init-finalize`);
migrate verbs are read-only proposals.
Human-only, same invocation rules as every skill here: always the full
`${CLAUDE_PLUGIN_ROOT}/bin/harness <verb>` path. First run
`/init-workspace`'s **step 0 environment bootstrap** exactly as written
there (that file owns the procedure — don't re-derive it).
## 1 · Detect (stop conditions first)
```
${CLAUDE_PLUGIN_ROOT}/bin/harness migrate-detect
```
- Surface `warnings` verbatim whenever present — e.g. an unreadable
`overrides.yaml` reports as bootstrapped *fail-closed*, and the
remediation lives in the warning, not here.
- `already_bootstrapped: true` → this workspace already runs v3.0. If
`inventory.legacy_context_files` is non-empty, a prior migration stopped
before archiving — offer the **archive-only finish** (steps 5–6; the
report on this path records `inventory` only, since `migrate-extract`
rightly refuses post-bootstrap — the carried-config record lives in the
earlier attempt's confirmations); otherwise **stop** and point the user
at `/workspace-config`.
- `legacy: null` → **stop**: nothing to adopt; point at `/init-workspace`.
- Otherwise show the `evidence` list (why this looks like v2.x), then the
`inventory`:
- **`in_flight` runs get a hard boundary, stated plainly:** run history
is never converted — v3.0 state is sealed evidence (red-proofs,
ledgers) that v2.x never produced, so migrating a half-done run would
fabricate its audit trail. **Recommend finishing or abandoning those
stories on v2.x before migrating**: step 5 archives the very config
files v2.x resumes from, so proceeding now means a later v2.x session
must first hand-restore them from `legacy-2.1/`. Proceeding anyway is
the user's call — record the choice in the step-5 report.
- Old `ai/` run dirs and `aborted` leftovers stay exactly where they are
as readable archives; v3.0 run discovery ignores them.
## 2 · Extract & confirm (propose-only)
```
${CLAUDE_PLUGIN_ROOT}/bin/harness migrate-extract
```
Present the proposal per section — `provider`, `repos`, `language` — next
to every `notes` entry (missing repo paths, unverifiable stories_dir) and
the `unmapped` list (what v2.x config has no v3.0 home, and why). The user
confirms or corrects **each section**; anything extract could not fill
falls through to the matching `/init-workspace` interview question — never
guess a value extraction didn't find.
**Re-entry:** if a target section file already exists under
`.claude/context/` (a prior attempt got that far), read it and present its
current value next to the legacy-derived proposal — never silently
re-propose stale legacy data over a correction the user already confirmed.
`optional_overrides.naming` is **opt-in, default NO**: translated v2.1
naming templates are usually the v2.1 defaults the user never chose, and
v3.0's `{type}/{id}-{slug}` handles change-types better than a frozen
`feature/` prefix. Offer it only as "did you deliberately customize
naming in v2.x?".
## 3 · Apply through the owned init path
Write each confirmed section with `init-section` exactly as
`/init-workspace` step 1 documents (self-nested payloads; `overrides`
flat). Then fill the gaps the same way that interview does:
- No `language` proposal for a repo → `discover --repo <path>` and confirm
(its dirty-repo/default-branch cautions live in `/init-workspace` step 2).
**`discover` switches a clean repo back to its default branch** — if
`inventory.in_flight` names a story whose v2.x feature branch may be
checked out in that repo, say so and get explicit confirmation first.
- MCP-transport providers (`jira`, `zoho`, `ado-mcp`) → the
model-in-the-loop MCP checklist from the interview applies unchanged.
## 4 · Verify + finalize (the same real gate)
`/init-workspace` step 4, verbatim: `init-verify` must pass (fix failures,
re-run), then `init-finalize`. A migrated workspace ends in exactly the
state a freshly-interviewed one does — there is no "migrated" flavor to
special-case later.
## 5 · Archive the legacy config
List the v2.x context files (`inventory.legacy_context_files`), confirm
with the user, then move them aside so nobody mistakes them for live
config:
```
mkdir -p .claude/context/legacy-2.1 && mv .claude/context/*.md .claude/context/legacy-2.1/
```
Write `.claude/context/legacy-2.1/migration-report.md`: what carried over
(per section), the full `unmapped` and `notes` lists, and any in-flight
v2.x stories with the finish-on-v2.x guidance. The old `ai/` dirs are the
run archive; this report is the config-decision record.
## 6 · Hand over
- `local-markdown` users: existing story files work in place — v2.1
`> Status:` blockquotes are read tolerantly and upgrade to the v3.0
`Status:` form on first write-back.
- Remote-provider users: work items live server-side; nothing moved.
- Offer repo-map generation (`/repo-map-refresh` owns the procedure),
then: `/dev-workflow <work-item-id>` is ready.
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!