Purpose
Verify and scaffold the consuming repo's tracked lane definitions at .claude/tidy-lanes/<lane>.md
so /code-tidying:tidy resolves project-specific scope globs and watch-for patterns deterministically
instead of falling back to the generic bundled lanes every run. A project lane at
${CLAUDE_PROJECT_DIR}/.claude/tidy-lanes/<lane>.md layers over the bundled lane of the same name. This is the plugin's seam-2 extension surface. How the two combine is governed by the project lane's
own ## Merge semantics section (see the tidy skill's Lane resolution): a lane declaring it merges
per-section with the bundled lane; a lane without it resolves project-only.
Project lanes are optional: with none, /code-tidying:tidy uses the bundled lanes, so their absence is
a reported INFO, never a FAIL. Check-centric per the uniform setup contract
(docs/PLUGIN-PHILOSOPHY.md "Setup is explicit and repeatable" in the marketplace repository):
check inspects read-only; apply scaffolds or retunes lanes, then re-runs check. No argument or
check runs the check; apply runs the check first, then the scaffold flow. apply <lane> targets a
single lane. Idempotent: re-running reads the existing lane files and proposes additions or edits
against that baseline rather than overwriting a consumer lane blind.
Lanes vs. templates, the distinction this skill turns on
- Bundled lanes (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/*.md. shell-tooling, docs-prose)
cover surfaces that look the same in most repos. They resolve automatically with no config;
a project override is worth writing only when this repo's tooling or doc directories differ from
the bundled defaults.
- Bundled templates (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/*.template.md) are <placeholder>
scaffolds for the lanes that are project-specific by design. Code the repo has but no generic
lane can name. This skill's primary job is turning the fitting templates into real lane files.
Never tell the user to "copy the bundled lanes." Scaffold from templates; override a bundled lane only
when its defaults miss this repo's actual layout.
The plugin's second tracked surface is ${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md,
optional and absent by default: root-relative globs that lift GLOBAL HARD path exclusions for every
run in this repository, the subtracting mirror of the consumer-declared protections that add to them.
check validates it; apply writes it only when the user asks. Contract, shape, precedence, and what
no channel lifts: the tidy skill's
exclusions reference section 4.
check (read-only)
Inspect the consumer's tracked lanes and report a PASS/FAIL/INFO table with one remediation line per
FAIL. Modify nothing, and do NOT run a tidy sweep. That is /code-tidying:tidy.
- Project lanes present. List
.claude/tidy-lanes/*.md. None → INFO: tidy resolves the bundled
lanes; apply scaffolds project lanes when this repo's layout diverges from the bundled defaults.
- Lane structure. Each present lane file carries the required sections (
## Scope,
## Watch-for patterns, ## Lane-specific extra exclusions, ## Verification commands,
## Conventional Commits type, ## Preferred research sources). A lane missing a section is FAIL, except a lane that declares ## Merge semantics and shares its name with one of
${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/*.md: that one
inherits every section it omits from its bundled counterpart, so a missing section is expected, not a
FAIL. Report which sections it inherits. The exemption belongs to the declaration, not to the heading:
read the section and confirm it either adopts the bundled lane's declaration by reference (the shape
apply writes. Merge semantics: per the bundled lane's declaration) or restates a disposition for
every required section the lane omits. A ## Merge semantics section that is empty, unrelated, or
silent on an omitted section is FAIL. Malformed merge declaration; remediation is to adopt the bundled
declaration by reference or to state the missing dispositions. FAIL too when the lane overrides a
section the bundled lane keys at ### granularity (shell-tooling's Verification commands and
Preferred research sources) without keying its own commands or sources under those ### language
headings. Unkeyed entries name no language to replace. Framing prose above the first ### is fine.
- No unreplaced placeholders, a lane still containing a template
<placeholder> resolves to a
broken scope glob or watch-for pattern; FAIL, naming the file and the leftover token.
- Tracked, not ignored. Per lane file, run both halves of the tracked-file pair:
git check-ignore -v <file> (a non-empty result means a .gitignore pattern excludes that lane;
FAIL with the matching pattern in the remediation line — a directory can be tracked while a
pattern excludes an individual .md inside it) AND git ls-files --error-unmatch <file>
(non-zero exit means the lane is un-ignored but untracked: report it — "commit it to share with
the team", downgraded to INFO only when the user confirms it is a deliberately private,
uncommitted lane per the declared deviation below).
- Bundled lanes and templates. INFO: report the bundled lanes and templates available as scaffold
sources, so the reader knows what
apply can generate.
- HARD-exclusion overrides. Read
${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md
if it exists. Absent is the normal state; report INFO naming the file and what it does. Present, then
check its shape against the tidy skill's
exclusions reference section 4: an
## Overrides heading with one fenced block, one root-relative glob per line. FAIL an absolute path
or an entry containing .., naming the line. FAIL a glob matching the overrides file itself or the
.claude/tidy-lanes/ definitions beside it: the file cannot lift its own protection, and a run is
never granted the switch that grants it. FAIL a glob that also matches a path this repo's own
CLAUDE.md / .claude/rules declare protected, naming both declarations: the protection wins and
the override is dead text. Run both halves of the tracked-file pair on it, exactly as for a lane
file: git check-ignore -v <file> must report no match, and git ls-files --error-unmatch <file>
must exit 0, since the file is a team statement that only counts when committed. Report the globs it
lifts, so the reader sees the loosening the repo is carrying.
hard_exclusions posture. Report the stored userConfig value as observed. enforce (the
default) is PASS. advisory is INFO, not a FAIL: it is a deliberate operator posture, and the line
states what it does (every GLOBAL HARD path entry is reported instead of blocking, in every run
this operator makes). Name the running session's behavior as not yet established when the value was
changed this session; the stored value is current, the session lags.
apply (idempotent)
Run check, then apply the convention-resolution ladder. Config present → use it; absent → infer from
the repo and persist; cannot infer → ask and offer to persist; else a safe default (skip that lane, no
empty file). Proceed non-interactively for whatever the invocation and the repo make unambiguous; ask
only where a lane's scope genuinely needs the user's call.
Read existing lanes first. List .claude/tidy-lanes/*.md. If any exist, read each and present a
short summary (lane name, scope globs, watch-for count). Propose changes against that baseline;
never overwrite an existing consumer lane without explicit confirmation in this conversation.
Explore the repo to draft candidate lanes. Before asking anything, map the four bundled template
patterns against what actually exists, and check whether either bundled lane needs a project override:
- apps (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/apps-lane.template.md). User-facing
applications + their tests: web/API/CLI app roots and their sibling test projects.
- dependency-root (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/dependency-root-lane.template.md): framework/library core that downstream code depends on: shared/domain/core library roots.
- host-wiring (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/host-wiring-lane.template.md). Hosting
infrastructure, logging, registration, service defaults: composition roots, DI wiring, service-default projects.
- polyglot-services (
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/polyglot-services-lane.template.md): non-primary-language services, MCP servers, sidecars.
- bundled-lane override. Inspect the repo's actual tooling dirs and doc dirs; a project override
of
shell-tooling or docs-prose is warranted only when they diverge from the bundled scope globs.
Read the actual directory names and file extensions from the repo. Do not assume a stack. Skip any
template pattern the repo has no surface for. When invoked as apply <lane>, scope this to that lane.
Interview, one lane at a time (recommendation-first). Present each candidate lane with its inferred
scope globs and the source template, marked with a recommendation; let the user accept, edit the globs,
or drop the lane. Offer a custom lane last ("any other glob-scoped slice this repo should tidy on its
own rotation?"). Ask about the highest-blast-radius lane first.
Fill the source lane from real repo values. For each accepted lane, read its full source in full,
then replace every <placeholder> (templates) or bundled default (overrides) with values drawn from
this repo. The source depends on the lane's origin:
- Template-pattern lanes (apps, dependency-root, host-wiring, polyglot-services) start from the
exact template filename presented in step 2.
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/<pattern>-lane.template.md
(e.g. apps-lane.template.md), and every <placeholder> is replaced.
- Bundled-lane overrides (
shell-tooling, docs-prose) have no template; read the bundled lane
file ${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/<lane>.md, then write only the sections this repo
actually diverges on (usually ## Scope, sometimes extra exclusions), plus a ## Merge semantics
section adopting the bundled lane's declaration. Do not copy the sections the repo keeps: a copied
section is frozen at its copy-time value, while an omitted one keeps inheriting bundled improvements.
Where the bundled lane keys a section at ### granularity, key the override the same way so it
resolves per language.
- Custom lanes (accepted from step 3's "any other slice?" offer) have no dedicated source: start
from whichever template pattern is closest in shape to the slice and re-fill it, or, when none fits, author a new lane file from scratch using the same section structure the templates use (
## Scope,
## Watch-for patterns, ## Lane-specific extra exclusions, ## Verification commands,
## Conventional Commits type, ## Preferred research sources). Never emit an ad-hoc lane missing a section.
Values to fill: scope globs from real directory paths, watch-for patterns tuned to the stack,
lane-specific exclusions for this repo's unverifiable surfaces, verification commands from the project's
own CLAUDE.md / rules / CI config (never invented), the Conventional Commits type, and preferred research
sources. Leave no <placeholder> behind.
Write the lane files. Materialize each accepted lane at .claude/tidy-lanes/<lane>.md. Write only
lanes the user confirmed; produce no empty scaffolds.
Verify after remediation. Re-run the check probes on each written file, required sections
present, no leftover placeholder, and (per file) both halves of the tracked-file pair:
git check-ignore -v <file> reports no match (a non-empty result means a .gitignore pattern
excludes that lane; surface the matching pattern and offer to fix .gitignore before reporting
success) AND git ls-files --error-unmatch <file> exits 0 (non-zero means un-ignored but still
untracked, the guaranteed state right after a fresh write, so report "written but untracked:
commit it to share with the team", never success), since these lanes are team-shared and must
be committed to take effect. /code-tidying:tidy resolves a lane only from
.claude/tidy-lanes/<lane>.md (then the bundled lane of that name), and its catalog lists
.claude/tidy-lanes/*.md. There is no user-global or *.local.* overlay resolution (a declared
deviation from the config-cascade contract). Every scaffolded lane is a tracked, team-shared file;
do not point developers at a *.local.* variant the tidy skill would never load. A developer who
wants a private lane uses a lane name the team does not track: keep .claude/tidy-lanes/<lane>.md
uncommitted (never add it to the index). Gitignoring a path the team already tracks does not make
it personal. Indexed files remain visible to Git regardless of .gitignore.
Offer the HARD-exclusion overrides file, only when the repo asked for one. Do not scaffold it by
default: absent is the correct state for almost every repository, and an empty overrides file is the
empty scaffold step 5 forbids. Offer it when the conversation named a path the plugin keeps dropping,
or when check reported a malformed existing file. Write
${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md in the section 4 shape (an
## Overrides heading, one fenced block, one root-relative glob per line, # comments), carrying
only globs the user named. Preserve any prose already in the file. Re-run the step 6 check probes
on what was written, including both halves of the tracked-file pair, and report it as written but
untracked until it is committed. State plainly what the file loosens.
Re-running apply after everything passes changes nothing and reports "already configured".
Personal configuration (userConfig)
Not apply surface. Claude Code owns the storage, and this contract forbids setup to write
pluginConfigs, so check reports the observed value and routes the change. Reconfigure through
Claude Code's native flow, per the marketplace's
plugin-reconfiguration convention
(which owns the verified-version record): interactive /plugin configure code-tidying@<marketplace>
any time, or headless:
claude plugin install code-tidying@<marketplace> -s <scope> --config hard_exclusions=advisory
Against an already-installed plugin this prints already installed and still writes the value; the
short-circuit is about the install, not the config write. Do not uninstall to reconfigure: that
drops this plugin's entire stored pluginConfigs entry. Pass the scope claude plugin list reports.
The value is stored immediately, but the running session is not re-read, so start a fresh session
before expecting the new behavior. hard_exclusions takes enforce (default, every GLOBAL HARD path
entry blocks) or advisory (every one is reported and none blocks); any other value is read as
enforce. The full option table is in the plugin README.
Output
Tracked .claude/tidy-lanes/<lane>.md file(s) in the consuming repo, plus a one-paragraph summary of which
lanes were written, which source each came from (template or bundled lane), and how to re-run this setup
to add or retune lanes. When an overrides file was written or already exists, the summary names it and the
globs it lifts.
What this skill does NOT do
- Run a tidy sweep. That is
/code-tidying:tidy. check only inspects config.
- Write the plugin cache, Claude Code user settings, or
pluginConfigs.
- Ship its own template copies. Lane files scaffold from
${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/;
duplicating those into this skill would drift from the source.
- Write machine-local state. Lane configuration lives in the consumer's tracked
.claude/tidy-lanes/,
never in the plugin directory or a plugin data directory.
1---2name: setup-313description: Verify and configure the code-tidying plugin for this repository. check inspects the tracked .claude/tidy-lanes/<lane>.md project lanes and the optional .claude/code-tidying/exclusion-overrides.md read-only (presence, required sections, unreplaced placeholders, override glob shape and protection collisions, tracked-not-ignored) and reports the stored hard_exclusions posture; apply interviews the repo, infers which lane patterns fit, and scaffolds project lane files from the bundled templates. Use when: 'set up code-tidying', 'is code-tidying configured', 'configure tidy lanes', 'code-tidying setup', 'scaffold a tidy lane', 'override the tidy exclusions for this repo', or the tidy skill reports no project lanes. Re-runnable. Safe to invoke again to add or retune lanes.4---56## Purpose78Verify and scaffold the consuming repo's tracked lane definitions at `.claude/tidy-lanes/<lane>.md`9so `/code-tidying:tidy` resolves project-specific scope globs and watch-for patterns deterministically10instead of falling back to the generic bundled lanes every run. A project lane at11`${CLAUDE_PROJECT_DIR}/.claude/tidy-lanes/<lane>.md` layers over the bundled lane of the same name. This is the plugin's seam-2 extension surface. How the two combine is governed by the project lane's12own `## Merge semantics` section (see the `tidy` skill's Lane resolution): a lane declaring it merges13per-section with the bundled lane; a lane without it resolves project-only.1415Project lanes are optional: with none, `/code-tidying:tidy` uses the bundled lanes, so their absence is16a reported INFO, never a FAIL. Check-centric per the uniform setup contract17(`docs/PLUGIN-PHILOSOPHY.md` "Setup is explicit and repeatable" in the marketplace repository):18`check` inspects read-only; `apply` scaffolds or retunes lanes, then re-runs `check`. No argument or19`check` runs the check; `apply` runs the check first, then the scaffold flow. `apply <lane>` targets a20single lane. Idempotent: re-running reads the existing lane files and proposes additions or edits21against that baseline rather than overwriting a consumer lane blind.2223## Lanes vs. templates, the distinction this skill turns on2425- **Bundled lanes** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/*.md`. `shell-tooling`, `docs-prose`)26 cover surfaces that look the same in most repos. They resolve automatically with **no config**;27 a project override is worth writing only when this repo's tooling or doc directories differ from28 the bundled defaults.29- **Bundled templates** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/*.template.md`) are `<placeholder>`30 scaffolds for the lanes that are project-specific **by design**. Code the repo has but no generic31 lane can name. This skill's primary job is turning the fitting templates into real lane files.3233Never tell the user to "copy the bundled lanes." Scaffold from templates; override a bundled lane only34when its defaults miss this repo's actual layout.3536The plugin's second tracked surface is `${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md`,37optional and absent by default: root-relative globs that lift GLOBAL HARD **path** exclusions for every38run in this repository, the subtracting mirror of the consumer-declared protections that add to them.39`check` validates it; `apply` writes it only when the user asks. Contract, shape, precedence, and what40no channel lifts: the `tidy` skill's41[exclusions reference](${CLAUDE_PLUGIN_ROOT}/skills/tidy/reference/exclusions.md) section 4.4243## `check` (read-only)4445Inspect the consumer's tracked lanes and report a PASS/FAIL/INFO table with one remediation line per46FAIL. Modify nothing, and do NOT run a tidy sweep. That is `/code-tidying:tidy`.47481. **Project lanes present**. List `.claude/tidy-lanes/*.md`. None → INFO: tidy resolves the bundled49 lanes; `apply` scaffolds project lanes when this repo's layout diverges from the bundled defaults.502. **Lane structure**. Each present lane file carries the required sections (`## Scope`,51 `## Watch-for patterns`, `## Lane-specific extra exclusions`, `## Verification commands`,52 `## Conventional Commits type`, `## Preferred research sources`). A lane missing a section is FAIL, except a lane that declares `## Merge semantics` **and** shares its name with one of53 `${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/*.md`: that one54 inherits every section it omits from its bundled counterpart, so a missing section is expected, not a55 FAIL. Report which sections it inherits. The exemption belongs to the declaration, not to the heading:56 read the section and confirm it either adopts the bundled lane's declaration by reference (the shape57 `apply` writes. `Merge semantics: per the bundled lane's declaration`) or restates a disposition for58 every required section the lane omits. A `## Merge semantics` section that is empty, unrelated, or59 silent on an omitted section is FAIL. Malformed merge declaration; remediation is to adopt the bundled60 declaration by reference or to state the missing dispositions. FAIL too when the lane overrides a61 section the bundled lane keys at `###` granularity (`shell-tooling`'s `Verification commands` and62 `Preferred research sources`) without keying its own commands or sources under those `###` language63 headings. Unkeyed entries name no language to replace. Framing prose above the first `###` is fine.643. **No unreplaced placeholders**, a lane still containing a template `<placeholder>` resolves to a65 broken scope glob or watch-for pattern; FAIL, naming the file and the leftover token.664. **Tracked, not ignored**. Per lane file, run both halves of the tracked-file pair:67 `git check-ignore -v <file>` (a non-empty result means a `.gitignore` pattern excludes that lane;68 FAIL with the matching pattern in the remediation line — a directory can be tracked while a69 pattern excludes an individual `.md` inside it) AND `git ls-files --error-unmatch <file>`70 (non-zero exit means the lane is un-ignored but untracked: report it — "commit it to share with71 the team", downgraded to INFO only when the user confirms it is a deliberately private,72 uncommitted lane per the declared deviation below).735. **Bundled lanes and templates**. INFO: report the bundled lanes and templates available as scaffold74 sources, so the reader knows what `apply` can generate.756. **HARD-exclusion overrides**. Read `${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md`76 if it exists. Absent is the normal state; report INFO naming the file and what it does. Present, then77 check its shape against the `tidy` skill's78 [exclusions reference](${CLAUDE_PLUGIN_ROOT}/skills/tidy/reference/exclusions.md) section 4: an79 `## Overrides` heading with one fenced block, one root-relative glob per line. FAIL an absolute path80 or an entry containing `..`, naming the line. FAIL a glob matching the overrides file itself or the81 `.claude/tidy-lanes/` definitions beside it: the file cannot lift its own protection, and a run is82 never granted the switch that grants it. FAIL a glob that also matches a path this repo's own83 `CLAUDE.md` / `.claude/rules` declare protected, naming both declarations: the protection wins and84 the override is dead text. Run both halves of the tracked-file pair on it, exactly as for a lane85 file: `git check-ignore -v <file>` must report no match, and `git ls-files --error-unmatch <file>`86 must exit 0, since the file is a team statement that only counts when committed. Report the globs it87 lifts, so the reader sees the loosening the repo is carrying.887. **`hard_exclusions` posture**. Report the stored `userConfig` value as observed. `enforce` (the89 default) is PASS. `advisory` is INFO, not a FAIL: it is a deliberate operator posture, and the line90 states what it does (every GLOBAL HARD **path** entry is reported instead of blocking, in every run91 this operator makes). Name the running session's behavior as not yet established when the value was92 changed this session; the stored value is current, the session lags.9394## `apply` (idempotent)9596Run `check`, then apply the convention-resolution ladder. Config present → use it; absent → infer from97the repo and persist; cannot infer → ask and offer to persist; else a safe default (skip that lane, no98empty file). Proceed non-interactively for whatever the invocation and the repo make unambiguous; ask99only where a lane's scope genuinely needs the user's call.1001011. **Read existing lanes first.** List `.claude/tidy-lanes/*.md`. If any exist, read each and present a102 short summary (lane name, scope globs, watch-for count). Propose changes against that baseline;103 **never overwrite an existing consumer lane without explicit confirmation in this conversation.**1042. **Explore the repo to draft candidate lanes.** Before asking anything, map the four bundled template105 patterns against what actually exists, and check whether either bundled lane needs a project override:106 - **apps** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/apps-lane.template.md`). User-facing107 applications + their tests: web/API/CLI app roots and their sibling test projects.108 - **dependency-root** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/dependency-root-lane.template.md`): framework/library core that downstream code depends on: shared/domain/core library roots.109 - **host-wiring** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/host-wiring-lane.template.md`). Hosting110 infrastructure, logging, registration, service defaults: composition roots, DI wiring, service-default projects.111 - **polyglot-services** (`${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/polyglot-services-lane.template.md`): non-primary-language services, MCP servers, sidecars.112 - **bundled-lane override**. Inspect the repo's actual tooling dirs and doc dirs; a project override113 of `shell-tooling` or `docs-prose` is warranted only when they diverge from the bundled scope globs.114 Read the actual directory names and file extensions from the repo. Do not assume a stack. Skip any115 template pattern the repo has no surface for. When invoked as `apply <lane>`, scope this to that lane.1163. **Interview, one lane at a time** (recommendation-first). Present each candidate lane with its inferred117 scope globs and the source template, marked with a recommendation; let the user accept, edit the globs,118 or drop the lane. Offer a custom lane last ("any other glob-scoped slice this repo should tidy on its119 own rotation?"). Ask about the highest-blast-radius lane first.1204. **Fill the source lane from real repo values.** For each accepted lane, read its full source in full,121 then replace every `<placeholder>` (templates) or bundled default (overrides) with values drawn from122 this repo. The source depends on the lane's origin:123 - **Template-pattern lanes** (apps, dependency-root, host-wiring, polyglot-services) start from the124 exact template filename presented in step 2. `${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/<pattern>-lane.template.md`125 (e.g. `apps-lane.template.md`), and every `<placeholder>` is replaced.126 - **Bundled-lane overrides** (`shell-tooling`, `docs-prose`) have no template; read the bundled lane127 file `${CLAUDE_PLUGIN_ROOT}/skills/tidy/lanes/<lane>.md`, then write **only** the sections this repo128 actually diverges on (usually `## Scope`, sometimes extra exclusions), plus a `## Merge semantics`129 section adopting the bundled lane's declaration. Do not copy the sections the repo keeps: a copied130 section is frozen at its copy-time value, while an omitted one keeps inheriting bundled improvements.131 Where the bundled lane keys a section at `###` granularity, key the override the same way so it132 resolves per language.133 - **Custom lanes** (accepted from step 3's "any other slice?" offer) have no dedicated source: start134 from whichever template pattern is closest in shape to the slice and re-fill it, or, when none fits, author a new lane file from scratch using the same section structure the templates use (`## Scope`,135 `## Watch-for patterns`, `## Lane-specific extra exclusions`, `## Verification commands`,136 `## Conventional Commits type`, `## Preferred research sources`). Never emit an ad-hoc lane missing a section.137 Values to fill: scope globs from real directory paths, watch-for patterns tuned to the stack,138 lane-specific exclusions for this repo's unverifiable surfaces, verification commands from the project's139 own CLAUDE.md / rules / CI config (never invented), the Conventional Commits type, and preferred research140 sources. Leave no `<placeholder>` behind.1415. **Write the lane files.** Materialize each accepted lane at `.claude/tidy-lanes/<lane>.md`. Write only142 lanes the user confirmed; produce no empty scaffolds.1436. **Verify after remediation.** Re-run the `check` probes on each written file, required sections144 present, no leftover placeholder, and (per file) both halves of the tracked-file pair:145 `git check-ignore -v <file>` reports no match (a non-empty result means a `.gitignore` pattern146 excludes that lane; surface the matching pattern and offer to fix `.gitignore` before reporting147 success) AND `git ls-files --error-unmatch <file>` exits 0 (non-zero means un-ignored but still148 untracked, the guaranteed state right after a fresh write, so report "written but untracked:149 commit it to share with the team", never success), since these lanes are team-shared and must150 be committed to take effect. `/code-tidying:tidy` resolves a lane only from151 `.claude/tidy-lanes/<lane>.md` (then the bundled lane of that name), and its catalog lists152 `.claude/tidy-lanes/*.md`. There is no user-global or `*.local.*` overlay resolution (a declared153 deviation from the config-cascade contract). Every scaffolded lane is a tracked, team-shared file;154 do not point developers at a `*.local.*` variant the tidy skill would never load. A developer who155 wants a private lane uses a lane name the team does not track: keep `.claude/tidy-lanes/<lane>.md`156 uncommitted (never add it to the index). Gitignoring a path the team already tracks does not make157 it personal. Indexed files remain visible to Git regardless of `.gitignore`.1581597. **Offer the HARD-exclusion overrides file, only when the repo asked for one.** Do not scaffold it by160 default: absent is the correct state for almost every repository, and an empty overrides file is the161 empty scaffold step 5 forbids. Offer it when the conversation named a path the plugin keeps dropping,162 or when `check` reported a malformed existing file. Write163 `${CLAUDE_PROJECT_DIR}/.claude/code-tidying/exclusion-overrides.md` in the section 4 shape (an164 `## Overrides` heading, one fenced block, one root-relative glob per line, `#` comments), carrying165 only globs the user named. Preserve any prose already in the file. Re-run the step 6 `check` probes166 on what was written, including both halves of the tracked-file pair, and report it as written but167 untracked until it is committed. State plainly what the file loosens.168169Re-running `apply` after everything passes changes nothing and reports "already configured".170171## Personal configuration (`userConfig`)172173Not `apply` surface. Claude Code owns the storage, and this contract forbids setup to write174`pluginConfigs`, so `check` reports the observed value and routes the change. Reconfigure through175Claude Code's native flow, per the marketplace's176[plugin-reconfiguration convention](https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md)177(which owns the verified-version record): interactive `/plugin configure code-tidying@<marketplace>`178any time, or headless:179180```shell181claude plugin install code-tidying@<marketplace> -s <scope> --config hard_exclusions=advisory182```183184Against an already-installed plugin this prints `already installed` and still writes the value; the185short-circuit is about the install, not the config write. Do **not** uninstall to reconfigure: that186drops this plugin's entire stored `pluginConfigs` entry. Pass the scope `claude plugin list` reports.187The value is stored immediately, but the running session is not re-read, so start a fresh session188before expecting the new behavior. `hard_exclusions` takes `enforce` (default, every GLOBAL HARD path189entry blocks) or `advisory` (every one is reported and none blocks); any other value is read as190`enforce`. The full option table is in the plugin README.191192## Output193194Tracked `.claude/tidy-lanes/<lane>.md` file(s) in the consuming repo, plus a one-paragraph summary of which195lanes were written, which source each came from (template or bundled lane), and how to re-run this setup196to add or retune lanes. When an overrides file was written or already exists, the summary names it and the197globs it lifts.198199## What this skill does NOT do200201- Run a tidy sweep. That is `/code-tidying:tidy`. `check` only inspects config.202- Write the plugin cache, Claude Code user settings, or `pluginConfigs`.203- Ship its own template copies. Lane files scaffold from `${CLAUDE_PLUGIN_ROOT}/skills/tidy/templates/`;204 duplicating those into this skill would drift from the source.205- Write machine-local state. Lane configuration lives in the consumer's tracked `.claude/tidy-lanes/`,206 never in the plugin directory or a plugin data directory.