From af5dc06babe424d128de93acbb2f97964e277075 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:01:47 -0400 Subject: [PATCH 01/12] docs: carry plugin-philosophy PLAN onto PR B branch Contract slice re-committed from the preserved working copy after the PR A prune; program log notes the #257 merge. Phases 1-4 DONE; Phase 5 (topic-docs 2.0.0 wave) executes on this branch. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/topics/plugin-philosophy/PLAN.md | 556 ++++++++++++++++++++++++++ 1 file changed, 556 insertions(+) create mode 100644 docs/topics/plugin-philosophy/PLAN.md diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md new file mode 100644 index 000000000..90e547776 --- /dev/null +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -0,0 +1,556 @@ +# plugin-philosophy + +## Brief + +### TLDR + +Extend the plugin doctrine to the full current component surface (13 component types, official docs +fetched 2026-07-17), lock a native-first principle with a maturity gate, fix the topic-docs two-tier +convention's visibility seams with native mechanisms, ship a complete official-doc link index, adopt +marketplace metadata maximally — then run a fanout conformance audit of all 47 plugins whose findings +graduate to tracker-managed remediation waves. + +### Goal + +Every plugin measurably conforms to an extended, freshness-guarded doctrine; no custom mechanism +exists where a fitting native one does; every cross-plugin convention has exactly one registered +owner doc; the remediation program lives on the work-item tracker where any session or machine can +resume it. + +### Locked decisions + +| # | Decision | +|---|---| +| D1 | Deliverable = doctrine revision + fleet-consistency audit, coupled in this one Brief. CI contract-gate automation deferred to follow-on (trigger: audit reveals automatable checks). | +| D2 | Doc-link index is a first-class deliverable: every plugin-relevant official doc page linked (components mapped to their doc pages); no undocumented component types. | +| D3 | Native-first principle: prefer built-in native mechanisms (userConfig, native component types, native lifecycle events) over custom extensibility points; custom only on genuine misfit, with the misfit documented. | +| D4 | Native-adoption gate (qualifies D3): adopt a native mechanism when it (1) fills a real existing gap, (2) is stable and works cleanly — experimental/immature features wait for maturity, (3) meets repo standards. Never custom-build what a fitting native mechanism covers. | +| D5 | Cross-plugin cooperation: hybrid. Native `dependencies` reserved for hard requires (plugin genuinely broken without collaborator) — none exist today; the `{name}--v{version}` git-tag release step lands with first use. Optional collaboration stays presence-gated with documented fallbacks; artifact protocol unchanged (data handoff, which dependencies don't cover). | +| D6 | Component stance table: skills = primary surface (new frontmatter — `paths`, `context: fork`, `arguments`, skill-scoped `hooks`/`once` — adopted case-by-case); `commands/` prohibited (officially legacy); agents, MCP, LSP, output styles, `bin/` = adopt-on-need (`bin/` requires collision-safe prefixed names; doctrine notes plugin agents ignore `hooks`/`mcpServers`/`permissionMode`); plugin `settings.json` `agent` (main-thread takeover) prohibited by default, exception needs documented justification; monitors, themes, channels = wait (experimental/immature), re-verified against current docs before each audit; dependencies per D5. Hooks addition: exec-form (`args`) mandatory wherever `${user_config.*}` appears (v2.1.207), else the `CLAUDE_PLUGIN_OPTION_` env mirror. | +| D7 | Freshness rider on all doctrine artifacts: every stance/inventory row carries a verified-date + link to its official doc page and an explicit disclaimer that the platform changes constantly — always re-fetch current docs before acting; never trust the repo file alone. | +| D8 | userConfig full-potential criterion: every personal/administrator scalar flowing through a custom channel (env-var toggle, gitignored personal file, documented hand-edit) migrates to userConfig using the full native schema — correct `type`, `default` preserving zero-config behavior, `required` only where truly blocking, `sensitive: true` for secrets, `claude plugin install --config` documented in each setup skill for headless use. Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK__ENABLED` toggles = flagship migration (userConfig booleans, `default: true`). | +| D9 | Setup doctrine v2: setup skill required iff (a) consumer-project config surface, (b) external prerequisites (CLI, service, credential), or (c) non-trivial userConfig — criteria applied through the modular/configurable/repo-/machine-/user-agnostic lens, never blanket ceremony; zero-config zero-prereq plugins exempt. Uniform contract: skill named `setup`, `disable-model-invocation: true`, `check` (read-only inspect/verify) + `apply` (idempotent configure) actions, complete-args non-interactive path. Formatter/linter plugins gain thin check-centric setups. Native `Setup` hook event = sanctioned headless/CI init surface; SessionStart + `${CLAUDE_PLUGIN_DATA}` manifest-diff = sanctioned runtime-dependency idiom. | +| D10 | Runtime-prerequisite visibility: anything with a runtime prereq (e.g. jq on PATH) degrades gracefully — never a hard crash; absence is surfaced to BOTH the agent and the user, with OTel as a candidate visibility channel; no black boxes. Extends the philosophy doc's "Prerequisites and failure behavior" section. | +| D11 | Convention registry: pointer-only section in PLUGIN-PHILOSOPHY.md — one owner doc per shared concern (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, artifact protocol, seam phrasing); registry names and points, never restates; audit rule = per-row conformance; a new convention lands in an owner doc before a second plugin adopts it. | +| D12 | Topic-docs tiers: keep the nature-based two-tier split and the `docs/topics/` name (contents are transient topic-scoped contract docs; `docs/specs/` is already the durable vault target — renaming would conflate tiers). | +| D13 | Two-tier seam fix package (all native): R1 `worktree.baseRef: "head"` in committed repo settings so worktree-isolated spawns carry task-branch state; R2 `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH — not baselines/raw scratch; one-way creation-time copy documented); R3 pointer discipline — durable surfaces (tickets, committed PLAN) never point at prunable or gitignored paths (decompose cites the PR, not the contract path; PLAN records distilled baseline values only); R4 isolated workers return results by value, the orchestrator writes both tiers in the parent checkout; R5 the work-item tracker is the cross-lane awareness/index layer (branch files stay lane-local; markdown-in-tickets as primary artifact store rejected — not diffable, drifts from code); R6 topic-docs convention doc corrected (worktree-visibility rationale, context×tier visibility matrix, mechanisms named) — a major contract version adopted by all implementers in one wave. | +| D14 | Doc-link index: dedicated `docs/OFFICIAL-DOCS.md` — complete categorized map of plugin-relevant official pages with a component→doc-page table, per-row verified-dates, the D7 staleness disclaimer, and `https://code.claude.com/docs/llms.txt` named as the authoritative self-updating master list. CLAUDE.md keeps its lean canonical table plus one pointer row to the index. | +| D15 | Marketplace metadata maximalism (machine-, user-, org-agnostic posture): populate every helpful-signal field — `relevance` signals wherever meaningful (audit criterion per plugin), `defaultEnabled: false` for personal/niche-category plugins, `displayName` where it genuinely clarifies, complete descriptive metadata. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + source declaration in managed settings). Hard rule: `version` lives in plugin.json only, never in marketplace entries (silent-precedence trap). | +| D16 | Audit execution: doctrine docs land first; then per-plugin subagent fanout scores all 47 plugins against a doctrine-derived checklist (~15 dimensions: setup criteria, userConfig migration, exec-form hooks, metadata completeness, component stances, registry conformance, prereq degradation, pointer discipline); findings distill into a plugin×dimension conformance matrix graduating to GitHub issues — one epic + per-wave issues (setup, userConfig, metadata, hooks, convention-seam waves) via the work-items seam; raw per-plugin detail stays memory-tier; automatable checks become the deferred CI gate's backlog. | + +### Constraints + +- Fresh-docs mandate applies at execution time: re-fetch the relevant official pages before each edit + wave; this Brief's doc facts were verified 2026-07-17. +- Work isolated in worktree, branch `docs/plugin-philosophy`; PRs required, squash merge, PR title + per Conventional Commits. +- Topic-docs convention change (D13/R6) is a major contract version; every implementer plugin adopts + in the same release wave (the contract carries no compatibility machinery). +- userConfig migrations preserve existing behavior via `default` values (guardrails toggles default + `true`). +- Every plugin change clears the migration playbook's gate + plugin-acceptance security review. + +### Acceptance criteria + +- PLUGIN-PHILOSOPHY.md revised: component stance table (D6) with D7 freshness riders, native-first + + adoption gate (D3/D4), convention registry (D11), config ownership updated (D8 criterion, exec-form + rule, version-placement rule), setup criteria (D9), prerequisite-visibility rule (D10). +- MIGRATION-PLAYBOOK.md updated consistently (setup contract, userConfig criterion, security review + touchpoints). +- `docs/OFFICIAL-DOCS.md` exists: complete categorized page map, component→doc table, verified-dates, + staleness disclaimer, llms.txt master pointer; CLAUDE.md carries the pointer row and stays lean. +- Topic-docs convention doc corrected per R6 with visibility matrix; R1 settings entry, R2 + `.worktreeinclude`, and R3 skill pointer fixes (decompose ticket provenance, architect baseline + recording) landed; the three flagged execution-time verifications resolved empirically and + recorded. +- marketplace.json metadata complete per D15; `claude plugin validate .` passes. +- Audit epic + wave issues filed on GitHub with the conformance matrix distilled into the epic; every + 47-plugin row scored; raw details in the memory slice. +- Existing CI (plugin contract tests, markdownlint) green on every PR. + +### Captured assumptions + +- Consumers run CC ≥ 2.1.207 (userConfig shell-form ban semantics, pluginConfigs scoping); older + clients degrade per official behavior, not worked around. +- Marketplace remains the melodic-software catalog but every decision holds machine-, user-, and + org-agnostic (no solo-consumer scoping). + +### Out-of-scope (deferred with triggers) + +- CI contract gate — trigger: audit identifies automatable checks (D16 backlog). +- Bundle plugin (name + dependencies curated set) — trigger: one-command curated install need beyond + the fleet-sync skill. +- Monitors, themes, channels adoption — trigger: feature exits experimental/immature status at a + future doc re-verification (D6 wait rows). +- `music` → `creative`, deployment category, and other plugin-organization deferrals remain owned by + that Brief. + +### Deferred questions + +- Windows `sensitive` userConfig storage behavior (docs silent on Windows keychain) — empirical + verification during audit, before any secret migrates. Arbiter: `/architect` (execution evidence). +- Worktree-sweep treatment of ignored files; `--bg` session worktree base semantics; + `worktree.baseRef` honored at project-settings scope — empirical smoke tests during D13 execution. + Arbiter: `/architect`. +- Per-plugin `relevance` signal quality (which signals are genuinely helpful vs noise) — decided + per-plugin during the metadata wave. Arbiter: `/architect`. + +## Plan + +> **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). Next: Phase 5 wave on this branch. + +Seven phases. Doctrine docs land first (D16 ordering), the topic-docs contract major version ships as +one wave, marketplace metadata follows, and the fleet audit runs last against the landed doctrine. +The fresh-docs mandate is embedded as the **first work item of every phase** that states platform +facts — never a standalone phase, never skipped. + +The three flagged empirical verifications resolve at their Brief-assigned execution points: +worktree-semantics smoke tests → Phase 4 (gates Phase 5 R1/R2); per-plugin `relevance` quality → +Phase 6 (per-plugin, during the metadata wave); Windows `sensitive` userConfig storage → Phase 7 +(before any userConfig-wave issue touching secrets is filed). + +### Phase 1: PLUGIN-PHILOSOPHY.md doctrine revision [DONE] + +Covers D3, D4, D6, D7, D8, D9, D10, D11. + +Work items: + +1. Fresh-fetch: `plugins`, `plugins-reference`, `skills`, `hooks`, `settings`, `plugin-dependencies` + pages; re-verify the 13 component types and the D6 stance facts (skill frontmatter additions, + `commands/` legacy status, `bin/` rules, agent field limitations, monitors/themes/channels + maturity, v2.1.207 exec-form rule). Any drift from the Brief's 2026-07-17 facts is recorded in + the memory slice and the stance table reflects current reality. The verified component-type + count (N, expected 13) is written to `.work/plugin-philosophy/component-count.txt` — Phases 1 + and 3 sanity checks assert against N, not a hard-coded 13. +2. Add **Native-first principle + adoption gate** section (D3/D4). +3. Add **Component stance table** (D6): 13 rows, each with stance, rationale, verified-date + + official-doc link (D7 rider), and the D7 staleness disclaimer heading the table. +4. Extend **Configuration ownership and scope**: D8 userConfig full-potential criterion (native + schema fields, `CLAUDE_PLUGIN_OPTION_` mirror, retirement of custom env channels), exec-form + hooks rule, version-placement rule (`version` in plugin.json only). +5. Rewrite **Setup is explicit and repeatable** to the D9 v2 criteria (required-iff conditions, + uniform `setup` skill contract, `Setup` hook event and SessionStart manifest-diff idioms). +6. Extend **Prerequisites and failure behavior** with D10 (graceful degradation, dual agent+user + visibility, OTel as candidate channel, no black boxes). +7. Add **Convention registry** section (D11): pointer-only table — one owner doc per shared concern + (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, + artifact protocol, seam phrasing); registry names and points, never restates. + +**Sanity Check:** + +- `grep -c "Verified 2026" docs/PLUGIN-PHILOSOPHY.md` ≥ N (one rider per stance row; N from + `component-count.txt`). +- `grep -n "Convention registry\|Native-first" docs/PLUGIN-PHILOSOPHY.md` returns both sections. +- Component stance table row count = N; Read confirms every verified component type named. +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.md` exit 0 (CI's + pinned action is authoritative; local run uses the repo config). + +### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [DONE] + +Depends on Phase 1 (doctrine wording is SSOT; playbook points, never restates). + +Work items: + +1. Update the per-plugin migration gate: setup-contract check (D9), userConfig criterion (D8), + exec-form hook rule — each as a pointer to the philosophy doc section plus playbook-specific + procedure only. +2. Extend the plugin-acceptance security review touchpoints: `sensitive` userConfig handling, + `bin/` collision-safe naming, plugin `settings.json` `agent` prohibition check. +3. Remove or redirect any playbook text that now duplicates Phase 1 doctrine (no restated stance + tables). + +**Sanity Check:** + +- `grep -n "PLUGIN-PHILOSOPHY" docs/MIGRATION-PLAYBOOK.md` shows pointer citations in the gate and + security-review sections. +- No restated stance table: no markdown table in MIGRATION-PLAYBOOK.md whose header row contains + both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. + +### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DONE] + +Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 +stance table. + +Work items: + +1. Fresh-fetch `https://code.claude.com/docs/llms.txt`; enumerate every plugin-relevant page. +2. Create `docs/OFFICIAL-DOCS.md`: categorized page map, component→doc-page table, per-row + verified-dates, D7 staleness disclaimer, llms.txt named as the authoritative self-updating + master list. +3. Add one pointer row to CLAUDE.md's canonical table; CLAUDE.md stays lean (no other growth). +4. **Wave A join step (main session):** reconcile the component→doc table against Phase 1's + verified component list (`component-count.txt` + stance table) before PR A — parallel work off + the Brief snapshot must converge on Phase 1's fresh-fetched reality. + +**Sanity Check:** + +- `test -f docs/OFFICIAL-DOCS.md` && component table has N rows (N from `component-count.txt`). +- `grep -n "llms.txt" docs/OFFICIAL-DOCS.md` and `grep -n "OFFICIAL-DOCS" CLAUDE.md` both hit. +- CLAUDE.md diff = exactly one added table row: `git diff origin/main...HEAD --stat -- CLAUDE.md` + shows a 1-2 line delta. +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/OFFICIAL-DOCS.md` exit 0; the + repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory + weekly — spot-check a sample of new URLs via WebFetch instead). + +### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DONE] + +Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe +with Phases 1–3 (touches scratchpad + throwaway worktrees only). + +All tests run in a **throwaway `git init` repo in the scratchpad with a synthetic `origin`** — +never in this repo (its ~30 live worktrees, runtime-written `.git/info/exclude`, and main checkout +on a feature branch confound every measurement). Use `claude -p --worktree` exclusively (skips the +trust dialog; interactive mode errors in a fresh repo). Unique worktree names per run (name reuse +resets clean worktrees to base since v2.1.208); the spike removes its own worktrees +(`-p`-created worktrees are never auto-cleaned; Windows: expect NTFS lock retries, +`git worktree remove --force`). + +Work items: + +1. Fresh-fetch the `worktrees` doc (the doc anchor for `baseRef`/`.worktreeinclude` — not the + settings page) plus `settings`; record cited behavior, including the documented fallback + "when `origin/HEAD` isn't resolvable, worktrees fall back to current local HEAD". +2. Smoke test A — `worktree.baseRef: "head"` at **project-settings scope**, two arms: **control** + (`baseRef` unset or `"fresh"`) asserts marker ABSENT; **treatment** (`baseRef: "head"` in + committed `.claude/settings.json`) asserts marker PRESENT. Verdict HONORED only if BOTH arms + behave — a marker-present-only test is defeated by the documented origin/HEAD fallback (false + positive). Variant A2: spawn from within an existing linked worktree (docs state `head` resolves + to that worktree's HEAD — test against that expected value). Variant A3: `settings.json` present + only in the worktree checkout vs only in the main checkout — pins which copy a linked-worktree + session reads (undocumented; only `settings.local.json` is documented as main-checkout-resolved). +3. Smoke test B — `.worktreeinclude` one-way creation-time copy: use real nested-gitignore paths + (`.work//…` ignored via a nested `*` `.gitignore`, mirroring this repo) — not a toy + root-level pattern; assert copy at creation; modify original, assert no sync-back. +4. Smoke test C — worktree-sweep treatment of ignored files (genuinely undocumented — this test is + the only source of truth; capture `git status --ignored` snapshots in the raw transcript) + + `--bg` session worktree base semantics. +5. The sub-agent records raw transcripts in `.work/plugin-philosophy/verifications/`, stamps every + VERDICT file with `claude --version`, and **returns the VERDICT lines by value**; the **main + session** fills the pending rows in this PLAN's "Empirical verification results" table (PLAN.md + edits stay main-session-only) and feeds them into Phase 5's R1/R2 design. If the CC version has + moved by the Phase 5 gate, re-run the cheap test-A control/treatment pair. + +**Sanity Check:** + +- `.work/plugin-philosophy/verifications/` contains ≥ 3 result files, one per smoke test, each + ending in a one-line VERDICT (`HONORED` / `NOT-HONORED` / behavior description) and a + `claude --version` stamp line. +- Test A result file contains BOTH `control:` and `treatment:` lines with opposite marker outcomes + (else verdict is invalid by construction). +- This PLAN's "Empirical verification results" table row 1 is filled (no `(pending)`). + +### Phase 5: Topic-docs contract 2.0.0 + seam fixes R1–R6 (one wave) [TODO] + +Covers D13. Contract-major change: every implementer adopts in the same wave (no compatibility +machinery). Gated by Phase 4 verdicts. + +Work items: + +1. **Pre-flight consumer check (first item):** `Grep`/`Glob` for every consumer parsing the + convention surface — `.claude/topic-docs.yaml` keys, slug spec, tier paths, runtime guards, the + `scripts/check-cross-plugin-source-drift.sh` registry, hooks reading `docs/topics/` or `.work/`. + Document parse paths in the memory slice before editing anything. +2. R6 — rewrite `docs/conventions/topic-docs/README.md`: worktree-visibility rationale, context × + tier visibility matrix, native mechanisms named (`worktree.baseRef`, `.worktreeinclude`, by-value + returns, tracker index); CHANGELOG entry `2.0.0`; schema untouched unless a key changes (KEEP + expected). **Reconcile the Implementers table with reality**: `toolchain` and `verification` + carry `reference/topic-docs.md` but are absent from the table; `knowledge`, `claude-ops`, + `docs-hygiene` are listed without delta docs — the 2.0.0 table must match the actual fleet + (add/annotate rows or document why a row is delta-doc-free). The CHANGELOG 2.0.0 entry states + the **mixed-fleet window** and why it is safe (no tier/key/slug-spec change — installed cache + copies and in-flight branches keep 1.x text until they update; divergence is doctrinal, not + layout-corrupting), and notes a post-PR-B stale-text sweep obligation for in-flight branches at + their merge time. +3. R1 — committed `.claude/settings.json` with `worktree.baseRef: "head"` (shape per Phase 4 smoke + test A verdict; if NOT-HONORED at project scope, execute the tagged fallback below). Rollout + note in the PR B description + convention doc: a clone with an existing untracked + `.claude/settings.json` hits "untracked working tree file would be overwritten" on pull — + document the remedy; state the repo-wide worktree-spawn behavior change; **gitignore + `.claude/worktrees/` in the same change** (mandatory — the runtime `.git/info/exclude` entry is + machine-local; CI checkouts and fresh clones lack it, and partial tracking of `.claude/` + otherwise turns nested worktrees into `git add -A` hazards); run the hygiene CI lanes + (machine-specific-paths, gitleaks, editorconfig) locally on the new tracked file. Document the + escape hatch: a personal `.claude/settings.local.json` (main-checkout-resolved, covers every + worktree) silently overrides R1 machine-wide — the convention doc states this; no audit + dimension may assume R1 is universally in force. + **Consumer-adoption path (mandatory):** repo settings never travel with marketplace-installed + plugins (isolated cache) — R1/R2 as files fix only this repo. The 2.0.0 doc ships a + consumer-adoption section: the settings snippet + a `.worktreeinclude` template, scoped as + "authoring-repo materialization; consumer repos self-apply" (routing it through a D9 setup-skill + `apply` action is recorded as a follow-on trigger, not built now). The visibility matrix gains a + caveat row: a `WorktreeCreate` hook makes `.worktreeinclude` inert (documented) — hook script + owns the copy. +4. R2 — `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH; not + baselines/raw scratch); one-way creation-time copy documented in the convention doc. +5. R3 — pointer-discipline fixes: `plugins/work-items/skills/decompose` cites the PR (not contract + paths) in ticket provenance; `plugins/planning/skills/architect` records distilled baseline + values in PLAN (raw captures stay memory-tier). Sweep both skill bodies for prunable-path + citations. +6. R4/R5 — convention doc text: isolated workers return results by value with the orchestrator + writing both tiers in the parent checkout (R4); the work-item tracker named as the cross-lane + awareness/index layer, markdown-in-tickets rejected with rationale (R5). +7. Implementer wave: update all 8 `plugins/*/reference/topic-docs.md` delta docs against the 2.0.0 + owner doc; bump each touched plugin's `plugin.json` semver + CHANGELOG; docs-hygiene declutter + detector references checked (reader row). + +File inventory (checkbox discipline — tick as processed): + +| File | Action | Rationale | +|---|---|---| +| [ ] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | +| [ ] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | +| [ ] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes expected | +| [ ] `docs/conventions/topic-docs/examples/*` | AUDIT | update only if matrix/mechanisms change examples | +| [ ] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | +| [ ] `.worktreeinclude` | CREATE | R2 patterns | +| [ ] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | +| [ ] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | +| [ ] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | +| [ ] 8–10 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | semver bump per touched plugin | +| [ ] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | implementer-table rows without delta docs — verify no stale convention text | + +**Sanity Check:** + +- `bash scripts/check-cross-plugin-source-drift.sh --check` exit 0 (the flag CI runs; flagless mode + is informational only). +- `grep -n "2.0.0" docs/conventions/topic-docs/CHANGELOG.md` hits; `grep -rn "visibility matrix" -i + docs/conventions/topic-docs/README.md` hits. +- Implementers-table parity: every `plugins/*/reference/topic-docs.md` path has a matching table + row and vice versa (Read assertion against the glob result). +- Pre-flight consumer list exists: `.work/plugin-philosophy/consumers-topic-docs.md` non-empty. +- Every plugin with a modified file has a `plugin.json` version bump: + `git diff origin/main...HEAD --name-only | grep '^plugins/' | cut -d/ -f2 | sort -u` each has a + matching `plugins//plugin.json` in the diff. +- `bash scripts/validate-plugins.sh` exit 0 (includes `generate-catalog.mjs --check` — regenerate + the catalog if any plugin.json description changed). +- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc` on touched .md files exit 0. + +### Phase 6: Marketplace metadata wave [TODO] + +Covers D15 + per-plugin `relevance` quality verification (deferred question c). + +Work items: + +1. Fresh-fetch `plugin-marketplaces` + `discover-plugins` + `plugins-reference` + (default-enablement section) + the dedicated `plugin-relevance` page; re-verify entry schema + (`relevance`, `defaultEnabled`, `displayName`, description precedence, `version` + silent-precedence trap). **`defaultEnabled` flip semantics for already-installed consumers are + undocumented** — if the fetched pages stay silent, run a 2-minute empirical flip on one plugin + before the wave (does a marketplace refresh disable an existing install?). Never touch a + plugin's `name` (breaks existing installs without a `renames` map); `displayName` is safe. +2. Per-plugin pass over all 47 entries: add `relevance` only where the signal is genuinely helpful + (judged per-plugin — noise rejected), `defaultEnabled: false` for personal/niche categories, + `displayName` where it clarifies, complete descriptions; assert **no `version` field in any + entry**. +3. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + + managed-settings source declaration) — lands in the discover/consumer section of README or + OFFICIAL-DOCS per where consumer docs live (decided at execution against the fetched page). +4. Record per-plugin relevance decisions (adopted vs rejected-as-noise) in + `.work/plugin-philosophy/relevance-decisions.md`. +5. Regenerate the README catalog: `node scripts/generate-catalog.mjs` (CI runs `--check`; metadata + edits drift the generated block otherwise). + +**Sanity Check:** + +- `claude plugin validate .` exit 0. +- `node scripts/generate-catalog.mjs --check` exit 0. +- `node -e` assertion: 47 entries; every entry resolves a description (entry or plugin.json); + `version` absent from all entries — exit 0. +- `.work/plugin-philosophy/relevance-decisions.md` has 47 rows. + +### Phase 7: Fleet conformance audit fanout + tracker graduation [TODO] + +Covers D16. Runs against merged doctrine (Phases 1–6 landed). + +Work items: + +1. **Search-before-create (first item):** `gh issue list --search` for an existing + plugin-conformance epic / wave issues. Match found → pivot to updating the existing items + (record the match + pivot in the memory slice); no match → proceed to create. Verify required + labels exist (`gh label list`) and create missing ones before any `gh issue create --label` + call (missing labels fail the create). +2. Derive the audit checklist (~15 dimensions) from the landed doctrine docs: setup criteria (D9), + userConfig migration (D8), exec-form hooks, metadata completeness (D15), component stances (D6), + registry conformance (D11), prereq degradation (D10), pointer discipline (R3), freshness riders + (D7), plus dimensions the doctrine text yields. **Freeze a rubric file** with per-dimension + anchored PASS/FAIL criteria + one worked example, injected verbatim into every worker prompt + (uncalibrated independent scoring across batches encodes rubric drift, not conformance). + **Authority rule:** plugins are scored against **landed doctrine only**; where a fresh-fetched + doc disagrees with doctrine, that is a doctrine-update finding (its own wave), never plugin + nonconformance. Dimensions may not assume R1 is universally in force (local-settings override + exists). Checklist + rubric → memory slice. +3. Fresh-fetch the component doc pages the checklist cites (to detect doctrine-vs-platform drift + per the authority rule above). +4. **Windows `sensitive` userConfig empirical verification** (deferred question a): configure a + throwaway `sensitive` userConfig value on this Windows machine; locate where it persists + (Credential Manager vs plaintext file); VERDICT recorded before any userConfig wave issue + involving secrets is filed. Secrets excluded from that wave if storage is plaintext (tagged + fallback below). +5. Fanout: **pilot batch of 3–5 plugins first**, reviewed by the main session against the rubric + before full fanout; then per-plugin subagents score the remainder in **batches of 8–10**; each + worker writes its own raw report to `.work/plugin-philosophy/audit/.md` (memory-tier + raw output is carved out of R4 — R4's orchestrator-writes rule governs contract/durable tiers) + and returns only its scored dimension row by value; the orchestrator (main session) appends + matrix rows incrementally per batch, so a compaction mid-run loses nothing. **Double-score a + random 3-plugin sample** with independent workers and reconcile disagreements before graduating + the matrix. +6. File the GitHub epic (conformance matrix distilled inline — **single-token score cells only**, + prose lives in per-wave issues; GitHub bodies cap near 64 KB) + per-wave issues (setup, + userConfig, metadata, hooks, convention-seam) via the work-items seam; issues cite the epic + PR + permalinks, never contract/memory paths (R3). Automatable checks list → epic section = deferred + CI gate backlog (D1 trigger). + +**Sanity Check:** + +- Search outcome recorded: `.work/plugin-philosophy/audit/tracker-search.md` states the query + hit + count + create-vs-update decision. +- `ls .work/plugin-philosophy/audit/*.md | wc -l` ≥ 47 (one report per plugin) + matrix file with + 47 scored rows. +- `gh issue list --label epic --search "plugin conformance"` (or equivalent) returns the epic; + epic body contains the matrix; ≥ 5 wave issues reference the epic. +- `grep -c "docs/topics/\|\.work/" ` = 0 (pointer discipline). +- Windows `sensitive` VERDICT file exists in `.work/plugin-philosophy/verifications/`. + +### Empirical verification results + +| # | Question | Phase | VERDICT | +|---|---|---|---| +| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | HONORED (CC 2.1.212, control+treatment): committed project `.claude/settings.json` `worktree.baseRef: "head"` honored, incl. from linked worktrees (A2: resolves to the worktree's own HEAD; A3: a linked-worktree session reads its OWN checkout's settings.json). `.worktreeinclude`: nested-gitignored files qualify, copy is one-way creation-time. Sweep: `--worktree` worktrees never auto-swept (empirical); subagent/bg sweep would remove ignored-only worktrees (INFERRED — ignored ≠ untracked). `--bg` base = origin/HEAD by default, so R1 moves it to local HEAD. Windows caveat: deep worktree base paths can trip git PATH_MAX (`'$GIT_DIR' too big`); this repo's base (~95 chars) is safe. | +| 2 | Per-plugin `relevance` signal quality | 6 | (pending — per-plugin ledger) | +| 3 | Windows `sensitive` userConfig storage | 7 | (pending) | + +## Blast radius + +**HIGH.** Matches stress-test triggers: new conventions constraining all future work (doctrine + +contract-major), architecture decisions across 47 plugins + 8 implementer materializations, shared +committed settings (`.claude/settings.json`) affecting every session, and undocumented behavior +(worktree semantics, Windows sensitive storage — mitigated by the empirical phases). Reversible via +git revert (docs/metadata only, no runtime code), and existing CI (contract tests, markdownlint, +drift check) gates every PR — hence HIGH, not CRITICAL. + +## Stress-test summary + +Two fresh-context adversarial passes ran; all findings verified against the repo before adoption. + +**Plan-reviewer (Step 3):** 9 IMPORTANT + 5 SUGGESTION, 0 CRITICAL — all applied: implementer-roster +reconciliation + parity check (Phase 5), CI-parity sanity commands (drift `--check`, catalog +`--check`, markdownlint config, `node -e` over Python), pointer-vs-restate check made structural +(Phase 2), Phase 4 by-value/fence contradiction resolved, component-count made variable with a +Wave A join step, PR-chain PLAN lifecycle defined, Phase 7 batching + label verify-or-create, +worktree-variant smoke tests, R1 rollout notes. + +**Devils-advocate (Step 4):** 16 assumptions attacked; 4 mandatory changes, all applied: +(1) Phase 4 redesigned — isolated scratch repo with synthetic origin, control+treatment arms +(defeats the documented origin/HEAD-fallback false positive), settings-scope variant A3, +CC-version-stamped verdicts with re-run at the Phase 5 gate; (2) PLAN lifecycle switched to +branch-local prune-per-PR (the program must not self-violate the contract it ships); (3) 2.0.0 doc +gains a consumer-adoption path — repo settings provably never reach marketplace-installed +consumers; (4) Phase 7 calibration — frozen anchored rubric, pilot batch, double-scored sample. +Also adopted: mandatory `.claude/worktrees/` gitignore in PR B, `WorktreeCreate`-hook caveat for +`.worktreeinclude`, mixed-fleet window statement in the CHANGELOG, doctrine-wins authority rule for +audit scoring, `defaultEnabled`-flip empirical check, matrix cell budget (64 KB body cap), `name` +immutability during the metadata wave. One finding escalated to a user gate: R6 major-vs-minor +contradiction with the contract's own versioning rule (see User-approval gates). + +## Execution shape + +Two parallel-safe waves inside an otherwise sequential PR chain; fanout inside Phase 7. + +| Phase | Surface | Basis | +|---|---|---| +| 1 | Main session | Judgment-heavy doctrine writing; SSOT wording others depend on | +| 2 | Main session | Depends on Phase 1 wording; pointer discipline needs judgment | +| 3 | Sub-agent worker (parallel with 1–2) | Mechanical index build from llms.txt; disjoint files (`OFFICIAL-DOCS.md`, one CLAUDE.md row) | +| 4 | Sub-agent worker (parallel with 1–3) | Scripted smoke tests; touches scratch/throwaway worktrees only | +| 5 | Main session (implementer sweep may fan out mechanically) | Contract-major judgment; 25-file wave needs single editorial voice | +| 6 | Main session | Single file; 47 per-plugin relevance judgments | +| 7 | Workflow/sub-agent fanout, orchestrated by main session | D16-locked fanout; R4 by-value returns | + +Wave A (parallel): Phase 1 (main) ∥ Phase 3 (sub-agent) ∥ Phase 4 (sub-agent). Zero file overlap: +P1 = `docs/PLUGIN-PHILOSOPHY.md`; P3 = `docs/OFFICIAL-DOCS.md` + CLAUDE.md; P4 = `.work/` + scratch. +Wave B (sequential): Phase 2 → Phase 5 → Phase 6 → Phase 7. + +Scope fences (Wave A): P3 agent ALLOWED `docs/OFFICIAL-DOCS.md`, `CLAUDE.md` (one row); +FORBIDDEN everything else incl. PLAN.md. P4 agent ALLOWED `.work/plugin-philosophy/verifications/` +and throwaway `git init` repos under the scratchpad (its own branches/worktrees live there); +FORBIDDEN every file and branch of THIS repo (note: `claude -p --worktree ` creates branches +named `worktree-` — another reason the spike never runs in this repo). +Sequential fallback: any fence violation or agent failure → that phase re-runs inline main-session +in Wave B order. PLAN.md edits are main-session-only. + +Cost note: Wave A = 2 extra agents vs sequential (~saves one serial doc-build + smoke-test round); +Phase 7 = ~47 scoring agents (D16-locked, run regardless of shape). + +## Open questions + +None blocking — the three empirical questions are scheduled inside phases with tagged fallbacks. + +## Handoff to implementation + +### User-approval gates + +- **[BRIEF CONTRADICTION — user decision required]** D13 locks R6 as a **major** contract version + ("2.0.0, one wave"), but the contract's own Versioning rule says major = "moves a tier, renames a + key, or alters the slug spec" — R6 does none (schema KEEP; the change is visibility semantics + + doctrine text). Options: (a) keep 2.0.0 and amend the Versioning rule so visibility-semantics + guarantees also count as major (the doctrine repo then applies its own rule consistently); + (b) downgrade to a 1.x minor, dissolving the one-wave coordination burden and most of Phase 5's + mixed-fleet risk. RECOMMENDED: (a) — the Brief locked the one-wave clean break deliberately, and + a visibility-guarantee change does alter what implementers may rely on; the rule amendment makes + the label honest. The plan as written assumes (a). +- [FALLBACK — confirm or override] Smoke test A fails (project-scope `worktree.baseRef` not + honored): R1 degrades to documenting the limitation + the strongest honored scope in the + convention doc, and an upstream issue is filed; R2/R6 proceed unchanged. +- [FALLBACK — confirm or override] Windows `sensitive` storage is plaintext: secret-bearing + userConfig migrations are excluded from the userConfig wave issue and recorded as blocked-upstream + in the epic; non-secret migrations proceed. +- Scope-expansion of any kind (new convention, new component adoption) mid-flight → stop and ask. + +### Execution shape ([EXEC-SHAPE] tagged) + +- [EXEC-SHAPE] PR slicing: PR A = Phases 1–3 (doctrine + index, current branch + `docs/plugin-philosophy`); PR B = Phases 4–5 (contract 2.0.0 wave; Phase 4 evidence rides the + memory tier, distilled results in PLAN); PR C = Phase 6 (metadata); PR D = close-out (Phase 7's + PLAN/verdict updates + prune-with-pointer). Rationale: reviewability + distinct concerns + (doctrine vs contract-major vs metadata); each PR independently green on existing CI. +- [EXEC-SHAPE] PLAN.md lifecycle across the PR chain — **branch-local, prune-per-PR**: the + topic-docs contract says contract slices are pruned before merge, and this program (which ships + that very contract's 2.0.0) must not self-violate by parking a slice on `main` for weeks. Each PR + branch commits the current PLAN, pastes it into its PR description, and prunes the slice in a + final commit before merge; the next PR branch (cut from post-squash `main`) re-commits the + updated PLAN from the local working tree. Cross-PR continuity = the PR-description pastes + (from + Phase 7) the epic. Close-out at PR D: Phase 7's verdict rows and final status tags commit there, + durable outcomes graduate, final prune-with-pointer. The Windows `sensitive` VERDICT is recorded + durably (PLAN verdict table → PR D description + epic), not only in gitignored `.work/`. + (Alternative rejected: adding a multi-PR-program exception clause to the 2.0.0 lifecycle text — + viable, but it lands only in PR B while PR A would already need it; override at approval if the + exception clause is preferred.) +- [EXEC-SHAPE] Wave A parallelism + fences as tabled above. +- [EXEC-SHAPE] Phase 7 fanout surface: per-plugin subagents (Workflow engine if available, plain + sub-agent fanout otherwise) — D16 locks the fanout itself. +- [EXEC-SHAPE] Empirical verifications embedded at Brief-assigned execution points (P4/P6/P7) + rather than a standalone verification phase. + +### Mechanical work + +- Commit boundaries: one commit per phase minimum; Phase 5 = one wave commit for the contract bump + + implementer adoption (clean break lands atomically); PLAN.md status-tag updates ride each phase's + commit. Each PR branch is cut from **post-squash `main`**, never from the previous PR branch + (stacking would replay the prior PR's squashed commits in the diff). +- Verification checkpoints: run each phase's Sanity Check before its commit; existing CI + (contract tests, markdownlint, drift check) green before each PR merge. +- Sequential fallback: documented under Execution shape; orchestrator-writes rule (R4) applies to + all fanout output. +- Close-out: `/architect close-out` at PR time — PLAN.md into PR description `
`, durable + outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. From ed9995aecc8b0e5512be650a4558bf00d754d7cf Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:23:50 -0400 Subject: [PATCH 02/12] =?UTF-8?q?docs(topic-docs):=20ship=20contract=202.0?= =?UTF-8?q?.0=20=E2=80=94=20visibility=20guarantees=20+=20seam=20fixes=20R?= =?UTF-8?q?1-R6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One-wave contract-major adoption per the plugin-philosophy program (Phase 5): - R6: owner doc gains a normative "Visibility across execution contexts" section — context × tier visibility matrix, the four native mechanisms (worktree.baseRef "head", .worktreeinclude, by-value worker returns, tracker as cross-lane index), WorktreeCreate-hook caveat, settings.local.json override escape hatch, pointer discipline on durable surfaces, and a consumer-adoption section. Versioning rule amended so a visibility-guarantee change counts as major. Implementers table reconciled with the fleet (verification + toolchain rows added; Binding column; manifest/baselines moved to the verification row). - R1: committed .claude/settings.json with worktree.baseRef "head" (verified honored at project scope, CC 2.1.212) + .claude/worktrees/ gitignored. - R2: .worktreeinclude carrying stage ledgers and EXPLORE/RESEARCH. - R3: decompose ticket provenance cites the PR, not the prunable contract-slice path; architect baseline step records distilled values only in PLAN.md. - 8 delta docs adopt 2.0.0; each touched plugin gets a minor version bump + CHANGELOG entry. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- .claude/settings.json | 5 + .gitignore | 1 + .worktreeinclude | 7 + docs/conventions/topic-docs/CHANGELOG.md | 38 +++++ docs/conventions/topic-docs/README.md | 152 ++++++++++++++++-- docs/topics/plugin-philosophy/PLAN.md | 44 ++--- plugins/discovery/.claude-plugin/plugin.json | 2 +- plugins/discovery/CHANGELOG.md | 9 ++ plugins/discovery/reference/topic-docs.md | 8 + .../implementation/.claude-plugin/plugin.json | 2 +- plugins/implementation/CHANGELOG.md | 8 + .../implementation/reference/topic-docs.md | 6 +- plugins/planning/.claude-plugin/plugin.json | 2 +- plugins/planning/CHANGELOG.md | 9 ++ plugins/planning/reference/topic-docs.md | 5 + plugins/planning/skills/architect/SKILL.md | 2 +- plugins/review/.claude-plugin/plugin.json | 2 +- plugins/review/CHANGELOG.md | 8 + plugins/review/reference/topic-docs.md | 5 +- .../session-flow/.claude-plugin/plugin.json | 2 +- plugins/session-flow/CHANGELOG.md | 9 ++ plugins/session-flow/reference/topic-docs.md | 5 + plugins/toolchain/.claude-plugin/plugin.json | 2 +- plugins/toolchain/CHANGELOG.md | 9 ++ plugins/toolchain/reference/topic-docs.md | 5 + .../verification/.claude-plugin/plugin.json | 2 +- plugins/verification/CHANGELOG.md | 8 + plugins/verification/reference/topic-docs.md | 5 + plugins/work-items/.claude-plugin/plugin.json | 2 +- plugins/work-items/CHANGELOG.md | 9 ++ plugins/work-items/reference/topic-docs.md | 6 + plugins/work-items/skills/decompose/SKILL.md | 4 +- 32 files changed, 336 insertions(+), 47 deletions(-) create mode 100644 .claude/settings.json create mode 100644 .worktreeinclude diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..75384642d --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "worktree": { + "baseRef": "head" + } +} diff --git a/.gitignore b/.gitignore index a4b61d20b..cba6deaa0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ Thumbs.db # Local-only Claude Code state .claude/settings.local.json .claude/observability/ +.claude/worktrees/ CLAUDE.local.md # Test-result artifacts (Pester runner output) diff --git a/.worktreeinclude b/.worktreeinclude new file mode 100644 index 000000000..97a6f86d2 --- /dev/null +++ b/.worktreeinclude @@ -0,0 +1,7 @@ +# Memory-tier files worth carrying into new worktrees (one-way, creation-time +# copy; gitignored-only). Never baselines or raw scratch — machine-bound. +.work/*/EXPLORE.md +.work/*/EXPLORE-*.md +.work/*/RESEARCH.md +.work/*/RESEARCH-*.md +.work/*/*-checklist.md diff --git a/docs/conventions/topic-docs/CHANGELOG.md b/docs/conventions/topic-docs/CHANGELOG.md index a9fc81d9d..ce2976ae8 100644 --- a/docs/conventions/topic-docs/CHANGELOG.md +++ b/docs/conventions/topic-docs/CHANGELOG.md @@ -1,5 +1,43 @@ # Changelog — topic-docs convention +## 2.0.0 — 2026-07-17 + +Visibility semantics are now normative contract guarantees. No tier moves, no +`topic-docs.yaml` key changes, no slug-spec changes — the schema is untouched. +The Versioning rule now counts a visibility-guarantee change as major; this +release is the first such change, and the rule amendment is what makes the +major label honest. + +- **Visibility across execution contexts** (new, normative): context × tier + visibility matrix; four native mechanisms — `worktree.baseRef: "head"` in + committed project settings (verified honored at project scope on CC 2.1.212, + including from linked worktrees), `.worktreeinclude` one-way creation-time + copy of gitignored memory files, by-value worker returns with the + orchestrator writing contract/durable tiers in the parent checkout, and the + work-item tracker as the cross-lane index (markdown-in-tickets as a primary + artifact store rejected: not diffable, no review gate, drifts from code). + Caveats documented: a `WorktreeCreate` hook makes `.worktreeinclude` inert; + a personal `.claude/settings.local.json` silently overrides the committed + `baseRef` machine-wide, so nothing may assume it universally in force. +- **Pointer discipline on durable surfaces** (new, normative): tickets, PR + bodies, and promoted docs never cite prunable contract paths or gitignored + memory paths — cite the PR, the promoted location, or distilled values. +- **Consumer adoption**: settings + `.worktreeinclude` templates; repository + files never travel with marketplace-installed plugins, so consuming repos + self-apply; rollout caveats (untracked-settings pull collision, Windows + worktree path limit). +- **Implementers table reconciled with the fleet**: verification and toolchain + rows added; a Binding column distinguishes delta-doc implementers from + adopt-by-reference rows (knowledge, claude-ops, docs-hygiene) with the + reason each needs no delta doc; the verification manifest and baselines + moved from the implementation row to the new verification row, matching the + plugins' actual bindings. + +Mixed-fleet window: installed plugin caches and in-flight branches keep 1.x +text until they update. Safe because no tier, key, or slug-spec changed — +divergence is doctrinal, never layout-corrupting. In-flight branches sweep +stale visibility text when they merge. + ## 1.0.1 — 2026-07-15 - Reserve `vault_backend: gitbook` without enabling writes: concern files preserve the key, skills diff --git a/docs/conventions/topic-docs/README.md b/docs/conventions/topic-docs/README.md index 923798036..c9ec44829 100644 --- a/docs/conventions/topic-docs/README.md +++ b/docs/conventions/topic-docs/README.md @@ -55,6 +55,120 @@ Every fact has exactly one home. Any other surface — a handoff, a summary, a map, a PR body — may only *reference* it (path, URL, or context pointer), never restate it. An index is not a store. +## Visibility across execution contexts + +Tier placement decides more than git hygiene: it decides **which +execution contexts can see a document at all**. A linked worktree, a +subagent worktree, a background session, and a cloud clone each +materialize a different slice of the repository, so a document's tier is +also its visibility guarantee. This section is normative — a change to +what a context may rely on seeing is a **major** contract change (see +Versioning). + +### Context × tier visibility matrix + +The worktree rows assume the consuming repo materializes both native +mechanisms below (`worktree.baseRef: "head"` and `.worktreeinclude`); +without them, every spawned worktree behaves as the default-base row. + +| Context | Memory `//` | Contract `//` (branch tier) | Durable (vault backend) | Machine state (`${CLAUDE_PLUGIN_DATA}`) | +|---|---|---|---|---| +| Writing checkout (same session or another session in it) | visible | visible, including uncommitted edits | visible | visible | +| Worktree spawned from local HEAD (`worktree.baseRef: "head"`) | invisible, except `.worktreeinclude`-carried patterns (one-way copy at creation time) | committed state visible; uncommitted edits invisible | visible | visible (machine-global) | +| Worktree spawned from the default base (`origin/HEAD`) | invisible, except `.worktreeinclude`-carried patterns | invisible — task-branch commits absent | merged state only | visible | +| Sibling lane (worktree on another branch) | invisible | invisible | merged state only | visible | +| Cloud clone / CI checkout | invisible | pushed commits only | pushed state only | invisible | + +Two consequences drive the rules below: a contract document is visible +to an isolated context only as **committed** state (commit plan updates +with their phase — the lifecycle already requires this), and a memory +document is visible **only in the checkout that wrote it** unless a +`.worktreeinclude` pattern carries it. + +### Native mechanisms + +Four native mechanisms, no custom machinery: + +- **`worktree.baseRef: "head"`** — committed project + `.claude/settings.json`. Spawned worktrees (including subagent + worktrees) branch from local `HEAD` instead of `origin/HEAD`, so they + carry the task branch's contract commits. Verified honored at + project-settings scope on CC 2.1.212, including from linked worktrees + (a linked-worktree session reads its *own* checkout's + `.claude/settings.json`, and `"head"` resolves to that worktree's + `HEAD`). Escape hatch: a personal `.claude/settings.local.json` + (resolved to the main checkout, covering every worktree) silently + overrides this machine-wide — no skill, gate, or audit may assume the + setting is universally in force. +- **`.worktreeinclude`** — repository root, `.gitignore` syntax; only + files that match a pattern *and* are gitignored are copied. The copy + is **one-way at worktree-creation time**: later edits sync in neither + direction, so carried files are read-only context, never a channel. + Carry cross-checkout-useful memory files (stage ledgers, + `EXPLORE.md` / `RESEARCH.md`); never baselines or raw scratch + (machine-bound). Caveat: a `WorktreeCreate` hook replaces the default + worktree creation entirely and `.worktreeinclude` is **not + processed** — the hook script owns any copying. +- **By-value returns** — an isolated worker (subagent worktree, + background session, dispatched fanout) returns its results **by + value**; the orchestrating session writes the contract and durable + tiers in the parent checkout. Workers never write those tiers from an + isolated checkout — commits and promotions land where the lifecycle + can see them. Raw per-worker output may land directly in the parent + checkout's memory slice when the orchestrator directs it there. +- **Tracker as the cross-lane index** — the work-item tracker is the + awareness layer across lanes: branch files stay lane-local, and a + session in another lane discovers state through tickets, which point + (PR URLs, promoted-doc locations) per the single-home rule. + Markdown-in-tickets as a primary artifact store is rejected: ticket + bodies are not diffable, carry no review gate, and drift from code. + +### Pointer discipline on durable surfaces + +Durable surfaces — tickets, PR bodies, promoted docs — never point at +prunable or gitignored paths. The contract slice is deleted before +merge and the memory slice never leaves its checkout, so such pointers +dangle by design. Cite the PR, the promoted location, or distilled +values instead: a ticket sourced from a plan records the PR that +carried the plan, and a plan records distilled baseline numbers, never +the memory-slice path of the raw capture. + +### Consumer adoption + +Repository settings and root files never travel with +marketplace-installed plugins (plugins run from an isolated cache), so +each consuming repository materializes the two files itself: + +```json +{ + "worktree": { + "baseRef": "head" + } +} +``` + +as committed `.claude/settings.json`, and a `.worktreeinclude` at the +repository root (substitute a non-default resolved `memory_dir` for +`.work`): + +```text +.work/*/EXPLORE.md +.work/*/EXPLORE-*.md +.work/*/RESEARCH.md +.work/*/RESEARCH-*.md +.work/*/*-checklist.md +``` + +Also gitignore `.claude/worktrees/` so worktree contents never appear +as untracked files. Rollout caveats: pulling a commit that adds +`.claude/settings.json` into a clone already holding an untracked file +at that path fails with "untracked working tree file would be +overwritten" — move the local file aside, pull, then merge its values +back; on Windows, deep repository base paths can trip git's path limit +inside nested worktrees (`'$GIT_DIR' too big`) — keep the repository +base path short. Routing this materialization through a setup-skill +apply action is a recorded follow-on, not built today. + ## The tracked concern file — `.claude/topic-docs.yaml` The consumer-side single source of truth. Shape in @@ -220,22 +334,30 @@ citations of retired paths as ghost refs. ## Implementers -| Plugin | Writes | Tier(s) | -|---|---|---| -| discovery | `EXPLORE.md`, `RESEARCH.md` | memory | -| planning | `PRD.md`, `PLAN.md` (Brief), `design/`, opt-in brainstorm persist | contract + memory | -| implementation | `PLAN.md` (Plan/progress), `verification/` manifest, baselines, raw captures | contract + memory | -| session-flow | handoffs | memory (`handoffs/`) | -| review | review reports | memory (`reviews/`) | -| work-items | per-topic action ledger; tracker projections | memory; ticket edge | -| knowledge | ingest trees — **formal carve-out**: its work root resolves through its own `library_dir` seam, not `memory_dir`; slug conformance is form-only (charset/reserved names), and its nested `//` sub-slices are sanctioned | memory (carved out) | -| claude-ops | telemetry | machine state | -| docs-hygiene | (reader) audit-noise detector recognizes these shapes | — | +Plugins with their own placement deltas carry a deltas-only binding +(`reference/topic-docs.md`); the rest adopt by reference — their +relationship to the contract is fully stated by their table row. + +| Plugin | Writes | Tier(s) | Binding | +|---|---|---|---| +| discovery | `EXPLORE.md`, `RESEARCH.md` | memory | delta doc | +| planning | `PRD.md`, `PLAN.md` (Brief), `design/`, opt-in brainstorm persist | contract + memory | delta doc | +| implementation | `PLAN.md` (Plan/progress), `DEVIATIONS.md`, status summaries | contract + memory | delta doc | +| verification | `verification/` manifest; baselines, raw captures | contract + memory | delta doc | +| session-flow | handoffs | memory (`handoffs/`) | delta doc | +| review | review reports | memory (`reviews/`) | delta doc | +| work-items | per-topic action ledger; tracker projections | memory; ticket edge | delta doc | +| toolchain | nothing of its own — its setup skill offers the concern file | — | delta doc | +| knowledge | ingest trees — **formal carve-out**: its work root resolves through its own `library_dir` seam, not `memory_dir`; slug conformance is form-only (charset/reserved names), and its nested `//` sub-slices are sanctioned | memory (carved out) | by reference — the carve-out above is its entire delta | +| claude-ops | telemetry | machine state | by reference — machine state resolves no contract paths | +| docs-hygiene | (reader) audit-noise detector recognizes these shapes | — | by reference — reads shapes, writes nothing | ## Versioning This contract is versioned in `CHANGELOG.md`. A change that moves a -tier, renames a key in `topic-docs.yaml`, or alters the slug spec is a -**major** contract change, and every implementer adopts it in the same -release wave (clean break — this contract carries no compatibility -machinery). Additive guidance is minor. +tier, renames a key in `topic-docs.yaml`, alters the slug spec, or +**changes a visibility guarantee** (what an execution context may rely +on seeing, per the visibility matrix) is a **major** contract change, +and every implementer adopts it in the same release wave (clean break — +this contract carries no compatibility machinery). Additive guidance is +minor. diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md index 90e547776..30972e9d0 100644 --- a/docs/topics/plugin-philosophy/PLAN.md +++ b/docs/topics/plugin-philosophy/PLAN.md @@ -100,7 +100,11 @@ resume it. > **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). Next: Phase 5 wave on this branch. +> (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. @@ -243,7 +247,7 @@ Work items: (else verdict is invalid by construction). - This PLAN's "Empirical verification results" table row 1 is filled (no `(pending)`). -### Phase 5: Topic-docs contract 2.0.0 + seam fixes R1–R6 (one wave) [TODO] +### 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. @@ -301,24 +305,24 @@ File inventory (checkbox discipline — tick as processed): | File | Action | Rationale | |---|---|---| -| [ ] `docs/conventions/topic-docs/README.md` | MODIFY | R6 rewrite, visibility matrix, R4/R5 text | -| [ ] `docs/conventions/topic-docs/CHANGELOG.md` | MODIFY | 2.0.0 entry | -| [ ] `docs/conventions/topic-docs/topic-docs.schema.json` | KEEP (audit) | no key changes expected | -| [ ] `docs/conventions/topic-docs/examples/*` | AUDIT | update only if matrix/mechanisms change examples | -| [ ] `.claude/settings.json` | CREATE | R1 `worktree.baseRef` | -| [ ] `.worktreeinclude` | CREATE | R2 patterns | -| [ ] `plugins/discovery/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/implementation/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/planning/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/review/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/session-flow/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/toolchain/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/verification/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/work-items/reference/topic-docs.md` | MODIFY | 2.0.0 adoption | -| [ ] `plugins/work-items/skills/decompose/SKILL.md` | MODIFY | R3 ticket provenance | -| [ ] `plugins/planning/skills/architect/SKILL.md` | MODIFY | R3 baseline recording | -| [ ] 8–10 × `plugins/*/plugin.json` + `CHANGELOG.md` | MODIFY | semver bump per touched plugin | -| [ ] `plugins/knowledge/…`, `plugins/claude-ops/…`, `plugins/docs-hygiene/…` | AUDIT | implementer-table rows without delta docs — verify no stale convention text | +| [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:** diff --git a/plugins/discovery/.claude-plugin/plugin.json b/plugins/discovery/.claude-plugin/plugin.json index dca4c643e..07339e37b 100644 --- a/plugins/discovery/.claude-plugin/plugin.json +++ b/plugins/discovery/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "discovery", - "version": "0.5.1", + "version": "0.6.0", "description": "Structured discovery before changes: explore the local codebase (inline or in an isolated forked subagent) and run disciplined multi-source external research with source tiers, falsification, and recency gates — persisting EXPLORE.md / RESEARCH.md handoff artifacts.", "author": { "name": "Melodic Software", diff --git a/plugins/discovery/CHANGELOG.md b/plugins/discovery/CHANGELOG.md index bb5d8f868..aea5e3e4e 100644 --- a/plugins/discovery/CHANGELOG.md +++ b/plugins/discovery/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog — discovery plugin +## 0.6.0 — 2026-07-17 + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` states that + `EXPLORE.md` / `RESEARCH.md` are checkout-local, are the cross-checkout-useful kind the + contract's `.worktreeinclude` template carries into new worktrees, and that forked/deep workers + return findings by value with the parent session writing the memory slice. + ## 0.5.1 — 2026-07-15 ### Fixed diff --git a/plugins/discovery/reference/topic-docs.md b/plugins/discovery/reference/topic-docs.md index c33adc9ae..eab910235 100644 --- a/plugins/discovery/reference/topic-docs.md +++ b/plugins/discovery/reference/topic-docs.md @@ -25,3 +25,11 @@ Discovery writes **memory tier only** — working documents nothing downstream e Discovery never writes the contract tier; the `contract_tier` setting does not change where its artifacts land. `/discovery:explore-deep` and a Tier-2 research subagent operate under the contract's **non-interactive / forked mode** rule. + +## Visibility (contract ≥ 2.0.0) + +These artifacts are memory-tier, so they exist only in the checkout that wrote them. They are +exactly the cross-checkout-useful kind the contract's `.worktreeinclude` template carries into new +worktrees (one-way, at creation time) where the consuming repo materializes it. Isolated workers +(`-deep` variants, forked subagents) return findings **by value**; the parent session writes the +memory slice in its own checkout — a worker's checkout-local writes are not the record. diff --git a/plugins/implementation/.claude-plugin/plugin.json b/plugins/implementation/.claude-plugin/plugin.json index 7eb0f7ba8..90461e91b 100644 --- a/plugins/implementation/.claude-plugin/plugin.json +++ b/plugins/implementation/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "implementation", - "version": "0.6.0", + "version": "0.7.0", "description": "Disciplined implementation stage: execute approved plans inline (`/implementation:implement`) or via orchestrated worker subagents (`/implementation:implement-dispatch`) with incremental validation, TDD-by-default cadence, green-checkpoint commits, scope-fence drift detection, and divergence detection that routes back to planning. Build/test/lint, testing, and outcome verification live in the companion `toolchain`, `testing`, and `verification` plugins, invoked when installed.", "author": { "name": "Melodic Software", diff --git a/plugins/implementation/CHANGELOG.md b/plugins/implementation/CHANGELOG.md index bceee2478..f8b8c6cdc 100644 --- a/plugins/implementation/CHANGELOG.md +++ b/plugins/implementation/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the `implementation` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.7.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` ties the + phase-commit rule to the contract's visibility guarantee — isolated contexts see the contract + slice as committed state only — and states the by-value return rule for dispatched workers. + ## [0.6.0] ### Changed — nine skills extracted into three new plugins (migration required to retain them) diff --git a/plugins/implementation/reference/topic-docs.md b/plugins/implementation/reference/topic-docs.md index 1b9801964..cd341568d 100644 --- a/plugins/implementation/reference/topic-docs.md +++ b/plugins/implementation/reference/topic-docs.md @@ -29,4 +29,8 @@ Verification manifests and baselines are the `verification` plugin's artifacts ( their placement); this plugin does not write them. **Phase-commit rule:** each implementation phase's plan updates ride the same commit as that -phase's source changes — one commit, one story; memory-tier files never enter the commit. +phase's source changes — one commit, one story; memory-tier files never enter the commit. Per the +contract's visibility rules (≥ 2.0.0) this is also what makes plan progress visible to isolated +contexts: a spawned worktree or dispatched worker sees the contract slice only as **committed** +state, so uncommitted plan marks are invisible outside the writing checkout. Dispatched workers +return results by value; this session writes both tiers in its own checkout. diff --git a/plugins/planning/.claude-plugin/plugin.json b/plugins/planning/.claude-plugin/plugin.json index 7c8ac8ac2..bb67591b7 100644 --- a/plugins/planning/.claude-plugin/plugin.json +++ b/plugins/planning/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "planning", - "version": "0.12.0", + "version": "0.13.0", "description": "Pre-implementation planning pipeline: chart a too-big, foggy effort as a decision map, diverge on candidate approaches, lock product intent and the engineering contract, actively maintain resolved domain language, explore the design space, stress-test adversarially, and produce a structured implementation plan with an approval gate.", "author": { "name": "Melodic Software", diff --git a/plugins/planning/CHANGELOG.md b/plugins/planning/CHANGELOG.md index 760cb09b6..05765d315 100644 --- a/plugins/planning/CHANGELOG.md +++ b/plugins/planning/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to the `planning` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.13.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` records that + baselines are checkout-local and `PLAN.md` carries distilled values only; + `/planning:architect`'s baseline step no longer directs `PLAN.md` to reference the stored + memory-slice capture (pointer discipline — the path is invisible outside the writing checkout). + ## [0.12.0] ### Changed diff --git a/plugins/planning/reference/topic-docs.md b/plugins/planning/reference/topic-docs.md index ebc698862..5622ddb6d 100644 --- a/plugins/planning/reference/topic-docs.md +++ b/plugins/planning/reference/topic-docs.md @@ -27,6 +27,11 @@ behavior; this binding and topic-docs remain authoritative for their placement. the contract's solo/offline mode. Roots are configurable via the concern file's `contract_dir` / `memory_dir` keys. +Baselines are machine-bound memory-tier captures, invisible outside the writing checkout: per the +contract's pointer discipline (≥ 2.0.0), `PLAN.md` records **distilled baseline values only** and +never cites a memory-slice capture path. Checklists are the stage-ledger kind the contract's +`.worktreeinclude` template carries into new worktrees where the consuming repo materializes it. + ## Close-out — the vault seam `/planning:architect` owns describing the contract-slice close-out. Its promotion step resolves diff --git a/plugins/planning/skills/architect/SKILL.md b/plugins/planning/skills/architect/SKILL.md index 9d33408e1..e3cb18b0e 100644 --- a/plugins/planning/skills/architect/SKILL.md +++ b/plugins/planning/skills/architect/SKILL.md @@ -108,7 +108,7 @@ Per-scale calibration examples live in [context/plan-template.md](context/plan-t **Integration-first phase ordering** — once the technique is the kept branch (tracer bullet / walking skeleton), for multi-layer features sequence the FIRST phase as the integration slice and make its `**Sanity Check:**` an end-to-end runtime probe. Skip for pure-horizontal work (migration, lint, doc pass). -**Measurable-goal baseline capture** — when the brief states a measurable goal (perf / latency / throughput / allocation / complexity / coverage keywords), capture a baseline **by default** BEFORE the change: route to `/verification:measure performance baseline` (perf) or `/verification:measure metrics baseline` (code metrics) if installed — the measurement mechanism is SSOT there; this skill routes, never reimplements — or measure the pre-change state manually. Store the raw capture under `//baselines/` (default `.work/`; the memory slice — baselines are machine-bound and never committed), then record the baseline value + target in PLAN.md. After the change, re-measure and compare through the same route (its `compare` phase reads the stored baseline, or re-measure manually) and record the comparison in PLAN.md, referencing the stored capture — the contract carries the distilled numbers, never the raw output. Never claim an improvement without a baseline. +**Measurable-goal baseline capture** — when the brief states a measurable goal (perf / latency / throughput / allocation / complexity / coverage keywords), capture a baseline **by default** BEFORE the change: route to `/verification:measure performance baseline` (perf) or `/verification:measure metrics baseline` (code metrics) if installed — the measurement mechanism is SSOT there; this skill routes, never reimplements — or measure the pre-change state manually. Store the raw capture under `//baselines/` (default `.work/`; the memory slice — baselines are machine-bound and never committed), then record the distilled baseline value + target in PLAN.md. After the change, re-measure and compare through the same route (its `compare` phase reads the stored baseline, or re-measure manually) and record the comparison in PLAN.md as distilled values only — PLAN never cites the memory-slice capture path (it is invisible outside the writing checkout and the pointer would dangle; topic-docs pointer discipline). Never claim an improvement without a baseline. ### Step 3: Plan Stress-Test (MANDATORY — never skip) diff --git a/plugins/review/.claude-plugin/plugin.json b/plugins/review/.claude-plugin/plugin.json index 791b3ab4d..4d1203bae 100644 --- a/plugins/review/.claude-plugin/plugin.json +++ b/plugins/review/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "review", - "version": "0.9.0", + "version": "0.10.0", "description": "Code-review toolkit: six read-only reviewer agents (code, security, architecture, doc drift, build/test/lint, CI-log audit) plus two orchestration skills — a single-lens quality gate and a multi-surface review fan-out with severity-ranked, deduplicated findings.", "author": { "name": "Melodic Software", diff --git a/plugins/review/CHANGELOG.md b/plugins/review/CHANGELOG.md index 22f6197ce..6661a90d2 100644 --- a/plugins/review/CHANGELOG.md +++ b/plugins/review/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the `review` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.10.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` states review + reports are lane-local (invisible to sibling worktrees and clones) and cross-lane findings + graduate through the work-item tracker as tickets that point, never as pasted report bodies. + ## [0.9.0] ### Added diff --git a/plugins/review/reference/topic-docs.md b/plugins/review/reference/topic-docs.md index 5a191734d..b8f04452b 100644 --- a/plugins/review/reference/topic-docs.md +++ b/plugins/review/reference/topic-docs.md @@ -19,7 +19,10 @@ reports sit under the memory root's reserved `reviews/` name rather than inside | `fanout` ranked reports | `.work/reviews//-.md` — never committed | Reports are write-only process output; nothing downstream enforces against them, which is what makes -them memory-tier by the convention's placement question. +them memory-tier by the convention's placement question. They are therefore lane-local (contract +≥ 2.0.0): a sibling worktree or cloud clone never sees them. Findings that must cross lanes +graduate through the work-item tracker — the contract's cross-lane index — as tickets that point, +never as pasted report bodies. ## Resolution (the contract's five-rung order, earlier wins) diff --git a/plugins/session-flow/.claude-plugin/plugin.json b/plugins/session-flow/.claude-plugin/plugin.json index ff820a6bf..ae0a8f6b1 100644 --- a/plugins/session-flow/.claude-plugin/plugin.json +++ b/plugins/session-flow/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "session-flow", - "version": "0.7.0", + "version": "0.8.0", "description": "Session-lifecycle toolkit of five skills: workflow (navigate a staged dev workflow and suggest the next stage), handoff (write a save-point and resume prompt for /clear, with optional --bg background-agent launch), keep-going (recover and continue after any interruption — inventory off-thread work, inspect its real state, resume or restart it, then continue the main task), retro (structured session retrospective with transcript metrics and learning codification), and orchestrate (arm a session or worker with proactive-orchestration imperatives).", "author": { "name": "Melodic Software", diff --git a/plugins/session-flow/CHANGELOG.md b/plugins/session-flow/CHANGELOG.md index 207895727..44ac9e36b 100644 --- a/plugins/session-flow/CHANGELOG.md +++ b/plugins/session-flow/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog — session-flow plugin +## 0.8.0 — 2026-07-17 + +Changed: + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` states + handoffs and the workflow checklist are checkout-local; the checklist is the stage-ledger kind + the contract's `.worktreeinclude` template carries into new worktrees, while handoffs are + session-scoped and deliberately not carried. + ## 0.7.0 — 2026-07-17 Added: diff --git a/plugins/session-flow/reference/topic-docs.md b/plugins/session-flow/reference/topic-docs.md index a3f9358f3..191ed4462 100644 --- a/plugins/session-flow/reference/topic-docs.md +++ b/plugins/session-flow/reference/topic-docs.md @@ -22,6 +22,11 @@ Timestamps are ISO-basic UTC `YYYYMMDDTHHMMSSZ` per the contract's filename spec is configurable via the concern file's `memory_dir` key; session-flow never writes the contract tier. +Both artifacts are memory-tier and therefore checkout-local (contract ≥ 2.0.0): a handoff written +in one worktree is invisible to a session resuming in another. The workflow checklist is a stage +ledger the contract's `.worktreeinclude` template carries into new worktrees where the consuming +repo materializes it; handoffs are session-scoped and deliberately not carried. + ## Resolution (the contract's five-rung order, earlier wins) 1. `.claude/topic-docs.yaml` present → use its `memory_dir`. diff --git a/plugins/toolchain/.claude-plugin/plugin.json b/plugins/toolchain/.claude-plugin/plugin.json index 7b1bb702a..80398dfed 100644 --- a/plugins/toolchain/.claude-plugin/plugin.json +++ b/plugins/toolchain/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "toolchain", - "version": "0.1.1", + "version": "0.2.0", "description": "Repo-agnostic polyglot verification toolchain: build + test + lint for changed files across .NET, Python, TypeScript, Bash, PowerShell, Markdown, YAML, and cross-cutting surfaces (`/toolchain:build`, `/toolchain:lint`), plus a re-runnable `/toolchain:setup` that writes the tracked per-ecosystem command config those skills resolve first.", "author": { "name": "Melodic Software", diff --git a/plugins/toolchain/CHANGELOG.md b/plugins/toolchain/CHANGELOG.md index d879457f7..9dd535a6d 100644 --- a/plugins/toolchain/CHANGELOG.md +++ b/plugins/toolchain/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to the `toolchain` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.2.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` clarifies the + contract's visibility mechanisms are consumer-repo root materializations outside the concern + file's schema, and `/toolchain:setup` does not write them today (a setup-skill apply action is + the contract's recorded follow-on). + ## [0.1.1] ### Fixed diff --git a/plugins/toolchain/reference/topic-docs.md b/plugins/toolchain/reference/topic-docs.md index 78d7fc807..263c3811a 100644 --- a/plugins/toolchain/reference/topic-docs.md +++ b/plugins/toolchain/reference/topic-docs.md @@ -20,6 +20,11 @@ YAML document parses as null and fails the contract schema's `type: object`), ru conflict check on the chosen contract root when the tier is `branch`, and never edits the consumer's root `.gitignore`. +The contract's visibility mechanisms (≥ 2.0.0 — committed worktree base setting, +`.worktreeinclude`) are consumer-repo root materializations outside the concern file's schema; +`/toolchain:setup` does not write them today (a setup-skill apply action is the contract's recorded +follow-on). + ## Where the artifacts land (owned by the companion plugins) The `implementation` and `verification` plugins bind this convention in their own diff --git a/plugins/verification/.claude-plugin/plugin.json b/plugins/verification/.claude-plugin/plugin.json index a9316c68b..68acf919e 100644 --- a/plugins/verification/.claude-plugin/plugin.json +++ b/plugins/verification/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "verification", - "version": "0.1.0", + "version": "0.2.0", "description": "Outcome-verification stage: prove a change achieved its intended outcome (`/verification:confirm` — a mechanical build/test/lint prerequisite gate, then intent-match + evidence + verdict with the criterion auto-detected by change type), and verify measurable-improvement claims against a planning-time baseline (`/verification:measure`), never fabricating numbers.", "author": { "name": "Melodic Software", diff --git a/plugins/verification/CHANGELOG.md b/plugins/verification/CHANGELOG.md index fedcb0cbc..6998257ad 100644 --- a/plugins/verification/CHANGELOG.md +++ b/plugins/verification/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the `verification` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.2.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` states + baselines and raw captures are checkout-local, and `/verification:measure` writes distilled + values only into `PLAN.md` — never a memory-slice capture path (pointer discipline). + ## [0.1.0] ### Added diff --git a/plugins/verification/reference/topic-docs.md b/plugins/verification/reference/topic-docs.md index 436d02282..6adda26c7 100644 --- a/plugins/verification/reference/topic-docs.md +++ b/plugins/verification/reference/topic-docs.md @@ -27,3 +27,8 @@ the contract's solo/offline mode. Roots are configurable via the concern file's `/verification:confirm` reads the contract-tier `PLAN.md` (produced upstream) for intent; when a plan states a measurable goal, `/verification:measure` records its baseline values + target into that same `PLAN.md`. The plan artifact itself is owned by the `implementation` / planning stages, not written here. + +Baselines and raw captures are machine-bound and checkout-local; per the contract's pointer +discipline (≥ 2.0.0), what `/verification:measure` writes into `PLAN.md` is **distilled values +only** — never a memory-slice capture path. The committed manifest is what isolated contexts and +reviewers see; it meets the redaction bar for exactly that reason. diff --git a/plugins/work-items/.claude-plugin/plugin.json b/plugins/work-items/.claude-plugin/plugin.json index 616da393b..c29bf97b4 100644 --- a/plugins/work-items/.claude-plugin/plugin.json +++ b/plugins/work-items/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "work-items", - "version": "0.8.0", + "version": "0.9.0", "description": "Manages development work items through a provider-neutral tracker seam (GitHub the bound adapter today): dashboard, taxonomy-labeled creation, a race-safe assignee-plus-lease claim protocol, recurring-schedule checks, TODO scanning, stale-lease auditing, plan decomposition into vertical-slice items, and raw-intake triage (issues and unsolicited PRs through raw, verified, briefed, autonomous-eligible states). Canonical role labels remap via the tracker binding; the recurring-schedule seam (.github/recurring-schedule.json) is seeded and reshaped by the re-runnable setup skill.", "author": { "name": "Melodic Software", diff --git a/plugins/work-items/CHANGELOG.md b/plugins/work-items/CHANGELOG.md index fcb36845c..cf259399f 100644 --- a/plugins/work-items/CHANGELOG.md +++ b/plugins/work-items/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to the `work-items` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.9.0] + +### Changed + +- Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` names the + tracker as the contract's cross-lane index — tickets point, never store primary artifacts; + `/work-items:decompose` ticket provenance now cites the PR carrying the source plan instead of + the contract-slice path, which is pruned before merge and would dangle. + ## [0.8.0] ### Changed (breaking) diff --git a/plugins/work-items/reference/topic-docs.md b/plugins/work-items/reference/topic-docs.md index bd8b90119..150788199 100644 --- a/plugins/work-items/reference/topic-docs.md +++ b/plugins/work-items/reference/topic-docs.md @@ -19,6 +19,12 @@ this document binds this plugin's artifacts to it. The memory root is configurable via the concern file's `memory_dir` key. This plugin never writes the contract tier (`//`). +The tracker is the contract's **cross-lane index** (≥ 2.0.0): tickets are how sessions in other +worktrees, clones, and machines discover work state, so ticket bodies point (PR URLs, +promoted-doc locations) and never store primary artifacts. Pointer discipline applies: +`/work-items:decompose` cites the PR carrying the source plan as provenance, never the +contract-slice path (pruned before merge) or a memory path (never leaves its checkout). + ## What this plugin reads — the tier-selected plan lookup `/work-items:decompose` (and any skill sourcing a plan or PRD) selects the location from the concern diff --git a/plugins/work-items/skills/decompose/SKILL.md b/plugins/work-items/skills/decompose/SKILL.md index 37ad6a2e5..6b6c47799 100644 --- a/plugins/work-items/skills/decompose/SKILL.md +++ b/plugins/work-items/skills/decompose/SKILL.md @@ -132,7 +132,9 @@ Use agent-brief body format (see [`${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.m ## Parent Refs # (if source was an existing item) - + ## What to build From fc5f14653a496b3e7e296b09d1698294c37c1c50 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:24:06 -0400 Subject: [PATCH 03/12] docs: prune plugin-philosophy contract slice before merge Contract-slice lifecycle: the PLAN is pasted into the PR description; the working copy continues at the preserved memory-tier location. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- docs/topics/plugin-philosophy/PLAN.md | 560 -------------------------- 1 file changed, 560 deletions(-) delete mode 100644 docs/topics/plugin-philosophy/PLAN.md diff --git a/docs/topics/plugin-philosophy/PLAN.md b/docs/topics/plugin-philosophy/PLAN.md deleted file mode 100644 index 30972e9d0..000000000 --- a/docs/topics/plugin-philosophy/PLAN.md +++ /dev/null @@ -1,560 +0,0 @@ -# plugin-philosophy - -## Brief - -### TLDR - -Extend the plugin doctrine to the full current component surface (13 component types, official docs -fetched 2026-07-17), lock a native-first principle with a maturity gate, fix the topic-docs two-tier -convention's visibility seams with native mechanisms, ship a complete official-doc link index, adopt -marketplace metadata maximally — then run a fanout conformance audit of all 47 plugins whose findings -graduate to tracker-managed remediation waves. - -### Goal - -Every plugin measurably conforms to an extended, freshness-guarded doctrine; no custom mechanism -exists where a fitting native one does; every cross-plugin convention has exactly one registered -owner doc; the remediation program lives on the work-item tracker where any session or machine can -resume it. - -### Locked decisions - -| # | Decision | -|---|---| -| D1 | Deliverable = doctrine revision + fleet-consistency audit, coupled in this one Brief. CI contract-gate automation deferred to follow-on (trigger: audit reveals automatable checks). | -| D2 | Doc-link index is a first-class deliverable: every plugin-relevant official doc page linked (components mapped to their doc pages); no undocumented component types. | -| D3 | Native-first principle: prefer built-in native mechanisms (userConfig, native component types, native lifecycle events) over custom extensibility points; custom only on genuine misfit, with the misfit documented. | -| D4 | Native-adoption gate (qualifies D3): adopt a native mechanism when it (1) fills a real existing gap, (2) is stable and works cleanly — experimental/immature features wait for maturity, (3) meets repo standards. Never custom-build what a fitting native mechanism covers. | -| D5 | Cross-plugin cooperation: hybrid. Native `dependencies` reserved for hard requires (plugin genuinely broken without collaborator) — none exist today; the `{name}--v{version}` git-tag release step lands with first use. Optional collaboration stays presence-gated with documented fallbacks; artifact protocol unchanged (data handoff, which dependencies don't cover). | -| D6 | Component stance table: skills = primary surface (new frontmatter — `paths`, `context: fork`, `arguments`, skill-scoped `hooks`/`once` — adopted case-by-case); `commands/` prohibited (officially legacy); agents, MCP, LSP, output styles, `bin/` = adopt-on-need (`bin/` requires collision-safe prefixed names; doctrine notes plugin agents ignore `hooks`/`mcpServers`/`permissionMode`); plugin `settings.json` `agent` (main-thread takeover) prohibited by default, exception needs documented justification; monitors, themes, channels = wait (experimental/immature), re-verified against current docs before each audit; dependencies per D5. Hooks addition: exec-form (`args`) mandatory wherever `${user_config.*}` appears (v2.1.207), else the `CLAUDE_PLUGIN_OPTION_` env mirror. | -| D7 | Freshness rider on all doctrine artifacts: every stance/inventory row carries a verified-date + link to its official doc page and an explicit disclaimer that the platform changes constantly — always re-fetch current docs before acting; never trust the repo file alone. | -| D8 | userConfig full-potential criterion: every personal/administrator scalar flowing through a custom channel (env-var toggle, gitignored personal file, documented hand-edit) migrates to userConfig using the full native schema — correct `type`, `default` preserving zero-config behavior, `required` only where truly blocking, `sensitive: true` for secrets, `claude plugin install --config` documented in each setup skill for headless use. Shell consumers read the native `CLAUDE_PLUGIN_OPTION_` mirror; custom env vars retired. Ownership table otherwise unchanged. Guardrails `HOOK__ENABLED` toggles = flagship migration (userConfig booleans, `default: true`). | -| D9 | Setup doctrine v2: setup skill required iff (a) consumer-project config surface, (b) external prerequisites (CLI, service, credential), or (c) non-trivial userConfig — criteria applied through the modular/configurable/repo-/machine-/user-agnostic lens, never blanket ceremony; zero-config zero-prereq plugins exempt. Uniform contract: skill named `setup`, `disable-model-invocation: true`, `check` (read-only inspect/verify) + `apply` (idempotent configure) actions, complete-args non-interactive path. Formatter/linter plugins gain thin check-centric setups. Native `Setup` hook event = sanctioned headless/CI init surface; SessionStart + `${CLAUDE_PLUGIN_DATA}` manifest-diff = sanctioned runtime-dependency idiom. | -| D10 | Runtime-prerequisite visibility: anything with a runtime prereq (e.g. jq on PATH) degrades gracefully — never a hard crash; absence is surfaced to BOTH the agent and the user, with OTel as a candidate visibility channel; no black boxes. Extends the philosophy doc's "Prerequisites and failure behavior" section. | -| D11 | Convention registry: pointer-only section in PLUGIN-PHILOSOPHY.md — one owner doc per shared concern (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, artifact protocol, seam phrasing); registry names and points, never restates; audit rule = per-row conformance; a new convention lands in an owner doc before a second plugin adopts it. | -| D12 | Topic-docs tiers: keep the nature-based two-tier split and the `docs/topics/` name (contents are transient topic-scoped contract docs; `docs/specs/` is already the durable vault target — renaming would conflate tiers). | -| D13 | Two-tier seam fix package (all native): R1 `worktree.baseRef: "head"` in committed repo settings so worktree-isolated spawns carry task-branch state; R2 `.worktreeinclude` with targeted memory-tier patterns (stage ledgers, EXPLORE/RESEARCH — not baselines/raw scratch; one-way creation-time copy documented); R3 pointer discipline — durable surfaces (tickets, committed PLAN) never point at prunable or gitignored paths (decompose cites the PR, not the contract path; PLAN records distilled baseline values only); R4 isolated workers return results by value, the orchestrator writes both tiers in the parent checkout; R5 the work-item tracker is the cross-lane awareness/index layer (branch files stay lane-local; markdown-in-tickets as primary artifact store rejected — not diffable, drifts from code); R6 topic-docs convention doc corrected (worktree-visibility rationale, context×tier visibility matrix, mechanisms named) — a major contract version adopted by all implementers in one wave. | -| D14 | Doc-link index: dedicated `docs/OFFICIAL-DOCS.md` — complete categorized map of plugin-relevant official pages with a component→doc-page table, per-row verified-dates, the D7 staleness disclaimer, and `https://code.claude.com/docs/llms.txt` named as the authoritative self-updating master list. CLAUDE.md keeps its lean canonical table plus one pointer row to the index. | -| D15 | Marketplace metadata maximalism (machine-, user-, org-agnostic posture): populate every helpful-signal field — `relevance` signals wherever meaningful (audit criterion per plugin), `defaultEnabled: false` for personal/niche-category plugins, `displayName` where it genuinely clarifies, complete descriptive metadata. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + source declaration in managed settings). Hard rule: `version` lives in plugin.json only, never in marketplace entries (silent-precedence trap). | -| D16 | Audit execution: doctrine docs land first; then per-plugin subagent fanout scores all 47 plugins against a doctrine-derived checklist (~15 dimensions: setup criteria, userConfig migration, exec-form hooks, metadata completeness, component stances, registry conformance, prereq degradation, pointer discipline); findings distill into a plugin×dimension conformance matrix graduating to GitHub issues — one epic + per-wave issues (setup, userConfig, metadata, hooks, convention-seam waves) via the work-items seam; raw per-plugin detail stays memory-tier; automatable checks become the deferred CI gate's backlog. | - -### Constraints - -- Fresh-docs mandate applies at execution time: re-fetch the relevant official pages before each edit - wave; this Brief's doc facts were verified 2026-07-17. -- Work isolated in worktree, branch `docs/plugin-philosophy`; PRs required, squash merge, PR title - per Conventional Commits. -- Topic-docs convention change (D13/R6) is a major contract version; every implementer plugin adopts - in the same release wave (the contract carries no compatibility machinery). -- userConfig migrations preserve existing behavior via `default` values (guardrails toggles default - `true`). -- Every plugin change clears the migration playbook's gate + plugin-acceptance security review. - -### Acceptance criteria - -- PLUGIN-PHILOSOPHY.md revised: component stance table (D6) with D7 freshness riders, native-first + - adoption gate (D3/D4), convention registry (D11), config ownership updated (D8 criterion, exec-form - rule, version-placement rule), setup criteria (D9), prerequisite-visibility rule (D10). -- MIGRATION-PLAYBOOK.md updated consistently (setup contract, userConfig criterion, security review - touchpoints). -- `docs/OFFICIAL-DOCS.md` exists: complete categorized page map, component→doc table, verified-dates, - staleness disclaimer, llms.txt master pointer; CLAUDE.md carries the pointer row and stays lean. -- Topic-docs convention doc corrected per R6 with visibility matrix; R1 settings entry, R2 - `.worktreeinclude`, and R3 skill pointer fixes (decompose ticket provenance, architect baseline - recording) landed; the three flagged execution-time verifications resolved empirically and - recorded. -- marketplace.json metadata complete per D15; `claude plugin validate .` passes. -- Audit epic + wave issues filed on GitHub with the conformance matrix distilled into the epic; every - 47-plugin row scored; raw details in the memory slice. -- Existing CI (plugin contract tests, markdownlint) green on every PR. - -### Captured assumptions - -- Consumers run CC ≥ 2.1.207 (userConfig shell-form ban semantics, pluginConfigs scoping); older - clients degrade per official behavior, not worked around. -- Marketplace remains the melodic-software catalog but every decision holds machine-, user-, and - org-agnostic (no solo-consumer scoping). - -### Out-of-scope (deferred with triggers) - -- CI contract gate — trigger: audit identifies automatable checks (D16 backlog). -- Bundle plugin (name + dependencies curated set) — trigger: one-command curated install need beyond - the fleet-sync skill. -- Monitors, themes, channels adoption — trigger: feature exits experimental/immature status at a - future doc re-verification (D6 wait rows). -- `music` → `creative`, deployment category, and other plugin-organization deferrals remain owned by - that Brief. - -### Deferred questions - -- Windows `sensitive` userConfig storage behavior (docs silent on Windows keychain) — empirical - verification during audit, before any secret migrates. Arbiter: `/architect` (execution evidence). -- Worktree-sweep treatment of ignored files; `--bg` session worktree base semantics; - `worktree.baseRef` honored at project-settings scope — empirical smoke tests during D13 execution. - Arbiter: `/architect`. -- Per-plugin `relevance` signal quality (which signals are genuinely helpful vs noise) — decided - per-plugin during the metadata wave. Arbiter: `/architect`. - -## Plan - -> **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_` mirror, retirement of custom env channels), exec-form - hooks rule, version-placement rule (`version` in plugin.json only). -5. Rewrite **Setup is explicit and repeatable** to the D9 v2 criteria (required-iff conditions, - uniform `setup` skill contract, `Setup` hook event and SessionStart manifest-diff idioms). -6. Extend **Prerequisites and failure behavior** with D10 (graceful degradation, dual agent+user - visibility, OTel as candidate channel, no black boxes). -7. Add **Convention registry** section (D11): pointer-only table — one owner doc per shared concern - (topic-docs binding, skill layout + evals schema, `lib/hook-utils.sh` sync, report vocabularies, - artifact protocol, seam phrasing); registry names and points, never restates. - -**Sanity Check:** - -- `grep -c "Verified 2026" docs/PLUGIN-PHILOSOPHY.md` ≥ N (one rider per stance row; N from - `component-count.txt`). -- `grep -n "Convention registry\|Native-first" docs/PLUGIN-PHILOSOPHY.md` returns both sections. -- Component stance table row count = N; Read confirms every verified component type named. -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/PLUGIN-PHILOSOPHY.md` exit 0 (CI's - pinned action is authoritative; local run uses the repo config). - -### Phase 2: MIGRATION-PLAYBOOK.md consistency pass [DONE] - -Depends on Phase 1 (doctrine wording is SSOT; playbook points, never restates). - -Work items: - -1. Update the per-plugin migration gate: setup-contract check (D9), userConfig criterion (D8), - exec-form hook rule — each as a pointer to the philosophy doc section plus playbook-specific - procedure only. -2. Extend the plugin-acceptance security review touchpoints: `sensitive` userConfig handling, - `bin/` collision-safe naming, plugin `settings.json` `agent` prohibition check. -3. Remove or redirect any playbook text that now duplicates Phase 1 doctrine (no restated stance - tables). - -**Sanity Check:** - -- `grep -n "PLUGIN-PHILOSOPHY" docs/MIGRATION-PLAYBOOK.md` shows pointer citations in the gate and - security-review sections. -- No restated stance table: no markdown table in MIGRATION-PLAYBOOK.md whose header row contains - both `Component` and `Stance` columns (Read assertion — pointers naming the section are fine). -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/MIGRATION-PLAYBOOK.md` exit 0. - -### Phase 3: docs/OFFICIAL-DOCS.md index + CLAUDE.md pointer [DONE] - -Covers D14. Parallel-safe with Phase 2 (disjoint files); component list comes from the Brief/Phase 1 -stance table. - -Work items: - -1. Fresh-fetch `https://code.claude.com/docs/llms.txt`; enumerate every plugin-relevant page. -2. Create `docs/OFFICIAL-DOCS.md`: categorized page map, component→doc-page table, per-row - verified-dates, D7 staleness disclaimer, llms.txt named as the authoritative self-updating - master list. -3. Add one pointer row to CLAUDE.md's canonical table; CLAUDE.md stays lean (no other growth). -4. **Wave A join step (main session):** reconcile the component→doc table against Phase 1's - verified component list (`component-count.txt` + stance table) before PR A — parallel work off - the Brief snapshot must converge on Phase 1's fresh-fetched reality. - -**Sanity Check:** - -- `test -f docs/OFFICIAL-DOCS.md` && component table has N rows (N from `component-count.txt`). -- `grep -n "llms.txt" docs/OFFICIAL-DOCS.md` and `grep -n "OFFICIAL-DOCS" CLAUDE.md` both hit. -- CLAUDE.md diff = exactly one added table row: `git diff origin/main...HEAD --stat -- CLAUDE.md` - shows a 1-2 line delta. -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc docs/OFFICIAL-DOCS.md` exit 0; the - repo's offline link-integrity check passes on the new file (external-URL lychee lane is advisory - weekly — spot-check a sample of new URLs via WebFetch instead). - -### Phase 4: Worktree-semantics empirical verification (throwaway spike) [DONE] - -Feasibility spike (might change Phase 5's shape) — results are evidence, no kept code. Parallel-safe -with Phases 1–3 (touches scratchpad + throwaway worktrees only). - -All tests run in a **throwaway `git init` repo in the scratchpad with a synthetic `origin`** — -never in this repo (its ~30 live worktrees, runtime-written `.git/info/exclude`, and main checkout -on a feature branch confound every measurement). Use `claude -p --worktree` exclusively (skips the -trust dialog; interactive mode errors in a fresh repo). Unique worktree names per run (name reuse -resets clean worktrees to base since v2.1.208); the spike removes its own worktrees -(`-p`-created worktrees are never auto-cleaned; Windows: expect NTFS lock retries, -`git worktree remove --force`). - -Work items: - -1. Fresh-fetch the `worktrees` doc (the doc anchor for `baseRef`/`.worktreeinclude` — not the - settings page) plus `settings`; record cited behavior, including the documented fallback - "when `origin/HEAD` isn't resolvable, worktrees fall back to current local HEAD". -2. Smoke test A — `worktree.baseRef: "head"` at **project-settings scope**, two arms: **control** - (`baseRef` unset or `"fresh"`) asserts marker ABSENT; **treatment** (`baseRef: "head"` in - committed `.claude/settings.json`) asserts marker PRESENT. Verdict HONORED only if BOTH arms - behave — a marker-present-only test is defeated by the documented origin/HEAD fallback (false - positive). Variant A2: spawn from within an existing linked worktree (docs state `head` resolves - to that worktree's HEAD — test against that expected value). Variant A3: `settings.json` present - only in the worktree checkout vs only in the main checkout — pins which copy a linked-worktree - session reads (undocumented; only `settings.local.json` is documented as main-checkout-resolved). -3. Smoke test B — `.worktreeinclude` one-way creation-time copy: use real nested-gitignore paths - (`.work//…` ignored via a nested `*` `.gitignore`, mirroring this repo) — not a toy - root-level pattern; assert copy at creation; modify original, assert no sync-back. -4. Smoke test C — worktree-sweep treatment of ignored files (genuinely undocumented — this test is - the only source of truth; capture `git status --ignored` snapshots in the raw transcript) + - `--bg` session worktree base semantics. -5. The sub-agent records raw transcripts in `.work/plugin-philosophy/verifications/`, stamps every - VERDICT file with `claude --version`, and **returns the VERDICT lines by value**; the **main - session** fills the pending rows in this PLAN's "Empirical verification results" table (PLAN.md - edits stay main-session-only) and feeds them into Phase 5's R1/R2 design. If the CC version has - moved by the Phase 5 gate, re-run the cheap test-A control/treatment pair. - -**Sanity Check:** - -- `.work/plugin-philosophy/verifications/` contains ≥ 3 result files, one per smoke test, each - ending in a one-line VERDICT (`HONORED` / `NOT-HONORED` / behavior description) and a - `claude --version` stamp line. -- Test A result file contains BOTH `control:` and `treatment:` lines with opposite marker outcomes - (else verdict is invalid by construction). -- This PLAN's "Empirical verification results" table row 1 is filled (no `(pending)`). - -### Phase 5: Topic-docs contract 2.0.0 + seam fixes R1–R6 (one wave) [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//plugin.json` in the diff. -- `bash scripts/validate-plugins.sh` exit 0 (includes `generate-catalog.mjs --check` — regenerate - the catalog if any plugin.json description changed). -- `npx markdownlint-cli2 --config .markdownlint-cli2.jsonc` on touched .md files exit 0. - -### Phase 6: Marketplace metadata wave [TODO] - -Covers D15 + per-plugin `relevance` quality verification (deferred question c). - -Work items: - -1. Fresh-fetch `plugin-marketplaces` + `discover-plugins` + `plugins-reference` - (default-enablement section) + the dedicated `plugin-relevance` page; re-verify entry schema - (`relevance`, `defaultEnabled`, `displayName`, description precedence, `version` - silent-precedence trap). **`defaultEnabled` flip semantics for already-installed consumers are - undocumented** — if the fetched pages stay silent, run a 2-minute empirical flip on one plugin - before the wave (does a marketplace refresh disable an existing install?). Never touch a - plugin's `name` (breaks existing installs without a `renames` map); `displayName` is safe. -2. Per-plugin pass over all 47 entries: add `relevance` only where the signal is genuinely helpful - (judged per-plugin — noise rejected), `defaultEnabled: false` for personal/niche categories, - `displayName` where it clarifies, complete descriptions; assert **no `version` field in any - entry**. -3. Consumer-facing doc section on org enablement of suggestions (`pluginSuggestionMarketplaces` + - managed-settings source declaration) — lands in the discover/consumer section of README or - OFFICIAL-DOCS per where consumer docs live (decided at execution against the fetched page). -4. Record per-plugin relevance decisions (adopted vs rejected-as-noise) in - `.work/plugin-philosophy/relevance-decisions.md`. -5. Regenerate the README catalog: `node scripts/generate-catalog.mjs` (CI runs `--check`; metadata - edits drift the generated block otherwise). - -**Sanity Check:** - -- `claude plugin validate .` exit 0. -- `node scripts/generate-catalog.mjs --check` exit 0. -- `node -e` assertion: 47 entries; every entry resolves a description (entry or plugin.json); - `version` absent from all entries — exit 0. -- `.work/plugin-philosophy/relevance-decisions.md` has 47 rows. - -### Phase 7: Fleet conformance audit fanout + tracker graduation [TODO] - -Covers D16. Runs against merged doctrine (Phases 1–6 landed). - -Work items: - -1. **Search-before-create (first item):** `gh issue list --search` for an existing - plugin-conformance epic / wave issues. Match found → pivot to updating the existing items - (record the match + pivot in the memory slice); no match → proceed to create. Verify required - labels exist (`gh label list`) and create missing ones before any `gh issue create --label` - call (missing labels fail the create). -2. Derive the audit checklist (~15 dimensions) from the landed doctrine docs: setup criteria (D9), - userConfig migration (D8), exec-form hooks, metadata completeness (D15), component stances (D6), - registry conformance (D11), prereq degradation (D10), pointer discipline (R3), freshness riders - (D7), plus dimensions the doctrine text yields. **Freeze a rubric file** with per-dimension - anchored PASS/FAIL criteria + one worked example, injected verbatim into every worker prompt - (uncalibrated independent scoring across batches encodes rubric drift, not conformance). - **Authority rule:** plugins are scored against **landed doctrine only**; where a fresh-fetched - doc disagrees with doctrine, that is a doctrine-update finding (its own wave), never plugin - nonconformance. Dimensions may not assume R1 is universally in force (local-settings override - exists). Checklist + rubric → memory slice. -3. Fresh-fetch the component doc pages the checklist cites (to detect doctrine-vs-platform drift - per the authority rule above). -4. **Windows `sensitive` userConfig empirical verification** (deferred question a): configure a - throwaway `sensitive` userConfig value on this Windows machine; locate where it persists - (Credential Manager vs plaintext file); VERDICT recorded before any userConfig wave issue - involving secrets is filed. Secrets excluded from that wave if storage is plaintext (tagged - fallback below). -5. Fanout: **pilot batch of 3–5 plugins first**, reviewed by the main session against the rubric - before full fanout; then per-plugin subagents score the remainder in **batches of 8–10**; each - worker writes its own raw report to `.work/plugin-philosophy/audit/.md` (memory-tier - raw output is carved out of R4 — R4's orchestrator-writes rule governs contract/durable tiers) - and returns only its scored dimension row by value; the orchestrator (main session) appends - matrix rows incrementally per batch, so a compaction mid-run loses nothing. **Double-score a - random 3-plugin sample** with independent workers and reconcile disagreements before graduating - the matrix. -6. File the GitHub epic (conformance matrix distilled inline — **single-token score cells only**, - prose lives in per-wave issues; GitHub bodies cap near 64 KB) + per-wave issues (setup, - userConfig, metadata, hooks, convention-seam) via the work-items seam; issues cite the epic + PR - permalinks, never contract/memory paths (R3). Automatable checks list → epic section = deferred - CI gate backlog (D1 trigger). - -**Sanity Check:** - -- Search outcome recorded: `.work/plugin-philosophy/audit/tracker-search.md` states the query + hit - count + create-vs-update decision. -- `ls .work/plugin-philosophy/audit/*.md | wc -l` ≥ 47 (one report per plugin) + matrix file with - 47 scored rows. -- `gh issue list --label epic --search "plugin conformance"` (or equivalent) returns the epic; - epic body contains the matrix; ≥ 5 wave issues reference the epic. -- `grep -c "docs/topics/\|\.work/" ` = 0 (pointer discipline). -- Windows `sensitive` VERDICT file exists in `.work/plugin-philosophy/verifications/`. - -### Empirical verification results - -| # | Question | Phase | VERDICT | -|---|---|---|---| -| 1 | `worktree.baseRef` at project scope; sweep of ignored files; `--bg` base | 4 | HONORED (CC 2.1.212, control+treatment): committed project `.claude/settings.json` `worktree.baseRef: "head"` honored, incl. from linked worktrees (A2: resolves to the worktree's own HEAD; A3: a linked-worktree session reads its OWN checkout's settings.json). `.worktreeinclude`: nested-gitignored files qualify, copy is one-way creation-time. Sweep: `--worktree` worktrees never auto-swept (empirical); subagent/bg sweep would remove ignored-only worktrees (INFERRED — ignored ≠ untracked). `--bg` base = origin/HEAD by default, so R1 moves it to local HEAD. Windows caveat: deep worktree base paths can trip git PATH_MAX (`'$GIT_DIR' too big`); this repo's base (~95 chars) is safe. | -| 2 | Per-plugin `relevance` signal quality | 6 | (pending — per-plugin ledger) | -| 3 | Windows `sensitive` userConfig storage | 7 | (pending) | - -## Blast radius - -**HIGH.** Matches stress-test triggers: new conventions constraining all future work (doctrine + -contract-major), architecture decisions across 47 plugins + 8 implementer materializations, shared -committed settings (`.claude/settings.json`) affecting every session, and undocumented behavior -(worktree semantics, Windows sensitive storage — mitigated by the empirical phases). Reversible via -git revert (docs/metadata only, no runtime code), and existing CI (contract tests, markdownlint, -drift check) gates every PR — hence HIGH, not CRITICAL. - -## Stress-test summary - -Two fresh-context adversarial passes ran; all findings verified against the repo before adoption. - -**Plan-reviewer (Step 3):** 9 IMPORTANT + 5 SUGGESTION, 0 CRITICAL — all applied: implementer-roster -reconciliation + parity check (Phase 5), CI-parity sanity commands (drift `--check`, catalog -`--check`, markdownlint config, `node -e` over Python), pointer-vs-restate check made structural -(Phase 2), Phase 4 by-value/fence contradiction resolved, component-count made variable with a -Wave A join step, PR-chain PLAN lifecycle defined, Phase 7 batching + label verify-or-create, -worktree-variant smoke tests, R1 rollout notes. - -**Devils-advocate (Step 4):** 16 assumptions attacked; 4 mandatory changes, all applied: -(1) Phase 4 redesigned — isolated scratch repo with synthetic origin, control+treatment arms -(defeats the documented origin/HEAD-fallback false positive), settings-scope variant A3, -CC-version-stamped verdicts with re-run at the Phase 5 gate; (2) PLAN lifecycle switched to -branch-local prune-per-PR (the program must not self-violate the contract it ships); (3) 2.0.0 doc -gains a consumer-adoption path — repo settings provably never reach marketplace-installed -consumers; (4) Phase 7 calibration — frozen anchored rubric, pilot batch, double-scored sample. -Also adopted: mandatory `.claude/worktrees/` gitignore in PR B, `WorktreeCreate`-hook caveat for -`.worktreeinclude`, mixed-fleet window statement in the CHANGELOG, doctrine-wins authority rule for -audit scoring, `defaultEnabled`-flip empirical check, matrix cell budget (64 KB body cap), `name` -immutability during the metadata wave. One finding escalated to a user gate: R6 major-vs-minor -contradiction with the contract's own versioning rule (see User-approval gates). - -## Execution shape - -Two parallel-safe waves inside an otherwise sequential PR chain; fanout inside Phase 7. - -| Phase | Surface | Basis | -|---|---|---| -| 1 | Main session | Judgment-heavy doctrine writing; SSOT wording others depend on | -| 2 | Main session | Depends on Phase 1 wording; pointer discipline needs judgment | -| 3 | Sub-agent worker (parallel with 1–2) | Mechanical index build from llms.txt; disjoint files (`OFFICIAL-DOCS.md`, one CLAUDE.md row) | -| 4 | Sub-agent worker (parallel with 1–3) | Scripted smoke tests; touches scratch/throwaway worktrees only | -| 5 | Main session (implementer sweep may fan out mechanically) | Contract-major judgment; 25-file wave needs single editorial voice | -| 6 | Main session | Single file; 47 per-plugin relevance judgments | -| 7 | Workflow/sub-agent fanout, orchestrated by main session | D16-locked fanout; R4 by-value returns | - -Wave A (parallel): Phase 1 (main) ∥ Phase 3 (sub-agent) ∥ Phase 4 (sub-agent). Zero file overlap: -P1 = `docs/PLUGIN-PHILOSOPHY.md`; P3 = `docs/OFFICIAL-DOCS.md` + CLAUDE.md; P4 = `.work/` + scratch. -Wave B (sequential): Phase 2 → Phase 5 → Phase 6 → Phase 7. - -Scope fences (Wave A): P3 agent ALLOWED `docs/OFFICIAL-DOCS.md`, `CLAUDE.md` (one row); -FORBIDDEN everything else incl. PLAN.md. P4 agent ALLOWED `.work/plugin-philosophy/verifications/` -and throwaway `git init` repos under the scratchpad (its own branches/worktrees live there); -FORBIDDEN every file and branch of THIS repo (note: `claude -p --worktree ` creates branches -named `worktree-` — another reason the spike never runs in this repo). -Sequential fallback: any fence violation or agent failure → that phase re-runs inline main-session -in Wave B order. PLAN.md edits are main-session-only. - -Cost note: Wave A = 2 extra agents vs sequential (~saves one serial doc-build + smoke-test round); -Phase 7 = ~47 scoring agents (D16-locked, run regardless of shape). - -## Open questions - -None blocking — the three empirical questions are scheduled inside phases with tagged fallbacks. - -## Handoff to implementation - -### User-approval gates - -- **[BRIEF CONTRADICTION — user decision required]** D13 locks R6 as a **major** contract version - ("2.0.0, one wave"), but the contract's own Versioning rule says major = "moves a tier, renames a - key, or alters the slug spec" — R6 does none (schema KEEP; the change is visibility semantics + - doctrine text). Options: (a) keep 2.0.0 and amend the Versioning rule so visibility-semantics - guarantees also count as major (the doctrine repo then applies its own rule consistently); - (b) downgrade to a 1.x minor, dissolving the one-wave coordination burden and most of Phase 5's - mixed-fleet risk. RECOMMENDED: (a) — the Brief locked the one-wave clean break deliberately, and - a visibility-guarantee change does alter what implementers may rely on; the rule amendment makes - the label honest. The plan as written assumes (a). -- [FALLBACK — confirm or override] Smoke test A fails (project-scope `worktree.baseRef` not - honored): R1 degrades to documenting the limitation + the strongest honored scope in the - convention doc, and an upstream issue is filed; R2/R6 proceed unchanged. -- [FALLBACK — confirm or override] Windows `sensitive` storage is plaintext: secret-bearing - userConfig migrations are excluded from the userConfig wave issue and recorded as blocked-upstream - in the epic; non-secret migrations proceed. -- Scope-expansion of any kind (new convention, new component adoption) mid-flight → stop and ask. - -### Execution shape ([EXEC-SHAPE] tagged) - -- [EXEC-SHAPE] PR slicing: PR A = Phases 1–3 (doctrine + index, current branch - `docs/plugin-philosophy`); PR B = Phases 4–5 (contract 2.0.0 wave; Phase 4 evidence rides the - memory tier, distilled results in PLAN); PR C = Phase 6 (metadata); PR D = close-out (Phase 7's - PLAN/verdict updates + prune-with-pointer). Rationale: reviewability + distinct concerns - (doctrine vs contract-major vs metadata); each PR independently green on existing CI. -- [EXEC-SHAPE] PLAN.md lifecycle across the PR chain — **branch-local, prune-per-PR**: the - topic-docs contract says contract slices are pruned before merge, and this program (which ships - that very contract's 2.0.0) must not self-violate by parking a slice on `main` for weeks. Each PR - branch commits the current PLAN, pastes it into its PR description, and prunes the slice in a - final commit before merge; the next PR branch (cut from post-squash `main`) re-commits the - updated PLAN from the local working tree. Cross-PR continuity = the PR-description pastes + (from - Phase 7) the epic. Close-out at PR D: Phase 7's verdict rows and final status tags commit there, - durable outcomes graduate, final prune-with-pointer. The Windows `sensitive` VERDICT is recorded - durably (PLAN verdict table → PR D description + epic), not only in gitignored `.work/`. - (Alternative rejected: adding a multi-PR-program exception clause to the 2.0.0 lifecycle text — - viable, but it lands only in PR B while PR A would already need it; override at approval if the - exception clause is preferred.) -- [EXEC-SHAPE] Wave A parallelism + fences as tabled above. -- [EXEC-SHAPE] Phase 7 fanout surface: per-plugin subagents (Workflow engine if available, plain - sub-agent fanout otherwise) — D16 locks the fanout itself. -- [EXEC-SHAPE] Empirical verifications embedded at Brief-assigned execution points (P4/P6/P7) - rather than a standalone verification phase. - -### Mechanical work - -- Commit boundaries: one commit per phase minimum; Phase 5 = one wave commit for the contract bump + - implementer adoption (clean break lands atomically); PLAN.md status-tag updates ride each phase's - commit. Each PR branch is cut from **post-squash `main`**, never from the previous PR branch - (stacking would replay the prior PR's squashed commits in the diff). -- Verification checkpoints: run each phase's Sanity Check before its commit; existing CI - (contract tests, markdownlint, drift check) green before each PR merge. -- Sequential fallback: documented under Execution shape; orchestrator-writes rule (R4) applies to - all fanout output. -- Close-out: `/architect close-out` at PR time — PLAN.md into PR description `
`, durable - outcomes graduate (vault_backend `docs`), contract slice pruned with pointer. From 35cf8af906472cad25cf05acce0999a08f5873a4 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:31:18 -0400 Subject: [PATCH 04/12] chore: trigger CI (pull_request workflows did not fire on open) From 5d3da2c0f120304023e88f9c8d331f1a91ff5999 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:53:44 -0400 Subject: [PATCH 05/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rev?= =?UTF-8?q?iew=20=E2=80=94=20carry=20self-ignore=20file,=20checkout-not-pr?= =?UTF-8?q?ocess=20by-value=20boundary,=20glob-skip=20in=20sync=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .worktreeinclude (repo + convention template) carries .work/.gitignore so copied memory files are ignored in a fresh worktree from creation. - By-value rule scoped to the checkout, not the process: same-checkout forks (discovery -deep variants) write the memory slice directly; only workers in their own checkout return by value. Owner doc, discovery binding, and the discovery CHANGELOG entry aligned. - /pull-request create worktreeinclude sync check skips unmatched globs (source-control 0.5.2) instead of reporting phantom CHANGED lines. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- .worktreeinclude | 3 +++ docs/conventions/topic-docs/README.md | 17 +++++++++++++---- plugins/discovery/CHANGELOG.md | 8 +++++--- plugins/discovery/reference/topic-docs.md | 8 +++++--- .../source-control/.claude-plugin/plugin.json | 2 +- plugins/source-control/CHANGELOG.md | 8 ++++++++ .../skills/pull-request/reference/create.md | 10 ++++++++-- 7 files changed, 43 insertions(+), 13 deletions(-) diff --git a/.worktreeinclude b/.worktreeinclude index 97a6f86d2..b2cc4c7ce 100644 --- a/.worktreeinclude +++ b/.worktreeinclude @@ -1,5 +1,8 @@ # Memory-tier files worth carrying into new worktrees (one-way, creation-time # copy; gitignored-only). Never baselines or raw scratch — machine-bound. +# The self-ignore file rides along so carried files stay ignored in the new +# worktree from creation, not only after the first memory-tier write heals it. +.work/.gitignore .work/*/EXPLORE.md .work/*/EXPLORE-*.md .work/*/RESEARCH.md diff --git a/docs/conventions/topic-docs/README.md b/docs/conventions/topic-docs/README.md index c9ec44829..7d08c426a 100644 --- a/docs/conventions/topic-docs/README.md +++ b/docs/conventions/topic-docs/README.md @@ -109,13 +109,16 @@ Four native mechanisms, no custom machinery: (machine-bound). Caveat: a `WorktreeCreate` hook replaces the default worktree creation entirely and `.worktreeinclude` is **not processed** — the hook script owns any copying. -- **By-value returns** — an isolated worker (subagent worktree, - background session, dispatched fanout) returns its results **by +- **By-value returns** — a worker running in its **own checkout** + (subagent worktree, background session) returns its results **by value**; the orchestrating session writes the contract and durable tiers in the parent checkout. Workers never write those tiers from an isolated checkout — commits and promotions land where the lifecycle - can see them. Raw per-worker output may land directly in the parent - checkout's memory slice when the orchestrator directs it there. + can see them. The boundary is the checkout, not the process: a forked + subagent running in the parent's checkout may write the memory slice + directly (its writes are already visible), and raw per-worker output + may land in the parent checkout's memory slice when the orchestrator + directs it there. - **Tracker as the cross-lane index** — the work-item tracker is the awareness layer across lanes: branch files stay lane-local, and a session in another lane discovers state through tickets, which point @@ -152,6 +155,7 @@ repository root (substitute a non-default resolved `memory_dir` for `.work`): ```text +.work/.gitignore .work/*/EXPLORE.md .work/*/EXPLORE-*.md .work/*/RESEARCH.md @@ -159,6 +163,11 @@ repository root (substitute a non-default resolved `memory_dir` for .work/*/*-checklist.md ``` +The first line carries the memory root's self-ignore file so the copied +files are ignored in the new worktree from creation; without it they +surface as untracked until the self-ignore guard heals on the first +memory-tier write. + Also gitignore `.claude/worktrees/` so worktree contents never appear as untracked files. Rollout caveats: pulling a commit that adds `.claude/settings.json` into a clone already holding an untracked file diff --git a/plugins/discovery/CHANGELOG.md b/plugins/discovery/CHANGELOG.md index aea5e3e4e..21ed7c3bb 100644 --- a/plugins/discovery/CHANGELOG.md +++ b/plugins/discovery/CHANGELOG.md @@ -5,9 +5,11 @@ ### Changed - Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` states that - `EXPLORE.md` / `RESEARCH.md` are checkout-local, are the cross-checkout-useful kind the - contract's `.worktreeinclude` template carries into new worktrees, and that forked/deep workers - return findings by value with the parent session writing the memory slice. + `EXPLORE.md` / `RESEARCH.md` are checkout-local and are the cross-checkout-useful kind the + contract's `.worktreeinclude` template carries into new worktrees. The by-value boundary is the + checkout, not the process: the `-deep` forks run in the parent's checkout and write the + artifacts there directly; only workers dispatched into their own checkout return findings by + value for the parent to write. ## 0.5.1 — 2026-07-15 diff --git a/plugins/discovery/reference/topic-docs.md b/plugins/discovery/reference/topic-docs.md index eab910235..33a0ae9ba 100644 --- a/plugins/discovery/reference/topic-docs.md +++ b/plugins/discovery/reference/topic-docs.md @@ -30,6 +30,8 @@ contract's **non-interactive / forked mode** rule. These artifacts are memory-tier, so they exist only in the checkout that wrote them. They are exactly the cross-checkout-useful kind the contract's `.worktreeinclude` template carries into new -worktrees (one-way, at creation time) where the consuming repo materializes it. Isolated workers -(`-deep` variants, forked subagents) return findings **by value**; the parent session writes the -memory slice in its own checkout — a worker's checkout-local writes are not the record. +worktrees (one-way, at creation time) where the consuming repo materializes it. The contract's +by-value boundary is the checkout, not the process: the `-deep` forks run in the parent's checkout +and write `EXPLORE.md` / `RESEARCH.md` there directly (already visible to the parent), returning a +summary by value; a worker dispatched into its **own** checkout (worktree or background session) +returns findings by value instead, and the parent writes the memory slice. diff --git a/plugins/source-control/.claude-plugin/plugin.json b/plugins/source-control/.claude-plugin/plugin.json index 9943dc455..21b4de0b7 100644 --- a/plugins/source-control/.claude-plugin/plugin.json +++ b/plugins/source-control/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "source-control", - "version": "0.5.1", + "version": "0.5.2", "description": "Git and GitHub delivery workflow: /commit (Conventional Commits + Co-Authored-By trailer via safe heredoc mechanics), /pull-request (prep, create, CI monitoring, review-comment triage, merge, multi-PR babysit loop), /worktree (create, status, cleanup, audit for parallel-session isolation), /setup (interview the repo and write the tracked commit-subject / PR-title convention config), and /resolve-conflicts (intent-first merge/rebase conflict resolution with a semantic-conflict sweep — never --abort). The commit-subject / PR-title convention is configurable per repo via a tracked .claude/source-control.md config written by a re-runnable setup skill; Conventional Commits is the default when no convention is declared.", "author": { "name": "Melodic Software", diff --git a/plugins/source-control/CHANGELOG.md b/plugins/source-control/CHANGELOG.md index 561e9ad61..1b7b525c8 100644 --- a/plugins/source-control/CHANGELOG.md +++ b/plugins/source-control/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the `source-control` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.5.2] + +### Fixed + +- `/pull-request create`'s worktreeinclude sync check no longer reports phantom `CHANGED:` lines + for `.worktreeinclude` patterns that match no files — an unmatched glob stays a literal string + in Bash and previously fell through to the changed-file branch; it is now skipped. + ## [0.5.1] ### Changed diff --git a/plugins/source-control/skills/pull-request/reference/create.md b/plugins/source-control/skills/pull-request/reference/create.md index 6bd3b5d9a..be0a2b68e 100644 --- a/plugins/source-control/skills/pull-request/reference/create.md +++ b/plugins/source-control/skills/pull-request/reference/create.md @@ -19,9 +19,15 @@ # Read .worktreeinclude patterns (one per line, .gitignore syntax) while IFS= read -r pattern; do [[ -z "$pattern" || "$pattern" == \#* ]] && continue - # For each matching file, diff worktree vs main + # For each matching file, diff worktree vs main. An unmatched glob + # stays literal — skip it (no phantom CHANGED for absent files). for f in $pattern; do - [[ -f "$f" && -f "$MAIN_ROOT/$f" ]] && diff -q "$f" "$MAIN_ROOT/$f" >/dev/null 2>&1 || echo "CHANGED: $f" + [[ -f "$f" ]] || continue + if [[ -f "$MAIN_ROOT/$f" ]]; then + diff -q "$f" "$MAIN_ROOT/$f" >/dev/null 2>&1 || echo "CHANGED: $f" + else + echo "CHANGED: $f" + fi done done < .worktreeinclude fi From 6502ccbf537739eb52124fe2880a60458ab4b235 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:05:57 -0400 Subject: [PATCH 06/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=202=20=E2=80=94=20durable=20pointers=20in=20wayfind=20maps,?= =?UTF-8?q?=20pre-PR=20provenance=20backfill=20in=20decompose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /planning:wayfind map Notes carry durable pointers only; memory-tier content is distilled inline (tracker issues are durable surfaces). - /work-items:decompose pre-PR publishes record slug + phase and backfill the PR reference as a comment when it opens, so provenance survives the prune. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- plugins/planning/CHANGELOG.md | 3 +++ plugins/planning/skills/wayfind/SKILL.md | 4 +++- plugins/planning/skills/wayfind/context/map-anatomy.md | 4 +++- plugins/work-items/CHANGELOG.md | 3 ++- plugins/work-items/skills/decompose/SKILL.md | 6 ++++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/planning/CHANGELOG.md b/plugins/planning/CHANGELOG.md index 66bcccb80..bd1f363e2 100644 --- a/plugins/planning/CHANGELOG.md +++ b/plugins/planning/CHANGELOG.md @@ -11,6 +11,9 @@ All notable changes to the `planning` plugin are documented here. Format follows baselines are checkout-local and `PLAN.md` carries distilled values only; `/planning:architect`'s baseline step no longer directs `PLAN.md` to reference the stored memory-slice capture (pointer discipline — the path is invisible outside the writing checkout). +- `/planning:wayfind` map-issue Notes carry durable pointers only (PRs, committed docs, prior + items, external links); memory-tier artifact content is distilled inline instead of pointed at — + tracker issues are durable surfaces under the contract's pointer discipline. ## [0.13.0] diff --git a/plugins/planning/skills/wayfind/SKILL.md b/plugins/planning/skills/wayfind/SKILL.md index 747e4edec..f6a88d72f 100644 --- a/plugins/planning/skills/wayfind/SKILL.md +++ b/plugins/planning/skills/wayfind/SKILL.md @@ -81,7 +81,9 @@ an interactive session — do not fabricate a map. source of truth, STOP and report the exact missing set to that owner; otherwise report the set and ask the user how labels are provisioned. Never create labels ad hoc from this skill. Then create one issue labelled bare `work-map` (+ any repo program labels). Body carries the five sections — **Destination** (where this is going once the - fog clears) / **Notes** (pointers to memory-tier `/` artifacts, research, prior context) / + fog clears) / **Notes** (durable pointers only — PRs, committed docs, prior items, external links; + memory-tier `/` artifacts are checkout-local, so distill their relevant content inline + instead of pointing at paths other readers cannot resolve) / **Decisions-so-far** (a *pointer index* — each resolved decision's home is its own item's resolution comment, never recopied here) / **Not-yet-specified** (fog, prose) / **Out-of-scope**. Template + exact `gh` calls: [`context/tracker-mechanics.md`](context/tracker-mechanics.md). diff --git a/plugins/planning/skills/wayfind/context/map-anatomy.md b/plugins/planning/skills/wayfind/context/map-anatomy.md index 9005821c4..83cf1a8e0 100644 --- a/plugins/planning/skills/wayfind/context/map-anatomy.md +++ b/plugins/planning/skills/wayfind/context/map-anatomy.md @@ -15,7 +15,9 @@ graduate into. One paragraph. This is the map's success condition.> ## Notes -- Pointers to `//` (default `.work/`) execution artifacts, prior research, upstream context. +- Durable pointers only: PRs, committed docs, prior items, external links. +- Memory-tier `//` artifacts are checkout-local — distill what matters into a + line here instead of pointing at a path other readers cannot resolve. - Links, not recaps. ## Decisions-so-far diff --git a/plugins/work-items/CHANGELOG.md b/plugins/work-items/CHANGELOG.md index cf259399f..61cbcac5e 100644 --- a/plugins/work-items/CHANGELOG.md +++ b/plugins/work-items/CHANGELOG.md @@ -10,7 +10,8 @@ All notable changes to the `work-items` plugin are documented here. Format follo - Adopt topic-docs contract 2.0.0 (visibility semantics): `reference/topic-docs.md` names the tracker as the contract's cross-lane index — tickets point, never store primary artifacts; `/work-items:decompose` ticket provenance now cites the PR carrying the source plan instead of - the contract-slice path, which is pruned before merge and would dangle. + the contract-slice path, which is pruned before merge and would dangle. Pre-PR publishes record + slug + phase (a label, not a path) and backfill the PR reference as a comment once it opens. ## [0.8.0] diff --git a/plugins/work-items/skills/decompose/SKILL.md b/plugins/work-items/skills/decompose/SKILL.md index 6b6c47799..f3ff56e1f 100644 --- a/plugins/work-items/skills/decompose/SKILL.md +++ b/plugins/work-items/skills/decompose/SKILL.md @@ -133,8 +133,10 @@ Use agent-brief body format (see [`${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.m Refs # (if source was an existing item) + exists. Before that PR exists, slug + phase alone is correct (it is a label, not a path); + when the PR opens, backfill it as a comment on each published item so the provenance + survives the slice prune. Never write the contract-slice path: the slice is pruned before + merge, so the pointer would dangle (topic-docs pointer discipline). --> ## What to build From c6fbb542b5e4ac6173ccde2841ab7cad1ee724c6 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:14:54 -0400 Subject: [PATCH 07/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=203=20=E2=80=94=20worktreeinclude=20sync=20detects=20deletio?= =?UTF-8?q?ns=20and=20creates=20parent=20dirs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Detection also expands each pattern from MAIN_ROOT so a carried file deleted in the worktree surfaces as DELETED instead of silently reappearing in future worktrees. - Copy-to-main mkdir -p's the destination parent (new topic slugs have no directory in main yet); new files diff against /dev/null; DELETED files offer removal of main's copy. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- .../skills/pull-request/reference/create.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/plugins/source-control/skills/pull-request/reference/create.md b/plugins/source-control/skills/pull-request/reference/create.md index be0a2b68e..52cfdcd6a 100644 --- a/plugins/source-control/skills/pull-request/reference/create.md +++ b/plugins/source-control/skills/pull-request/reference/create.md @@ -19,28 +19,36 @@ # Read .worktreeinclude patterns (one per line, .gitignore syntax) while IFS= read -r pattern; do [[ -z "$pattern" || "$pattern" == \#* ]] && continue - # For each matching file, diff worktree vs main. An unmatched glob - # stays literal — skip it (no phantom CHANGED for absent files). + # Worktree side: modified or new files. An unmatched glob stays + # literal — skip it (no phantom CHANGED for absent files). for f in $pattern; do [[ -f "$f" ]] || continue if [[ -f "$MAIN_ROOT/$f" ]]; then diff -q "$f" "$MAIN_ROOT/$f" >/dev/null 2>&1 || echo "CHANGED: $f" else - echo "CHANGED: $f" + echo "CHANGED (new): $f" fi done + # Main side: a carried file deleted in the worktree no longer expands + # locally — expand from MAIN_ROOT too so deletions surface. + for m in "$MAIN_ROOT"/$pattern; do + [[ -f "$m" ]] || continue + f="${m#"$MAIN_ROOT"/}" + [[ -f "$f" ]] || echo "DELETED in worktree: $f" + done done < .worktreeinclude fi ``` **If differences found:** - 1. Show diff for each changed file (`diff --unified "$MAIN_ROOT/$f" "$f"`) + 1. Show diff for each changed file (`diff --unified "$MAIN_ROOT/$f" "$f"`; for a `(new)` file + diff against `/dev/null` — main has no copy yet; for a `DELETED` file show main's copy) 2. Show active worktrees (`git worktree list`) — if >1 worktree exists beyond main, warn: *"Other active worktrees have their own copies of this file. Overwriting main's copy won't affect existing worktrees but will affect future ones."* 3. Present options per file: - - **Copy to main** — overwrite main's copy with worktree's version. Safe for cosmetic changes (reordering), new additions, or when this is the only active session + - **Copy to main** — overwrite main's copy with worktree's version (for a `DELETED` file, remove main's copy so future worktrees stop re-carrying it). Safe for cosmetic changes (reordering), new additions, or when this is the only active session - **Skip** — proceed without syncing. User accepts that worktree changes will be lost on cleanup - 4. If user chooses "copy to main": `cp "$f" "$MAIN_ROOT/$f"` + 4. If user chooses "copy to main": `mkdir -p "$(dirname "$MAIN_ROOT/$f")" && cp "$f" "$MAIN_ROOT/$f"` (a new topic slug has no parent directory in main yet); for a `DELETED` file: `rm "$MAIN_ROOT/$f"` **Why here (not WorktreeRemove hook):** this is the last intentional checkpoint where user is engaged and can inspect a diff. WorktreeRemove hooks cannot block removal or prompt — a silent copy could overwrite concurrent session changes. One mechanism per concern. From 6693d68e3433779a048914dc8d59c73fe908ac63 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:27:51 -0400 Subject: [PATCH 08/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=204=20=E2=80=94=20run=20worktreeinclude=20sync=20from=20the?= =?UTF-8?q?=20worktree=20toplevel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .worktreeinclude lives at the repo root with root-relative globs; the detection snippet now cd's to git rev-parse --show-toplevel first, so invocations from a subdirectory neither skip nor misexpand the check. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a From c924b098553cf680e4d820414c7fd6d0879a8456 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:36:24 -0400 Subject: [PATCH 09/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=205=20=E2=80=94=20absent=20carried=20files=20are=20ambiguous?= =?UTF-8?q?,=20never=20auto-remove=20from=20main?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An absent local file may have been deleted here or never carried at all (manual git worktree add, pre-.worktreeinclude worktree). Detection reports ABSENT instead of DELETED; removing main's copy now requires explicit user confirmation of a deliberate same-session deletion, defaulting to Skip. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- .../skills/pull-request/reference/create.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/source-control/skills/pull-request/reference/create.md b/plugins/source-control/skills/pull-request/reference/create.md index 514250ce0..de5bcc393 100644 --- a/plugins/source-control/skills/pull-request/reference/create.md +++ b/plugins/source-control/skills/pull-request/reference/create.md @@ -33,11 +33,13 @@ fi done # Main side: a carried file deleted in the worktree no longer expands - # locally — expand from MAIN_ROOT too so deletions surface. + # locally — expand from MAIN_ROOT too. ABSENT is ambiguous: the file may + # have been deleted here, or never copied at all (manual `git worktree + # add`, or a worktree created before .worktreeinclude existed). for m in "$MAIN_ROOT"/$pattern; do [[ -f "$m" ]] || continue f="${m#"$MAIN_ROOT"/}" - [[ -f "$f" ]] || echo "DELETED in worktree: $f" + [[ -f "$f" ]] || echo "ABSENT here (deleted, or never carried): $f" done done < .worktreeinclude fi @@ -46,12 +48,13 @@ **If differences found:** 1. Show diff for each changed file (`diff --unified "$MAIN_ROOT/$f" "$f"`; for a `(new)` file - diff against `/dev/null` — main has no copy yet; for a `DELETED` file show main's copy) + diff against `/dev/null` — main has no copy yet; for an `ABSENT` file show main's copy) 2. Show active worktrees (`git worktree list`) — if >1 worktree exists beyond main, warn: *"Other active worktrees have their own copies of this file. Overwriting main's copy won't affect existing worktrees but will affect future ones."* 3. Present options per file: - - **Copy to main** — overwrite main's copy with worktree's version (for a `DELETED` file, remove main's copy so future worktrees stop re-carrying it). Safe for cosmetic changes (reordering), new additions, or when this is the only active session + - **Copy to main** — overwrite main's copy with worktree's version. Safe for cosmetic changes (reordering), new additions, or when this is the only active session - **Skip** — proceed without syncing. User accepts that worktree changes will be lost on cleanup - 4. If user chooses "copy to main": `mkdir -p "$(dirname "$MAIN_ROOT/$f")" && cp "$f" "$MAIN_ROOT/$f"` (a new topic slug has no parent directory in main yet); for a `DELETED` file: `rm "$MAIN_ROOT/$f"` + - For an `ABSENT` file only: **Remove from main** — offered only if the user confirms the file was deliberately deleted in this worktree this session. ABSENT is ambiguous (a manual or pre-`.worktreeinclude` worktree never received the copy), so default to **Skip**; never remove main's copy without that explicit confirmation + 4. If user chooses "copy to main": `mkdir -p "$(dirname "$MAIN_ROOT/$f")" && cp "$f" "$MAIN_ROOT/$f"` (a new topic slug has no parent directory in main yet); confirmed deliberate deletion: `rm "$MAIN_ROOT/$f"` **Why here (not WorktreeRemove hook):** this is the last intentional checkpoint where user is engaged and can inspect a diff. WorktreeRemove hooks cannot block removal or prompt — a silent copy could overwrite concurrent session changes. One mechanism per concern. From 323eb8c11b5efdbdc40b7cf4b865a17ad5a0caf3 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:58:50 -0400 Subject: [PATCH 10/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=206=20=E2=80=94=20worktree=20cleanup=20guards=20carried=20ig?= =?UTF-8?q?nored=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git worktree remove exits 0 on a tree whose only edits are gitignored, so /worktree cleanup now diffs .worktreeinclude-carried files against the main checkout before any removal and offers the copy-to-main sync first. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- plugins/source-control/skills/worktree/context/cleanup.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/source-control/skills/worktree/context/cleanup.md b/plugins/source-control/skills/worktree/context/cleanup.md index 1e674d2cc..0dcd2381c 100644 --- a/plugins/source-control/skills/worktree/context/cleanup.md +++ b/plugins/source-control/skills/worktree/context/cleanup.md @@ -66,6 +66,14 @@ rm -rf git worktree remove ``` +**Carried-ignored-file guard (before ANY removal, plain or forced):** `git worktree remove` +succeeds on a worktree whose only edits are gitignored files — `status --porcelain` does not show +them, so plain removal silently discards them. When the repo root has a `.worktreeinclude`, diff +each carried file against the main checkout's copy first (same per-pattern loop as +`/pull-request create`'s pre-flight: expand each pattern from the worktree toplevel, skip +unmatched globs, compare against `MAIN_ROOT`). Any differing or new carried file → offer the +copy-to-main sync before removing; removal without that offer loses the edits with exit 0. + **Escalation guard (before any `--force`):** when the plain removal fails, inspect why — `git -C status --porcelain` (uncommitted edits) and `git -C log --branches --not --remotes --oneline | head` (unpushed commits). If either is non-empty, present the summary to the user and get explicit per-worktree confirmation BEFORE forcing — forced removal permanently discards those changes. Only after confirmation (or when the failure is a lock/metadata issue with a verifiably clean tree): ```bash From c26f7006cb2149c8976d848de2e03f85ab8caddd Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 17:09:16 -0400 Subject: [PATCH 11/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=207=20=E2=80=94=20cleanup=20guard=20covers=20main-side=20abs?= =?UTF-8?q?ent=20carried=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cleanup carried-file pass now mirrors the pre-flight fully: main-side expansion surfaces files absent in the worktree, with removal of main's copy gated on explicit deliberate-deletion confirmation (default keep). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- .../source-control/skills/worktree/context/cleanup.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/source-control/skills/worktree/context/cleanup.md b/plugins/source-control/skills/worktree/context/cleanup.md index 0dcd2381c..06b4f2cf4 100644 --- a/plugins/source-control/skills/worktree/context/cleanup.md +++ b/plugins/source-control/skills/worktree/context/cleanup.md @@ -68,11 +68,12 @@ git worktree remove **Carried-ignored-file guard (before ANY removal, plain or forced):** `git worktree remove` succeeds on a worktree whose only edits are gitignored files — `status --porcelain` does not show -them, so plain removal silently discards them. When the repo root has a `.worktreeinclude`, diff -each carried file against the main checkout's copy first (same per-pattern loop as -`/pull-request create`'s pre-flight: expand each pattern from the worktree toplevel, skip -unmatched globs, compare against `MAIN_ROOT`). Any differing or new carried file → offer the -copy-to-main sync before removing; removal without that offer loses the edits with exit 0. +them, so plain removal silently discards them. When the repo root has a `.worktreeinclude`, run +the same per-pattern comparison as `/pull-request create`'s pre-flight — expand each pattern from +the worktree toplevel (skip unmatched globs) AND from `MAIN_ROOT` — before removing. Differing or +new carried file → offer the copy-to-main sync; main-side file ABSENT in the worktree → offer +removing main's copy only on explicit confirmation of a deliberate deletion (default keep — the +file may simply never have been carried). Removal without this pass loses the edits with exit 0. **Escalation guard (before any `--force`):** when the plain removal fails, inspect why — `git -C status --porcelain` (uncommitted edits) and `git -C log --branches --not --remotes --oneline | head` (unpushed commits). If either is non-empty, present the summary to the user and get explicit per-worktree confirmation BEFORE forcing — forced removal permanently discards those changes. Only after confirmation (or when the failure is a lock/metadata issue with a verifiably clean tree): From a87f75c9fafd4716474a48177c4779412f4b3d8d Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 17 Jul 2026 17:19:39 -0400 Subject: [PATCH 12/12] =?UTF-8?q?docs(topic-docs):=20address=20Codex=20rou?= =?UTF-8?q?nd=208=20=E2=80=94=20qualify=20wayfind=20no-recaps=20rule=20for?= =?UTF-8?q?=20memory=20distillation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Links, not recaps" now names the memory-tier distillation as its one sanctioned exception; no other reader can follow such a link, so the distilled line is the preserved context. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01M1owJj9ZzkV36V3C1CyX4a --- plugins/planning/skills/wayfind/context/map-anatomy.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/planning/skills/wayfind/context/map-anatomy.md b/plugins/planning/skills/wayfind/context/map-anatomy.md index de37bffb3..c7831646a 100644 --- a/plugins/planning/skills/wayfind/context/map-anatomy.md +++ b/plugins/planning/skills/wayfind/context/map-anatomy.md @@ -18,7 +18,9 @@ graduate into. One paragraph. This is the map's success condition.> - Durable pointers only: PRs, committed docs, prior items, external links. - Memory-tier `//` artifacts are checkout-local — distill what matters into a line here instead of pointing at a path other readers cannot resolve. -- Links, not recaps. +- Links, not recaps — for anything durably linkable. The memory-tier distillation above is the + one sanctioned exception: no other reader can follow such a link, so the distilled line IS the + preserved context. ## Decisions-so-far