Change one config section (overrides / provider / language / repos) on an already-bootstrapped workspace, without re-running the full /init-workspace interview. USER-ENTRY — invoke only when the user explicitly runs /workspace-config; 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 workspace-config --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Workspace Config?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mostashraf-workspace-config)More formats (shields.io, HTML) on the badges page.
---
name: workspace-config
description: >
Change one config section (overrides / provider / language / repos) on an
already-bootstrapped workspace, without re-running the full /init-workspace
interview. USER-ENTRY — invoke only when the user explicitly runs
/workspace-config; never autonomously, never from a subagent
(guard-enforced).
---
# workspace-config
Every command below is `${CLAUDE_PLUGIN_ROOT}/bin/harness <verb> …` — run it
yourself via Bash. Never ask the user to type a `harness` command; the user
only answers the questions below.
Not this skill's job: **registering a brand-new repo** (that's `/add-repo` —
discovery, duplicate-name/path refusal, permission-allowlist refresh; this
skill only *changes* an already-registered repo's path/name/`test_cmd`), and
**first-time setup** (`/init-workspace`'s interview).
## 0 · Confirm the workspace is actually bootstrapped
**Resolve the plugin root** if not already set (native Qwen first run —
each Bash call is a fresh subprocess, so the probe prints the path for
textual substitution). Same resolution logic as `/init-workspace` step 0:
```
R="${CLAUDE_PLUGIN_ROOT:-}"; [ -z "$R" ] && {
for p in "$HOME/.qwen/extensions/ai-sdlc-harness/bin/harness" \
"$HOME/.qwen/extensions/ai-sdlc-harness/.qwen-extension-install.json"; do
[ -e "$p" ] && { case "$p" in *install.json)
R=$(python3 -c "import json,sys;print(json.load(open(sys.argv[1])).get('source',''))" "$p");;
*) R=$(cd "$(dirname "$p")/.." && pwd);; esac
[ -x "$R/bin/harness" ] && break; }; done; }
[ -x "$R/bin/harness" ] || { echo "ERROR: set CLAUDE_PLUGIN_ROOT to the dir with bin/harness" >&2; exit 1; }
echo "PLUGIN_ROOT=$R"
```
**Use the printed path in place of `${CLAUDE_PLUGIN_ROOT}` below.**
Read `.claude/context/overrides.yaml`. Missing, or no `bootstrap_completed`
key: `/init-workspace` never finished — stop and send the user there.
Proceeding anyway reports "the change is live," and the user only learns
otherwise later, at a confusing `bootstrap incomplete` refusal the next
time `/dev-workflow` runs.
## 1 · Ask which section, and what's changing
- `overrides` — any top-level key in `config/defaults/*.yaml` other than
`provider`/`repos`/`language` (`status_mapping`, `subagent_models`,
`quick_mode`, `naming` + `change_types`, `review_rounds`, `stall`,
`repo_map` staleness N, `review_policy`, `security.scan_cmd`/
`severity_order`, …). Most single-setting changes land here.
- `provider` — work-item/git provider + specifics (`stories_dir`,
`github_repo`, `github_project` + `github_project_owner` (+
`github_project_repo`, which keeps board ids bare issue numbers),
`ado_org`, `ado_project`, …).
- `language` — per-repo `test_cmd` / `coverage_cmd` / `quarantine`, under
`language.repos.<name>` (not the whole-workspace `test_paths`/
`test_closure`). Quarantine drops a **known-failing spec unrelated to any
run** from every test + coverage command (`reason` + `since` required,
`init-verify` gates the shape, each run flags the exclusions): `{"language":
{"repos": {"fe": {"test_cmd": "npx vitest run", "quarantine":
{"exclude_template": "--exclude {test}", "tests": [{"test": "t/a.spec.ts",
"reason": "fails on main", "since": "2026-07-22"}]}}}}}` — `language` is a
full REPLACE (§2): re-send every repo's existing keys.
- `repos` — repointing or renaming an *existing* entry's path. A path may be
a checkout root **or** a subtree of one (`<checkout>/frontend`) — that's
how a monorepo's logical repos are registered, one entry per root.
## 2 · Read the current section before writing it
`overrides` deep-merges — a call only needs the keys actually changing:
`init-section --section overrides --json '{"quick_mode": {"loc_max": 50}}'`.
If the `init-section` result carries a `notice` key, relay its text to the
user verbatim.
Exception: a **list**-valued key (`review_policy` is the only shipped one)
still replaces wholesale — dicts recurse, list items don't — so resend the
whole list, including entries you're not changing, or one silently vanishes.
`provider`/`language`/`repos` are full-**replace**: the write IS the whole
file. Read `.claude/context/<section>.yaml` first (Read tool, never a Bash
one-liner), splice in the change, resend the **complete** set — a partial
payload, or a forgotten self-nesting (`{"repos": {...}}` — `overrides` is
the one flat, non-nested exception), silently drops every entry you didn't
restate. For `repos`/`language` this is NOT caught by `init-verify` if it
zeroes the whole map (step 4 covers what verify does check).
**Known gap**: `overrides` only adds/updates keys, never unsets — removing
one needs a direct edit to `overrides.yaml`; say so rather than improvising.
## 3 · Confirm a `test_cmd` change by running it, and mind two risks
Confirm any `test_cmd` change by actually running it in that repo — same
rule `/add-repo`/`/init-workspace` follow, never accept it unconfirmed. Run
it **at the registered path**, which may be a subtree of a checkout: test
commands run with the registered path as their cwd, so a command
confirmed from the enclosing checkout root proves nothing about that logical
repo. Repointing an entry between a checkout root and a subtree of it is a
legal `repos` write (`init-verify` accepts either), but it moves the command's
cwd — re-confirm that repo's `test_cmd` in the same pass.
**Known risks**: (1) `init-section --section repos` has none of `/add-repo`'s
collision checks — a duplicate name (case-insensitive: collides on-disk on
a case-insensitive filesystem) or a path under two names (misattributes
`test_cmd`/`scan_cmd`) writes cleanly; check the full map yourself before
sending it. Renaming also orphans `language.repos.<old-name>`,
`security.scan_cmd.<old-name>`, and `.claude/context/repo-map/<old-name>/`
— carry them to the new name or tell the user to. (2) Avoid repointing a
path or changing a `test_cmd` while a `/dev-workflow` run has in-flight
tasks against that repo — resolution is by exact registered path, so a
run mid-flight can start failing with a confusing "no test command" error.
## 4 · Re-verify if the section could affect verify or permissions
`init-verify` covers `provider`, `repos` (≥1 registered, each path inside a
git work tree — a checkout root *or* any subtree of one, which is how a
monorepo's logical repos register), and `language` (`test_cmd` runnability)
— **not** `overrides`. A `repo:<name>` detail reading `<path> (subtree of
<checkout>)` is a pass stating where the git tree actually is, not a
failure.
- `provider` only: re-run `init-verify`, fix any failure.
- `repos` (a path) or `language` (a `test_cmd` binary): re-run `init-verify`,
**then** `init-finalize` too — that's what refreshes the permission
allowlist (`Read` on the repo path, `Bash` on the `test_cmd` binary) to
the new value; skip it and the OLD path/binary stays allow-listed while
the new one doesn't, so a background/`mode:auto` run hits an unprompted
permission stall the first time it touches the changed repo.
- `overrides` only: no re-verify/re-finalize needed.
## 5 · Tell the user what changed
State the section, the exact keys written, and (if re-verified/re-finalized)
the result.
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!