doc-spec
Store a feature spec.md in the central spec registry (default ~/.claude/spec-registry/<service>/, override with $CLAUDE_DOC_HOME for team-shared registries), or list the specs registered for the curre
Files2
View on GitHubSKILL.mdskills/doc-spec/SKILL.md
GitHubSpec Registry
Why this exists
In the SDD pipeline, /sdd:mr already publishes the feature spec to the registry
(it calls spec-publish.sh when a .specwork/_spec/<slug>-spec.md exists). This
skill is the standalone / vibe-coding counterpart: when you wrote a spec by
hand (or outside the pipeline) and never ran /sdd:mr, /sdd:doc-spec pushes that
file into the same registry so /sdd:doc-spec-query can read it.
Authoring a spec is still the SDD pipeline command /sdd:spec. doc-spec is only the
registry side of the spec lifecycle: it takes an existing spec.md and stores it,
the counterpart to /sdd:doc-spec-query reading it back.
It is a store-only wrapper — it does not generate a spec from your diff. The
file you point at is copied verbatim. For best /sdd:doc-spec-query results the spec
should follow the canonical SDD sections (## Summary, ## Behavior, ## Scope,
## Implementation Context, ## Safe Constraints, ## Open Questions), but this
skill never rewrites or enforces them.
Modes
| Invocation | Action |
|---|---|
/sdd:doc-spec <path> |
Store mode — copy the given spec file into spec-registry/<service>/. |
/sdd:doc-spec (no arg) |
Auto-detect — store the active pipeline spec (.specwork/_spec/<slug>-spec.md for the current branch) if one exists; otherwise stop with usage. |
/sdd:doc-spec list |
List mode — print the specs registered for the current repo's service. Read-only. |
Reject any other argument with a usage message.
Registry Path
All registry I/O resolves through a single environment variable, exactly like
/sdd:doc-catalog, /sdd:doc-adr, and /sdd:doc-spec-query:
REGISTRY="${CLAUDE_DOC_HOME:-$HOME/.claude}/spec-registry"
- Default (no env var set):
~/.claude/spec-registry/. - Override:
export CLAUDE_DOC_HOME=/path/to/registry-root— e.g. a cloned GitLab repo for team-shared specs. The skill writes/reads under$CLAUDE_DOC_HOME/spec-registry/.
Specs are keyed by service exactly like ADRs:
spec-registry/<service>/<slug>-spec.md. The <service> key is derived the same
way /sdd:doc-catalog and /sdd:doc-adr derive it, so the spec-registry/<service>/
key lines up with adr-registry/<service>/.
List Mode
Run when the argument is list. This is scoped to the current repo's service — it
prints only that service's specs and exits before any store logic runs. (To ask
questions across every service, use /sdd:doc-spec-query.)
- Detect the service the same way Store Mode does (see Step 2):
spring.application.name→docs/service-info.mdheading → git repo basename, lowercased. - List that service's specs:
SERVICE="<detected-service>"
DIR="${CLAUDE_DOC_HOME:-$HOME/.claude}/spec-registry/$SERVICE"
if [ ! -d "$DIR" ] || ! ls "$DIR"/*-spec.md >/dev/null 2>&1; then
echo "No specs registered for $SERVICE."
echo "Store one with /sdd:doc-spec <path>, or run the SDD pipeline through /sdd:mr."
exit 0
fi
echo "Specs for $SERVICE in $DIR:"
for spec in "$DIR"/*-spec.md; do
echo " $(basename "$spec")"
done
After listing, exit. Do not proceed to the store steps below.
Store Mode
| Step | Action |
|---|---|
| 1 | Resolve the spec file to store (argument path, or auto-detect) |
| 2 | Detect the service name (same order as /sdd:doc-catalog) |
| 3 | Normalize the destination filename to end in -spec.md |
| 4 | Copy into spec-registry/<service>/ |
| 5 | Confirm, and remind about canonical structure for /sdd:doc-spec-query |
Step 1 — Resolve the spec file
Argument given: treat
$ARGUMENTSas a path. If the file does not exist, stop:Spec file not found: <path> Pass the path to a spec markdown file: /sdd:doc-spec docs/my-feature-spec.mdNo argument: look for an active pipeline spec for the current branch:
BRANCH="$(git branch --show-current)" SPEC="$(find .specwork/_spec -name "*-spec.md" -type f 2>/dev/null | head -1)"If found, use it. If not, stop with usage (do not guess at random files):
Nothing to publish. Pass a spec file path: /sdd:doc-spec docs/my-feature-spec.md Or run this from a project with an active SDD pipeline (.specwork/_spec/).
Step 2 — Detect the service name
Try in order (first hit wins) — the same order /sdd:doc-catalog, /sdd:doc-adr,
and spec-publish.sh use, so the service-catalog, adr-registry, and spec-registry
all agree on one key per service:
spring.application.namefromsrc/main/resources/application.yml/.yaml(orapplication.properties) — authoritative for Spring services.- the first
# <ServiceName>heading ofdocs/service-info.md(kebab-cased). - git repo basename:
git rev-parse --show-toplevel | xargs basename
Lowercase the result to kebab-case. If nothing resolves, use unknown.
Step 3 — Normalize the destination filename
/sdd:doc-spec-query only discovers files matching *-spec.md, so the destination name
must end in -spec.md:
- If the source basename already matches
*-spec.md, keep it. - Otherwise derive a slug and append
-spec.md:- Prefer the current branch name with its type prefix stripped
(
feature/payment-retry→payment-retry). - Else use the source basename without its extension.
- A bare
spec.mdmust not becomespec-spec.md— fall back to the branch slug, or ask the user for a slug if neither a branch nor a meaningful basename is available.
- Prefer the current branch name with its type prefix stripped
(
Result: DEST_NAME="<slug>-spec.md".
Step 4 — Copy
REGISTRY="${CLAUDE_DOC_HOME:-$HOME/.claude}/spec-registry"
DEST="$REGISTRY/<service>"
mkdir -p "$DEST"
cp "<spec-file>" "$DEST/<DEST_NAME>"
This is a plain copy into the local-or-shared registry. It does not commit anything to the project repo.
Step 5 — Confirm
After the copy succeeds, list the specs now registered for that service so the user sees the result:
ls -1 "$DEST"/*-spec.md 2>/dev/null | xargs -n1 basename | sort
Then print:
Published: <spec-file> → ~/.claude/spec-registry/<service>/<DEST_NAME>
<service> now has:
<slug-a>-spec.md
<slug-b>-spec.md
Run /sdd:doc-spec-query to ask feature/spec questions across services.
If the published spec is missing canonical sections, add a one-line note (do not
fail): "Tip: /sdd:doc-spec-query reads ## Summary, ## Behavior, ## Scope,
## Safe Constraints, and ## Open Questions — add them for richer answers."
Rules
- Store-only — never generate or rewrite the spec; copy it verbatim.
- Never commit anything to the project repo (it is a
cpinto the registry). - Destination filename must end in
-spec.mdor/sdd:doc-spec-querywill not find it. - The
<service>key must match/sdd:doc-catalog//sdd:doc-adrso all registries align.
Related Skills
doc-spec-query— reads every spec in the registry and answers cross-service questionsmr(sdd bundle) — publishes the pipeline spec automatically after creating the MRspec(sdd bundle) — authors thespec.mdthis registry storesdoc-catalog/doc-adr— same create-and-store pattern for catalogs and ADRs