Purpose
Verify and settle the topic-docs seam for the CONSUMING repo: where the planning pipeline's contract
documents (PRD.md, PLAN.md, design/) and working memory (checklists, baselines, scratch) land,
persisting it to the tracked concern file .claude/topic-docs.yaml, the consumer-side single
source of truth every consuming plugin resolves first. The file's shape is the convention's
topic-docs.schema.json; every key is optional and absent keys mean the documented defaults
(contract_dir: docs/topics, memory_dir: .work, contract_tier: branch, vault_backend: docs).
This plugin's binding, its tier table and vault-seam close-out pointer, lives in
${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md;
the contract it cites owns the resolution order and runtime guards.
Both concern files are optional: with none, the pipeline uses the documented defaults, so their absence
is a reported INFO, never a FAIL. check inspects read-only; apply resolves and persists, then
re-runs check. No argument or check runs the check; apply runs the check first, then the
resolve-and-write flow. Idempotent: re-running reads the current state and offers an update rather than
overwriting blind.
check (read-only)
Inspect both concerns and report a PASS/FAIL/INFO table with one remediation line per FAIL. Modify
nothing, and do NOT run a planning stage. Those are the pipeline skills.
- topic-docs concern file. Read
.claude/topic-docs.yaml if present and report its effective
values (absent keys mean the documented defaults). Absent file → INFO: the documented defaults apply;
apply persists a concern file when the repo diverges. A file that does not parse as the schema
(e.g. a comment-only document YAML parses as null) is FAIL.
- Committed-tier conflict. Only when the effective
contract_tier is branch (local mode has no
committed tier to guard): git check-ignore -v on a representative file path inside the chosen
contract root (e.g. <contract_dir>/probe/PLAN.md. A bare directory misses ** patterns). A
consumer ignore rule that matches is FAIL: a "committed" tier that git ignores is the failure the
guard exists to catch; surface the exact rule and source line.
- Deferred backend. If the effective
vault_backend is gitbook, INFO: it is reserved but not
enabled. Git remains the storage layer because GitBook offers no concurrency-safe, lossless write
path, so it is deferred and non-writable; durable writes target docs.
- Standards index. The index presence test at the resolved
<standards_dir>/README.md
(.claude/standards.yaml may relocate the root from the documented default). Absent → INFO: the
standards concern is not bootstrapped; apply offers to scaffold it. A present index whose
standards-contract frontmatter version is behind the plugin binding's is INFO with the DIRECTIONAL
version-delta noted (migration runs under apply). A present README.md that is hand-authored (not
a conforming index) is INFO, flagged for the apply confirmation gate.
- Interview-rendering toggle. INFO: report the effective
use_ask_user_question value,
${user_config.use_ask_user_question} (unexpanded or empty means the default false. The pipeline
skills' question rounds render as inline prose). This is a native userConfig toggle, not a
consumer-project file; apply gives the reconfigure guidance below.
apply (idempotent)
Run check, then resolve and persist both concerns. Proceed non-interactively where the invocation and
the repo make the values unambiguous; ask only where a choice genuinely needs the user. No silent
writes. Every bootstrap write is user-accepted.
First concern. Topic-docs
- Read the current state first. In order: an existing
.claude/topic-docs.yaml (report its
effective values as the baseline. The interview proposes changes against it); a working-docs
convention declared in the consumer's CLAUDE.md / .claude/rules (an inference source,
surface it as the recommended values and offer to persist it into the concern file).
- Infer before asking. With no concern file and no declared convention, look for an existing
conforming layout (a
docs/topics/-shaped contract root, a self-ignoring .work/) and
confirm it rather than guessing.
- Interview. One decision. The load-bearing choice is
contract_tier: branch
(RECOMMENDED). Contract documents commit on the task branch, travel to worktrees and cloud
clones, and are pruned before merge, versus local: solo/offline mode; contract kinds join the
memory tier and the PR-description paste is the only publication surface. Keep contract_dir,
memory_dir, and vault_backend at their defaults unless the repo's own conventions say
otherwise. But offer every schema key and preserve every key an existing file carries (a
re-run never drops one); do not invent knobs beyond the schema. Whenever the effective
vault_backend is, or becomes, gitbook, preserved from an existing file, inferred from the
repo's own CLAUDE.md / .claude/rules, or chosen by the user during this interview, report
that GitBook is deferred and non-writable: the effective writable promotion target remains
docs until a later reviewed decision enables the backend. Do not configure or test a GitBook
API, MCP, or Git Sync writer; offer to replace the key with docs only if the user chooses that
change.
- Run the conflict check before writing. Only when the chosen tier is
branch (local mode
has no committed tier to guard). git check-ignore -v on a representative file path
inside the chosen contract root (e.g. <contract_dir>/probe/PLAN.md. A bare directory misses
** patterns): if a consumer ignore rule matches, STOP and surface the exact rule and
source line. A "committed" tier that git ignores is the failure the guard exists to catch.
Resolving the rule is the user's edit to make: never modify the consumer's root
.gitignore (or any ignore file this setup did not itself create. The standards root's
own bootstrap-shipped .gitignore below is the one setup-owned exception).
- Persist. Write
.claude/topic-docs.yaml (tracked, team-shared), recording only the keys
the user chose. Absent keys mean the documented defaults, so an all-defaults answer may
yield a file with contract_tier: branch alone or the schema-valid empty mapping {}
(optionally followed by comments), never a comment-only document, which YAML parses as null.
Preserve every schema key an existing file carries. After the write, run the tracked-file pair
on it: git check-ignore -v reports no match (a match is FAIL with the pattern) AND
git ls-files --error-unmatch exits 0 (non-zero right after a fresh write means "written but
untracked: commit it to share with the team", never success).
Second concern. Standards bootstrap
Settle where the consumer's standards live, the adopted conventions and criteria the
planning skills ground plans in, by implementing the normative "Setup and migration" section of
the plugin's contract binding
${CLAUDE_PLUGIN_ROOT}/reference/standards-contract.md.
The procedure (state reading via the index presence test, the conforming-index short-circuit, the
hand-authored-README confirmation gate, interview, skeleton write, row-path validation,
DIRECTIONAL version-delta detection with guided migration, idempotent re-run) lives there,
implement it by reference, do not restate it. Plugin-side notes only:
- State reading order:
.claude/standards.yaml → index presence test at the resolved
<standards_dir>/README.md → inference sources (existing docs directories, ecosystem configs,
ambient CLAUDE.md content).
- Bootstrap writes (interactive, user-accepted. No silent writes): the skeleton index with
its
standards-contract frontmatter at the binding's version, and the setup-owned
<standards_dir>/.gitignore containing *.local.md (the personal-overlay ignore). Write
.claude/standards.yaml only when the user relocates the root from the documented default.
After a bootstrap write, run the tracked-file pair on each written team file:
git check-ignore -v reports no match (a match is FAIL with the pattern) AND
git ls-files --error-unmatch exits 0 (non-zero right after a fresh write means "written but
untracked: commit it to share with the team", never success).
- Optional offers, never demands: pointer-rule generation for indexed ecosystem surfaces
(interactive only), and reorganizing mixed or spread standards content toward the SRP + index
shape.
- Migration is this skill re-run. No separate action; direction and messaging per the
binding. It is a versioned-contract upgrade under
apply, the schema-evolution path the
binding sanctions.
Interview-rendering toggle
use_ask_user_question is a native userConfig boolean (default false) governing whether the
pipeline skills' question rounds render through AskUserQuestion or as inline prose. It is not a
consumer-project file this skill writes. Reconfigure through Claude Code's native flow, per the
marketplace's plugin-reconfiguration convention
(https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md,
which owns the verified-version record): interactive /plugin configure planning@<marketplace> any
time, or headless claude plugin install planning@<marketplace> -s <scope> --config use_ask_user_question=true
(repeatable per key) — against an already-installed plugin it prints already installed and still
writes the value. Do not uninstall to reconfigure: that drops the plugin's entire stored
pluginConfigs entry, resetting every option in the README's Options reference to its manifest
default. -s defaults to user; pass the scope claude plugin list reports, and run from that
project's directory for a project/local scope, or the write lands at a scope that does not load.
This skill never writes Claude Code user settings or pluginConfigs. Afterwards rerun check in a
fresh session — the rendered ${user_config.*} and each hook's CLAUDE_PLUGIN_OPTION_* are
fixed at session start, so a same-session check still reports the OLD value; report the observed
effective value, never an unobserved change.
Verify after remediation
Re-run the check probes on what was written, the topic-docs conflict check on the persisted tier
and the standards index presence/row-path validation, and report the actual results, never success on
the write alone.
Re-running apply after everything passes changes nothing and reports "already configured".
Output
A written (or confirmed) .claude/topic-docs.yaml, plus. When the standards concern was
exercised. A written (or confirmed-healthy) standards index and its overlay .gitignore, a
one-line summary of the effective values, the conflict-check and row-validation results, and how
to re-run this setup to reconfigure or migrate.
What this skill does NOT do
- Run a planning stage. That is the pipeline skills (
/planning:brainstorm, /planning:prd,
/planning:interview, /planning:design, /planning:design-handoff,
/planning:devils-advocate, /planning:plan). check only inspects config.
- Edit the consumer's root
.gitignore or any ignore file it did not itself create. The
conflict check surfaces rules; the user resolves them. (The memory root's own self-ignoring
.gitignore is created by the first memory-tier write, announced. Not by setup. The single
setup-owned ignore file is the standards root's bootstrap-shipped <standards_dir>/.gitignore.)
- Write anything into the plugin directory or the plugin data directory
(
${CLAUDE_PLUGIN_DATA} is for caches and generated state only).
1---2name: setup-83description: Verify and configure the planning plugin for this repository across its two concerns. check inspects read-only the topic-docs seam (.claude/topic-docs.yaml effective values, committed-tier conflict) and the standards index presence; apply resolves where topic documents land (persisting .claude/topic-docs.yaml) and bootstraps the standards index (docs/standards/ and, on relocation, .claude/standards.yaml). Use when: 'set up planning', 'is planning configured', 'configure the planning plugin', 'planning setup', 'where do planning artifacts land', 'set up standards', 'bootstrap the standards index', or a planning skill reports missing or thin config. Re-runnable. Safe to invoke again to reconfigure or migrate.4---56## Purpose78Verify and settle the topic-docs seam for the CONSUMING repo: where the planning pipeline's contract9documents (`PRD.md`, `PLAN.md`, `design/`) and working memory (checklists, baselines, scratch) land,10persisting it to the tracked concern file **`.claude/topic-docs.yaml`**, the consumer-side single11source of truth every consuming plugin resolves first. The file's shape is the convention's12`topic-docs.schema.json`; every key is optional and absent keys mean the documented defaults13(`contract_dir: docs/topics`, `memory_dir: .work`, `contract_tier: branch`, `vault_backend: docs`).14This plugin's binding, its tier table and vault-seam close-out pointer, lives in15[`${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md`](${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md);16the contract it cites owns the resolution order and runtime guards.1718Both concern files are optional: with none, the pipeline uses the documented defaults, so their absence19is a reported INFO, never a FAIL. `check` inspects read-only; `apply` resolves and persists, then20re-runs `check`. No argument or `check` runs the check; `apply` runs the check first, then the21resolve-and-write flow. Idempotent: re-running reads the current state and offers an update rather than22overwriting blind.2324## `check` (read-only)2526Inspect both concerns and report a PASS/FAIL/INFO table with one remediation line per FAIL. Modify27nothing, and do NOT run a planning stage. Those are the pipeline skills.28291. **topic-docs concern file**. Read `.claude/topic-docs.yaml` if present and report its effective30 values (absent keys mean the documented defaults). Absent file → INFO: the documented defaults apply;31 `apply` persists a concern file when the repo diverges. A file that does not parse as the schema32 (e.g. a comment-only document YAML parses as null) is FAIL.332. **Committed-tier conflict**. Only when the effective `contract_tier` is `branch` (local mode has no34 committed tier to guard): `git check-ignore -v` on a representative file path inside the chosen35 contract root (e.g. `<contract_dir>/probe/PLAN.md`. A bare directory misses `**` patterns). A36 consumer ignore rule that matches is FAIL: a "committed" tier that git ignores is the failure the37 guard exists to catch; surface the exact rule and source line.383. **Deferred backend.** If the effective `vault_backend` is `gitbook`, INFO: it is reserved but not39 enabled. Git remains the storage layer because GitBook offers no concurrency-safe, lossless write40 path, so it is deferred and non-writable; durable writes target `docs`.414. **Standards index**. The index presence test at the resolved `<standards_dir>/README.md`42 (`.claude/standards.yaml` may relocate the root from the documented default). Absent → INFO: the43 standards concern is not bootstrapped; `apply` offers to scaffold it. A present index whose44 `standards-contract` frontmatter version is behind the plugin binding's is INFO with the DIRECTIONAL45 version-delta noted (migration runs under `apply`). A present `README.md` that is hand-authored (not46 a conforming index) is INFO, flagged for the `apply` confirmation gate.475. **Interview-rendering toggle**. INFO: report the effective `use_ask_user_question` value,48 `${user_config.use_ask_user_question}` (unexpanded or empty means the default `false`. The pipeline49 skills' question rounds render as inline prose). This is a native `userConfig` toggle, not a50 consumer-project file; `apply` gives the reconfigure guidance below.5152## `apply` (idempotent)5354Run `check`, then resolve and persist both concerns. Proceed non-interactively where the invocation and55the repo make the values unambiguous; ask only where a choice genuinely needs the user. No silent56writes. Every bootstrap write is user-accepted.5758### First concern. Topic-docs59601. **Read the current state first.** In order: an existing `.claude/topic-docs.yaml` (report its61 effective values as the baseline. The interview proposes changes against it); a working-docs62 convention declared in the consumer's `CLAUDE.md` / `.claude/rules` (an inference source,63 surface it as the recommended values and offer to persist it into the concern file).642. **Infer before asking.** With no concern file and no declared convention, look for an existing65 conforming layout (a `docs/topics/`-shaped contract root, a self-ignoring `.work/`) and66 confirm it rather than guessing.673. **Interview. One decision.** The load-bearing choice is `contract_tier`: **`branch`68 (RECOMMENDED)**. Contract documents commit on the task branch, travel to worktrees and cloud69 clones, and are pruned before merge, versus `local`: solo/offline mode; contract kinds join the70 memory tier and the PR-description paste is the only publication surface. Keep `contract_dir`,71 `memory_dir`, and `vault_backend` at their defaults unless the repo's own conventions say72 otherwise. But offer every schema key and preserve every key an existing file carries (a73 re-run never drops one); do not invent knobs beyond the schema. Whenever the effective74 `vault_backend` is, or becomes, `gitbook`, preserved from an existing file, inferred from the75 repo's own `CLAUDE.md` / `.claude/rules`, or chosen by the user during this interview, report76 that GitBook is deferred and non-writable: the effective writable promotion target remains77 `docs` until a later reviewed decision enables the backend. Do not configure or test a GitBook78 API, MCP, or Git Sync writer; offer to replace the key with `docs` only if the user chooses that79 change.804. **Run the conflict check before writing**. Only when the chosen tier is `branch` (local mode81 has no committed tier to guard). `git check-ignore -v` on a representative file path82 inside the chosen contract root (e.g. `<contract_dir>/probe/PLAN.md`. A bare directory misses83 `**` patterns): if a consumer ignore rule matches, STOP and surface the exact rule and84 source line. A "committed" tier that git ignores is the failure the guard exists to catch.85 Resolving the rule is the user's edit to make: **never modify the consumer's root86 `.gitignore`** (or any ignore file this setup did not itself create. The standards root's87 own bootstrap-shipped `.gitignore` below is the one setup-owned exception).885. **Persist.** Write `.claude/topic-docs.yaml` (tracked, team-shared), recording only the keys89 the user chose. Absent keys mean the documented defaults, so an all-defaults answer may90 yield a file with `contract_tier: branch` alone or the schema-valid empty mapping `{}`91 (optionally followed by comments), never a comment-only document, which YAML parses as null.92 Preserve every schema key an existing file carries. After the write, run the tracked-file pair93 on it: `git check-ignore -v` reports no match (a match is FAIL with the pattern) AND94 `git ls-files --error-unmatch` exits 0 (non-zero right after a fresh write means "written but95 untracked: commit it to share with the team", never success).9697### Second concern. Standards bootstrap9899Settle where the consumer's **standards** live, the adopted conventions and criteria the100planning skills ground plans in, by implementing the normative "Setup and migration" section of101the plugin's contract binding102[`${CLAUDE_PLUGIN_ROOT}/reference/standards-contract.md`](${CLAUDE_PLUGIN_ROOT}/reference/standards-contract.md).103The procedure (state reading via the index presence test, the conforming-index short-circuit, the104hand-authored-README confirmation gate, interview, skeleton write, row-path validation,105DIRECTIONAL version-delta detection with guided migration, idempotent re-run) lives there,106implement it by reference, do not restate it. Plugin-side notes only:107108- **State reading order:** `.claude/standards.yaml` → index presence test at the resolved109 `<standards_dir>/README.md` → inference sources (existing docs directories, ecosystem configs,110 ambient `CLAUDE.md` content).111- **Bootstrap writes** (interactive, user-accepted. No silent writes): the skeleton index with112 its `standards-contract` frontmatter at the binding's version, and the setup-owned113 `<standards_dir>/.gitignore` containing `*.local.md` (the personal-overlay ignore). Write114 `.claude/standards.yaml` only when the user relocates the root from the documented default.115 After a bootstrap write, run the tracked-file pair on each written team file:116 `git check-ignore -v` reports no match (a match is FAIL with the pattern) AND117 `git ls-files --error-unmatch` exits 0 (non-zero right after a fresh write means "written but118 untracked: commit it to share with the team", never success).119- **Optional offers, never demands:** pointer-rule generation for indexed ecosystem surfaces120 (interactive only), and reorganizing mixed or spread standards content toward the SRP + index121 shape.122- **Migration is this skill re-run.** No separate action; direction and messaging per the123 binding. It is a versioned-contract upgrade under `apply`, the schema-evolution path the124 binding sanctions.125126### Interview-rendering toggle127128`use_ask_user_question` is a native `userConfig` boolean (default `false`) governing whether the129pipeline skills' question rounds render through `AskUserQuestion` or as inline prose. It is not a130consumer-project file this skill writes. Reconfigure through Claude Code's native flow, per the131marketplace's plugin-reconfiguration convention132(<https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md>,133which owns the verified-version record): interactive `/plugin configure planning@<marketplace>` any134time, or headless `claude plugin install planning@<marketplace> -s <scope> --config use_ask_user_question=true`135(repeatable per key) — against an already-installed plugin it prints `already installed` and still136writes the value. Do **not** uninstall to reconfigure: that drops the plugin's entire stored137`pluginConfigs` entry, resetting every option in the README's Options reference to its manifest138default. `-s` defaults to `user`; pass the scope `claude plugin list` reports, and run from that139project's directory for a `project`/`local` scope, or the write lands at a scope that does not load.140This skill never writes Claude Code user settings or `pluginConfigs`. Afterwards rerun `check` in a141**fresh session** — the rendered `${user_config.*}` and each hook's `CLAUDE_PLUGIN_OPTION_*` are142fixed at session start, so a same-session `check` still reports the OLD value; report the observed143effective value, never an unobserved change.144145### Verify after remediation146147Re-run the `check` probes on what was written, the topic-docs conflict check on the persisted tier148and the standards index presence/row-path validation, and report the actual results, never success on149the write alone.150151Re-running `apply` after everything passes changes nothing and reports "already configured".152153## Output154155A written (or confirmed) `.claude/topic-docs.yaml`, plus. When the standards concern was156exercised. A written (or confirmed-healthy) standards index and its overlay `.gitignore`, a157one-line summary of the effective values, the conflict-check and row-validation results, and how158to re-run this setup to reconfigure or migrate.159160## What this skill does NOT do161162- Run a planning stage. That is the pipeline skills (`/planning:brainstorm`, `/planning:prd`,163 `/planning:interview`, `/planning:design`, `/planning:design-handoff`,164 `/planning:devils-advocate`, `/planning:plan`). `check` only inspects config.165- Edit the consumer's root `.gitignore` or any ignore file it did not itself create. The166 conflict check surfaces rules; the user resolves them. (The memory root's own self-ignoring167 `.gitignore` is created by the first memory-tier write, announced. Not by setup. The single168 setup-owned ignore file is the standards root's bootstrap-shipped `<standards_dir>/.gitignore`.)169- Write anything into the plugin directory or the plugin data directory170 (`${CLAUDE_PLUGIN_DATA}` is for caches and generated state only).