docs: extend plugin doctrine — component stances, native-first, official-docs index - #257
Conversation
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
…P1-P2) 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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
|
Claude finished @kyle-sexton's task in 2m 16s —— View job PR Review
This is a documentation-only PR (no plugin code, no executable surface). I've reviewed all five changed files for correctness, internal consistency, alignment with the repo's CLAUDE.md requirements, and any doctrine gaps. OverallThe changes are high-quality and internally coherent. The 13-row component stance table, native-first gate, convention registry, and exec-form hook rule all land cleanly and follow the pointer-only, non-restating pattern the repo enforces. The fresh-docs mandate is satisfied: every row carries a verified 2026-07-17 date, and the staleness disclaimer is appropriately prominent. Four findings below — one is a factual discrepancy worth fixing before merge, one is a doctrine ambiguity, one is an in-flight completeness gap (the stated pruning commit hasn't landed yet), and one is a minor consistency gap. Finding 1 — Monitor component row points to wrong doc page (factual discrepancy)File: The "Plugin components → doc page" table header says "one row per plugin component type, per the current Plugins reference." The Monitors row maps to The two tables now disagree about the authoritative doc page for the same component. An agent following the OFFICIAL-DOCS index would land on tools-reference to read about the monitors manifest format, which isn't there. Fix this → Finding 2 — "Seam phrasing" registry entry is ambiguous about conformance statusFile: The convention registry row for "Seam phrasing (presence-gated fallbacks)" says "Unowned — used by convention, no owner doc yet; next adopter creates one first." The registry's own rule (line 163–164) states "A new cross-plugin convention lands in an owner doc before a second plugin adopts it." If this convention is already in use across multiple plugins without an owner doc, the entry is tracking an existing non-conformance. But the phrasing "next adopter creates one first" could be read as permitting another adoption without the owner doc (contradicting the rule), rather than as a call to fix the existing gap. Suggest rewording to make the status unambiguous — either "tracking an existing gap; no new adoption until an owner doc exists" or, if there's only one adopter today, "single adopter; must create owner doc before any second adoption." Fix this → Finding 3 — PLAN.md pruning commit not yet landed (stated acceptance criterion)File: The PR body states: "The topic contract slice ( This isn't a content correctness issue, but it means the branch is incomplete relative to its stated acceptance criteria. Finding 4 — Setup section describes platform-specific hook event details without a freshness markerFile: The Setup section names specific platform behaviors: the The PR's own freshness-rider principle (D7 in the Brief) applies here too. A staleness note or an inline source link would keep this consistent with the rest of the doctrine. Fix this → No issues found
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a89abf608e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c7b0a695a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
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.
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
|
Claude review findings — classification and disposition:
All four confirmed against the tree before fixing. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 92099a42dc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 94ff8b4b29
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude finished @kyle-sexton's task in 2m 41s —— View job PR Review
All four findings from the first review are confirmed fixed. Three Codex observations have been addressed. One finding from the latest Codex pass (commit Finding —
|
Codex + Claude review: CLAUDE_PLUGIN_OPTION_<KEY> 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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
|
Second Claude review finding (CLAUDE_PLUGIN_OPTION_ scope): VALID — fixed in 39524cc with slightly wider phrasing than the one-word suggestion: the sentence now names the hook-only export explicitly, excludes skill Bash calls and monitors, and gives non-hook consumers their supported channels (non-sensitive ${user_config.*} substitution, explicit arguments). All prior findings remain addressed. |
|
Claude finished @kyle-sexton's task in 3m 11s —— View job PR Review
This is the third review pass, picking up after the errored run (29601221764). All four findings from the first review and the single finding from the second review are confirmed fixed and verified against the tree. One Codex observation (PLAN pruning) was also verified clean — Latest fix confirmed (39524cc)File: The 39524cc wording is wider and clearer than the one-word "Shell consumers → Hook processes" suggestion: it names hook processes explicitly, excludes a Bash call made by a skill and monitor processes, and gives non-hook consumers (a All prior findings confirmed addressed
No new issues found
|
) Codifies the marketplace naming convention in PLUGIN-PHILOSOPHY: - Imperative-verb grammar; namespace supplies the object. Documented deviation from the official gerund preference (sanctioned alternative + collection-consistency requirement), chosen for sentence-composability. - Fixed verb meanings: `audit`/`scan` read-only (mutation only behind explicit override), `check` = pass/fail gate, `clean`/`tidy`/`fix` mutate, `setup`, `update`. - Sanctioned exceptions: knowledge/lifecycle-object noun routers, vendor-wrapper stutter, `-deep` isolation tier. - Cross-plugin reference rule: declared `dependencies` (auto-install) or "if installed" guard — bare references are defects. - Adds the `shadowed-skill-renames` topic contract (interview output) that drives the follow-up rename PRs. Sources fetched this session, linked in Authoritative references (verified 2026-07-17). No external content copied. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01YVApnNGoKxYMJKNQx1QK8C ## Related No linked issue. Companion doctrine PR: #257. Drives the follow-up shadowed-skill rename PRs: #268, #269, #270, #271. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…fixes R1-R6 (#292) ## Topic-docs contract 2.0.0 — visibility guarantees + seam fixes R1–R6 Phase 5 of the plugin-philosophy program (PR B of the chain; PR A was #257). One-wave contract-major adoption: owner doc, 8 implementer delta docs, 2 skill fixes, and the repo's own materialization of the native mechanisms, landed atomically. No linked issue. ## Related - #257 — PR A of the program: the doctrine wave this contract release implements. ### What changed - **R6 owner doc** (`docs/conventions/topic-docs/README.md`): new normative "Visibility across execution contexts" section — context × tier visibility matrix; four native mechanisms (`worktree.baseRef: "head"`, `.worktreeinclude`, by-value worker returns with orchestrator-writes, tracker as the cross-lane index); `WorktreeCreate`-hook caveat; `settings.local.json` override escape hatch; pointer discipline on durable surfaces; consumer-adoption section. Versioning rule amended: a visibility-guarantee change is **major** (that amendment is what makes this release's 2.0.0 label honest — no tier/key/slug change). Implementers table reconciled with the fleet: verification + toolchain rows added, Binding column distinguishes delta-doc implementers from adopt-by-reference rows, and the verification manifest/baselines moved from the implementation row to the new verification row (matching the plugins' actual bindings). - **R1**: committed `.claude/settings.json` with `worktree.baseRef: "head"` — verified honored at project-settings scope on CC 2.1.212, including from linked worktrees (control+treatment smoke tests; a linked-worktree session reads its own checkout's settings). `.claude/worktrees/` added to `.gitignore` (the runtime `.git/info/exclude` entry is machine-local; fresh clones and CI checkouts lack it). - **R2**: `.worktreeinclude` carrying stage ledgers and `EXPLORE.md`/`RESEARCH.md` into new worktrees (one-way, creation-time, gitignored-only); baselines and raw scratch deliberately excluded (machine-bound). - **R3**: `/work-items:decompose` ticket provenance cites the PR carrying the plan, never the prunable contract-slice path; `/planning:architect` baseline step records distilled values only in `PLAN.md`, never memory-slice capture paths. - **R4/R5** (owner-doc text): isolated workers return results by value and the orchestrator writes contract/durable tiers in the parent checkout; the work-item tracker is the cross-lane awareness layer (markdown-in-tickets as primary artifact store rejected — not diffable, no review gate, drifts from code). - **Implementer wave**: all 8 delta docs (`plugins/*/reference/topic-docs.md`) adopt 2.0.0; each touched plugin gets a minor version bump + CHANGELOG entry (discovery 0.6.0, implementation 0.7.0, planning 0.17.0, review 0.11.0, session-flow 0.8.0, toolchain 0.3.0, verification 0.2.0, work-items 0.9.0, source-control 0.5.2 for the review-driven sync-check fixes — several re-bumped over releases that landed on main mid-flight). ### Rollout notes - **Repo behavior change**: every worktree Claude Code spawns in this repo (including subagent worktrees) now branches from local `HEAD` instead of `origin/HEAD`. A personal `.claude/settings.local.json` silently overrides this machine-wide — nothing may assume the setting universally in force. - **Pull collision**: a clone already holding an untracked `.claude/settings.json` hits "untracked working tree file would be overwritten" on pull — move the file aside, pull, merge values back. - **Mixed-fleet window**: installed plugin caches and in-flight branches keep 1.x text until they update — safe because no tier/key/slug-spec changed; divergence is doctrinal, never layout-corrupting. In-flight branches sweep stale visibility text when they merge. - **Windows**: deep repository base paths can trip git's path limit inside nested worktrees (`'$GIT_DIR' too big`); this repo's base (~95 chars) is safe. ### Verification Drift check `--check`, `validate-plugins.sh` (incl. catalog `--check`), markdownlint (46 files, 0 errors), delta-doc/Implementers-table parity both directions, 8/8 version-bump coverage, gitleaks clean on the new tracked files. Phase 4 empirical evidence (worktree semantics, CC 2.1.212) is in the PLAN's verdict table below. <details> <summary>PLAN.md (contract slice — pruned before merge per its own lifecycle)</summary> # 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_<KEY>` 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_<KEY>` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK_<NAME>_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 > **Program log.** 2026-07-17: PR A (#257, Phases 1–3 + P4 evidence) squash-merged to main; all > review findings (2 Codex inline + 2 follow-ups + 6 Claude-review) classified, fixed, and > verified; contract slice pruned on that branch and re-committed here on `docs/topic-docs-2.0.0` > (the PR B branch, cut from post-squash main). Phase 5 wave executed on this branch (fresh-fetched > worktrees + settings pages; all sanity checks green: drift `--check`, validate-plugins incl. > catalog `--check`, markdownlint, delta-doc/table parity, 8-plugin bump coverage). Implementers > table also corrected: verification manifest/baselines moved off the implementation row to a new > verification row. Next: PR B. 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_<KEY>` 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/<slug>/…` 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) [DONE] 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 | |---|---|---| | [x] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | | [x] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | | [x] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes — untouched | | [x] `docs/conventions/topic-docs/examples/*` | AUDIT | layout unaffected by matrix/mechanisms — untouched | | [x] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | | [x] `.worktreeinclude` | CREATE | R2 patterns (+ `.claude/worktrees/` gitignored) | | [x] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | | [x] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | | [x] 8 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | minor bump per touched plugin | | [x] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | no stale convention text found — untouched; table annotates by-reference rationale | **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/<name>/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/<plugin>.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/" <epic and wave issue bodies>` = 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 <name>` creates branches named `worktree-<name>` — 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 `<details>`, durable outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ent, display names (#310) ## Marketplace metadata wave — relevance, default enablement, display names, org-suggestion docs Phase 6 of the plugin-philosophy program (PR C; PR A #257, PR B #292). Metadata maximalism decided per-plugin over the live 50-plugin fleet (Brief said 47 — `ai-briefing`, `miro`, `domain-driven-design` landed after the Brief lock; intent is "all plugins"). No linked issue. ## Related - #257 — PR A: doctrine wave (component stances incl. D15 metadata maximalism). - #292 — PR B: topic-docs contract 2.0.0 wave. ### What changed - **`relevance` on 11 entries** whose signals genuinely discriminate (suggestions only surface for marketplaces an admin allowlists; matching is local): bash-format, biome-format, ruff-format, powershell-format, actionlint, mcp-tools, knowledge, firecrawl, claude-config, playwright, skill-quality. Rejected as noise everywhere a signal would fire in any repo — markdown globs and `CLAUDE.md` are noise by construction (auto-loaded memory files count as `filesRead`), and universal workflow skills (planning, review, source-control, …) have no discriminating session signal. - **`defaultEnabled: false` on 5** personal/niche/external-service entries: firecrawl (paid API service), songwriting, kindle-dedrm, ai-briefing (personal), miro (bundles an external MCP server). Documented semantics: an existing user's `enabledPlugins` entry persists, so a later flip never disables an existing install — the PLAN's empirical-flip check was waived on that doc evidence. - **`displayName` on 5 acronym names**: EOL Normalizer, MCP Tools, TDD, Kindle DeDRM, AI Briefing. `name` untouched everywhere (breaks installs; `renames` map is the only rename path). - **`version` asserted absent from every entry** — plugin.json silently wins, so entry versions are a masking trap. Descriptions stay single-homed in plugin.json (entries add none). - **README org-enablement section**: `pluginSuggestionMarketplaces` + the required source declaration in managed settings, with the anti-spoofing rationale, plus a note on opt-in (`defaultEnabled: false`) entries. ### Verification `node scripts/generate-catalog.mjs --check` clean; `claude plugin validate .` passed; scripted assertion: 50 entries, every entry resolves a description, `version` absent from all entries; markdownlint clean on README. Per-plugin adopt/reject rationale ledger lives in the memory slice (machine-local), per the topic-docs convention. <details> <summary>PLAN.md (contract slice — pruned before merge per its own lifecycle)</summary> # 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_<KEY>` 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_<KEY>` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK_<NAME>_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 > **Program log.** 2026-07-17: PR A (#257, Phases 1–3 + P4 evidence) squash-merged to main; all > review findings (2 Codex inline + 2 follow-ups + 6 Claude-review) classified, fixed, and > verified; contract slice pruned on that branch and re-committed here on `docs/topic-docs-2.0.0` > (the PR B branch, cut from post-squash main). Phase 5 wave executed on this branch (fresh-fetched > worktrees + settings pages; all sanity checks green: drift `--check`, validate-plugins incl. > catalog `--check`, markdownlint, delta-doc/table parity, 8-plugin bump coverage). Implementers > table also corrected: verification manifest/baselines moved off the implementation row to a new > verification row. PR B (#292) squash-merged as `143db4d5fe` after 8 Codex review rounds (12 P2 > findings, all validated and fixed: self-ignore carry, checkout-not-process by-value boundary, > pre-flight glob/deletion/toplevel/never-copied hardening, cleanup carried-file guard, wayfind > durable-pointer + no-recaps qualification, decompose pre-PR provenance backfill; source-control > bumped 0.5.2) and three concurrent-main merges (planning landed 0.13.0–0.16.0 mid-flight incl. > the architect→plan rename and a new `domain-driven-design` plugin — wave bumps renumbered: > planning 0.17.0, review 0.11.0, toolchain 0.3.0). **Fleet drift:** 50 plugins now (Brief said > 47; ai-briefing, miro, domain-driven-design landed after the Brief lock) — Phase 6/7 counts > track the live fleet, intent is "all plugins". `defaultEnabled`-flip empirical check waived: > plugins-reference documents that an existing user's `enabledPlugins` entry persists, so a later > flip never disables an existing install. Now: Phase 6 on `docs/marketplace-metadata`. 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_<KEY>` 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/<slug>/…` 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) [DONE] 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 | |---|---|---| | [x] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | | [x] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | | [x] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes — untouched | | [x] `docs/conventions/topic-docs/examples/*` | AUDIT | layout unaffected by matrix/mechanisms — untouched | | [x] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | | [x] `.worktreeinclude` | CREATE | R2 patterns (+ `.claude/worktrees/` gitignored) | | [x] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | | [x] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | | [x] 8 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | minor bump per touched plugin | | [x] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | no stale convention text found — untouched; table annotates by-reference rationale | **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/<name>/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 [DONE] 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/<plugin>.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/" <epic and wave issue bodies>` = 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 | DECIDED per-plugin over the live 50-plugin fleet: 11 adopted (discriminating file/CLI/dep signals — bash/biome/ruff/powershell/actionlint formatters, mcp-tools, knowledge, firecrawl, claude-config, playwright, skill-quality), 39 rejected as noise (universal-workflow skills; `**/*.md` and `CLAUDE.md` patterns are noise by construction — auto-loaded memory counts as filesRead). Also: `defaultEnabled: false` on 5 (firecrawl, songwriting, kindle-dedrm, ai-briefing, miro), `displayName` on 5 acronym names. Flip semantics documented (existing installs never flipped) — empirical check waived. Full ledger: memory slice. | | 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 <name>` creates branches named `worktree-<name>` — 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 `<details>`, durable outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… (0.6.0) (#300) Extracts the all-PR babysit loop from `/source-control:pull-request` into a standalone `/source-control:babysit-prs` skill (distinct discovery intent: fleet loop vs single-PR lifecycle) and hoists the shared review discipline to plugin scope. Phase 1 of the babysit-prs migration contract (`docs/topics/babysit-prs-migration/PLAN.md` on this branch); capability convergence with the dotfiles skill (tiers, Python engine, userConfig) is the follow-up PR. Closes #260 ## Change set - **New skill `plugins/source-control/skills/babysit-prs/`** — SKILL.md (compact per-PR checklist, NEVER-merges invariant, gotchas from observed failure history), `reference/loop.md` (the former `babysit.md`, reworked), routing/refusal/anti-pattern evals. Phase-1 behavior is identical to the former `babysit` action (all open non-draft PRs, Dependabot included); the own-PRs safe-default narrowing is a Phase 2 deliverable. - **Plugin-scope seam** — `reference/review-discipline.md` is the single committed copy of the shared discipline (finding extraction + mandatory ≥3-finding subagent dispatch, per-finding D1–D7 verification gates, self-reply filter); both skills' checklists cite it. `monitor.md`'s three cross-references into the former babysit reference invert to the seam. - **Shared scripts hoisted** to plugin-root `scripts/` via `git mv`: `fetch-all-pr-comments.sh`, `babysit-readiness-gate.sh`, `test-helpers.sh` (+ tests); all citations re-rooted to `${CLAUDE_PLUGIN_ROOT}/scripts/`. `discover-prs.sh` retired (inline `gh pr list` filter is the discovery contract). - **Breaking (0.5.1 → 0.6.0, 0.x breaking-by-minor):** the `babysit` action leaves the pull-request surface; pull-request keeps only negative-routing pointers. Eval 9 moved to the new skill's eval set (ids stay stable; gap is legal per the evals schema). - Metadata: plugin description/keywords, marketplace tags, plugin README skill section, CHANGELOG 0.6.0, root README catalog regenerated. ## Trigger continuity (skill split — decompose step 5 evidence) | Retired trigger (old `pull-request` surface) | Successor | |---|---| | `'babysit PRs'` (description trigger) | `babysit-prs`: "Use when: 'babysit PRs', 'babysit my PRs', 'watch my open PRs', 'keep my PRs moving', 'advance all open PRs', or pairing with /loop" | | `/pull-request babysit` (action) | `/source-control:babysit-prs` | | `/loop /pull-request babysit` (loop pairing) | `/loop /source-control:babysit-prs` | Negative routing boundaries: `pull-request` description now carries "not for the all-PR babysit loop (use /babysit-prs)"; `babysit-prs` carries "not for the single-PR lifecycle: prep, create, monitor one PR, or merge (use /pull-request)". Routing evals: `babysit-prs` evals 1–2 (vocabulary routes to the loop skill; single-PR lifecycle stays with `pull-request`). `/skill-quality:check` on the same-path `pull-request` rewrite with `CHECK_SKILL_BASE_REF=origin/main` reports the expected check-3 finding — dropped trigger `'babysit PRs'` — which this table answers (the checker deliberately skips new paths; this table + the routing evals are the required split evidence). New-path check on `babysit-prs`: PASS, 0 errors, 0 warnings. ## Fresh-docs citations (Gate 0) - Skills — directory structure, frontmatter fields, description-driven auto-invocation, supporting files: <https://code.claude.com/docs/en/skills> (fetched this session) - Plugins reference — `skills/` location rule, `${CLAUDE_PLUGIN_ROOT}` semantics, manifest `version`/`keywords`: <https://code.claude.com/docs/en/plugins-reference> (fetched this session) ## Naming rationale `babysit-prs` carries its object in the leaf name for trigger continuity with the migrated vocabulary ("babysit PRs" is the phrase users reach with) and to disambiguate from babysitting other source-control objects; verb-object compound precedent: `scan-todos`, `youtube-digest`. ## Validation - `scripts/run-plugin-tests.sh` affected tests green (hoisted `fetch-all-pr-comments`, `babysit-readiness-gate`; re-pointed `fetch-annotations`, `fetch-failed-logs`, `parse-branch-issue`); full lane re-verified by CI - `scripts/validate-plugins.sh` exit 0 (contracts, catalog `--check`, `claude plugin validate` per plugin + `--strict`) - markdownlint + shellcheck clean; exec bits preserved via `git mv` - Non-source-repo smoke (`claude --plugin-dir … -p` from a clean consumer repo): `/source-control:babysit-prs` discovered with the new description. Known transition-window condition: the user-level dotfiles `babysit-prs` skill shares the vocabulary until the migration's cutover phase retires it - Residue sweep: `grep -ri babysit` in the pull-request skill returns only the three deliberate sibling pointers; no stale `babysit.md` or old script-path citations anywhere in the plugin ## Contract note `docs/topics/babysit-prs-migration/PLAN.md` (Brief + phased Plan) rides this branch and stays for the follow-up convergence PR; the slice is pruned at the migration's final PR per the topic-docs close-out. ## Related - #256 — skill-naming grammar + cross-plugin reference rules this split implements (decompose procedure, trigger-continuity evidence) - #257 — plugin doctrine (component stances, shared-policy-at-plugin-scope) governing the seam placement - Follow-up: PR-B (capability convergence — dotfiles babysit-prs port, tiers, Python engine, userConfig/setup) per the migration contract on this branch 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…e pruned) (#319) ## Plugin-philosophy program close-out (PR D) Final PR of the plugin-philosophy program chain: PR A #257 (doctrine + official-docs index), PR B #292 (topic-docs contract 2.0.0), PR C #310 (marketplace metadata wave), and this close-out. Net diff is intentionally zero: the branch carries the PLAN's final state (all seven phases DONE, all three empirical verdicts recorded) and then prunes the contract slice per the topic-docs lifecycle this very program shipped. The PLAN's durable outcomes have graduated to the work-item tracker. No linked issue. ## Related - #313 — conformance epic: 50-plugin × 15-dimension matrix, doctrine-update findings, Windows `sensitive` plaintext verdict (blocked-upstream), deferred CI-gate backlog. - #314 / #315 / #316 / #317 / #318 — the five remediation wave sub-issues (setup contract, userConfig migration with secrets excluded, CHANGELOG + freshness, prerequisite visibility + cross-platform, naming + registry + doctrine updates). - #257, #292, #310 — the program's merged delivery PRs. ### Program outcome - Doctrine extended and review-hardened (component stances for 13 native component types, native-first gate, convention registry, userConfig criterion, setup contract, prerequisite-visibility rule, official-docs index). - Topic-docs contract 2.0.0: visibility semantics are normative (context × tier matrix), materialized natively (`worktree.baseRef: "head"`, `.worktreeinclude`, by-value returns, tracker index) with the repo's own R1/R2 files landed and the Versioning rule amended honestly. - Marketplace metadata maximalism over the live 50-plugin fleet: 11 relevance adopts / 39 reasoned rejects, 5 defaultEnabled opt-ins, 5 displayNames, org-enablement docs; `version` verified absent from every entry. - Fleet audited 50/50 with a frozen rubric and a 3-plugin blind double-score (exact agreement); zero fleet failures on the two dimensions the program itself shipped (pointer discipline, metadata); remediation program filed as one epic + five waves on the tracker. - Empirical verdicts: worktree semantics (control+treatment, CC 2.1.212), relevance-signal quality (per-plugin ledger), Windows `sensitive` storage = plaintext (secrets excluded from the userConfig wave, blocked upstream). <details> <summary>PLAN.md — final state (contract slice, pruned in this PR per its own lifecycle)</summary> # 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_<KEY>` 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_<KEY>` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK_<NAME>_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 > **Program log.** 2026-07-17: PR A (#257, Phases 1–3 + P4 evidence) squash-merged to main; all > review findings (2 Codex inline + 2 follow-ups + 6 Claude-review) classified, fixed, and > verified; contract slice pruned on that branch and re-committed here on `docs/topic-docs-2.0.0` > (the PR B branch, cut from post-squash main). Phase 5 wave executed on this branch (fresh-fetched > worktrees + settings pages; all sanity checks green: drift `--check`, validate-plugins incl. > catalog `--check`, markdownlint, delta-doc/table parity, 8-plugin bump coverage). Implementers > table also corrected: verification manifest/baselines moved off the implementation row to a new > verification row. PR B (#292) squash-merged as `143db4d5fe` after 8 Codex review rounds (12 P2 > findings, all validated and fixed: self-ignore carry, checkout-not-process by-value boundary, > pre-flight glob/deletion/toplevel/never-copied hardening, cleanup carried-file guard, wayfind > durable-pointer + no-recaps qualification, decompose pre-PR provenance backfill; source-control > bumped 0.5.2) and three concurrent-main merges (planning landed 0.13.0–0.16.0 mid-flight incl. > the architect→plan rename and a new `domain-driven-design` plugin — wave bumps renumbered: > planning 0.17.0, review 0.11.0, toolchain 0.3.0). **Fleet drift:** 50 plugins now (Brief said > 47; ai-briefing, miro, domain-driven-design landed after the Brief lock) — Phase 6/7 counts > track the live fleet, intent is "all plugins". `defaultEnabled`-flip empirical check waived: > plugins-reference documents that an existing user's `enabledPlugins` entry persists, so a later > flip never disables an existing install. Phase 6 shipped as PR C (#310), clean review, > squash-merged. Phase 7 executed: tracker search → CREATE path (no epic existed; label taxonomy > is github-iac-managed so no new labels — native sub-issues used instead); 15-dimension rubric > frozen with anchored PASS/FAIL + worked example; Windows `sensitive` probe → PLAINTEXT (verdict > row 3; fallback applied); 4-plugin pilot calibrated two rulings (HOOK_*_ENABLED toggles FAIL > dims 3/6 per the Brief's flagship designation; out-of-table imperative verbs PASS dim 2), then > batched fanout scored ALL 50 plugins (one mid-run session-limit burst killed 4 workers whose > reports had already landed; 2 re-runs); 3 blind double-scores reconciled with exact agreement. > Findings graduated: epic #313 (matrix inline, single-token cells) + wave sub-issues #314 > (setup, 31 plugins), #315 (userConfig, secrets excluded), #316 (CHANGELOG+freshness), #317 > (prereq visibility + cross-platform, incl. shared hook-utils fix), #318 (naming + registry + > 5 doctrine updates). Zero fleet FAILs on pointer discipline and metadata — the two dimensions > PRs #292/#310 shipped. 3 DOCTRINE-UPDATE findings + 1 dependency question filed in #313/#318. > PR D closes out. 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_<KEY>` 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/<slug>/…` 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) [DONE] 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 | |---|---|---| | [x] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | | [x] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | | [x] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes — untouched | | [x] `docs/conventions/topic-docs/examples/*` | AUDIT | layout unaffected by matrix/mechanisms — untouched | | [x] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | | [x] `.worktreeinclude` | CREATE | R2 patterns (+ `.claude/worktrees/` gitignored) | | [x] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | | [x] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | | [x] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | | [x] 8 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | minor bump per touched plugin | | [x] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | no stale convention text found — untouched; table annotates by-reference rationale | **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/<name>/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 [DONE] 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 [DONE] 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/<plugin>.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/" <epic and wave issue bodies>` = 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 | DECIDED per-plugin over the live 50-plugin fleet: 11 adopted (discriminating file/CLI/dep signals — bash/biome/ruff/powershell/actionlint formatters, mcp-tools, knowledge, firecrawl, claude-config, playwright, skill-quality), 39 rejected as noise (universal-workflow skills; `**/*.md` and `CLAUDE.md` patterns are noise by construction — auto-loaded memory counts as filesRead). Also: `defaultEnabled: false` on 5 (firecrawl, songwriting, kindle-dedrm, ai-briefing, miro), `displayName` on 5 acronym names. Flip semantics documented (existing installs never flipped) — empirical check waived. Full ledger: memory slice. | | 3 | Windows `sensitive` userConfig storage | 7 | PLAINTEXT (Windows 11, CC 2.1.212, empirical throwaway-plugin probe): `sensitive: true` value persists as plaintext JSON in `~/.claude/.credentials.json` under `pluginSecrets`; NO Credential Manager entry (`cmdkey /list` empty of claude); removed cleanly on uninstall. Documented no-keychain fallback confirmed observed. Tagged fallback APPLIED: secrets excluded from the userConfig wave issue (#315), blocked-upstream recorded in epic #313. | ## 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 <name>` creates branches named `worktree-<name>` — 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 `<details>`, durable outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Doctrine wave of the plugin-philosophy program (Phases 1-3 of the approved PLAN, committed on this branch at
docs/topics/plugin-philosophy/PLAN.md):${user_config.*}never in shell form, v2.1.207);versionsingle-home rule (plugin.json only); setup required-iff criteria with the uniformcheck/applycontract; runtime-prerequisite visibility rules.settings.jsonagenttakeover,bin/PATH executables), setup section now defers to the philosophy doc.llms.txtnamed as the authoritative self-updating master list. CLAUDE.md gains exactly one pointer row.All facts re-fetched from official docs this session per the repo fresh-docs mandate. Follow-on PRs in the approved chain: topic-docs 2.0.0 seam wave (PR B), marketplace metadata (PR C), audit close-out (PR D).
The topic contract slice (
docs/topics/plugin-philosophy/) is pruned in the final commit on this branch per the topic-docs convention; the full PLAN.md has now been graduated into this description under the Plan heading below.🤖 Generated with Claude Code
https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a
Related
No linked issue. Companion naming-convention PR: #256.
Plan (graduated from docs/topics/plugin-philosophy/PLAN.md)
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
dependenciesreserved 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).paths,context: fork,arguments, skill-scopedhooks/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 ignorehooks/mcpServers/permissionMode); pluginsettings.jsonagent(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 theCLAUDE_PLUGIN_OPTION_<KEY>env mirror.type,defaultpreserving zero-config behavior,requiredonly where truly blocking,sensitive: truefor secrets,claude plugin install --configdocumented in each setup skill for headless use. Shell consumers read the nativeCLAUDE_PLUGIN_OPTION_<KEY>mirror; custom env vars retired. Ownership table otherwise unchanged. GuardrailsHOOK_<NAME>_ENABLEDtoggles = flagship migration (userConfig booleans,default: true).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. NativeSetuphook event = sanctioned headless/CI init surface; SessionStart +${CLAUDE_PLUGIN_DATA}manifest-diff = sanctioned runtime-dependency idiom.lib/hook-utils.shsync, 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.docs/topics/name (contents are transient topic-scoped contract docs;docs/specs/is already the durable vault target — renaming would conflate tiers).worktree.baseRef: "head"in committed repo settings so worktree-isolated spawns carry task-branch state; R2.worktreeincludewith 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.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, andhttps://code.claude.com/docs/llms.txtnamed as the authoritative self-updating master list. CLAUDE.md keeps its lean canonical table plus one pointer row to the index.relevancesignals wherever meaningful (audit criterion per plugin),defaultEnabled: falsefor personal/niche-category plugins,displayNamewhere it genuinely clarifies, complete descriptive metadata. Consumer-facing doc section on org enablement of suggestions (pluginSuggestionMarketplaces+ source declaration in managed settings). Hard rule:versionlives in plugin.json only, never in marketplace entries (silent-precedence trap).Constraints
wave; this Brief's doc facts were verified 2026-07-17.
docs/plugin-philosophy; PRs required, squash merge, PR titleper Conventional Commits.
in the same release wave (the contract carries no compatibility machinery).
defaultvalues (guardrails toggles defaulttrue).Acceptance criteria
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).
touchpoints).
docs/OFFICIAL-DOCS.mdexists: complete categorized page map, component→doc table, verified-dates,staleness disclaimer, llms.txt master pointer; CLAUDE.md carries the pointer row and stays lean.
.worktreeinclude, and R3 skill pointer fixes (decompose ticket provenance, architect baselinerecording) landed; the three flagged execution-time verifications resolved empirically and
recorded.
claude plugin validate .passes.47-plugin row scored; raw details in the memory slice.
Captured assumptions
clients degrade per official behavior, not worked around.
org-agnostic (no solo-consumer scoping).
Out-of-scope (deferred with triggers)
the fleet-sync skill.
future doc re-verification (D6 wait rows).
music→creative, deployment category, and other plugin-organization deferrals remain owned bythat Brief.
Deferred questions
sensitiveuserConfig storage behavior (docs silent on Windows keychain) — empiricalverification during audit, before any secret migrates. Arbiter:
/architect(execution evidence).--bgsession worktree base semantics;worktree.baseRefhonored at project-settings scope — empirical smoke tests during D13 execution.Arbiter:
/architect.relevancesignal quality (which signals are genuinely helpful vs noise) — decidedper-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
relevancequality →Phase 6 (per-plugin, during the metadata wave); Windows
sensitiveuserConfig 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:
plugins,plugins-reference,skills,hooks,settings,plugin-dependenciespages; re-verify the 13 component types and the D6 stance facts (skill frontmatter additions,
commands/legacy status,bin/rules, agent field limitations, monitors/themes/channelsmaturity, 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 1and 3 sanity checks assert against N, not a hard-coded 13.
official-doc link (D7 rider), and the D7 staleness disclaimer heading the table.
schema fields,
CLAUDE_PLUGIN_OPTION_<KEY>mirror, retirement of custom env channels), exec-formhooks rule, version-placement rule (
versionin plugin.json only).uniform
setupskill contract,Setuphook event and SessionStart manifest-diff idioms).visibility, OTel as candidate channel, no black boxes).
(topic-docs binding, skill layout + evals schema,
lib/hook-utils.shsync, 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 fromcomponent-count.txt).grep -n "Convention registry\|Native-first" docs/PLUGIN-PHILOSOPHY.mdreturns both sections.npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.mdexit 0 (CI'spinned 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:
exec-form hook rule — each as a pointer to the philosophy doc section plus playbook-specific
procedure only.
sensitiveuserConfig handling,bin/collision-safe naming, pluginsettings.jsonagentprohibition check.tables).
Sanity Check:
grep -n "PLUGIN-PHILOSOPHY" docs/MIGRATION-PLAYBOOK.mdshows pointer citations in the gate andsecurity-review sections.
both
ComponentandStancecolumns (Read assertion — pointers naming the section are fine).npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.mdexit 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:
https://code.claude.com/docs/llms.txt; enumerate every plugin-relevant page.docs/OFFICIAL-DOCS.md: categorized page map, component→doc-page table, per-rowverified-dates, D7 staleness disclaimer, llms.txt named as the authoritative self-updating
master list.
verified component list (
component-count.txt+ stance table) before PR A — parallel work offthe 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 fromcomponent-count.txt).grep -n "llms.txt" docs/OFFICIAL-DOCS.mdandgrep -n "OFFICIAL-DOCS" CLAUDE.mdboth hit.git diff origin/main...HEAD --stat -- CLAUDE.mdshows a 1-2 line delta.
npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/OFFICIAL-DOCS.mdexit 0; therepo'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 initrepo in the scratchpad with a syntheticorigin—never in this repo (its ~30 live worktrees, runtime-written
.git/info/exclude, and main checkouton a feature branch confound every measurement). Use
claude -p --worktreeexclusively (skips thetrust 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:
worktreesdoc (the doc anchor forbaseRef/.worktreeinclude— not thesettings page) plus
settings; record cited behavior, including the documented fallback"when
origin/HEADisn't resolvable, worktrees fall back to current local HEAD".worktree.baseRef: "head"at project-settings scope, two arms: control(
baseRefunset or"fresh") asserts marker ABSENT; treatment (baseRef: "head"incommitted
.claude/settings.json) asserts marker PRESENT. Verdict HONORED only if BOTH armsbehave — 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
headresolvesto that worktree's HEAD — test against that expected value). Variant A3:
settings.jsonpresentonly in the worktree checkout vs only in the main checkout — pins which copy a linked-worktree
session reads (undocumented; only
settings.local.jsonis documented as main-checkout-resolved)..worktreeincludeone-way creation-time copy: use real nested-gitignore paths(
.work/<slug>/…ignored via a nested*.gitignore, mirroring this repo) — not a toyroot-level pattern; assert copy at creation; modify original, assert no sync-back.
the only source of truth; capture
git status --ignoredsnapshots in the raw transcript) +--bgsession worktree base semantics..work/plugin-philosophy/verifications/, stamps everyVERDICT file with
claude --version, and returns the VERDICT lines by value; the mainsession 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, eachending in a one-line VERDICT (
HONORED/NOT-HONORED/ behavior description) and aclaude --versionstamp line.control:andtreatment:lines with opposite marker outcomes(else verdict is invalid by construction).
(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:
Grep/Globfor every consumer parsing theconvention surface —
.claude/topic-docs.yamlkeys, slug spec, tier paths, runtime guards, thescripts/check-cross-plugin-source-drift.shregistry, hooks readingdocs/topics/or.work/.Document parse paths in the memory slice before editing anything.
docs/conventions/topic-docs/README.md: worktree-visibility rationale, context ×tier visibility matrix, native mechanisms named (
worktree.baseRef,.worktreeinclude, by-valuereturns, tracker index); CHANGELOG entry
2.0.0; schema untouched unless a key changes (KEEPexpected). Reconcile the Implementers table with reality:
toolchainandverificationcarry
reference/topic-docs.mdbut are absent from the table;knowledge,claude-ops,docs-hygieneare 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.
.claude/settings.jsonwithworktree.baseRef: "head"(shape per Phase 4 smoketest 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.jsonhits "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/excludeentry ismachine-local; CI checkouts and fresh clones lack it, and partial tracking of
.claude/otherwise turns nested worktrees into
git add -Ahazards); 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 everyworktree) 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
.worktreeincludetemplate, scoped as"authoring-repo materialization; consumer repos self-apply" (routing it through a D9 setup-skill
applyaction is recorded as a follow-on trigger, not built now). The visibility matrix gains acaveat row: a
WorktreeCreatehook makes.worktreeincludeinert (documented) — hook scriptowns the copy.
.worktreeincludewith targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH; notbaselines/raw scratch); one-way creation-time copy documented in the convention doc.
plugins/work-items/skills/decomposecites the PR (not contractpaths) in ticket provenance;
plugins/planning/skills/architectrecords distilled baselinevalues in PLAN (raw captures stay memory-tier). Sweep both skill bodies for prunable-path
citations.
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).
plugins/*/reference/topic-docs.mddelta docs against the 2.0.0owner doc; bump each touched plugin's
plugin.jsonsemver + CHANGELOG; docs-hygiene declutterdetector references checked (reader row).
File inventory (checkbox discipline — tick as processed):
docs/conventions/topic-docs/README.mddocs/conventions/topic-docs/CHANGELOG.mddocs/conventions/topic-docs/topic-docs.schema.jsondocs/conventions/topic-docs/examples/*.claude/settings.jsonworktree.baseRef.worktreeincludeplugins/discovery/reference/topic-docs.mdplugins/implementation/reference/topic-docs.mdplugins/planning/reference/topic-docs.mdplugins/review/reference/topic-docs.mdplugins/session-flow/reference/topic-docs.mdplugins/toolchain/reference/topic-docs.mdplugins/verification/reference/topic-docs.mdplugins/work-items/reference/topic-docs.mdplugins/work-items/skills/decompose/SKILL.mdplugins/planning/skills/architect/SKILL.mdplugins/*/plugin.json+CHANGELOG.mdplugins/knowledge/…,plugins/claude-ops/…,plugins/docs-hygiene/…Sanity Check:
bash scripts/check-cross-plugin-source-drift.sh --checkexit 0 (the flag CI runs; flagless modeis informational only).
grep -n "2.0.0" docs/conventions/topic-docs/CHANGELOG.mdhits;grep -rn "visibility matrix" -i docs/conventions/topic-docs/README.mdhits.plugins/*/reference/topic-docs.mdpath has a matching tablerow and vice versa (Read assertion against the glob result).
.work/plugin-philosophy/consumers-topic-docs.mdnon-empty.plugin.jsonversion bump:git diff origin/main...HEAD --name-only | grep '^plugins/' | cut -d/ -f2 | sort -ueach has amatching
plugins/<name>/plugin.jsonin the diff.bash scripts/validate-plugins.shexit 0 (includesgenerate-catalog.mjs --check— regeneratethe catalog if any plugin.json description changed).
npx markdownlint-cli2 --config .markdownlint-cli2.jsoncon touched .md files exit 0.Phase 6: Marketplace metadata wave [TODO]
Covers D15 + per-plugin
relevancequality verification (deferred question c).Work items:
plugin-marketplaces+discover-plugins+plugins-reference(default-enablement section) + the dedicated
plugin-relevancepage; re-verify entry schema(
relevance,defaultEnabled,displayName, description precedence,versionsilent-precedence trap).
defaultEnabledflip semantics for already-installed consumers areundocumented — 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 arenamesmap);displayNameis safe.relevanceonly where the signal is genuinely helpful(judged per-plugin — noise rejected),
defaultEnabled: falsefor personal/niche categories,displayNamewhere it clarifies, complete descriptions; assert noversionfield in anyentry.
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).
.work/plugin-philosophy/relevance-decisions.md.node scripts/generate-catalog.mjs(CI runs--check; metadataedits drift the generated block otherwise).
Sanity Check:
claude plugin validate .exit 0.node scripts/generate-catalog.mjs --checkexit 0.node -eassertion: 47 entries; every entry resolves a description (entry or plugin.json);versionabsent from all entries — exit 0..work/plugin-philosophy/relevance-decisions.mdhas 47 rows.Phase 7: Fleet conformance audit fanout + tracker graduation [TODO]
Covers D16. Runs against merged doctrine (Phases 1–6 landed).
Work items:
gh issue list --searchfor an existingplugin-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 anygh issue create --labelcall (missing labels fail the create).
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.
per the authority rule above).
sensitiveuserConfig empirical verification (deferred question a): configure athrowaway
sensitiveuserConfig 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).
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/<plugin>.md(memory-tierraw 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.
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:
.work/plugin-philosophy/audit/tracker-search.mdstates the query + hitcount + create-vs-update decision.
ls .work/plugin-philosophy/audit/*.md | wc -l≥ 47 (one report per plugin) + matrix file with47 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/" <epic and wave issue bodies>= 0 (pointer discipline).sensitiveVERDICT file exists in.work/plugin-philosophy/verifications/.Empirical verification results
worktree.baseRefat project scope; sweep of ignored files;--bgbase.claude/settings.jsonworktree.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:--worktreeworktrees never auto-swept (empirical); subagent/bg sweep would remove ignored-only worktrees (INFERRED — ignored ≠ untracked).--bgbase = 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.relevancesignal qualitysensitiveuserConfig storageBlast 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 -eover 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 foraudit scoring,
defaultEnabled-flip empirical check, matrix cell budget (64 KB body cap),nameimmutability 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.
OFFICIAL-DOCS.md, one CLAUDE.md row)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 initrepos under the scratchpad (its own branches/worktrees live there);FORBIDDEN every file and branch of THIS repo (note:
claude -p --worktree <name>creates branchesnamed
worktree-<name>— 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
("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).
worktree.baseRefnothonored): R1 degrades to documenting the limitation + the strongest honored scope in the
convention doc, and an upstream issue is filed; R2/R6 proceed unchanged.
sensitivestorage is plaintext: secret-bearinguserConfig migrations are excluded from the userConfig wave issue and recorded as blocked-upstream
in the epic; non-secret migrations proceed.
Execution shape ([EXEC-SHAPE] tagged)
docs/plugin-philosophy); PR B = Phases 4–5 (contract 2.0.0 wave; Phase 4 evidence rides thememory 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.
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
mainfor weeks. Each PRbranch 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 theupdated 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
sensitiveVERDICT is recordeddurably (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.)
sub-agent fanout otherwise) — D16 locks the fanout itself.
rather than a standalone verification phase.
Mechanical work
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).
(contract tests, markdownlint, drift check) green before each PR merge.
all fanout output.
/architect close-outat PR time — PLAN.md into PR description<details>, durableoutcomes graduate (vault_backend
docs), contract slice pruned with pointer.