From 5f2c7724c7363262167711f20eb6f945f2a47fc2 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:15:52 -0400 Subject: [PATCH 01/10] docs: lock plugin-philosophy Brief (doctrine + fleet audit) Interview contract for extending the plugin doctrine to the full current component surface (official docs verified 2026-07-17): native-first with maturity gate, component stance table, userConfig full-potential criterion, criteria-gated setup mandate, convention registry, topic-docs two-tier seam fixes (worktree visibility), official-docs index, marketplace metadata maximalism, and a 47-plugin fanout conformance audit graduating to tracker waves. D1-D16 locked; Plan section awaits /architect. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/topics/plugin-philosophy/PLAN.md | 100 ++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 docs/topics/plugin-philosophy/PLAN.md diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md new file mode 100644 index 000000000..559c6416f --- /dev/null +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -0,0 +1,100 @@ +# plugin-philosophy + +## Brief + +### TLDR + +Extend the plugin doctrine to the full current component surface (13 component types, official docs +fetched 2026-07-17), lock a native-first principle with a maturity gate, fix the topic-docs two-tier +convention's visibility seams with native mechanisms, ship a complete official-doc link index, adopt +marketplace metadata maximally — then run a fanout conformance audit of all 47 plugins whose findings +graduate to tracker-managed remediation waves. + +### Goal + +Every plugin measurably conforms to an extended, freshness-guarded doctrine; no custom mechanism +exists where a fitting native one does; every cross-plugin convention has exactly one registered +owner doc; the remediation program lives on the work-item tracker where any session or machine can +resume it. + +### Locked decisions + +| # | Decision | +|---|---| +| D1 | Deliverable = doctrine revision + fleet-consistency audit, coupled in this one Brief. CI contract-gate automation deferred to follow-on (trigger: audit reveals automatable checks). | +| D2 | Doc-link index is a first-class deliverable: every plugin-relevant official doc page linked (components mapped to their doc pages); no undocumented component types. | +| D3 | Native-first principle: prefer built-in native mechanisms (userConfig, native component types, native lifecycle events) over custom extensibility points; custom only on genuine misfit, with the misfit documented. | +| D4 | Native-adoption gate (qualifies D3): adopt a native mechanism when it (1) fills a real existing gap, (2) is stable and works cleanly — experimental/immature features wait for maturity, (3) meets repo standards. Never custom-build what a fitting native mechanism covers. | +| D5 | Cross-plugin cooperation: hybrid. Native `dependencies` reserved for hard requires (plugin genuinely broken without collaborator) — none exist today; the `{name}--v{version}` git-tag release step lands with first use. Optional collaboration stays presence-gated with documented fallbacks; artifact protocol unchanged (data handoff, which dependencies don't cover). | +| D6 | Component stance table: skills = primary surface (new frontmatter — `paths`, `context: fork`, `arguments`, skill-scoped `hooks`/`once` — adopted case-by-case); `commands/` prohibited (officially legacy); agents, MCP, LSP, output styles, `bin/` = adopt-on-need (`bin/` requires collision-safe prefixed names; doctrine notes plugin agents ignore `hooks`/`mcpServers`/`permissionMode`); plugin `settings.json` `agent` (main-thread takeover) prohibited by default, exception needs documented justification; monitors, themes, channels = wait (experimental/immature), re-verified against current docs before each audit; dependencies per D5. Hooks addition: exec-form (`args`) mandatory wherever `${user_config.*}` appears (v2.1.207), else the `CLAUDE_PLUGIN_OPTION_` env mirror. | +| D7 | Freshness rider on all doctrine artifacts: every stance/inventory row carries a verified-date + link to its official doc page and an explicit disclaimer that the platform changes constantly — always re-fetch current docs before acting; never trust the repo file alone. | +| D8 | userConfig full-potential criterion: every personal/administrator scalar flowing through a custom channel (env-var toggle, gitignored personal file, documented hand-edit) migrates to userConfig using the full native schema — correct `type`, `default` preserving zero-config behavior, `required` only where truly blocking, `sensitive: true` for secrets, `claude plugin install --config` documented in each setup skill for headless use. Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK__ENABLED` toggles = flagship migration (userConfig booleans, `default: true`). | +| D9 | Setup doctrine v2: setup skill required iff (a) consumer-project config surface, (b) external prerequisites (CLI, service, credential), or (c) non-trivial userConfig — criteria applied through the modular/configurable/repo-/machine-/user-agnostic lens, never blanket ceremony; zero-config zero-prereq plugins exempt. Uniform contract: skill named `setup`, `disable-model-invocation: true`, `check` (read-only inspect/verify) + `apply` (idempotent configure) actions, complete-args non-interactive path. Formatter/linter plugins gain thin check-centric setups. Native `Setup` hook event = sanctioned headless/CI init surface; SessionStart + `${CLAUDE_PLUGIN_DATA}` manifest-diff = sanctioned runtime-dependency idiom. | +| D10 | Runtime-prerequisite visibility: anything with a runtime prereq (e.g. jq on PATH) degrades gracefully — never a hard crash; absence is surfaced to BOTH the agent and the user, with OTel as a candidate visibility channel; no black boxes. Extends the philosophy doc's "Prerequisites and failure behavior" section. | +| D11 | Convention registry: pointer-only section in PLUGIN-PHILOSOPHY.md — one owner doc per shared concern (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, artifact protocol, seam phrasing); registry names and points, never restates; audit rule = per-row conformance; a new convention lands in an owner doc before a second plugin adopts it. | +| D12 | Topic-docs tiers: keep the nature-based two-tier split and the `docs/topics/` name (contents are transient topic-scoped contract docs; `docs/specs/` is already the durable vault target — renaming would conflate tiers). | +| D13 | Two-tier seam fix package (all native): R1 `worktree.baseRef: "head"` in committed repo settings so worktree-isolated spawns carry task-branch state; R2 `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH — not baselines/raw scratch; one-way creation-time copy documented); R3 pointer discipline — durable surfaces (tickets, committed PLAN) never point at prunable or gitignored paths (decompose cites the PR, not the contract path; PLAN records distilled baseline values only); R4 isolated workers return results by value, the orchestrator writes both tiers in the parent checkout; R5 the work-item tracker is the cross-lane awareness/index layer (branch files stay lane-local; markdown-in-tickets as primary artifact store rejected — not diffable, drifts from code); R6 topic-docs convention doc corrected (worktree-visibility rationale, context×tier visibility matrix, mechanisms named) — a major contract version adopted by all implementers in one wave. | +| D14 | Doc-link index: dedicated `docs/OFFICIAL-DOCS.md` — complete categorized map of plugin-relevant official pages with a component→doc-page table, per-row verified-dates, the D7 staleness disclaimer, and `https://code.claude.com/docs/llms.txt` named as the authoritative self-updating master list. CLAUDE.md keeps its lean canonical table plus one pointer row to the index. | +| D15 | Marketplace metadata maximalism (machine-, user-, org-agnostic posture): populate every helpful-signal field — `relevance` signals wherever meaningful (audit criterion per plugin), `defaultEnabled: false` for personal/niche-category plugins, `displayName` where it genuinely clarifies, complete descriptive metadata. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + source declaration in managed settings). Hard rule: `version` lives in plugin.json only, never in marketplace entries (silent-precedence trap). | +| D16 | Audit execution: doctrine docs land first; then per-plugin subagent fanout scores all 47 plugins against a doctrine-derived checklist (~15 dimensions: setup criteria, userConfig migration, exec-form hooks, metadata completeness, component stances, registry conformance, prereq degradation, pointer discipline); findings distill into a plugin×dimension conformance matrix graduating to GitHub issues — one epic + per-wave issues (setup, userConfig, metadata, hooks, convention-seam waves) via the work-items seam; raw per-plugin detail stays memory-tier; automatable checks become the deferred CI gate's backlog. | + +### Constraints + +- Fresh-docs mandate applies at execution time: re-fetch the relevant official pages before each edit + wave; this Brief's doc facts were verified 2026-07-17. +- Work isolated in worktree, branch `docs/plugin-philosophy`; PRs required, squash merge, PR title + per Conventional Commits. +- Topic-docs convention change (D13/R6) is a major contract version; every implementer plugin adopts + in the same release wave (the contract carries no compatibility machinery). +- userConfig migrations preserve existing behavior via `default` values (guardrails toggles default + `true`). +- Every plugin change clears the migration playbook's gate + plugin-acceptance security review. + +### Acceptance criteria + +- PLUGIN-PHILOSOPHY.md revised: component stance table (D6) with D7 freshness riders, native-first + + adoption gate (D3/D4), convention registry (D11), config ownership updated (D8 criterion, exec-form + rule, version-placement rule), setup criteria (D9), prerequisite-visibility rule (D10). +- MIGRATION-PLAYBOOK.md updated consistently (setup contract, userConfig criterion, security review + touchpoints). +- `docs/OFFICIAL-DOCS.md` exists: complete categorized page map, component→doc table, verified-dates, + staleness disclaimer, llms.txt master pointer; CLAUDE.md carries the pointer row and stays lean. +- Topic-docs convention doc corrected per R6 with visibility matrix; R1 settings entry, R2 + `.worktreeinclude`, and R3 skill pointer fixes (decompose ticket provenance, architect baseline + recording) landed; the three flagged execution-time verifications resolved empirically and + recorded. +- marketplace.json metadata complete per D15; `claude plugin validate .` passes. +- Audit epic + wave issues filed on GitHub with the conformance matrix distilled into the epic; every + 47-plugin row scored; raw details in the memory slice. +- Existing CI (plugin contract tests, markdownlint) green on every PR. + +### Captured assumptions + +- Consumers run CC ≥ 2.1.207 (userConfig shell-form ban semantics, pluginConfigs scoping); older + clients degrade per official behavior, not worked around. +- Marketplace remains the melodic-software catalog but every decision holds machine-, user-, and + org-agnostic (no solo-consumer scoping). + +### Out-of-scope (deferred with triggers) + +- CI contract gate — trigger: audit identifies automatable checks (D16 backlog). +- Bundle plugin (name + dependencies curated set) — trigger: one-command curated install need beyond + the fleet-sync skill. +- Monitors, themes, channels adoption — trigger: feature exits experimental/immature status at a + future doc re-verification (D6 wait rows). +- `music` → `creative`, deployment category, and other plugin-organization deferrals remain owned by + that Brief. + +### Deferred questions + +- Windows `sensitive` userConfig storage behavior (docs silent on Windows keychain) — empirical + verification during audit, before any secret migrates. Arbiter: `/architect` (execution evidence). +- Worktree-sweep treatment of ignored files; `--bg` session worktree base semantics; + `worktree.baseRef` honored at project-settings scope — empirical smoke tests during D13 execution. + Arbiter: `/architect`. +- Per-plugin `relevance` signal quality (which signals are genuinely helpful vs noise) — decided + per-plugin during the metadata wave. Arbiter: `/architect`. + +## Plan + +(unfilled — /architect) From 70952abf7514afc873be2447f53f62fa1c86f093 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:53:22 -0400 Subject: [PATCH 02/10] docs: draft plugin-philosophy execution plan (7 phases, stress-tested) Plan section filled by /architect: doctrine revision (P1-P3), worktree empirical spike (P4), topic-docs 2.0.0 wave (P5), marketplace metadata (P6), 47-plugin conformance audit + tracker graduation (P7). Two fresh-context adversarial passes applied; pending user approval. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/topics/plugin-philosophy/PLAN.md | 453 +++++++++++++++++++++++++- 1 file changed, 452 insertions(+), 1 deletion(-) diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md index 559c6416f..0dfb25cee 100644 --- a/docs/topics/plugin-philosophy/PLAN.md +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -97,4 +97,455 @@ resume it. ## Plan -(unfilled — /architect) +Seven phases. Doctrine docs land first (D16 ordering), the topic-docs contract major version ships as +one wave, marketplace metadata follows, and the fleet audit runs last against the landed doctrine. +The fresh-docs mandate is embedded as the **first work item of every phase** that states platform +facts — never a standalone phase, never skipped. + +The three flagged empirical verifications resolve at their Brief-assigned execution points: +worktree-semantics smoke tests → Phase 4 (gates Phase 5 R1/R2); per-plugin `relevance` quality → +Phase 6 (per-plugin, during the metadata wave); Windows `sensitive` userConfig storage → Phase 7 +(before any userConfig-wave issue touching secrets is filed). + +### Phase 1: PLUGIN-PHILOSOPHY.md doctrine revision [TODO] + +Covers D3, D4, D6, D7, D8, D9, D10, D11. + +Work items: + +1. Fresh-fetch: `plugins`, `plugins-reference`, `skills`, `hooks`, `settings`, `plugin-dependencies` + pages; re-verify the 13 component types and the D6 stance facts (skill frontmatter additions, + `commands/` legacy status, `bin/` rules, agent field limitations, monitors/themes/channels + maturity, v2.1.207 exec-form rule). Any drift from the Brief's 2026-07-17 facts is recorded in + the memory slice and the stance table reflects current reality. The verified component-type + count (N, expected 13) is written to `.work/plugin-philosophy/component-count.txt` — Phases 1 + and 3 sanity checks assert against N, not a hard-coded 13. +2. Add **Native-first principle + adoption gate** section (D3/D4). +3. Add **Component stance table** (D6): 13 rows, each with stance, rationale, verified-date + + official-doc link (D7 rider), and the D7 staleness disclaimer heading the table. +4. Extend **Configuration ownership and scope**: D8 userConfig full-potential criterion (native + schema fields, `CLAUDE_PLUGIN_OPTION_` mirror, retirement of custom env channels), exec-form + hooks rule, version-placement rule (`version` in plugin.json only). +5. Rewrite **Setup is explicit and repeatable** to the D9 v2 criteria (required-iff conditions, + uniform `setup` skill contract, `Setup` hook event and SessionStart manifest-diff idioms). +6. Extend **Prerequisites and failure behavior** with D10 (graceful degradation, dual agent+user + visibility, OTel as candidate channel, no black boxes). +7. Add **Convention registry** section (D11): pointer-only table — one owner doc per shared concern + (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, + artifact protocol, seam phrasing); registry names and points, never restates. + +**Sanity Check:** + +- `grep -c "Verified 2026" docs/PLUGIN-PHILOSOPHY.md` ≥ N (one rider per stance row; N from + `component-count.txt`). +- `grep -n "Convention registry\|Native-first" docs/PLUGIN-PHILOSOPHY.md` returns both sections. +- Component stance table row count = N; Read confirms every verified component type named. +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.md` exit 0 (CI's + pinned action is authoritative; local run uses the repo config). + +### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [TODO] + +Depends on Phase 1 (doctrine wording is SSOT; playbook points, never restates). + +Work items: + +1. Update the per-plugin migration gate: setup-contract check (D9), userConfig criterion (D8), + exec-form hook rule — each as a pointer to the philosophy doc section plus playbook-specific + procedure only. +2. Extend the plugin-acceptance security review touchpoints: `sensitive` userConfig handling, + `bin/` collision-safe naming, plugin `settings.json` `agent` prohibition check. +3. Remove or redirect any playbook text that now duplicates Phase 1 doctrine (no restated stance + tables). + +**Sanity Check:** + +- `grep -n "PLUGIN-PHILOSOPHY" docs/MIGRATION-PLAYBOOK.md` shows pointer citations in the gate and + security-review sections. +- No restated stance table: no markdown table in MIGRATION-PLAYBOOK.md whose header row contains + both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. + +### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [TODO] + +Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 +stance table. + +Work items: + +1. Fresh-fetch `https://code.claude.com/docs/llms.txt`; enumerate every plugin-relevant page. +2. Create `docs/OFFICIAL-DOCS.md`: categorized page map, component→doc-page table, per-row + verified-dates, D7 staleness disclaimer, llms.txt named as the authoritative self-updating + master list. +3. Add one pointer row to CLAUDE.md's canonical table; CLAUDE.md stays lean (no other growth). +4. **Wave A join step (main session):** reconcile the component→doc table against Phase 1's + verified component list (`component-count.txt` + stance table) before PR A — parallel work off + the Brief snapshot must converge on Phase 1's fresh-fetched reality. + +**Sanity Check:** + +- `test -f docs/OFFICIAL-DOCS.md` && component table has N rows (N from `component-count.txt`). +- `grep -n "llms.txt" docs/OFFICIAL-DOCS.md` and `grep -n "OFFICIAL-DOCS" CLAUDE.md` both hit. +- CLAUDE.md diff = exactly one added table row: `git diff origin/main...HEAD --stat -- CLAUDE.md` + shows a 1-2 line delta. +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/OFFICIAL-DOCS.md` exit 0; the + repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory + weekly — spot-check a sample of new URLs via WebFetch instead). + +### Phase 4: Worktree-semantics empirical verification (throwaway spike) [TODO] + +Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe +with Phases 1–3 (touches scratchpad + throwaway worktrees only). + +All tests run in a **throwaway `git init` repo in the scratchpad with a synthetic `origin`** — +never in this repo (its ~30 live worktrees, runtime-written `.git/info/exclude`, and main checkout +on a feature branch confound every measurement). Use `claude -p --worktree` exclusively (skips the +trust dialog; interactive mode errors in a fresh repo). Unique worktree names per run (name reuse +resets clean worktrees to base since v2.1.208); the spike removes its own worktrees +(`-p`-created worktrees are never auto-cleaned; Windows: expect NTFS lock retries, +`git worktree remove --force`). + +Work items: + +1. Fresh-fetch the `worktrees` doc (the doc anchor for `baseRef`/`.worktreeinclude` — not the + settings page) plus `settings`; record cited behavior, including the documented fallback + "when `origin/HEAD` isn't resolvable, worktrees fall back to current local HEAD". +2. Smoke test A — `worktree.baseRef: "head"` at **project-settings scope**, two arms: **control** + (`baseRef` unset or `"fresh"`) asserts marker ABSENT; **treatment** (`baseRef: "head"` in + committed `.claude/settings.json`) asserts marker PRESENT. Verdict HONORED only if BOTH arms + behave — a marker-present-only test is defeated by the documented origin/HEAD fallback (false + positive). Variant A2: spawn from within an existing linked worktree (docs state `head` resolves + to that worktree's HEAD — test against that expected value). Variant A3: `settings.json` present + only in the worktree checkout vs only in the main checkout — pins which copy a linked-worktree + session reads (undocumented; only `settings.local.json` is documented as main-checkout-resolved). +3. Smoke test B — `.worktreeinclude` one-way creation-time copy: use real nested-gitignore paths + (`.work//…` ignored via a nested `*` `.gitignore`, mirroring this repo) — not a toy + root-level pattern; assert copy at creation; modify original, assert no sync-back. +4. Smoke test C — worktree-sweep treatment of ignored files (genuinely undocumented — this test is + the only source of truth; capture `git status --ignored` snapshots in the raw transcript) + + `--bg` session worktree base semantics. +5. The sub-agent records raw transcripts in `.work/plugin-philosophy/verifications/`, stamps every + VERDICT file with `claude --version`, and **returns the VERDICT lines by value**; the **main + session** fills the pending rows in this PLAN's "Empirical verification results" table (PLAN.md + edits stay main-session-only) and feeds them into Phase 5's R1/R2 design. If the CC version has + moved by the Phase 5 gate, re-run the cheap test-A control/treatment pair. + +**Sanity Check:** + +- `.work/plugin-philosophy/verifications/` contains ≥ 3 result files, one per smoke test, each + ending in a one-line VERDICT (`HONORED` / `NOT-HONORED` / behavior description) and a + `claude --version` stamp line. +- Test A result file contains BOTH `control:` and `treatment:` lines with opposite marker outcomes + (else verdict is invalid by construction). +- This PLAN's "Empirical verification results" table row 1 is filled (no `(pending)`). + +### Phase 5: Topic-docs contract 2.0.0 + seam fixes R1–R6 (one wave) [TODO] + +Covers D13. Contract-major change: every implementer adopts in the same wave (no compatibility +machinery). Gated by Phase 4 verdicts. + +Work items: + +1. **Pre-flight consumer check (first item):** `Grep`/`Glob` for every consumer parsing the + convention surface — `.claude/topic-docs.yaml` keys, slug spec, tier paths, runtime guards, the + `scripts/check-cross-plugin-source-drift.sh` registry, hooks reading `docs/topics/` or `.work/`. + Document parse paths in the memory slice before editing anything. +2. R6 — rewrite `docs/conventions/topic-docs/README.md`: worktree-visibility rationale, context × + tier visibility matrix, native mechanisms named (`worktree.baseRef`, `.worktreeinclude`, by-value + returns, tracker index); CHANGELOG entry `2.0.0`; schema untouched unless a key changes (KEEP + expected). **Reconcile the Implementers table with reality**: `toolchain` and `verification` + carry `reference/topic-docs.md` but are absent from the table; `knowledge`, `claude-ops`, + `docs-hygiene` are listed without delta docs — the 2.0.0 table must match the actual fleet + (add/annotate rows or document why a row is delta-doc-free). The CHANGELOG 2.0.0 entry states + the **mixed-fleet window** and why it is safe (no tier/key/slug-spec change — installed cache + copies and in-flight branches keep 1.x text until they update; divergence is doctrinal, not + layout-corrupting), and notes a post-PR-B stale-text sweep obligation for in-flight branches at + their merge time. +3. R1 — committed `.claude/settings.json` with `worktree.baseRef: "head"` (shape per Phase 4 smoke + test A verdict; if NOT-HONORED at project scope, execute the tagged fallback below). Rollout + note in the PR B description + convention doc: a clone with an existing untracked + `.claude/settings.json` hits "untracked working tree file would be overwritten" on pull — + document the remedy; state the repo-wide worktree-spawn behavior change; **gitignore + `.claude/worktrees/` in the same change** (mandatory — the runtime `.git/info/exclude` entry is + machine-local; CI checkouts and fresh clones lack it, and partial tracking of `.claude/` + otherwise turns nested worktrees into `git add -A` hazards); run the hygiene CI lanes + (machine-specific-paths, gitleaks, editorconfig) locally on the new tracked file. Document the + escape hatch: a personal `.claude/settings.local.json` (main-checkout-resolved, covers every + worktree) silently overrides R1 machine-wide — the convention doc states this; no audit + dimension may assume R1 is universally in force. + **Consumer-adoption path (mandatory):** repo settings never travel with marketplace-installed + plugins (isolated cache) — R1/R2 as files fix only this repo. The 2.0.0 doc ships a + consumer-adoption section: the settings snippet + a `.worktreeinclude` template, scoped as + "authoring-repo materialization; consumer repos self-apply" (routing it through a D9 setup-skill + `apply` action is recorded as a follow-on trigger, not built now). The visibility matrix gains a + caveat row: a `WorktreeCreate` hook makes `.worktreeinclude` inert (documented) — hook script + owns the copy. +4. R2 — `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH; not + baselines/raw scratch); one-way creation-time copy documented in the convention doc. +5. R3 — pointer-discipline fixes: `plugins/work-items/skills/decompose` cites the PR (not contract + paths) in ticket provenance; `plugins/planning/skills/architect` records distilled baseline + values in PLAN (raw captures stay memory-tier). Sweep both skill bodies for prunable-path + citations. +6. R4/R5 — convention doc text: isolated workers return results by value with the orchestrator + writing both tiers in the parent checkout (R4); the work-item tracker named as the cross-lane + awareness/index layer, markdown-in-tickets rejected with rationale (R5). +7. Implementer wave: update all 8 `plugins/*/reference/topic-docs.md` delta docs against the 2.0.0 + owner doc; bump each touched plugin's `plugin.json` semver + CHANGELOG; docs-hygiene declutter + detector references checked (reader row). + +File inventory (checkbox discipline — tick as processed): + +| File | Action | Rationale | +|---|---|---| +| [ ] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | +| [ ] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | +| [ ] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes expected | +| [ ] `docs/conventions/topic-docs/examples/*` | AUDIT | update only if matrix/mechanisms change examples | +| [ ] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | +| [ ] `.worktreeinclude` | CREATE | R2 patterns | +| [ ] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | +| [ ] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | +| [ ] 8–10 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | semver bump per touched plugin | +| [ ] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | implementer-table rows without delta docs — verify no stale convention text | + +**Sanity Check:** + +- `bash scripts/check-cross-plugin-source-drift.sh --check` exit 0 (the flag CI runs; flagless mode + is informational only). +- `grep -n "2.0.0" docs/conventions/topic-docs/CHANGELOG.md` hits; `grep -rn "visibility matrix" -i + docs/conventions/topic-docs/README.md` hits. +- Implementers-table parity: every `plugins/*/reference/topic-docs.md` path has a matching table + row and vice versa (Read assertion against the glob result). +- Pre-flight consumer list exists: `.work/plugin-philosophy/consumers-topic-docs.md` non-empty. +- Every plugin with a modified file has a `plugin.json` version bump: + `git diff origin/main...HEAD --name-only | grep '^plugins/' | cut -d/ -f2 | sort -u` each has a + matching `plugins//plugin.json` in the diff. +- `bash scripts/validate-plugins.sh` exit 0 (includes `generate-catalog.mjs --check` — regenerate + the catalog if any plugin.json description changed). +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc` on touched .md files exit 0. + +### Phase 6: Marketplace metadata wave [TODO] + +Covers D15 + per-plugin `relevance` quality verification (deferred question c). + +Work items: + +1. Fresh-fetch `plugin-marketplaces` + `discover-plugins` + `plugins-reference` + (default-enablement section) + the dedicated `plugin-relevance` page; re-verify entry schema + (`relevance`, `defaultEnabled`, `displayName`, description precedence, `version` + silent-precedence trap). **`defaultEnabled` flip semantics for already-installed consumers are + undocumented** — if the fetched pages stay silent, run a 2-minute empirical flip on one plugin + before the wave (does a marketplace refresh disable an existing install?). Never touch a + plugin's `name` (breaks existing installs without a `renames` map); `displayName` is safe. +2. Per-plugin pass over all 47 entries: add `relevance` only where the signal is genuinely helpful + (judged per-plugin — noise rejected), `defaultEnabled: false` for personal/niche categories, + `displayName` where it clarifies, complete descriptions; assert **no `version` field in any + entry**. +3. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + + managed-settings source declaration) — lands in the discover/consumer section of README or + OFFICIAL-DOCS per where consumer docs live (decided at execution against the fetched page). +4. Record per-plugin relevance decisions (adopted vs rejected-as-noise) in + `.work/plugin-philosophy/relevance-decisions.md`. +5. Regenerate the README catalog: `node scripts/generate-catalog.mjs` (CI runs `--check`; metadata + edits drift the generated block otherwise). + +**Sanity Check:** + +- `claude plugin validate .` exit 0. +- `node scripts/generate-catalog.mjs --check` exit 0. +- `node -e` assertion: 47 entries; every entry resolves a description (entry or plugin.json); + `version` absent from all entries — exit 0. +- `.work/plugin-philosophy/relevance-decisions.md` has 47 rows. + +### Phase 7: Fleet conformance audit fanout + tracker graduation [TODO] + +Covers D16. Runs against merged doctrine (Phases 1–6 landed). + +Work items: + +1. **Search-before-create (first item):** `gh issue list --search` for an existing + plugin-conformance epic / wave issues. Match found → pivot to updating the existing items + (record the match + pivot in the memory slice); no match → proceed to create. Verify required + labels exist (`gh label list`) and create missing ones before any `gh issue create --label` + call (missing labels fail the create). +2. Derive the audit checklist (~15 dimensions) from the landed doctrine docs: setup criteria (D9), + userConfig migration (D8), exec-form hooks, metadata completeness (D15), component stances (D6), + registry conformance (D11), prereq degradation (D10), pointer discipline (R3), freshness riders + (D7), plus dimensions the doctrine text yields. **Freeze a rubric file** with per-dimension + anchored PASS/FAIL criteria + one worked example, injected verbatim into every worker prompt + (uncalibrated independent scoring across batches encodes rubric drift, not conformance). + **Authority rule:** plugins are scored against **landed doctrine only**; where a fresh-fetched + doc disagrees with doctrine, that is a doctrine-update finding (its own wave), never plugin + nonconformance. Dimensions may not assume R1 is universally in force (local-settings override + exists). Checklist + rubric → memory slice. +3. Fresh-fetch the component doc pages the checklist cites (to detect doctrine-vs-platform drift + per the authority rule above). +4. **Windows `sensitive` userConfig empirical verification** (deferred question a): configure a + throwaway `sensitive` userConfig value on this Windows machine; locate where it persists + (Credential Manager vs plaintext file); VERDICT recorded before any userConfig wave issue + involving secrets is filed. Secrets excluded from that wave if storage is plaintext (tagged + fallback below). +5. Fanout: **pilot batch of 3–5 plugins first**, reviewed by the main session against the rubric + before full fanout; then per-plugin subagents score the remainder in **batches of 8–10**; each + worker writes its own raw report to `.work/plugin-philosophy/audit/.md` (memory-tier + raw output is carved out of R4 — R4's orchestrator-writes rule governs contract/durable tiers) + and returns only its scored dimension row by value; the orchestrator (main session) appends + matrix rows incrementally per batch, so a compaction mid-run loses nothing. **Double-score a + random 3-plugin sample** with independent workers and reconcile disagreements before graduating + the matrix. +6. File the GitHub epic (conformance matrix distilled inline — **single-token score cells only**, + prose lives in per-wave issues; GitHub bodies cap near 64 KB) + per-wave issues (setup, + userConfig, metadata, hooks, convention-seam) via the work-items seam; issues cite the epic + PR + permalinks, never contract/memory paths (R3). Automatable checks list → epic section = deferred + CI gate backlog (D1 trigger). + +**Sanity Check:** + +- Search outcome recorded: `.work/plugin-philosophy/audit/tracker-search.md` states the query + hit + count + create-vs-update decision. +- `ls .work/plugin-philosophy/audit/*.md | wc -l` ≥ 47 (one report per plugin) + matrix file with + 47 scored rows. +- `gh issue list --label epic --search "plugin conformance"` (or equivalent) returns the epic; + epic body contains the matrix; ≥ 5 wave issues reference the epic. +- `grep -c "docs/topics/\|\.work/" ` = 0 (pointer discipline). +- Windows `sensitive` VERDICT file exists in `.work/plugin-philosophy/verifications/`. + +### Empirical verification results + +| # | Question | Phase | VERDICT | +|---|---|---|---| +| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | (pending) | +| 2 | Per-plugin `relevance` signal quality | 6 | (pending — per-plugin ledger) | +| 3 | Windows `sensitive` userConfig storage | 7 | (pending) | + +## Blast radius + +**HIGH.** Matches stress-test triggers: new conventions constraining all future work (doctrine + +contract-major), architecture decisions across 47 plugins + 8 implementer materializations, shared +committed settings (`.claude/settings.json`) affecting every session, and undocumented behavior +(worktree semantics, Windows sensitive storage — mitigated by the empirical phases). Reversible via +git revert (docs/metadata only, no runtime code), and existing CI (contract tests, markdownlint, +drift check) gates every PR — hence HIGH, not CRITICAL. + +## Stress-test summary + +Two fresh-context adversarial passes ran; all findings verified against the repo before adoption. + +**Plan-reviewer (Step 3):** 9 IMPORTANT + 5 SUGGESTION, 0 CRITICAL — all applied: implementer-roster +reconciliation + parity check (Phase 5), CI-parity sanity commands (drift `--check`, catalog +`--check`, markdownlint config, `node -e` over Python), pointer-vs-restate check made structural +(Phase 2), Phase 4 by-value/fence contradiction resolved, component-count made variable with a +Wave A join step, PR-chain PLAN lifecycle defined, Phase 7 batching + label verify-or-create, +worktree-variant smoke tests, R1 rollout notes. + +**Devils-advocate (Step 4):** 16 assumptions attacked; 4 mandatory changes, all applied: +(1) Phase 4 redesigned — isolated scratch repo with synthetic origin, control+treatment arms +(defeats the documented origin/HEAD-fallback false positive), settings-scope variant A3, +CC-version-stamped verdicts with re-run at the Phase 5 gate; (2) PLAN lifecycle switched to +branch-local prune-per-PR (the program must not self-violate the contract it ships); (3) 2.0.0 doc +gains a consumer-adoption path — repo settings provably never reach marketplace-installed +consumers; (4) Phase 7 calibration — frozen anchored rubric, pilot batch, double-scored sample. +Also adopted: mandatory `.claude/worktrees/` gitignore in PR B, `WorktreeCreate`-hook caveat for +`.worktreeinclude`, mixed-fleet window statement in the CHANGELOG, doctrine-wins authority rule for +audit scoring, `defaultEnabled`-flip empirical check, matrix cell budget (64 KB body cap), `name` +immutability during the metadata wave. One finding escalated to a user gate: R6 major-vs-minor +contradiction with the contract's own versioning rule (see User-approval gates). + +## Execution shape + +Two parallel-safe waves inside an otherwise sequential PR chain; fanout inside Phase 7. + +| Phase | Surface | Basis | +|---|---|---| +| 1 | Main session | Judgment-heavy doctrine writing; SSOT wording others depend on | +| 2 | Main session | Depends on Phase 1 wording; pointer discipline needs judgment | +| 3 | Sub-agent worker (parallel with 1–2) | Mechanical index build from llms.txt; disjoint files (`OFFICIAL-DOCS.md`, one CLAUDE.md row) | +| 4 | Sub-agent worker (parallel with 1–3) | Scripted smoke tests; touches scratch/throwaway worktrees only | +| 5 | Main session (implementer sweep may fan out mechanically) | Contract-major judgment; 25-file wave needs single editorial voice | +| 6 | Main session | Single file; 47 per-plugin relevance judgments | +| 7 | Workflow/sub-agent fanout, orchestrated by main session | D16-locked fanout; R4 by-value returns | + +Wave A (parallel): Phase 1 (main) ∥ Phase 3 (sub-agent) ∥ Phase 4 (sub-agent). Zero file overlap: +P1 = `docs/PLUGIN-PHILOSOPHY.md`; P3 = `docs/OFFICIAL-DOCS.md` + CLAUDE.md; P4 = `.work/` + scratch. +Wave B (sequential): Phase 2 → Phase 5 → Phase 6 → Phase 7. + +Scope fences (Wave A): P3 agent ALLOWED `docs/OFFICIAL-DOCS.md`, `CLAUDE.md` (one row); +FORBIDDEN everything else incl. PLAN.md. P4 agent ALLOWED `.work/plugin-philosophy/verifications/` +and throwaway `git init` repos under the scratchpad (its own branches/worktrees live there); +FORBIDDEN every file and branch of THIS repo (note: `claude -p --worktree ` creates branches +named `worktree-` — another reason the spike never runs in this repo). +Sequential fallback: any fence violation or agent failure → that phase re-runs inline main-session +in Wave B order. PLAN.md edits are main-session-only. + +Cost note: Wave A = 2 extra agents vs sequential (~saves one serial doc-build + smoke-test round); +Phase 7 = ~47 scoring agents (D16-locked, run regardless of shape). + +## Open questions + +None blocking — the three empirical questions are scheduled inside phases with tagged fallbacks. + +## Handoff to implementation + +### User-approval gates + +- **[BRIEF CONTRADICTION — user decision required]** D13 locks R6 as a **major** contract version + ("2.0.0, one wave"), but the contract's own Versioning rule says major = "moves a tier, renames a + key, or alters the slug spec" — R6 does none (schema KEEP; the change is visibility semantics + + doctrine text). Options: (a) keep 2.0.0 and amend the Versioning rule so visibility-semantics + guarantees also count as major (the doctrine repo then applies its own rule consistently); + (b) downgrade to a 1.x minor, dissolving the one-wave coordination burden and most of Phase 5's + mixed-fleet risk. RECOMMENDED: (a) — the Brief locked the one-wave clean break deliberately, and + a visibility-guarantee change does alter what implementers may rely on; the rule amendment makes + the label honest. The plan as written assumes (a). +- [FALLBACK — confirm or override] Smoke test A fails (project-scope `worktree.baseRef` not + honored): R1 degrades to documenting the limitation + the strongest honored scope in the + convention doc, and an upstream issue is filed; R2/R6 proceed unchanged. +- [FALLBACK — confirm or override] Windows `sensitive` storage is plaintext: secret-bearing + userConfig migrations are excluded from the userConfig wave issue and recorded as blocked-upstream + in the epic; non-secret migrations proceed. +- Scope-expansion of any kind (new convention, new component adoption) mid-flight → stop and ask. + +### Execution shape ([EXEC-SHAPE] tagged) + +- [EXEC-SHAPE] PR slicing: PR A = Phases 1–3 (doctrine + index, current branch + `docs/plugin-philosophy`); PR B = Phases 4–5 (contract 2.0.0 wave; Phase 4 evidence rides the + memory tier, distilled results in PLAN); PR C = Phase 6 (metadata); PR D = close-out (Phase 7's + PLAN/verdict updates + prune-with-pointer). Rationale: reviewability + distinct concerns + (doctrine vs contract-major vs metadata); each PR independently green on existing CI. +- [EXEC-SHAPE] PLAN.md lifecycle across the PR chain — **branch-local, prune-per-PR**: the + topic-docs contract says contract slices are pruned before merge, and this program (which ships + that very contract's 2.0.0) must not self-violate by parking a slice on `main` for weeks. Each PR + branch commits the current PLAN, pastes it into its PR description, and prunes the slice in a + final commit before merge; the next PR branch (cut from post-squash `main`) re-commits the + updated PLAN from the local working tree. Cross-PR continuity = the PR-description pastes + (from + Phase 7) the epic. Close-out at PR D: Phase 7's verdict rows and final status tags commit there, + durable outcomes graduate, final prune-with-pointer. The Windows `sensitive` VERDICT is recorded + durably (PLAN verdict table → PR D description + epic), not only in gitignored `.work/`. + (Alternative rejected: adding a multi-PR-program exception clause to the 2.0.0 lifecycle text — + viable, but it lands only in PR B while PR A would already need it; override at approval if the + exception clause is preferred.) +- [EXEC-SHAPE] Wave A parallelism + fences as tabled above. +- [EXEC-SHAPE] Phase 7 fanout surface: per-plugin subagents (Workflow engine if available, plain + sub-agent fanout otherwise) — D16 locks the fanout itself. +- [EXEC-SHAPE] Empirical verifications embedded at Brief-assigned execution points (P4/P6/P7) + rather than a standalone verification phase. + +### Mechanical work + +- Commit boundaries: one commit per phase minimum; Phase 5 = one wave commit for the contract bump + + implementer adoption (clean break lands atomically); PLAN.md status-tag updates ride each phase's + commit. Each PR branch is cut from **post-squash `main`**, never from the previous PR branch + (stacking would replay the prior PR's squashed commits in the diff). +- Verification checkpoints: run each phase's Sanity Check before its commit; existing CI + (contract tests, markdownlint, drift check) green before each PR merge. +- Sequential fallback: documented under Execution shape; orchestrator-writes rule (R4) applies to + all fanout output. +- Close-out: `/architect close-out` at PR time — PLAN.md into PR description `
`, durable + outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. From ee1c540380657475e852d00216bc36f19f7614d3 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:09:03 -0400 Subject: [PATCH 03/10] =?UTF-8?q?docs:=20revise=20plugin=20doctrine=20?= =?UTF-8?q?=E2=80=94=20stance=20table,=20native-first,=20registry=20(P1-P2?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLUGIN-PHILOSOPHY.md: 13-row component stance table with per-row verified-date riders and staleness disclaimer, native-first principle with adoption gate, userConfig full-potential criterion, exec-form hook rule, version single-home rule, setup-required-iff criteria with check/apply contract, runtime-prerequisite visibility, convention registry (pointer-only). MIGRATION-PLAYBOOK.md: gate step 7 (component stances), security-review surface 7 (settings.json agent, bin/ PATH), setup section now points at the philosophy doc. Facts re-fetched from official docs 2026-07-17. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/MIGRATION-PLAYBOOK.md | 52 +++++++---- docs/PLUGIN-PHILOSOPHY.md | 122 +++++++++++++++++++++++--- docs/topics/plugin-philosophy/PLAN.md | 8 +- 3 files changed, 149 insertions(+), 33 deletions(-) diff --git a/docs/MIGRATION-PLAYBOOK.md b/docs/MIGRATION-PLAYBOOK.md index 0bf9a6182..06b6bb55a 100644 --- a/docs/MIGRATION-PLAYBOOK.md +++ b/docs/MIGRATION-PLAYBOOK.md @@ -257,15 +257,17 @@ The **adopted** rule for how a plugin settles a value at runtime, applied to eve No baked repo assumptions, ever. A plugin never hardcodes a consumer's layout; it reads a declared value, infers-and-records, or asks — never guesses silently. -## Setup action — every configurable plugin ships one - -Every plugin that carries any `userConfig` or tracked-config seam ships a re-runnable `setup` / -`configure` action (a skill) that interviews the consumer and writes the tracked config. It is -idempotent — safe to re-run to reconfigure. The Thariq `config.json` first-run pattern is **rejected** -for plugins: it is not an official mechanism, and it writes into `${CLAUDE_PLUGIN_ROOT}`, which is -replaced on every update (the plugins-reference caching note), so its state does not survive. Setup -writes only the consumer configuration the plugin owns. Claude Code's native configuration surface -collects `userConfig` and owns `pluginConfigs`; a setup skill never edits that key directly. +## Setup action — required iff the criteria hold + +Whether a plugin needs a `setup` skill, and the uniform contract it follows (`setup` name, +`disable-model-invocation: true`, `check` + `apply` actions, non-interactive completion), is owned +by [PLUGIN-PHILOSOPHY.md § Setup is explicit and repeatable](PLUGIN-PHILOSOPHY.md). Migration work +applies it as-is. Playbook-specific additions: the Thariq `config.json` first-run pattern is +**rejected** for plugins — it is not an official mechanism, and it writes into +`${CLAUDE_PLUGIN_ROOT}`, which is replaced on every update (the plugins-reference caching note), so +its state does not survive. Setup writes only the consumer configuration the plugin owns; Claude +Code's native configuration surface collects `userConfig` and owns `pluginConfigs` — a setup skill +never edits that key directly. ## Upstream sync — every upstream-sourced plugin ships an update path @@ -565,15 +567,22 @@ For each skill/hook/agent being migrated: 3. **De-couple from the source repo.** Remove hardcoded paths/names; route project-specifics to the consumer's context. 4. **Bundle + isolate.** Move required assets inside the plugin; reference via `${CLAUDE_PLUGIN_ROOT}`. -5. **Expose extensibility.** Declare `userConfig` for consumer choices; document each option. +5. **Expose extensibility.** Declare `userConfig` for consumer choices; document each option. Apply + the userConfig full-potential criterion and the exec-form hook rule from + [PLUGIN-PHILOSOPHY.md § Configuration ownership and scope](PLUGIN-PHILOSOPHY.md): no custom + config channel where the native schema fits, and no `${user_config.*}` in shell-form hooks. 6. **Strip PII / secrets.** Hard gate — before the first commit. -7. **Idempotent, modular, extensible.** Re-running is safe; pieces compose; variability is declared. -8. **Validate.** `claude plugin validate`; test with `--plugin-dir` in a clean repo that is NOT the +7. **Check component stances.** Every component the plugin ships conforms to the component stance + table in [PLUGIN-PHILOSOPHY.md](PLUGIN-PHILOSOPHY.md) — no `commands/`, no unjustified + `settings.json` `agent`, wait-listed components absent; setup criteria applied per its setup + section; runtime prerequisites degrade per its failure-behavior rules. +8. **Idempotent, modular, extensible.** Re-running is safe; pieces compose; variability is declared. +9. **Validate.** `claude plugin validate`; test with `--plugin-dir` in a clean repo that is NOT the source repo (proves repo-agnosticism). -9. **Version.** Set an explicit semver `version` in `plugin.json`. A later bump that changes behavior a +10. **Version.** Set an explicit semver `version` in `plugin.json`. A later bump that changes behavior a consumer depends on records the change in the plugin's changelog — see "Version pinning and update delivery" above. -10. **Publish.** Add the entry to `.claude-plugin/marketplace.json` — the plugin `source` is the +11. **Publish.** Add the entry to `.claude-plugin/marketplace.json` — the plugin `source` is the `./`-prefixed relative path (e.g. `./plugins/`). Bare names fail `claude plugin validate --strict` even with `metadata.pluginRoot` set, despite the marketplaces-doc example to the contrary (verified 2026-06-23). Then run `claude plugin validate --strict ` to validate the **catalog manifest @@ -609,7 +618,8 @@ license-gated units to per-item triage rather than a blanket hold. The ordering A plugin runs code on the consumer's machine and can wire Claude to external systems. **Every plugin accepted here — new, or a version bump that adds a trust surface — passes this review** in addition to the migration gate above (whose step 6 gates PII/secrets). **Deny by default** any surface below that can't be justified. -Facts verified against the plugins/MCP reference 2026-07-09; re-verify per the `CLAUDE.md` fresh-docs mandate. +Facts verified against the plugins/MCP reference 2026-07-09 and re-verified against the plugins, +plugins-reference, and hooks pages 2026-07-17; re-verify per the `CLAUDE.md` fresh-docs mandate. 1. **Code execution — hooks & scripts.** A hook command runs on the consumer's machine on matched events, with `${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_PROJECT_DIR}`, `${CLAUDE_PLUGIN_DATA}`, and any `${ENV_VAR}` @@ -646,9 +656,15 @@ Facts verified against the plugins/MCP reference 2026-07-09; re-verify per the ` third-party SaaS is a trust delegation — record accept/deny with rationale. Note the platform already blocks plugin-shipped **agents** from declaring `hooks` / `mcpServers` / `permissionMode` "for security reasons" — don't design around that. - -Record accept/deny + rationale for any plugin touching surfaces 2, 5, or 6; a later version bump that -introduces a new surface re-triggers this review. +7. **Main-thread and PATH surfaces.** A plugin `settings.json` `agent` entry takes over the + consumer's main thread — prohibited by default per the component stance table in + [PLUGIN-PHILOSOPHY.md](PLUGIN-PHILOSOPHY.md); an exception requires the documented justification + the stance demands, reviewed here. `bin/` executables join the Bash tool's `PATH` while the + plugin is enabled: names must be collision-safe (plugin-prefixed), and each binary's provenance + is reviewed like any hook script. + +Record accept/deny + rationale for any plugin touching surfaces 2, 5, 6, or 7; a later version bump +that introduces a new surface re-triggers this review. ## Local development loop diff --git a/docs/PLUGIN-PHILOSOPHY.md b/docs/PLUGIN-PHILOSOPHY.md index 9f89b67d4..fb10bfa61 100644 --- a/docs/PLUGIN-PHILOSOPHY.md +++ b/docs/PLUGIN-PHILOSOPHY.md @@ -18,6 +18,10 @@ Keep plugins horizontally decoupled: - It never imports files from a sibling plugin or discovers another plugin's installation directory. - Cooperation uses a documented public seam: an artifact contract, an explicit invocation argument, or an optional namespaced skill invocation. +- Native manifest `dependencies` are reserved for hard requires — a plugin genuinely broken without + its collaborator. Optional collaboration stays presence-gated with a documented fallback. The + first versioned dependency brings the `{name}--v{version}` release-tag step + (`claude plugin tag --push`) with it. - Every plugin remains useful alone. If an optional collaborator is absent, use a documented fallback or report the missing optional capability clearly. @@ -25,6 +29,44 @@ This follows Claude Code's distinction between project-specific standalone confi intended for reusable, versioned distribution. Namespaced skill invocations are part of that isolation, not an implementation detail. +## Native-first + +Prefer a built-in native mechanism — `userConfig`, a native component type, a native lifecycle +event — over any custom extensibility point. Build custom only on genuine misfit, and document the +misfit where the custom mechanism lives. + +Adoption gate, applied per mechanism: adopt a native mechanism when it + +1. fills a real existing gap — never adopt for novelty; +2. is stable and works cleanly — experimental or immature features wait for maturity and are + re-verified against current docs before each fleet audit; and +3. meets repository standards. + +Never custom-build what a fitting native mechanism already covers; retire the custom channel when a +native one matures into fitness. + +## Component stances + +> **Staleness disclaimer.** The platform changes constantly. Every row carries the date its facts +> were verified against the linked official page. Always re-fetch the current page before acting on +> a row; never trust this table alone. + +| Component | Stance | Rationale and constraints | Verified | +|---|---|---|---| +| [Skills](https://code.claude.com/docs/en/skills) | Primary surface | The default unit of capability. Newer frontmatter — `paths`, `context: fork` (+ `agent`), `arguments`, skill-scoped `hooks` with `once` — adopted case-by-case through the adoption gate. | 2026-07-17 | +| [`commands/`](https://code.claude.com/docs/en/plugins-reference) | Prohibited | Officially merged into skills; docs direct "use `skills/` for new plugins". Existing flat commands migrate to skill directories. | 2026-07-17 | +| [Agents](https://code.claude.com/docs/en/sub-agents) | Adopt on need | Plugin agents do not support `hooks`, `mcpServers`, or `permissionMode` (security restriction) — design within that limit rather than working around it. | 2026-07-17 | +| [Hooks](https://code.claude.com/docs/en/hooks) | Adopt on need | Exec form (`args`) is mandatory wherever `${user_config.*}` appears — shell form errors since v2.1.207; otherwise read the `CLAUDE_PLUGIN_OPTION_` mirror. Windows exec form spawns real executables only (no `.cmd`/`.bat` shims): use `"command": "node", "args": [...]`. | 2026-07-17 | +| [MCP servers](https://code.claude.com/docs/en/mcp) | Adopt on need | Clears the plugin-acceptance security review for egress and trust delegation. | 2026-07-17 | +| [LSP servers](https://code.claude.com/docs/en/plugins-reference) | Adopt on need | Consumer must have the language-server binary; declare the prerequisite per the failure-behavior rules. | 2026-07-17 | +| [Output styles](https://code.claude.com/docs/en/plugins-reference) | Adopt on need | — | 2026-07-17 | +| [`bin/`](https://code.claude.com/docs/en/plugins) | Adopt on need | Executables join the Bash tool's `PATH` while the plugin is enabled; names must be collision-safe (plugin-prefixed) — the platform does not namespace them. | 2026-07-17 | +| [Plugin `settings.json`](https://code.claude.com/docs/en/plugins) | `agent` prohibited by default | Supports only `agent` and `subagentStatusLine`. `agent` takes over the main thread — a consumer-hostile default for a marketplace plugin; any exception requires documented justification in the plugin README. | 2026-07-17 | +| [Monitors](https://code.claude.com/docs/en/plugins-reference) | Wait | Experimental (`experimental.monitors`); interactive-CLI-only, unsandboxed at hook trust level, no `${user_config.*}` and no `CLAUDE_PLUGIN_OPTION_*` in monitor processes; keep running after mid-session disable. Re-verify before each audit. | 2026-07-17 | +| [Themes](https://code.claude.com/docs/en/plugins-reference) | Wait | Experimental (`experimental.themes`); schema may change between releases. Re-verify before each audit. | 2026-07-17 | +| [Channels](https://code.claude.com/docs/en/plugins-reference) | Wait | No longer carries an official experimental label, but fails the adoption gate today: no fleet gap it fills. Re-verify before each audit. | 2026-07-17 | +| [Dependencies](https://code.claude.com/docs/en/plugin-dependencies) | Adopt on need (hard requires only) | See the design boundary: hard requires only, semver-constrained, released via `{name}--v{version}` tags. None exist in this fleet today. | 2026-07-17 | + ## Configuration ownership and scope Choose one authoritative owner for each value: @@ -43,6 +85,25 @@ from user settings, `--settings`, and managed settings. It ignores project and l key. Claude Code owns the configuration prompt and storage; plugin skills must not hand-edit `pluginConfigs` or invent a marketplace-qualified plugin ID. +Use `userConfig` to its full native extent. Every personal or administrator scalar that flows +through a custom channel — an environment-variable toggle, a gitignored personal file, a documented +hand-edit — migrates to `userConfig` with the schema used honestly: + +- correct `type` (`string`, `number`, `boolean`, `directory`, `file`); +- a `default` that preserves zero-config behavior; +- `required: true` only where the plugin is genuinely unusable without the value; +- `sensitive: true` for secrets — noting that on platforms without a supported keychain the value + lands in `~/.claude/.credentials.json`, so verify storage on the target platform before migrating + a secret; and +- `claude plugin install --config` documented in the plugin's setup skill for headless use. + +Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; the custom environment variable +is retired when the migration lands. + +`version` lives in `plugin.json` only, never in a marketplace entry. The platform resolves +plugin.json first, but a marketplace-entry copy is dead metadata that silently becomes live if the +manifest field is ever removed — one home, no shadow. + For project configuration, use neutral repository-relative paths anchored at `${CLAUDE_PROJECT_DIR}`. Validate configured paths at the boundary, reject absolute paths and traversal when the contract requires containment, and document precedence. Do not add an environment variable @@ -50,8 +111,14 @@ merely to create a second configuration channel. ## Setup is explicit and repeatable -A configurable plugin provides an explicit `setup` or `configure` skill with -`disable-model-invocation: true`. Setup must be: +A plugin requires a `setup` skill iff it has (a) a consumer-project configuration surface, (b) an +external prerequisite — CLI, service, credential — or (c) non-trivial `userConfig`. Apply the +criteria through the modular, configurable, repo-, machine-, and user-agnostic lens; zero-config +zero-prerequisite plugins are exempt — setup is never blanket ceremony. Formatter and linter +plugins carry a thin check-centric setup. + +The uniform contract: the skill is named `setup`, sets `disable-model-invocation: true`, and offers +`check` (read-only inspect and verify) and `apply` (idempotent configure) actions. Setup must be: - idempotent and safe to rerun; - transparent about what it inferred, changed, skipped, or could not verify; @@ -64,6 +131,11 @@ must not write into the installed plugin cache, mutate Claude Code user settings `pluginConfigs`. Personal scalar configuration is collected through Claude Code's native plugin configuration surface. +Two native idioms are the sanctioned initialization surfaces: the `Setup` hook event +(`--init-only`, or `--init`/`--maintenance` in `-p` mode) for headless and CI preparation, and a +`SessionStart` hook comparing a bundled manifest against its `${CLAUDE_PLUGIN_DATA}` copy for +runtime-dependency installation. + ## Prerequisites and failure behavior Declare every required runtime, shell, CLI, service, credential, and platform constraint at the point @@ -76,10 +148,34 @@ Classify absence deliberately: documented reduced result. - **Not applicable:** exit quietly and successfully. +Anything with a runtime prerequisite (for example `jq` on `PATH`) degrades gracefully — never a hard +crash. Absence is surfaced to both the agent and the user; a candidate channel for durable +visibility is the hook-telemetry convention's OTel surface. No black boxes: a silently skipped +feature is a defect. + Hooks follow the event's official control contract. Use a blocking result only when the event can still be blocked and the hook is enforcing a policy. Advisory hooks surface a visible non-blocking diagnostic. Do not swallow errors or claim success when the promised result was not produced. +## Convention registry + +One owner doc per shared concern. This registry names and points — it never restates; each owner doc +carries the rules, versioning, and adoption story. A new cross-plugin convention lands in an owner +doc before a second plugin adopts it. Fleet audits check conformance per row. + +| Shared concern | Owner | +|---|---| +| Topic-docs two-tier binding | [`docs/conventions/topic-docs/`](conventions/topic-docs/README.md) | +| Lifecycle artifact protocol | [`docs/PLUGIN-ARTIFACT-PROTOCOL.md`](PLUGIN-ARTIFACT-PROTOCOL.md) | +| Shared hook utility library | `lib/hook-utils.sh`, synced by `scripts/sync-hook-utils.sh` | +| Cross-plugin shared-source clusters | `scripts/cross-plugin-source-registry.txt` | +| Ecosystem command resolution | [`docs/conventions/ecosystem-commands/`](conventions/ecosystem-commands/README.md) | +| Hook telemetry | [`docs/conventions/hook-telemetry/`](conventions/hook-telemetry/README.md) | +| Permission-rule hygiene | [`docs/conventions/permission-rule-hygiene/`](conventions/permission-rule-hygiene/README.md) | +| Skill layout contract and evals schema | `skill-quality` plugin (contract gate + bundled schema) | +| Review severity vocabulary | `review` plugin (`context/severity.md`) | +| Seam phrasing (presence-gated fallbacks) | Unowned — used by convention, no owner doc yet; next adopter creates one first | + ## Cross-platform contract Windows, macOS, and Linux are supported unless a plugin explicitly declares a narrower, inherent @@ -114,16 +210,20 @@ per concern, cross-platform operation, and stress-testing before presentation. ## Authoritative references -Verified 2026-07-14: - -- [Create plugins](https://code.claude.com/docs/en/plugins) — reusable plugins versus project-specific - standalone configuration, namespaces, structure, testing, and migration. -- [Plugins reference](https://code.claude.com/docs/en/plugins-reference) — `userConfig`, plugin paths, - cache isolation, and persistent plugin data. +The complete categorized index of plugin-relevant official pages is +[`docs/OFFICIAL-DOCS.md`](OFFICIAL-DOCS.md); `https://code.claude.com/docs/llms.txt` is the +authoritative self-updating master list. Pages load-bearing for this document, verified 2026-07-17: + +- [Create plugins](https://code.claude.com/docs/en/plugins) — plugin structure incl. `bin/` and + plugin `settings.json`, namespaces, testing, and migration. +- [Plugins reference](https://code.claude.com/docs/en/plugins-reference) — component schemas, + `userConfig`, experimental components, version management, cache isolation, persistent data. +- [Skills](https://code.claude.com/docs/en/skills) — frontmatter reference and skill lifecycle. +- [Hooks reference](https://code.claude.com/docs/en/hooks) — exec form vs shell form, event list, + `Setup` event, skill-scoped hooks. +- [Plugin dependencies](https://code.claude.com/docs/en/plugin-dependencies) — constraints, release + tags, bundles. - [Claude Code settings](https://code.claude.com/docs/en/settings) — settings scopes, precedence, and the special storage and read scopes of `pluginConfigs`. -- [Hooks reference](https://code.claude.com/docs/en/hooks) — exit-code visibility and blocking behavior. -- [Claude Code memory](https://code.claude.com/docs/en/memory) — project, user, and local instruction - scopes. - `melodic-software/standards` engineering philosophy and cross-platform review criteria — repository design and verification policy. diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md index 0dfb25cee..4d7a32fdb 100644 --- a/docs/topics/plugin-philosophy/PLAN.md +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -107,7 +107,7 @@ worktree-semantics smoke tests → Phase 4 (gates Phase 5 R1/R2); per-plugin `re Phase 6 (per-plugin, during the metadata wave); Windows `sensitive` userConfig storage → Phase 7 (before any userConfig-wave issue touching secrets is filed). -### Phase 1: PLUGIN-PHILOSOPHY.md doctrine revision [TODO] +### Phase 1: PLUGIN-PHILOSOPHY.md doctrine revision [DONE] Covers D3, D4, D6, D7, D8, D9, D10, D11. @@ -143,7 +143,7 @@ Work items: - `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.md` exit 0 (CI's pinned action is authoritative; local run uses the repo config). -### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [TODO] +### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [DONE] Depends on Phase 1 (doctrine wording is SSOT; playbook points, never restates). @@ -165,7 +165,7 @@ Work items: both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). - `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. -### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [TODO] +### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DOING] Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 stance table. @@ -191,7 +191,7 @@ Work items: repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory weekly — spot-check a sample of new URLs via WebFetch instead). -### Phase 4: Worktree-semantics empirical verification (throwaway spike) [TODO] +### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DOING] Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe with Phases 1–3 (touches scratchpad + throwaway worktrees only). From a89abf608e6ade55f60d084cfaf81057d6c08e94 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:10:58 -0400 Subject: [PATCH 04/10] docs: add official-docs index with component-to-page map (P3) docs/OFFICIAL-DOCS.md: categorized map of every plugin-relevant official page, 13-row component-to-doc table with per-row verified dates, staleness disclaimer, llms.txt named as the authoritative master list. CLAUDE.md gains one pointer row. Wave A join reconciled the component set at 13 (dependencies included; statusline folded into settings). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- CLAUDE.md | 1 + docs/OFFICIAL-DOCS.md | 107 ++++++++++++++++++++++++++ docs/topics/plugin-philosophy/PLAN.md | 2 +- 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 docs/OFFICIAL-DOCS.md diff --git a/CLAUDE.md b/CLAUDE.md index 33db5350a..e69a1658d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,6 +27,7 @@ from a fetched page this session, treat it as unverified and say so. | MCP | https://code.claude.com/docs/en/mcp | | Tools reference (monitors) | https://code.claude.com/docs/en/tools-reference | | Docs index (discover any other page) | https://code.claude.com/docs/llms.txt | +| Official-doc index (all plugin-relevant pages) | docs/OFFICIAL-DOCS.md | Machine-readable JSON Schemas (editor validation for the JSON in this repo; Claude Code ignores the `$schema` field at load time): `marketplace.json` → diff --git a/docs/OFFICIAL-DOCS.md b/docs/OFFICIAL-DOCS.md new file mode 100644 index 000000000..3d9d579c2 --- /dev/null +++ b/docs/OFFICIAL-DOCS.md @@ -0,0 +1,107 @@ +# Official docs index + +This is a link index into Claude Code's official documentation, scoped to pages relevant to +authoring, distributing, or consuming plugins in this marketplace. It exists so an agent or +contributor can jump straight to the current canonical page instead of guessing a URL or trusting +training-data recall. + +> [!WARNING] +> **This file goes stale. The platform changes constantly.** Always re-fetch the linked page before +> acting on it — never trust this file's descriptions, and never trust remembered content from a +> prior fetch. The authoritative, self-updating master list is +> [`https://code.claude.com/docs/llms.txt`](https://code.claude.com/docs/llms.txt); if a page listed +> here is missing from it, or a page you need isn't listed here, treat `llms.txt` as the source of +> truth and update this file. Every row below was verified against a live fetch on the date shown — +> that date is the ceiling on how current the row still is, not a guarantee. + +## Plugin components → doc page + +One row per plugin component type, per the current [Plugins reference](https://code.claude.com/docs/en/plugins-reference). +`Commands` is the legacy flat-markdown form of a skill — the [Skills](https://code.claude.com/docs/en/skills) +page is authoritative for both. Statusline is not its own plugin component: it is one of the two +settings keys (`subagentStatusLine`) a plugin's `settings.json` may set. Channels are declared via a +`channels` manifest field bound to an MCP server, not a separate file location. + +| Component | Official doc page | Verified date | +|---|---|---| +| Skills (`skills/`) | | 2026-07-17 | +| Commands — legacy flat-file skills (`commands/`) | | 2026-07-17 | +| Agents / subagents (`agents/`) | | 2026-07-17 | +| Hooks (`hooks/hooks.json`) | | 2026-07-17 | +| MCP servers (`.mcp.json`) | | 2026-07-17 | +| LSP servers (`.lsp.json`) | | 2026-07-17 | +| Output styles (`output-styles/`) | | 2026-07-17 | +| Themes (`themes/`) | | 2026-07-17 | +| Monitors (`monitors/monitors.json`) | | 2026-07-17 | +| Channels (`channels` manifest field) | | 2026-07-17 | +| Executables (`bin/`) | | 2026-07-17 | +| Settings (`settings.json` defaults) | | 2026-07-17 | +| Dependencies (`dependencies` manifest field) | | 2026-07-17 | + +## Authoring + +| Page | Official doc page | Verified date | +|---|---|---| +| Create plugins | | 2026-07-17 | +| Plugins reference (schemas, variables, CLI) | | 2026-07-17 | +| Skills | | 2026-07-17 | +| Slash commands | | 2026-07-17 | +| Hooks reference | | 2026-07-17 | +| Automate actions with hooks (guide) | | 2026-07-17 | +| Subagents | | 2026-07-17 | +| MCP | | 2026-07-17 | +| Connect to MCP servers (quickstart) | | 2026-07-17 | +| Output styles | | 2026-07-17 | +| Statusline | | 2026-07-17 | +| Push events into a session with channels | | 2026-07-17 | +| Channels reference | | 2026-07-17 | +| Sandboxing the Bash tool | | 2026-07-17 | +| Sandbox environments | | 2026-07-17 | +| Run parallel sessions with worktrees | | 2026-07-17 | +| Tools reference (includes the Monitor tool) | | 2026-07-17 | + +## Distribution / marketplace + +| Page | Official doc page | Verified date | +|---|---|---| +| Create & distribute a marketplace | | 2026-07-17 | +| Discover & install plugins | | 2026-07-17 | +| Plugin dependencies (version constraints) | | 2026-07-17 | +| Recommend plugins for your org (plugin relevance) | | 2026-07-17 | +| Recommend your plugin from your CLI (plugin hints) | | 2026-07-17 | +| Plugins in the Agent SDK | | 2026-07-17 | + +The Agent SDK's own skills/hooks/subagents/MCP pages (`agent-sdk/skills`, `agent-sdk/hooks`, +`agent-sdk/subagents`, `agent-sdk/mcp`) describe those concepts for custom SDK-built agent hosts, not +for authoring or distributing a Claude Code CLI plugin — deliberately out of scope here. Only +`agent-sdk/plugins` is in scope, because it covers how this repo's plugins behave when loaded by an +SDK-based host. + +## Configuration / settings + +| Page | Official doc page | Verified date | +|---|---|---| +| Settings | | 2026-07-17 | +| Server-managed settings | | 2026-07-17 | +| Control MCP server access for your organization | | 2026-07-17 | +| Memory — CLAUDE.md, `.claude/rules/`, auto memory | | 2026-07-17 | +| The `.claude` directory | | 2026-07-17 | +| Permissions | | 2026-07-17 | +| Permission modes | | 2026-07-17 | +| Environment variables | | 2026-07-17 | + +## Reference / schemas + +| Page | Official doc page | Verified date | +|---|---|---| +| Docs index (discover any other page) | | 2026-07-17 | +| CLI reference | | 2026-07-17 | +| Error reference | | 2026-07-17 | +| Glossary | | 2026-07-17 | + +Machine-readable JSON Schemas (editor validation only; Claude Code ignores the `$schema` field at +load time — already cited in this repo's `CLAUDE.md`): `marketplace.json` → +[`https://json.schemastore.org/claude-code-marketplace.json`](https://json.schemastore.org/claude-code-marketplace.json), +`plugin.json` → +[`https://json.schemastore.org/claude-code-plugin-manifest.json`](https://json.schemastore.org/claude-code-plugin-manifest.json) +(published on SchemaStore, sourced from the same plugin system these pages document). diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md index 4d7a32fdb..fa0d8aa96 100644 --- a/docs/topics/plugin-philosophy/PLAN.md +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -165,7 +165,7 @@ Work items: both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). - `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. -### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DOING] +### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DONE] Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 stance table. From 9c7b0a695a95bc09799dd997ca19724d58ad56cd Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:39:37 -0400 Subject: [PATCH 05/10] docs: record worktree smoke-test verdicts in PLAN (P4) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/topics/plugin-philosophy/PLAN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md index fa0d8aa96..047a72e06 100644 --- a/docs/topics/plugin-philosophy/PLAN.md +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -191,7 +191,7 @@ Work items: repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory weekly — spot-check a sample of new URLs via WebFetch instead). -### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DOING] +### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DONE] Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe with Phases 1–3 (touches scratchpad + throwaway worktrees only). @@ -421,7 +421,7 @@ Work items: | # | Question | Phase | VERDICT | |---|---|---|---| -| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | (pending) | +| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | HONORED (CC 2.1.212, control+treatment): committed project `.claude/settings.json` `worktree.baseRef: "head"` honored, incl. from linked worktrees (A2: resolves to the worktree's own HEAD; A3: a linked-worktree session reads its OWN checkout's settings.json). `.worktreeinclude`: nested-gitignored files qualify, copy is one-way creation-time. Sweep: `--worktree` worktrees never auto-swept (empirical); subagent/bg sweep would remove ignored-only worktrees (INFERRED — ignored ≠ untracked). `--bg` base = origin/HEAD by default, so R1 moves it to local HEAD. Windows caveat: deep worktree base paths can trip git PATH_MAX (`'$GIT_DIR' too big`); this repo's base (~95 chars) is safe. | | 2 | Per-plugin `relevance` signal quality | 6 | (pending — per-plugin ledger) | | 3 | Windows `sensitive` userConfig storage | 7 | (pending) | From 4a952dc183e14d711df4f75a6c243af68ea9b85d Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:51:47 -0400 Subject: [PATCH 06/10] docs: prune plugin-philosophy topic contract slice before merge (P1-P3) Final prune-with-pointer step for PR A (Phases 1-3): remove the branch-only topic contract slice `docs/topics/plugin-philosophy/` per the topic-docs convention, which requires the merged diff to carry no `docs/topics/**` path. The full PLAN.md has been graduated into the PR description under the Plan heading; the PR body and the follow-on PR chain (B/C/D) are the surviving context pointers. --- docs/topics/plugin-philosophy/PLAN.md | 551 -------------------------- 1 file changed, 551 deletions(-) delete mode 100644 docs/topics/plugin-philosophy/PLAN.md diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md deleted file mode 100644 index 047a72e06..000000000 --- a/docs/topics/plugin-philosophy/PLAN.md +++ /dev/null @@ -1,551 +0,0 @@ -# plugin-philosophy - -## Brief - -### TLDR - -Extend the plugin doctrine to the full current component surface (13 component types, official docs -fetched 2026-07-17), lock a native-first principle with a maturity gate, fix the topic-docs two-tier -convention's visibility seams with native mechanisms, ship a complete official-doc link index, adopt -marketplace metadata maximally — then run a fanout conformance audit of all 47 plugins whose findings -graduate to tracker-managed remediation waves. - -### Goal - -Every plugin measurably conforms to an extended, freshness-guarded doctrine; no custom mechanism -exists where a fitting native one does; every cross-plugin convention has exactly one registered -owner doc; the remediation program lives on the work-item tracker where any session or machine can -resume it. - -### Locked decisions - -| # | Decision | -|---|---| -| D1 | Deliverable = doctrine revision + fleet-consistency audit, coupled in this one Brief. CI contract-gate automation deferred to follow-on (trigger: audit reveals automatable checks). | -| D2 | Doc-link index is a first-class deliverable: every plugin-relevant official doc page linked (components mapped to their doc pages); no undocumented component types. | -| D3 | Native-first principle: prefer built-in native mechanisms (userConfig, native component types, native lifecycle events) over custom extensibility points; custom only on genuine misfit, with the misfit documented. | -| D4 | Native-adoption gate (qualifies D3): adopt a native mechanism when it (1) fills a real existing gap, (2) is stable and works cleanly — experimental/immature features wait for maturity, (3) meets repo standards. Never custom-build what a fitting native mechanism covers. | -| D5 | Cross-plugin cooperation: hybrid. Native `dependencies` reserved for hard requires (plugin genuinely broken without collaborator) — none exist today; the `{name}--v{version}` git-tag release step lands with first use. Optional collaboration stays presence-gated with documented fallbacks; artifact protocol unchanged (data handoff, which dependencies don't cover). | -| D6 | Component stance table: skills = primary surface (new frontmatter — `paths`, `context: fork`, `arguments`, skill-scoped `hooks`/`once` — adopted case-by-case); `commands/` prohibited (officially legacy); agents, MCP, LSP, output styles, `bin/` = adopt-on-need (`bin/` requires collision-safe prefixed names; doctrine notes plugin agents ignore `hooks`/`mcpServers`/`permissionMode`); plugin `settings.json` `agent` (main-thread takeover) prohibited by default, exception needs documented justification; monitors, themes, channels = wait (experimental/immature), re-verified against current docs before each audit; dependencies per D5. Hooks addition: exec-form (`args`) mandatory wherever `${user_config.*}` appears (v2.1.207), else the `CLAUDE_PLUGIN_OPTION_` env mirror. | -| D7 | Freshness rider on all doctrine artifacts: every stance/inventory row carries a verified-date + link to its official doc page and an explicit disclaimer that the platform changes constantly — always re-fetch current docs before acting; never trust the repo file alone. | -| D8 | userConfig full-potential criterion: every personal/administrator scalar flowing through a custom channel (env-var toggle, gitignored personal file, documented hand-edit) migrates to userConfig using the full native schema — correct `type`, `default` preserving zero-config behavior, `required` only where truly blocking, `sensitive: true` for secrets, `claude plugin install --config` documented in each setup skill for headless use. Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK__ENABLED` toggles = flagship migration (userConfig booleans, `default: true`). | -| D9 | Setup doctrine v2: setup skill required iff (a) consumer-project config surface, (b) external prerequisites (CLI, service, credential), or (c) non-trivial userConfig — criteria applied through the modular/configurable/repo-/machine-/user-agnostic lens, never blanket ceremony; zero-config zero-prereq plugins exempt. Uniform contract: skill named `setup`, `disable-model-invocation: true`, `check` (read-only inspect/verify) + `apply` (idempotent configure) actions, complete-args non-interactive path. Formatter/linter plugins gain thin check-centric setups. Native `Setup` hook event = sanctioned headless/CI init surface; SessionStart + `${CLAUDE_PLUGIN_DATA}` manifest-diff = sanctioned runtime-dependency idiom. | -| D10 | Runtime-prerequisite visibility: anything with a runtime prereq (e.g. jq on PATH) degrades gracefully — never a hard crash; absence is surfaced to BOTH the agent and the user, with OTel as a candidate visibility channel; no black boxes. Extends the philosophy doc's "Prerequisites and failure behavior" section. | -| D11 | Convention registry: pointer-only section in PLUGIN-PHILOSOPHY.md — one owner doc per shared concern (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, artifact protocol, seam phrasing); registry names and points, never restates; audit rule = per-row conformance; a new convention lands in an owner doc before a second plugin adopts it. | -| D12 | Topic-docs tiers: keep the nature-based two-tier split and the `docs/topics/` name (contents are transient topic-scoped contract docs; `docs/specs/` is already the durable vault target — renaming would conflate tiers). | -| D13 | Two-tier seam fix package (all native): R1 `worktree.baseRef: "head"` in committed repo settings so worktree-isolated spawns carry task-branch state; R2 `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH — not baselines/raw scratch; one-way creation-time copy documented); R3 pointer discipline — durable surfaces (tickets, committed PLAN) never point at prunable or gitignored paths (decompose cites the PR, not the contract path; PLAN records distilled baseline values only); R4 isolated workers return results by value, the orchestrator writes both tiers in the parent checkout; R5 the work-item tracker is the cross-lane awareness/index layer (branch files stay lane-local; markdown-in-tickets as primary artifact store rejected — not diffable, drifts from code); R6 topic-docs convention doc corrected (worktree-visibility rationale, context×tier visibility matrix, mechanisms named) — a major contract version adopted by all implementers in one wave. | -| D14 | Doc-link index: dedicated `docs/OFFICIAL-DOCS.md` — complete categorized map of plugin-relevant official pages with a component→doc-page table, per-row verified-dates, the D7 staleness disclaimer, and `https://code.claude.com/docs/llms.txt` named as the authoritative self-updating master list. CLAUDE.md keeps its lean canonical table plus one pointer row to the index. | -| D15 | Marketplace metadata maximalism (machine-, user-, org-agnostic posture): populate every helpful-signal field — `relevance` signals wherever meaningful (audit criterion per plugin), `defaultEnabled: false` for personal/niche-category plugins, `displayName` where it genuinely clarifies, complete descriptive metadata. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + source declaration in managed settings). Hard rule: `version` lives in plugin.json only, never in marketplace entries (silent-precedence trap). | -| D16 | Audit execution: doctrine docs land first; then per-plugin subagent fanout scores all 47 plugins against a doctrine-derived checklist (~15 dimensions: setup criteria, userConfig migration, exec-form hooks, metadata completeness, component stances, registry conformance, prereq degradation, pointer discipline); findings distill into a plugin×dimension conformance matrix graduating to GitHub issues — one epic + per-wave issues (setup, userConfig, metadata, hooks, convention-seam waves) via the work-items seam; raw per-plugin detail stays memory-tier; automatable checks become the deferred CI gate's backlog. | - -### Constraints - -- Fresh-docs mandate applies at execution time: re-fetch the relevant official pages before each edit - wave; this Brief's doc facts were verified 2026-07-17. -- Work isolated in worktree, branch `docs/plugin-philosophy`; PRs required, squash merge, PR title - per Conventional Commits. -- Topic-docs convention change (D13/R6) is a major contract version; every implementer plugin adopts - in the same release wave (the contract carries no compatibility machinery). -- userConfig migrations preserve existing behavior via `default` values (guardrails toggles default - `true`). -- Every plugin change clears the migration playbook's gate + plugin-acceptance security review. - -### Acceptance criteria - -- PLUGIN-PHILOSOPHY.md revised: component stance table (D6) with D7 freshness riders, native-first + - adoption gate (D3/D4), convention registry (D11), config ownership updated (D8 criterion, exec-form - rule, version-placement rule), setup criteria (D9), prerequisite-visibility rule (D10). -- MIGRATION-PLAYBOOK.md updated consistently (setup contract, userConfig criterion, security review - touchpoints). -- `docs/OFFICIAL-DOCS.md` exists: complete categorized page map, component→doc table, verified-dates, - staleness disclaimer, llms.txt master pointer; CLAUDE.md carries the pointer row and stays lean. -- Topic-docs convention doc corrected per R6 with visibility matrix; R1 settings entry, R2 - `.worktreeinclude`, and R3 skill pointer fixes (decompose ticket provenance, architect baseline - recording) landed; the three flagged execution-time verifications resolved empirically and - recorded. -- marketplace.json metadata complete per D15; `claude plugin validate .` passes. -- Audit epic + wave issues filed on GitHub with the conformance matrix distilled into the epic; every - 47-plugin row scored; raw details in the memory slice. -- Existing CI (plugin contract tests, markdownlint) green on every PR. - -### Captured assumptions - -- Consumers run CC ≥ 2.1.207 (userConfig shell-form ban semantics, pluginConfigs scoping); older - clients degrade per official behavior, not worked around. -- Marketplace remains the melodic-software catalog but every decision holds machine-, user-, and - org-agnostic (no solo-consumer scoping). - -### Out-of-scope (deferred with triggers) - -- CI contract gate — trigger: audit identifies automatable checks (D16 backlog). -- Bundle plugin (name + dependencies curated set) — trigger: one-command curated install need beyond - the fleet-sync skill. -- Monitors, themes, channels adoption — trigger: feature exits experimental/immature status at a - future doc re-verification (D6 wait rows). -- `music` → `creative`, deployment category, and other plugin-organization deferrals remain owned by - that Brief. - -### Deferred questions - -- Windows `sensitive` userConfig storage behavior (docs silent on Windows keychain) — empirical - verification during audit, before any secret migrates. Arbiter: `/architect` (execution evidence). -- Worktree-sweep treatment of ignored files; `--bg` session worktree base semantics; - `worktree.baseRef` honored at project-settings scope — empirical smoke tests during D13 execution. - Arbiter: `/architect`. -- Per-plugin `relevance` signal quality (which signals are genuinely helpful vs noise) — decided - per-plugin during the metadata wave. Arbiter: `/architect`. - -## Plan - -Seven phases. Doctrine docs land first (D16 ordering), the topic-docs contract major version ships as -one wave, marketplace metadata follows, and the fleet audit runs last against the landed doctrine. -The fresh-docs mandate is embedded as the **first work item of every phase** that states platform -facts — never a standalone phase, never skipped. - -The three flagged empirical verifications resolve at their Brief-assigned execution points: -worktree-semantics smoke tests → Phase 4 (gates Phase 5 R1/R2); per-plugin `relevance` quality → -Phase 6 (per-plugin, during the metadata wave); Windows `sensitive` userConfig storage → Phase 7 -(before any userConfig-wave issue touching secrets is filed). - -### Phase 1: PLUGIN-PHILOSOPHY.md doctrine revision [DONE] - -Covers D3, D4, D6, D7, D8, D9, D10, D11. - -Work items: - -1. Fresh-fetch: `plugins`, `plugins-reference`, `skills`, `hooks`, `settings`, `plugin-dependencies` - pages; re-verify the 13 component types and the D6 stance facts (skill frontmatter additions, - `commands/` legacy status, `bin/` rules, agent field limitations, monitors/themes/channels - maturity, v2.1.207 exec-form rule). Any drift from the Brief's 2026-07-17 facts is recorded in - the memory slice and the stance table reflects current reality. The verified component-type - count (N, expected 13) is written to `.work/plugin-philosophy/component-count.txt` — Phases 1 - and 3 sanity checks assert against N, not a hard-coded 13. -2. Add **Native-first principle + adoption gate** section (D3/D4). -3. Add **Component stance table** (D6): 13 rows, each with stance, rationale, verified-date + - official-doc link (D7 rider), and the D7 staleness disclaimer heading the table. -4. Extend **Configuration ownership and scope**: D8 userConfig full-potential criterion (native - schema fields, `CLAUDE_PLUGIN_OPTION_` mirror, retirement of custom env channels), exec-form - hooks rule, version-placement rule (`version` in plugin.json only). -5. Rewrite **Setup is explicit and repeatable** to the D9 v2 criteria (required-iff conditions, - uniform `setup` skill contract, `Setup` hook event and SessionStart manifest-diff idioms). -6. Extend **Prerequisites and failure behavior** with D10 (graceful degradation, dual agent+user - visibility, OTel as candidate channel, no black boxes). -7. Add **Convention registry** section (D11): pointer-only table — one owner doc per shared concern - (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, - artifact protocol, seam phrasing); registry names and points, never restates. - -**Sanity Check:** - -- `grep -c "Verified 2026" docs/PLUGIN-PHILOSOPHY.md` ≥ N (one rider per stance row; N from - `component-count.txt`). -- `grep -n "Convention registry\|Native-first" docs/PLUGIN-PHILOSOPHY.md` returns both sections. -- Component stance table row count = N; Read confirms every verified component type named. -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.md` exit 0 (CI's - pinned action is authoritative; local run uses the repo config). - -### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [DONE] - -Depends on Phase 1 (doctrine wording is SSOT; playbook points, never restates). - -Work items: - -1. Update the per-plugin migration gate: setup-contract check (D9), userConfig criterion (D8), - exec-form hook rule — each as a pointer to the philosophy doc section plus playbook-specific - procedure only. -2. Extend the plugin-acceptance security review touchpoints: `sensitive` userConfig handling, - `bin/` collision-safe naming, plugin `settings.json` `agent` prohibition check. -3. Remove or redirect any playbook text that now duplicates Phase 1 doctrine (no restated stance - tables). - -**Sanity Check:** - -- `grep -n "PLUGIN-PHILOSOPHY" docs/MIGRATION-PLAYBOOK.md` shows pointer citations in the gate and - security-review sections. -- No restated stance table: no markdown table in MIGRATION-PLAYBOOK.md whose header row contains - both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. - -### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DONE] - -Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 -stance table. - -Work items: - -1. Fresh-fetch `https://code.claude.com/docs/llms.txt`; enumerate every plugin-relevant page. -2. Create `docs/OFFICIAL-DOCS.md`: categorized page map, component→doc-page table, per-row - verified-dates, D7 staleness disclaimer, llms.txt named as the authoritative self-updating - master list. -3. Add one pointer row to CLAUDE.md's canonical table; CLAUDE.md stays lean (no other growth). -4. **Wave A join step (main session):** reconcile the component→doc table against Phase 1's - verified component list (`component-count.txt` + stance table) before PR A — parallel work off - the Brief snapshot must converge on Phase 1's fresh-fetched reality. - -**Sanity Check:** - -- `test -f docs/OFFICIAL-DOCS.md` && component table has N rows (N from `component-count.txt`). -- `grep -n "llms.txt" docs/OFFICIAL-DOCS.md` and `grep -n "OFFICIAL-DOCS" CLAUDE.md` both hit. -- CLAUDE.md diff = exactly one added table row: `git diff origin/main...HEAD --stat -- CLAUDE.md` - shows a 1-2 line delta. -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/OFFICIAL-DOCS.md` exit 0; the - repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory - weekly — spot-check a sample of new URLs via WebFetch instead). - -### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DONE] - -Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe -with Phases 1–3 (touches scratchpad + throwaway worktrees only). - -All tests run in a **throwaway `git init` repo in the scratchpad with a synthetic `origin`** — -never in this repo (its ~30 live worktrees, runtime-written `.git/info/exclude`, and main checkout -on a feature branch confound every measurement). Use `claude -p --worktree` exclusively (skips the -trust dialog; interactive mode errors in a fresh repo). Unique worktree names per run (name reuse -resets clean worktrees to base since v2.1.208); the spike removes its own worktrees -(`-p`-created worktrees are never auto-cleaned; Windows: expect NTFS lock retries, -`git worktree remove --force`). - -Work items: - -1. Fresh-fetch the `worktrees` doc (the doc anchor for `baseRef`/`.worktreeinclude` — not the - settings page) plus `settings`; record cited behavior, including the documented fallback - "when `origin/HEAD` isn't resolvable, worktrees fall back to current local HEAD". -2. Smoke test A — `worktree.baseRef: "head"` at **project-settings scope**, two arms: **control** - (`baseRef` unset or `"fresh"`) asserts marker ABSENT; **treatment** (`baseRef: "head"` in - committed `.claude/settings.json`) asserts marker PRESENT. Verdict HONORED only if BOTH arms - behave — a marker-present-only test is defeated by the documented origin/HEAD fallback (false - positive). Variant A2: spawn from within an existing linked worktree (docs state `head` resolves - to that worktree's HEAD — test against that expected value). Variant A3: `settings.json` present - only in the worktree checkout vs only in the main checkout — pins which copy a linked-worktree - session reads (undocumented; only `settings.local.json` is documented as main-checkout-resolved). -3. Smoke test B — `.worktreeinclude` one-way creation-time copy: use real nested-gitignore paths - (`.work//…` ignored via a nested `*` `.gitignore`, mirroring this repo) — not a toy - root-level pattern; assert copy at creation; modify original, assert no sync-back. -4. Smoke test C — worktree-sweep treatment of ignored files (genuinely undocumented — this test is - the only source of truth; capture `git status --ignored` snapshots in the raw transcript) + - `--bg` session worktree base semantics. -5. The sub-agent records raw transcripts in `.work/plugin-philosophy/verifications/`, stamps every - VERDICT file with `claude --version`, and **returns the VERDICT lines by value**; the **main - session** fills the pending rows in this PLAN's "Empirical verification results" table (PLAN.md - edits stay main-session-only) and feeds them into Phase 5's R1/R2 design. If the CC version has - moved by the Phase 5 gate, re-run the cheap test-A control/treatment pair. - -**Sanity Check:** - -- `.work/plugin-philosophy/verifications/` contains ≥ 3 result files, one per smoke test, each - ending in a one-line VERDICT (`HONORED` / `NOT-HONORED` / behavior description) and a - `claude --version` stamp line. -- Test A result file contains BOTH `control:` and `treatment:` lines with opposite marker outcomes - (else verdict is invalid by construction). -- This PLAN's "Empirical verification results" table row 1 is filled (no `(pending)`). - -### Phase 5: Topic-docs contract 2.0.0 + seam fixes R1–R6 (one wave) [TODO] - -Covers D13. Contract-major change: every implementer adopts in the same wave (no compatibility -machinery). Gated by Phase 4 verdicts. - -Work items: - -1. **Pre-flight consumer check (first item):** `Grep`/`Glob` for every consumer parsing the - convention surface — `.claude/topic-docs.yaml` keys, slug spec, tier paths, runtime guards, the - `scripts/check-cross-plugin-source-drift.sh` registry, hooks reading `docs/topics/` or `.work/`. - Document parse paths in the memory slice before editing anything. -2. R6 — rewrite `docs/conventions/topic-docs/README.md`: worktree-visibility rationale, context × - tier visibility matrix, native mechanisms named (`worktree.baseRef`, `.worktreeinclude`, by-value - returns, tracker index); CHANGELOG entry `2.0.0`; schema untouched unless a key changes (KEEP - expected). **Reconcile the Implementers table with reality**: `toolchain` and `verification` - carry `reference/topic-docs.md` but are absent from the table; `knowledge`, `claude-ops`, - `docs-hygiene` are listed without delta docs — the 2.0.0 table must match the actual fleet - (add/annotate rows or document why a row is delta-doc-free). The CHANGELOG 2.0.0 entry states - the **mixed-fleet window** and why it is safe (no tier/key/slug-spec change — installed cache - copies and in-flight branches keep 1.x text until they update; divergence is doctrinal, not - layout-corrupting), and notes a post-PR-B stale-text sweep obligation for in-flight branches at - their merge time. -3. R1 — committed `.claude/settings.json` with `worktree.baseRef: "head"` (shape per Phase 4 smoke - test A verdict; if NOT-HONORED at project scope, execute the tagged fallback below). Rollout - note in the PR B description + convention doc: a clone with an existing untracked - `.claude/settings.json` hits "untracked working tree file would be overwritten" on pull — - document the remedy; state the repo-wide worktree-spawn behavior change; **gitignore - `.claude/worktrees/` in the same change** (mandatory — the runtime `.git/info/exclude` entry is - machine-local; CI checkouts and fresh clones lack it, and partial tracking of `.claude/` - otherwise turns nested worktrees into `git add -A` hazards); run the hygiene CI lanes - (machine-specific-paths, gitleaks, editorconfig) locally on the new tracked file. Document the - escape hatch: a personal `.claude/settings.local.json` (main-checkout-resolved, covers every - worktree) silently overrides R1 machine-wide — the convention doc states this; no audit - dimension may assume R1 is universally in force. - **Consumer-adoption path (mandatory):** repo settings never travel with marketplace-installed - plugins (isolated cache) — R1/R2 as files fix only this repo. The 2.0.0 doc ships a - consumer-adoption section: the settings snippet + a `.worktreeinclude` template, scoped as - "authoring-repo materialization; consumer repos self-apply" (routing it through a D9 setup-skill - `apply` action is recorded as a follow-on trigger, not built now). The visibility matrix gains a - caveat row: a `WorktreeCreate` hook makes `.worktreeinclude` inert (documented) — hook script - owns the copy. -4. R2 — `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH; not - baselines/raw scratch); one-way creation-time copy documented in the convention doc. -5. R3 — pointer-discipline fixes: `plugins/work-items/skills/decompose` cites the PR (not contract - paths) in ticket provenance; `plugins/planning/skills/architect` records distilled baseline - values in PLAN (raw captures stay memory-tier). Sweep both skill bodies for prunable-path - citations. -6. R4/R5 — convention doc text: isolated workers return results by value with the orchestrator - writing both tiers in the parent checkout (R4); the work-item tracker named as the cross-lane - awareness/index layer, markdown-in-tickets rejected with rationale (R5). -7. Implementer wave: update all 8 `plugins/*/reference/topic-docs.md` delta docs against the 2.0.0 - owner doc; bump each touched plugin's `plugin.json` semver + CHANGELOG; docs-hygiene declutter - detector references checked (reader row). - -File inventory (checkbox discipline — tick as processed): - -| File | Action | Rationale | -|---|---|---| -| [ ] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | -| [ ] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | -| [ ] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes expected | -| [ ] `docs/conventions/topic-docs/examples/*` | AUDIT | update only if matrix/mechanisms change examples | -| [ ] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | -| [ ] `.worktreeinclude` | CREATE | R2 patterns | -| [ ] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | -| [ ] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | -| [ ] 8–10 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | semver bump per touched plugin | -| [ ] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | implementer-table rows without delta docs — verify no stale convention text | - -**Sanity Check:** - -- `bash scripts/check-cross-plugin-source-drift.sh --check` exit 0 (the flag CI runs; flagless mode - is informational only). -- `grep -n "2.0.0" docs/conventions/topic-docs/CHANGELOG.md` hits; `grep -rn "visibility matrix" -i - docs/conventions/topic-docs/README.md` hits. -- Implementers-table parity: every `plugins/*/reference/topic-docs.md` path has a matching table - row and vice versa (Read assertion against the glob result). -- Pre-flight consumer list exists: `.work/plugin-philosophy/consumers-topic-docs.md` non-empty. -- Every plugin with a modified file has a `plugin.json` version bump: - `git diff origin/main...HEAD --name-only | grep '^plugins/' | cut -d/ -f2 | sort -u` each has a - matching `plugins//plugin.json` in the diff. -- `bash scripts/validate-plugins.sh` exit 0 (includes `generate-catalog.mjs --check` — regenerate - the catalog if any plugin.json description changed). -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc` on touched .md files exit 0. - -### Phase 6: Marketplace metadata wave [TODO] - -Covers D15 + per-plugin `relevance` quality verification (deferred question c). - -Work items: - -1. Fresh-fetch `plugin-marketplaces` + `discover-plugins` + `plugins-reference` - (default-enablement section) + the dedicated `plugin-relevance` page; re-verify entry schema - (`relevance`, `defaultEnabled`, `displayName`, description precedence, `version` - silent-precedence trap). **`defaultEnabled` flip semantics for already-installed consumers are - undocumented** — if the fetched pages stay silent, run a 2-minute empirical flip on one plugin - before the wave (does a marketplace refresh disable an existing install?). Never touch a - plugin's `name` (breaks existing installs without a `renames` map); `displayName` is safe. -2. Per-plugin pass over all 47 entries: add `relevance` only where the signal is genuinely helpful - (judged per-plugin — noise rejected), `defaultEnabled: false` for personal/niche categories, - `displayName` where it clarifies, complete descriptions; assert **no `version` field in any - entry**. -3. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + - managed-settings source declaration) — lands in the discover/consumer section of README or - OFFICIAL-DOCS per where consumer docs live (decided at execution against the fetched page). -4. Record per-plugin relevance decisions (adopted vs rejected-as-noise) in - `.work/plugin-philosophy/relevance-decisions.md`. -5. Regenerate the README catalog: `node scripts/generate-catalog.mjs` (CI runs `--check`; metadata - edits drift the generated block otherwise). - -**Sanity Check:** - -- `claude plugin validate .` exit 0. -- `node scripts/generate-catalog.mjs --check` exit 0. -- `node -e` assertion: 47 entries; every entry resolves a description (entry or plugin.json); - `version` absent from all entries — exit 0. -- `.work/plugin-philosophy/relevance-decisions.md` has 47 rows. - -### Phase 7: Fleet conformance audit fanout + tracker graduation [TODO] - -Covers D16. Runs against merged doctrine (Phases 1–6 landed). - -Work items: - -1. **Search-before-create (first item):** `gh issue list --search` for an existing - plugin-conformance epic / wave issues. Match found → pivot to updating the existing items - (record the match + pivot in the memory slice); no match → proceed to create. Verify required - labels exist (`gh label list`) and create missing ones before any `gh issue create --label` - call (missing labels fail the create). -2. Derive the audit checklist (~15 dimensions) from the landed doctrine docs: setup criteria (D9), - userConfig migration (D8), exec-form hooks, metadata completeness (D15), component stances (D6), - registry conformance (D11), prereq degradation (D10), pointer discipline (R3), freshness riders - (D7), plus dimensions the doctrine text yields. **Freeze a rubric file** with per-dimension - anchored PASS/FAIL criteria + one worked example, injected verbatim into every worker prompt - (uncalibrated independent scoring across batches encodes rubric drift, not conformance). - **Authority rule:** plugins are scored against **landed doctrine only**; where a fresh-fetched - doc disagrees with doctrine, that is a doctrine-update finding (its own wave), never plugin - nonconformance. Dimensions may not assume R1 is universally in force (local-settings override - exists). Checklist + rubric → memory slice. -3. Fresh-fetch the component doc pages the checklist cites (to detect doctrine-vs-platform drift - per the authority rule above). -4. **Windows `sensitive` userConfig empirical verification** (deferred question a): configure a - throwaway `sensitive` userConfig value on this Windows machine; locate where it persists - (Credential Manager vs plaintext file); VERDICT recorded before any userConfig wave issue - involving secrets is filed. Secrets excluded from that wave if storage is plaintext (tagged - fallback below). -5. Fanout: **pilot batch of 3–5 plugins first**, reviewed by the main session against the rubric - before full fanout; then per-plugin subagents score the remainder in **batches of 8–10**; each - worker writes its own raw report to `.work/plugin-philosophy/audit/.md` (memory-tier - raw output is carved out of R4 — R4's orchestrator-writes rule governs contract/durable tiers) - and returns only its scored dimension row by value; the orchestrator (main session) appends - matrix rows incrementally per batch, so a compaction mid-run loses nothing. **Double-score a - random 3-plugin sample** with independent workers and reconcile disagreements before graduating - the matrix. -6. File the GitHub epic (conformance matrix distilled inline — **single-token score cells only**, - prose lives in per-wave issues; GitHub bodies cap near 64 KB) + per-wave issues (setup, - userConfig, metadata, hooks, convention-seam) via the work-items seam; issues cite the epic + PR - permalinks, never contract/memory paths (R3). Automatable checks list → epic section = deferred - CI gate backlog (D1 trigger). - -**Sanity Check:** - -- Search outcome recorded: `.work/plugin-philosophy/audit/tracker-search.md` states the query + hit - count + create-vs-update decision. -- `ls .work/plugin-philosophy/audit/*.md | wc -l` ≥ 47 (one report per plugin) + matrix file with - 47 scored rows. -- `gh issue list --label epic --search "plugin conformance"` (or equivalent) returns the epic; - epic body contains the matrix; ≥ 5 wave issues reference the epic. -- `grep -c "docs/topics/\|\.work/" ` = 0 (pointer discipline). -- Windows `sensitive` VERDICT file exists in `.work/plugin-philosophy/verifications/`. - -### Empirical verification results - -| # | Question | Phase | VERDICT | -|---|---|---|---| -| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | HONORED (CC 2.1.212, control+treatment): committed project `.claude/settings.json` `worktree.baseRef: "head"` honored, incl. from linked worktrees (A2: resolves to the worktree's own HEAD; A3: a linked-worktree session reads its OWN checkout's settings.json). `.worktreeinclude`: nested-gitignored files qualify, copy is one-way creation-time. Sweep: `--worktree` worktrees never auto-swept (empirical); subagent/bg sweep would remove ignored-only worktrees (INFERRED — ignored ≠ untracked). `--bg` base = origin/HEAD by default, so R1 moves it to local HEAD. Windows caveat: deep worktree base paths can trip git PATH_MAX (`'$GIT_DIR' too big`); this repo's base (~95 chars) is safe. | -| 2 | Per-plugin `relevance` signal quality | 6 | (pending — per-plugin ledger) | -| 3 | Windows `sensitive` userConfig storage | 7 | (pending) | - -## Blast radius - -**HIGH.** Matches stress-test triggers: new conventions constraining all future work (doctrine + -contract-major), architecture decisions across 47 plugins + 8 implementer materializations, shared -committed settings (`.claude/settings.json`) affecting every session, and undocumented behavior -(worktree semantics, Windows sensitive storage — mitigated by the empirical phases). Reversible via -git revert (docs/metadata only, no runtime code), and existing CI (contract tests, markdownlint, -drift check) gates every PR — hence HIGH, not CRITICAL. - -## Stress-test summary - -Two fresh-context adversarial passes ran; all findings verified against the repo before adoption. - -**Plan-reviewer (Step 3):** 9 IMPORTANT + 5 SUGGESTION, 0 CRITICAL — all applied: implementer-roster -reconciliation + parity check (Phase 5), CI-parity sanity commands (drift `--check`, catalog -`--check`, markdownlint config, `node -e` over Python), pointer-vs-restate check made structural -(Phase 2), Phase 4 by-value/fence contradiction resolved, component-count made variable with a -Wave A join step, PR-chain PLAN lifecycle defined, Phase 7 batching + label verify-or-create, -worktree-variant smoke tests, R1 rollout notes. - -**Devils-advocate (Step 4):** 16 assumptions attacked; 4 mandatory changes, all applied: -(1) Phase 4 redesigned — isolated scratch repo with synthetic origin, control+treatment arms -(defeats the documented origin/HEAD-fallback false positive), settings-scope variant A3, -CC-version-stamped verdicts with re-run at the Phase 5 gate; (2) PLAN lifecycle switched to -branch-local prune-per-PR (the program must not self-violate the contract it ships); (3) 2.0.0 doc -gains a consumer-adoption path — repo settings provably never reach marketplace-installed -consumers; (4) Phase 7 calibration — frozen anchored rubric, pilot batch, double-scored sample. -Also adopted: mandatory `.claude/worktrees/` gitignore in PR B, `WorktreeCreate`-hook caveat for -`.worktreeinclude`, mixed-fleet window statement in the CHANGELOG, doctrine-wins authority rule for -audit scoring, `defaultEnabled`-flip empirical check, matrix cell budget (64 KB body cap), `name` -immutability during the metadata wave. One finding escalated to a user gate: R6 major-vs-minor -contradiction with the contract's own versioning rule (see User-approval gates). - -## Execution shape - -Two parallel-safe waves inside an otherwise sequential PR chain; fanout inside Phase 7. - -| Phase | Surface | Basis | -|---|---|---| -| 1 | Main session | Judgment-heavy doctrine writing; SSOT wording others depend on | -| 2 | Main session | Depends on Phase 1 wording; pointer discipline needs judgment | -| 3 | Sub-agent worker (parallel with 1–2) | Mechanical index build from llms.txt; disjoint files (`OFFICIAL-DOCS.md`, one CLAUDE.md row) | -| 4 | Sub-agent worker (parallel with 1–3) | Scripted smoke tests; touches scratch/throwaway worktrees only | -| 5 | Main session (implementer sweep may fan out mechanically) | Contract-major judgment; 25-file wave needs single editorial voice | -| 6 | Main session | Single file; 47 per-plugin relevance judgments | -| 7 | Workflow/sub-agent fanout, orchestrated by main session | D16-locked fanout; R4 by-value returns | - -Wave A (parallel): Phase 1 (main) ∥ Phase 3 (sub-agent) ∥ Phase 4 (sub-agent). Zero file overlap: -P1 = `docs/PLUGIN-PHILOSOPHY.md`; P3 = `docs/OFFICIAL-DOCS.md` + CLAUDE.md; P4 = `.work/` + scratch. -Wave B (sequential): Phase 2 → Phase 5 → Phase 6 → Phase 7. - -Scope fences (Wave A): P3 agent ALLOWED `docs/OFFICIAL-DOCS.md`, `CLAUDE.md` (one row); -FORBIDDEN everything else incl. PLAN.md. P4 agent ALLOWED `.work/plugin-philosophy/verifications/` -and throwaway `git init` repos under the scratchpad (its own branches/worktrees live there); -FORBIDDEN every file and branch of THIS repo (note: `claude -p --worktree ` creates branches -named `worktree-` — another reason the spike never runs in this repo). -Sequential fallback: any fence violation or agent failure → that phase re-runs inline main-session -in Wave B order. PLAN.md edits are main-session-only. - -Cost note: Wave A = 2 extra agents vs sequential (~saves one serial doc-build + smoke-test round); -Phase 7 = ~47 scoring agents (D16-locked, run regardless of shape). - -## Open questions - -None blocking — the three empirical questions are scheduled inside phases with tagged fallbacks. - -## Handoff to implementation - -### User-approval gates - -- **[BRIEF CONTRADICTION — user decision required]** D13 locks R6 as a **major** contract version - ("2.0.0, one wave"), but the contract's own Versioning rule says major = "moves a tier, renames a - key, or alters the slug spec" — R6 does none (schema KEEP; the change is visibility semantics + - doctrine text). Options: (a) keep 2.0.0 and amend the Versioning rule so visibility-semantics - guarantees also count as major (the doctrine repo then applies its own rule consistently); - (b) downgrade to a 1.x minor, dissolving the one-wave coordination burden and most of Phase 5's - mixed-fleet risk. RECOMMENDED: (a) — the Brief locked the one-wave clean break deliberately, and - a visibility-guarantee change does alter what implementers may rely on; the rule amendment makes - the label honest. The plan as written assumes (a). -- [FALLBACK — confirm or override] Smoke test A fails (project-scope `worktree.baseRef` not - honored): R1 degrades to documenting the limitation + the strongest honored scope in the - convention doc, and an upstream issue is filed; R2/R6 proceed unchanged. -- [FALLBACK — confirm or override] Windows `sensitive` storage is plaintext: secret-bearing - userConfig migrations are excluded from the userConfig wave issue and recorded as blocked-upstream - in the epic; non-secret migrations proceed. -- Scope-expansion of any kind (new convention, new component adoption) mid-flight → stop and ask. - -### Execution shape ([EXEC-SHAPE] tagged) - -- [EXEC-SHAPE] PR slicing: PR A = Phases 1–3 (doctrine + index, current branch - `docs/plugin-philosophy`); PR B = Phases 4–5 (contract 2.0.0 wave; Phase 4 evidence rides the - memory tier, distilled results in PLAN); PR C = Phase 6 (metadata); PR D = close-out (Phase 7's - PLAN/verdict updates + prune-with-pointer). Rationale: reviewability + distinct concerns - (doctrine vs contract-major vs metadata); each PR independently green on existing CI. -- [EXEC-SHAPE] PLAN.md lifecycle across the PR chain — **branch-local, prune-per-PR**: the - topic-docs contract says contract slices are pruned before merge, and this program (which ships - that very contract's 2.0.0) must not self-violate by parking a slice on `main` for weeks. Each PR - branch commits the current PLAN, pastes it into its PR description, and prunes the slice in a - final commit before merge; the next PR branch (cut from post-squash `main`) re-commits the - updated PLAN from the local working tree. Cross-PR continuity = the PR-description pastes + (from - Phase 7) the epic. Close-out at PR D: Phase 7's verdict rows and final status tags commit there, - durable outcomes graduate, final prune-with-pointer. The Windows `sensitive` VERDICT is recorded - durably (PLAN verdict table → PR D description + epic), not only in gitignored `.work/`. - (Alternative rejected: adding a multi-PR-program exception clause to the 2.0.0 lifecycle text — - viable, but it lands only in PR B while PR A would already need it; override at approval if the - exception clause is preferred.) -- [EXEC-SHAPE] Wave A parallelism + fences as tabled above. -- [EXEC-SHAPE] Phase 7 fanout surface: per-plugin subagents (Workflow engine if available, plain - sub-agent fanout otherwise) — D16 locks the fanout itself. -- [EXEC-SHAPE] Empirical verifications embedded at Brief-assigned execution points (P4/P6/P7) - rather than a standalone verification phase. - -### Mechanical work - -- Commit boundaries: one commit per phase minimum; Phase 5 = one wave commit for the contract bump + - implementer adoption (clean break lands atomically); PLAN.md status-tag updates ride each phase's - commit. Each PR branch is cut from **post-squash `main`**, never from the previous PR branch - (stacking would replay the prior PR's squashed commits in the diff). -- Verification checkpoints: run each phase's Sanity Check before its commit; existing CI - (contract tests, markdownlint, drift check) green before each PR merge. -- Sequential fallback: documented under Execution shape; orchestrator-writes rule (R4) applies to - all fanout output. -- Close-out: `/architect close-out` at PR time — PLAN.md into PR description `
`, durable - outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. From 41ca9c85fddd6bd83d4f57f78c5d15fd3b92c834 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:53:23 -0400 Subject: [PATCH 07/10] docs: phrase formatter setup rule as requirement, not shipped state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex review: the setup criteria read as if formatter/linter plugins already ship check-centric setups; none do yet. The rule is normative — the fleet conformance audit tracks adoption gaps. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/PLUGIN-PHILOSOPHY.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/PLUGIN-PHILOSOPHY.md b/docs/PLUGIN-PHILOSOPHY.md index fb10bfa61..254b750e1 100644 --- a/docs/PLUGIN-PHILOSOPHY.md +++ b/docs/PLUGIN-PHILOSOPHY.md @@ -114,8 +114,9 @@ merely to create a second configuration channel. A plugin requires a `setup` skill iff it has (a) a consumer-project configuration surface, (b) an external prerequisite — CLI, service, credential — or (c) non-trivial `userConfig`. Apply the criteria through the modular, configurable, repo-, machine-, and user-agnostic lens; zero-config -zero-prerequisite plugins are exempt — setup is never blanket ceremony. Formatter and linter -plugins carry a thin check-centric setup. +zero-prerequisite plugins are exempt — setup is never blanket ceremony. For formatter and linter +plugins the requirement is a thin check-centric setup; where one is not yet shipped, the fleet +conformance audit tracks the gap. The uniform contract: the skill is named `setup`, sets `disable-model-invocation: true`, and offers `check` (read-only inspect and verify) and `apply` (idempotent configure) actions. Setup must be: From 92099a42dc67a03378f8e0bfc4162c5547cdbb53 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:55:47 -0400 Subject: [PATCH 08/10] docs: fix monitors doc link, seam-phrasing status, setup freshness rider Claude review: OFFICIAL-DOCS Monitors row now points at plugins-reference#monitors (the manifest schema home) instead of tools-reference (the runtime Monitor tool); the seam-phrasing registry row states the existing multi-adopter gap unambiguously; the setup idioms sentence carries its verified date and source links per D7. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/OFFICIAL-DOCS.md | 2 +- docs/PLUGIN-PHILOSOPHY.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/OFFICIAL-DOCS.md b/docs/OFFICIAL-DOCS.md index 3d9d579c2..391e76c2a 100644 --- a/docs/OFFICIAL-DOCS.md +++ b/docs/OFFICIAL-DOCS.md @@ -32,7 +32,7 @@ settings keys (`subagentStatusLine`) a plugin's `settings.json` may set. Channel | LSP servers (`.lsp.json`) | | 2026-07-17 | | Output styles (`output-styles/`) | | 2026-07-17 | | Themes (`themes/`) | | 2026-07-17 | -| Monitors (`monitors/monitors.json`) | | 2026-07-17 | +| Monitors (`monitors/monitors.json`) | | 2026-07-17 | | Channels (`channels` manifest field) | | 2026-07-17 | | Executables (`bin/`) | | 2026-07-17 | | Settings (`settings.json` defaults) | | 2026-07-17 | diff --git a/docs/PLUGIN-PHILOSOPHY.md b/docs/PLUGIN-PHILOSOPHY.md index 254b750e1..25655cb0e 100644 --- a/docs/PLUGIN-PHILOSOPHY.md +++ b/docs/PLUGIN-PHILOSOPHY.md @@ -132,7 +132,9 @@ must not write into the installed plugin cache, mutate Claude Code user settings `pluginConfigs`. Personal scalar configuration is collected through Claude Code's native plugin configuration surface. -Two native idioms are the sanctioned initialization surfaces: the `Setup` hook event +Two native idioms are the sanctioned initialization surfaces (verified 2026-07-17 against the +[hooks reference](https://code.claude.com/docs/en/hooks) and +[plugins reference](https://code.claude.com/docs/en/plugins-reference)): the `Setup` hook event (`--init-only`, or `--init`/`--maintenance` in `-p` mode) for headless and CI preparation, and a `SessionStart` hook comparing a bundled manifest against its `${CLAUDE_PLUGIN_DATA}` copy for runtime-dependency installation. @@ -175,7 +177,7 @@ doc before a second plugin adopts it. Fleet audits check conformance per row. | Permission-rule hygiene | [`docs/conventions/permission-rule-hygiene/`](conventions/permission-rule-hygiene/README.md) | | Skill layout contract and evals schema | `skill-quality` plugin (contract gate + bundled schema) | | Review severity vocabulary | `review` plugin (`context/severity.md`) | -| Seam phrasing (presence-gated fallbacks) | Unowned — used by convention, no owner doc yet; next adopter creates one first | +| Seam phrasing (presence-gated fallbacks) | Unowned — already used by multiple plugins without an owner doc: a tracked non-conformance and an audit dimension. No further adoption until an owner doc lands | ## Cross-platform contract From 94ff8b4b29c95ac360d644eb5c7d291bd3fa60f0 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:12:46 -0400 Subject: [PATCH 09/10] docs: mark setup check/apply contract as normative target Codex review: 17 shipped setup skills predate the check/apply contract; the doctrine now states the audit tracks that gap instead of implying current conformance. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/PLUGIN-PHILOSOPHY.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/PLUGIN-PHILOSOPHY.md b/docs/PLUGIN-PHILOSOPHY.md index 25655cb0e..86dcb960a 100644 --- a/docs/PLUGIN-PHILOSOPHY.md +++ b/docs/PLUGIN-PHILOSOPHY.md @@ -119,7 +119,10 @@ plugins the requirement is a thin check-centric setup; where one is not yet ship conformance audit tracks the gap. The uniform contract: the skill is named `setup`, sets `disable-model-invocation: true`, and offers -`check` (read-only inspect and verify) and `apply` (idempotent configure) actions. Setup must be: +`check` (read-only inspect and verify) and `apply` (idempotent configure) actions. This is a +normative target — setup skills that predate this contract are nonconforming until migrated, and +the fleet conformance audit tracks the gap rather than the doctrine pretending it is closed. Setup +must be: - idempotent and safe to rerun; - transparent about what it inferred, changed, skipped, or could not verify; From 39524cc951b519dfb71bdf7d15da05ba8c8d2ca1 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:44:37 -0400 Subject: [PATCH 10/10] docs: scope userConfig env mirror to hook processes only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex + Claude review: CLAUDE_PLUGIN_OPTION_ is exported to hook processes only — skill Bash calls and monitors do not receive it. The migration guidance now routes non-hook consumers through user_config substitution or explicit arguments instead of a mirror that would be empty. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/PLUGIN-PHILOSOPHY.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/PLUGIN-PHILOSOPHY.md b/docs/PLUGIN-PHILOSOPHY.md index 86dcb960a..94f7e9716 100644 --- a/docs/PLUGIN-PHILOSOPHY.md +++ b/docs/PLUGIN-PHILOSOPHY.md @@ -97,8 +97,11 @@ hand-edit — migrates to `userConfig` with the schema used honestly: a secret; and - `claude plugin install --config` documented in the plugin's setup skill for headless use. -Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; the custom environment variable -is retired when the migration lands. +Hook processes read the native `CLAUDE_PLUGIN_OPTION_` mirror — a hook-only export: a Bash +call made by a skill and monitor processes do not receive it. A non-hook consumer (a `bin/` script, +a skill-invoked shell script) takes the value through non-sensitive `${user_config.*}` substitution +in skill or agent content, an explicit argument, or a component field that substitutes it. The +custom environment variable is retired when the migration lands. `version` lives in `plugin.json` only, never in a marketplace entry. The platform resolves plugin.json first, but a marketplace-entry copy is dead metadata that silently becomes live if the