spec¶
Verfasst, übersetzt, indiziert und prüft mehrsprachige Spezifikationen unter spec/.
Creates, translates, indexes, deduplicates, and drift-checks multilingual specifications stored under the project's spec/ folder. Invoke when the user wants to write a new spec, update or translate an existing one, check whether a requirement is already covered, regenerate the spec index, or verify that translations are still in sync with the canonical version. Supports writing the request in any configured language; specs on disk always exist in all configured languages, with one canonical source and the rest as translations kept strictly in sync. Don't use for readiness audit (contradiction detection, audience fit, AC coverage) — use spec-readiness-reviewer. Supports resume on re-invocation per spec/claude/resumable-work/.
- Plugin:
nolte-shared - Phase: 3 Design (
design) - Tags:
scaffolding - Quelle: skills/spec/SKILL.md
Anwenden wenn¶
- you want to write a new specification under spec/
- you want to translate an existing spec into another configured language
- you suspect a requirement is already covered and want to dedupe before authoring
- you want to regenerate the spec index after adding or renaming a spec
- you want to verify translations are still in sync with the canonical version
Nicht anwenden wenn¶
- You want to audit a spec for contradictions, AC coverage, or audience fit →
spec-readiness-reviewer - You want to reconcile a spec against the actual implementation in the codebase →
spec-drift-audit
Siehe auch¶
Referenziert von¶
Beispiele¶
- Prompt: Write a new spec for the foo workflow under spec/project/foo/
- Ergebnis: Bilingual spec files at spec/project/foo/{en,de}.md plus regenerated spec index.
- Prompt: The German translation of spec/project/bar/ is out of sync — refresh it.
- Ergebnis: spec/project/bar/de.md re-aligned with the canonical EN version.
Multilingual Spec Skill¶
Manages specifications inside a project's spec/ folder. Layout: one folder per spec, one file per language. Specs may optionally be grouped under a one-level topic folder.
Why this is a skill, not an agent¶
- Mid-flow interactivity is the contract — duplicate-check confirmation ("extend existing, supersede, or proceed as new?"), translation review, slug-rename gates, and drift-resolution choices are all per-step user dialogues; an agent's fire-and-forget contract would lose them.
- Persistent on-disk artifact is the deliverable — every operation writes spec files (canonical + translations) under
spec/[<topic>/]<slug>/<lang>.mdin pairs and may also regeneratespec/README.md; skills own persistent state. - Multilingual sync requires conversational context — when a translation drifts from the canonical, the skill negotiates the resolution with the user (lift the change, discard the edit) rather than picking silently; that gating only fits in a skill.
- Counter-dimension considered: translation itself benefits from a narrow specialised prompt, but the load-bearing dimension is the canonical-vs-translation flow control, not the per-string translation quality — skill wins; if translation quality ever needs sharpening, dispatch a translation agent from inside this skill rather than reshaping it.
spec/
├── .spec-config.yml
├── README.md # autogenerated index
└── [<topic>/]<slug>/
├── en.md # canonical
└── de.md # translation
Topic folders group related specs (for example spec/api/, spec/claude/). Only one level of topic nesting is allowed. Without a topic, specs live directly under spec/<slug>/.
Defaults¶
- Canonical language:
en - Translations:
de - Spec root:
spec/(relative to project root)
Overridable via spec/.spec-config.yml (validated against spec/schemas/spec-config-v1.0.schema.yaml by scripts/validate_schemas.py):
canonical_language: en
languages: [en, de]
spec_root: spec
inherits: # optional — portfolio-inherited spec layer
- source: nolte-shared # the hub plugin whose portfolio-scope specs are inherited
ref: v0.1.8 # tag-pinned hub release (never a floating branch)
overrides: # optional declared deviations from inherited specs
- spec: project/branching-model
section: "§Branch roles"
reason: "trunk-based repo; the long-lived develop branch role does not apply"
local: spec/project/branching-model/override.md
If the file is missing, use the defaults. Create it on the first create operation so downstream projects have a visible extension point.
Portfolio-inherited spec layer (the inherits: key)¶
Per spec/project/portfolio-inherited-spec-layer/, a consumer repo may reference portfolio-wide specs that live canonically in a hub (claude-shared) instead of copying them. The contract this skill must respect:
inherits:is optional and absent on the hub itself (the hub is the root; resolution terminates there). A consumer's effective spec set islocal ∪ inherited— the localspec/tree plus every hub spec whose canonical file carries aPortfolio-Scope: portfolioheader, resolved at each source's pinnedreffrom${CLAUDE_PLUGIN_ROOT}/spec/.- A spec is inheritable only if its canonical file carries a
Portfolio-Scope:header line (sibling toStatus:), valueportfolioorlocal. A spec with no such line defaults tolocal. When creating or editing a spec, preserve anyPortfolio-Scope:line; do not addportfolioscope unprompted (promoting a spec to portfolio-wide is an explicit maintainer act). - Inherited specs are authoritative by default. A consumer deviates only through a declared
overrides:record (with a non-emptyreason:) plus alocaloverride file containing only the replaced sections — never by copying the inherited spec into the local tree, and never by an undeclared same-key local spec. - A requirement marked
[locked]immediately after its RFC 2119 keyword (- **MUST** [locked] …) is non-overridable downstream; never author an override against a locked section.
User-language policy¶
- Detect the user's language from their message and reply in that language.
- Spec files on disk always exist in every configured language. The canonical file is authoritative; translations must mirror it semantically.
- If the user describes a feature in a non-canonical language, still produce the canonical version first, then translate.
Slug and topic rules¶
- Slug: ASCII kebab-case, derived from the canonical EN title. Example: user says "Benutzer-Authentifizierung" → canonical title "User Authentication" → slug
user-authentication. - Topic (optional): ASCII kebab-case, chosen to group related specs. Use an existing topic if one fits; otherwise propose a new one to the user before creating it.
- Slugs and topics are stable. Renaming is a conscious operation—confirm with the user before moving folders.
Operations¶
1. Create¶
- Take the user's description (any language).
- Duplicate check first (see operation 5). If clear overlap exists, stop and ask: extend existing, supersede, or proceed as new. Show candidate paths.
- Draft the canonical spec from
templates/spec.template.md, filling every section with content from the user's description. Mark unknowns explicitly instead of inventing. - Translate into each other configured language. Translation preserves structure (headings, requirement order, checklist items). RFC 2119 keywords stay in English and are glossed in-language, for example
MUSS [MUST],SOLLTE [SHOULD],KANN [MAY]. - Write
spec/[<topic>/]<slug>/<lang>.mdfor every configured language in a single operation—never leave a spec partially written. - Regenerate
spec/README.md(operation 4). - Confirm in the user's language with relative paths.
2. Update / prevent drift¶
- The canonical version is the only source of truth.
- If the user edits the canonical version: regenerate every translation from it.
- If the user edits a translation directly: warn that changes must flow through the canonical. Offer:
- (a) lift the semantic change into the canonical, then regenerate all translations, or
- (b) discard the translation edit and regenerate from the canonical.
- After any update operation, all language files for that spec must match structurally and semantically.
3. Drift check¶
A. Translation-vs-canonical drift (always):
- For every spec folder, compare each translation to the canonical:
- Same headings in the same order
- Same count of requirement bullets and acceptance-criteria checkboxes
- Same requirement IDs / ordering
- Report mismatches. Offer to regenerate the affected translations from the canonical.
B. Local-vs-inherited drift (only when spec/.spec-config.yml carries an inherits: key; per spec/project/portfolio-inherited-spec-layer/ §"Drift detection"):
- Run against each source's pinned
ref, not against the hub's currentdevelop, so conformance is judged against the exact upstream the consumer pinned. Resolve the inherited corpus from${CLAUDE_PLUGIN_ROOT}/spec/at that release. - Run the comparisons canonical-to-canonical (in the hub's canonical language); never compare against a translation view, which is derived and never authoritative.
- For each
inherits:source, report: - Critical — a tracked verbatim copy of an inherited spec in the local
spec/tree; a local spec sharing a logical key<topic>/<slug>with an inheritedportfolio-scope spec without a declared override (undeclared divergence); anoverrides:record whosesectioncontains a[locked]requirement; a cross-reference that is a ghost reference or a duplicate-key collision in the combined namespace; a cyclic inheritance declaration. - Warning — an
overrides:specthat does not resolve to aportfolio-scope spec at the pinnedref(broken reference); an overriddensectionthat no longer exists upstream (stale override); an empty or missingreason; a floating or absentref. - Severities are the canonical scale from
spec/claude/review-plan/§"Severity scale"; surface findings forspec-drift-auditto reconcile. Treat any open Critical as a gate failure (the silent fork must not reachdevelop).
4. Regenerate index¶
- Write
spec/README.mdwith a table: - Topic | Slug | Title (per language) | Status | Scope | Last updated
Statusis read from theStatus:line in the canonical file's header. If absent, usedraft.Scopeis read from thePortfolio-Scope:line in the canonical file's header (portfolio|local). If absent, uselocal(the default perspec/project/portfolio-inherited-spec-layer/). This column makes the inheritable subset visible at a glance.Last updatedusesgit log -1 --format=%cs -- <canonical file>. If the file is untracked, useunversioned.- Don't invent values—if something can't be read, mark it
unknown.
5. Coverage / duplicate check¶
Can be invoked standalone ("is X already covered?") or as step 2 of create.
- Extract salient nouns/verbs from the user's requirement.
Grepthe canonical files underspec/for those terms.Readevery canonical file with more than one keyword hit and assess semantic overlap against the user's requirement—not just keyword overlap.- Respond in the user's language with:
- which existing specs fully cover the requirement,
- which partially cover it and the specific gap,
- none, if no overlap.
Template maintenance¶
The starter template at templates/spec.template.md is deliberately minimal. Every time this skill is used for a non-trivial spec, briefly assess fitness:
- If real specs repeatedly need a section the template lacks → propose adding it.
- If template sections stay empty across most specs → propose trimming them.
Don't silently modify the template. Surface the proposal to the user and let them decide.
Examples¶
- Read
examples/01-create-new-spec-multilingual.mdwhen creating a new spec from scratch in all configured languages simultaneously. - Read
examples/02-translate-existing-spec.mdwhen translating an existing canonical spec into a second language. - Read
examples/03-drift-check-translations.mdwhen checking whether a translation has drifted from the canonical version.
Gotchas¶
spec/.spec-config.ymlis the authoritative language source: the canonical language and the full language list come from this file; if it is missing, fall back toen/[en, de]defaults but create the config on the firstcreateoperation — guessing language settings from the conversation language will produce wrong canonical paths in multilingual repos.- Canonical file must be written first, translations second: if a spec is only partially written (canonical exists, translations absent), the repo is in a broken state per the "always together" rule; ensure the write step covers every configured language in a single operation or rolls back entirely.
git log -1forLast updatedrequires the file to be tracked: untracked spec files produce no git log output; the index regeneration step must handle this case by markingLast updatedasunversionedrather than leaving the cell empty or erroring out.
Resumability¶
Per spec/claude/resumable-work/, this skill is resumable: true. State is persisted to .resume/spec/<run-id>.yml after every successful user-approval gate and after each named phase boundary. On re-invocation, scan that directory for files with status: in_progress whose inputs: snapshot matches the current invocation; if one matches, prompt the operator with Resume run <run_id> from phase <phase> (last checkpoint <last_checkpoint_at>)? [resume / start-new / discard]. The state-file envelope (schema_version, run_id, inputs, phase, decisions[], status, ...) and the fail-closed semantics on schema or YAML errors are load-bearing in the spec; don't duplicate those rules here.
Hard rules¶
- Canonical and translation files are always created and updated together. Never leave a spec with only one language file on disk.
- After any operation that touches spec content, translations must be in sync with the canonical—no drift, ever.
- Slugs are ASCII kebab-case and never change silently.
- Never modify
spec/.spec-config.ymlwithout telling the user. - Never invent
Status, dates, or requirement content. Read from source or mark unknown.