Relocate Idea
A thin shell over specscore idea relocate. All relocation mechanics — pre-flight clean-tree checks, file copy + in-file rewrite, cross-repo link cleanup, per-repo commits, rollback on failure — live in the CLI. This skill exists to:
- Make the verb conversation-triggerable (
/relocate-idea).
- Prompt for missing arguments before shelling out.
- Surface the CLI's stdout/stderr verbatim and propagate its exit code.
- Append an opt-in mismatch-log line on success so a future Feature can tune the sidekick destination-resolution prompt against real correction signal.
Hard Gate
When to Use
- The user (or you, on the user's behalf) determines that an Idea or seed in the current repo belongs in a different SpecScore-managed repo.
- The user is reacting to a sidekick-capture destination mismatch: the seed went to repo A but should be in repo B.
- The user explicitly types
/relocate-idea or one of the other triggers.
Pre-flight
CLI present (mandatory-class detection). relocate-idea is a thin wrapper over specscore idea relocate with no fallback — a mandatory-class skill per ../shared/cli-detection.md. Do not run a standalone command -v probe; detect via the relocate call's exit status (see ## Invocation). If that call exits 127 (binary not installed), emit the standardized install message verbatim and stop without writing:
The specscore CLI is not installed. Invoke /specscore:install to see install options, or install from https://specscore.md/install. Then retry your command.
On any other non-zero exit, surface the CLI's error. Stop. Do not proceed.
Collect arguments. The skill needs two values:
- slug — the artifact's slug (basename of
spec/ideas/<slug>.md or spec/ideas/seeds/<slug>.md in the source repo).
- target — value for
--to-repo. Either a repo slug (no / — resolved via sibling-dir scan against each candidate's project.repo) or a path (contains / — resolved relative to source project root, or absolute).
If either is missing from the trigger arguments, ask the user, one batched question, before shelling out. Suggested phrasing:
Which artifact do you want to relocate (slug) and where to (--to-repo value)?
Do not infer either value silently from cwd or recent history. The CLI's slug-resolution (REQ slug-resolves-idea-or-seed — Idea first, then seed) handles the path lookup once you have the bare slug.
Optional flag. If the user passed --no-commit (verbatim, no synonyms), pass it through to the CLI. Otherwise, omit it.
Invocation
Shell-exec the CLI verb:
specscore idea relocate <slug> --to-repo=<target> [--no-commit]
Run it from the source repo's working directory (the user's cwd at invocation time). Capture both stdout and stderr. Capture the exit code.
The skill MUST NOT add additional flags, environment variables, or pre/post commands beyond the shell-exec itself. The CLI's cli/idea/relocate Feature is the contract — don't paper over it.
Output handling
On exit 0 (success)
Surface the CLI's full stdout to the host conversation verbatim. The format the CLI emits is the stdout-format contract — per-repo lines plus a summary line. Do not paraphrase, summarize, or add inference.
Append one JSON line to .specscore/destination-resolution-log.jsonl (see "Mismatch log" below).
Exit 0.
On any non-zero exit
Surface the CLI's full stderr to the host conversation verbatim, including any user-runnable rollback commands the CLI printed (e.g., git -C <repo> reset HEAD~1 --hard). Do NOT paraphrase, summarize, or strip whitespace/formatting.
Propagate the CLI's exit code as the skill's exit code. The CLI's exit-code contract defines the semantics; don't reinterpret them.
Do NOT append a mismatch-log line on failure — the log records corrections, not attempts.
Mismatch log
On exit-0 success only, append one single-line JSON object to .specscore/destination-resolution-log.jsonl in the user's cwd at the moment the skill was invoked (the source repo — i.e., the repo where the misfiled artifact lived before the relocate). Create the .specscore/ directory lazily if it doesn't exist.
Record schema
{
"ts": "<ISO-8601 UTC, e.g., 2026-05-21T14:32:00Z>",
"kind": "idea" | "seed",
"slug": "<artifact-slug>",
"original_repo": "<source-repo's project.repo value>",
"correct_repo": "<target-repo's project.repo value>"
}
Field sources:
- ts — current time, UTC, ISO-8601.
- kind — parse from the CLI's stdout: the
moved/received/updated-links lines are formatted <repo-slug>: <action> <kind> <slug> [<sha>]. The <kind> token is the third field after the colon (idea or seed).
- slug — the slug argument the user supplied.
- original_repo — the
<repo-slug> on the line whose action is moved (the source). If parsing fails, fall back to reading project.repo from the source repo's specscore.yaml.
- correct_repo — the
<repo-slug> on the line whose action is received (the target).
Implementations MAY add additional fields (e.g., the agent's pick at original-write time, retrieved via session state or absent if unknown). Consumers tolerate unknown fields. Schema evolution is permissive at this stage.
Best-effort discipline (REQ relocate-skill-writes-mismatch-log + AC relocate-skill-log-write-failure-non-blocking)
The log write is best-effort. On any failure (directory creation fails, file unwritable, disk full, permission denied):
Display a single short warning line to the host conversation:
Warning: could not append destination-resolution log line: <error>. The relocate succeeded.
Do NOT modify the skill's exit code — still propagate the CLI's exit-0.
Do NOT retry. The seed write being durable matters; the log being durable does not.
Anti-patterns
| Anti-pattern |
Why it's wrong |
Reading the source artifact, doing the in-file specscore/ → specscore/ rewrite locally, then "letting the CLI commit" |
The CLI's contract is the whole relocate, not a tail end. Splitting the rewrite into the skill creates two implementations of the same substitution rules. |
| Paraphrasing the CLI's stderr ("The CLI hit a conflict; you may want to ...") |
The CLI's stderr includes exact rollback commands per REQ:stop-on-first-commit-failure. Paraphrasing strips actionability. |
Auto-running git commit in the source repo because "the CLI's --no-commit left things staged" |
If the user passed --no-commit, they want to commit manually. The skill's exit reproduces the CLI's behavior — staged-not-committed is the requested outcome. |
Adding --include-code or other flags the CLI doesn't yet support |
The CLI's scope is the SpecScore-doc relocate. Code-annotation cleanup is deferred to a later CLI version. The skill should not invent flags the CLI rejects. |
Hardcoding --to-repo=specscore because the most common target is the specscore repo |
Forecloses on every other target. The skill is a generic wrapper, not a specscore-targeted shortcut. |
See also
1---2name: relocate-idea3description: Thin wrapper over the `specscore idea relocate` CLI verb. Relocates an Idea or sidekick-seed artifact from the current repo to another SpecScore-managed repo by shell-execing the CLI and surfacing its output verbatim. On success, appends one JSON line to `.specscore/destination-resolution-log.jsonl` in the source-repo cwd so future destination-resolution tuning can learn from misroute corrections. Triggers: "specstudio:relocate-idea", "/relocate-idea", "relocate this idea", "move this seed to another repo".4---56# Relocate Idea78A thin shell over [`specscore idea relocate`](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md). All relocation mechanics — pre-flight clean-tree checks, file copy + in-file rewrite, cross-repo link cleanup, per-repo commits, rollback on failure — live in the CLI. This skill exists to:9101. Make the verb conversation-triggerable (`/relocate-idea`).112. Prompt for missing arguments before shelling out.123. Surface the CLI's stdout/stderr verbatim and propagate its exit code.134. Append an opt-in mismatch-log line on success so a future Feature can tune the sidekick destination-resolution prompt against real correction signal.1415## Hard Gate1617<HARD-GATE>18This skill MUST NOT replicate any of the CLI verb's logic. No file copy, no in-file rewrite, no link rewriting, no git commit/stage, no rollback computation happens in this skill — every one of those concerns lives inside `specscore idea relocate` and stays there. The skill's job is argument collection, shell-out, output surfacing, and a single best-effort log-line append. If the CLI is not on PATH, surface the install path (`/specscore:install`) and stop — do NOT fall back to an ad-hoc reimplementation.19</HARD-GATE>2021## When to Use2223- The user (or you, on the user's behalf) determines that an Idea or seed in the current repo belongs in a different SpecScore-managed repo.24- The user is reacting to a sidekick-capture destination mismatch: the seed went to repo A but should be in repo B.25- The user explicitly types `/relocate-idea` or one of the other triggers.2627## Pre-flight28291. **CLI present (mandatory-class detection).** `relocate-idea` is a thin wrapper over `specscore idea relocate` with no fallback — a **mandatory-class** skill per [`../shared/cli-detection.md`](../shared/cli-detection.md). Do **not** run a standalone `command -v` probe; detect via the relocate call's exit status (see `## Invocation`). If that call exits `127` (binary not installed), emit the standardized install message verbatim and stop without writing:30 > The `specscore` CLI is not installed. Invoke `/specscore:install` to see install options, or install from <https://specscore.md/install>. Then retry your command.31 On any other non-zero exit, surface the CLI's error. Stop. Do not proceed.32332. **Collect arguments.** The skill needs two values:34 - **slug** — the artifact's slug (basename of `spec/ideas/<slug>.md` or `spec/ideas/seeds/<slug>.md` in the source repo).35 - **target** — value for `--to-repo`. Either a repo slug (no `/` — resolved via sibling-dir scan against each candidate's `project.repo`) or a path (contains `/` — resolved relative to source project root, or absolute).3637 If either is missing from the trigger arguments, **ask the user**, one batched question, before shelling out. Suggested phrasing:38 > Which artifact do you want to relocate (slug) and where to (`--to-repo` value)?3940 Do not infer either value silently from cwd or recent history. The CLI's slug-resolution (REQ `slug-resolves-idea-or-seed` — Idea first, then seed) handles the path lookup once you have the bare slug.41423. **Optional flag.** If the user passed `--no-commit` (verbatim, no synonyms), pass it through to the CLI. Otherwise, omit it.4344## Invocation4546Shell-exec the CLI verb:4748```bash49specscore idea relocate <slug> --to-repo=<target> [--no-commit]50```5152Run it from the source repo's working directory (the user's cwd at invocation time). Capture both stdout and stderr. Capture the exit code.5354The skill MUST NOT add additional flags, environment variables, or pre/post commands beyond the shell-exec itself. The CLI's [`cli/idea/relocate`](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md) Feature is the contract — don't paper over it.5556## Output handling5758### On exit 0 (success)59601. Surface the CLI's full stdout to the host conversation verbatim. The format the CLI emits is the [stdout-format contract](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md#req-stdout-format) — per-repo lines plus a summary line. Do not paraphrase, summarize, or add inference.61622. Append one JSON line to `.specscore/destination-resolution-log.jsonl` (see "Mismatch log" below).63643. Exit 0.6566### On any non-zero exit67681. Surface the CLI's full stderr to the host conversation **verbatim**, including any user-runnable rollback commands the CLI printed (e.g., `git -C <repo> reset HEAD~1 --hard`). Do NOT paraphrase, summarize, or strip whitespace/formatting.69702. Propagate the CLI's exit code as the skill's exit code. The CLI's [exit-code contract](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md#exit-codes) defines the semantics; don't reinterpret them.71723. Do NOT append a mismatch-log line on failure — the log records corrections, not attempts.7374## Mismatch log7576On exit-0 success only, append one single-line JSON object to `.specscore/destination-resolution-log.jsonl` in the user's cwd at the moment the skill was invoked (the source repo — i.e., the repo where the misfiled artifact lived before the relocate). Create the `.specscore/` directory lazily if it doesn't exist.7778### Record schema7980```json81{82 "ts": "<ISO-8601 UTC, e.g., 2026-05-21T14:32:00Z>",83 "kind": "idea" | "seed",84 "slug": "<artifact-slug>",85 "original_repo": "<source-repo's project.repo value>",86 "correct_repo": "<target-repo's project.repo value>"87}88```8990Field sources:9192- **ts** — current time, UTC, ISO-8601.93- **kind** — parse from the CLI's stdout: the `moved`/`received`/`updated-links` lines are formatted `<repo-slug>: <action> <kind> <slug> [<sha>]`. The `<kind>` token is the third field after the colon (`idea` or `seed`).94- **slug** — the slug argument the user supplied.95- **original_repo** — the `<repo-slug>` on the line whose action is `moved` (the source). If parsing fails, fall back to reading `project.repo` from the source repo's `specscore.yaml`.96- **correct_repo** — the `<repo-slug>` on the line whose action is `received` (the target).9798Implementations MAY add additional fields (e.g., the agent's pick at original-write time, retrieved via session state or absent if unknown). Consumers tolerate unknown fields. Schema evolution is permissive at this stage.99100### Best-effort discipline (REQ `relocate-skill-writes-mismatch-log` + AC `relocate-skill-log-write-failure-non-blocking`)101102The log write is **best-effort**. On any failure (directory creation fails, file unwritable, disk full, permission denied):1031041. Display a single short warning line to the host conversation:105 > Warning: could not append destination-resolution log line: `<error>`. The relocate succeeded.1061072. Do NOT modify the skill's exit code — still propagate the CLI's exit-0.1083. Do NOT retry. The seed write being durable matters; the log being durable does not.109110## Anti-patterns111112| Anti-pattern | Why it's wrong |113|---|---|114| Reading the source artifact, doing the in-file `specscore/` → `specscore/` rewrite locally, then "letting the CLI commit" | The CLI's contract is the *whole* relocate, not a tail end. Splitting the rewrite into the skill creates two implementations of the same substitution rules. |115| Paraphrasing the CLI's stderr ("The CLI hit a conflict; you may want to ...") | The CLI's stderr includes exact rollback commands per [REQ:stop-on-first-commit-failure](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md#req-stop-on-first-commit-failure). Paraphrasing strips actionability. |116| Auto-running `git commit` in the source repo because "the CLI's --no-commit left things staged" | If the user passed `--no-commit`, they want to commit manually. The skill's exit reproduces the CLI's behavior — staged-not-committed is the requested outcome. |117| Adding `--include-code` or other flags the CLI doesn't yet support | The CLI's scope is the SpecScore-doc relocate. Code-annotation cleanup is deferred to a later CLI version. The skill should not invent flags the CLI rejects. |118| Hardcoding `--to-repo=specscore` because the most common target is the specscore repo | Forecloses on every other target. The skill is a generic wrapper, not a `specscore`-targeted shortcut. |119120## See also121122- CLI verb spec: [`cli/idea/relocate`](https://github.com/specscore/specscore-cli/blob/main/spec/features/cli/idea/relocate/README.md) — the source of truth for behavior, exit codes, and stdout/stderr format.123- Companion Feature: [`sidekick-capture/destination-resolution`](../../spec/features/sidekick-capture/destination-resolution/README.md) — the broader context in which this skill exists; the sidekick pre-write hook + this recovery skill ship together.124- Source Idea: [`idea-skills-destination-resolution`](../../spec/ideas/idea-skills-destination-resolution.md) — the rationale for the two-Feature change and the design constraints both halves inherit.