# Plan: Adept discovery and tiered knowledge folders **Design**: `designs/2026-09-18-adept-discovery.md` **Date**: 2026-09-18 --- ## Decisions ### Q1: Journal relocation — worth the churn? **Decision: Move journals to `journal/` subfolder.** No existing adept folders exist in this repo, so there is zero churn here. The design's lazy migration path (next adept into a legacy folder does the `git mv`) is sound for other projects. The clean `ls` benefit is real and permanent; the migration cost is one-time and bounded. ### Q2: Doc vocabulary — fixed or free? **Decision: Suggested vocabulary, free additions, index rule enforces discoverability.** A fixed vocabulary would be over-prescriptive for domains that don't map cleanly to `key-files / conventions / architecture / gotchas`. The index rule ("if it is not listed in CLAUDE.md, it does not exist") is the enforcement mechanism — it makes free naming safe. The `_template/CLAUDE.md` should list the suggested names as comments so a founding adept sees the vocabulary without being constrained by it. ### Q3: `## Adepts` in journal — grepping enough, or add a counter? **Decision: Grepping is enough.** A counter is exactly the hand-maintained metadata the design principle forbids. The `## Adepts` section in the journal provides a grep-friendly surface (`grep -l 'auth —' journals/`). If someone ever wants counts, a one-liner over journal files derives them. ### Q4: `roster.sh` location — skill folder vs. Justfile recipe **Decision: Skill folder (`${CLAUDE_SKILL_DIR}/roster.sh`).** This avoids a Justfile dependency that the design otherwise does not introduce. The Justfile in this repo is currently unstaged and minimal. Adding a `just adepts` recipe would couple a plugin-internal concern to the consuming project's build tool. The skill folder is the natural home — `spire:project` already uses the same `${CLAUDE_SKILL_DIR}` mechanism for `cat`. ### Q5: Parallel sessions — acceptable conflict risk? **Decision: Acceptable for now; document the worktree in `handoff.md`.** The conflict surface is `handoff.md`, which is short and human-resolvable. The adept should record its worktree/branch in `handoff.md`'s frontmatter `branch:` field (already in the design). Rare enough that engineering a lock or merge protocol would be premature. --- ## Implementation Phases ### Phase 1 — New `spire:adepts` skill (the roster) **Dependencies**: None. Foundational new component. #### 1.1 Create `plugins/spire/skills/adepts/SKILL.md` Content per design §D. Frontmatter: ```yaml --- name: adepts description: Lists the adept domains in the workpad — what each covers, when it was last active, its status. Loaded by Igor at boot; any agent may invoke it for a fresh listing. allowed-tools: Bash(bash:*) --- ``` Body: the shell-injection line `` !`bash "${CLAUDE_SKILL_DIR}/roster.sh"` `` followed by the empty-roster comment. #### 1.2 Create `plugins/spire/skills/adepts/roster.sh` Implement the script from design §D. Key implementation details: - Workpad resolution: `WORKPAD_FOLDER` env var → `just workpad-folder 2>/dev/null` → `docs/workpad` → `.workpad`. Also grep `.claude/spire/project.md` for the `Workpad:` line as fallback for the external-tickets-folder case. - Iterate `"$WP"/adepts/*/`, skip `_template`. - Parse frontmatter from each domain's `CLAUDE.md` using `sed` (extract lines between opening and closing `---`). - Derive `newest` and `sessions` from `journal/` filenames (also check the domain root for legacy `YYYY-MM-DD-HH-journal-*` files for backward compatibility with unmigrated folders). - Output one `- **slug** — summary ...` line per domain. - Make the script executable (`chmod +x`). #### Verification - `bash plugins/spire/skills/adepts/roster.sh` in a repo with no `adepts/` folder produces the "none" fallback line. - Frontmatter parsing handles values with colons, and files with no frontmatter produce empty output (not errors). --- ### Phase 2 — Update `agents/adept.md` (tiered layout + handoff protocol) **Dependencies**: None (parallel with Phase 1). #### 2.1 Rewrite domain folder structure section Replace current `## Domain folder structure` (lines 62-66) with new layout from design §A (showing `journal/` subfolder, `handoff.md`, knowledge docs). #### 2.2 Split genesis into founding and successor protocols Replace current `## Genesis` section (lines 18-31) with two subsections: - **Successor genesis** (design §E): nine numbered steps — read `adepts/CLAUDE.md`, read domain `CLAUDE.md` (index), read `handoff.md`, run drift check, read Must-read docs, read only named journal entries, verify-and-correct if drift found, write genesis journal, rewrite `handoff.md`. - **Founding genesis** (design §E): copy `_template/CLAUDE.md` and `_template/handoff.md`, fill frontmatter during orientation, create at minimum `key-files.md`, write `handoff.md` before first consultation with `verified-at` = current HEAD, write genesis journal entry. #### 2.3 Add handoff.md duties New section `## Handoff` after genesis: rolling, overwritten, short (≤40 lines). Written early, refreshed after significant consultations. Frontmatter fields: `updated`, `session`, `branch`, `verified-at`. The drift check mechanism. #### 2.4 Update consultation section Add after existing point 5: refresh `handoff.md` after state-changing consultations; use `Skill("spire:adepts")` for sibling discovery; update index when adding docs. #### 2.5 Add index maintenance rules `CLAUDE.md` stays under ~60 lines. Tiers are conditional (state the condition). Docs split at ~200 lines. Siblings introspected on demand, not preloaded. Every root file must appear in the index. #### 2.6 Update end-of-life and knowledge tiers Make "wrap up" concrete (refresh handoff, closing journal). Add four-tier table from design §A. #### Verification - No reference to flat `YYYY-MM-DD-HH-journal-.md` at root level remains. - Both founding and successor genesis protocols present as distinct subsections. - `handoff.md` mentioned with overwrite-not-append rule. --- ### Phase 3 — Update `skills/igor/SKILL.md` (roster integration + spawning) **Dependencies**: Phase 1 (skill must exist to be referenced). #### 3.1 Rewrite `## Adepts` section Remove "Check the workpad's `adepts/` folder before spawning." Replace with: roster is loaded by `spire:adepts` at boot; Igor does not read adept folders directly. Two brief shapes (successor vs. founding). Roster matching uses the gravity-well rule. Shell-disabled fallback: Haiku subagent runs `roster.sh`. #### 3.2 Update session start steps After creating journal: seed `## Adepts` from roster rows relevant to topic. May name a matching adept in the greeting. #### 3.3 Add wrap-up step for adepts In session lifecycle wrap-up: `SendMessage` each live adept to close, wait via `ListAgents`, journal final state per adept. #### Verification - No reference to "Check the workpad's `adepts/` folder" remains. - Both brief shapes present. Fallback documented. --- ### Phase 4 — Update `agents/igor.md` (add skill) **Dependencies**: Phase 1. Add `spire:adepts` to `skills:` list after `spire:workpad`. --- ### Phase 5 — Update journal template **Dependencies**: None (parallel with other phases). Add `## Adepts` section between `## Log` and `## Artifacts` in `skills/igor/references/journal-template.md`. --- ### Phase 6 — Update `skills/init/SKILL.md` (new templates) **Dependencies**: Phases 1-2 (references the new layout). - Rewrite Phase 4 `adepts/CLAUDE.md` content to match design §G. - Rewrite `_template/CLAUDE.md` to be an index template with frontmatter and tiered reading list. - Add `_template/handoff.md` template. - Update Phase 7 commit file list. --- ### Phase 7 — Update supporting files **Dependencies**: None (logically last). - `skills/workpad/SKILL.md`: add `adepts/` to optional-folders list. - `skills/igor/references/project.md`: update `Adepts:` line to reference roster. - `skills/curator/SKILL.md`: add scope note distinguishing knowledge docs (curator targets) from handoff/journal (not targets). --- ## Commit Strategy **Commit 1** — `✨ Add spire:adepts roster skill` - `plugins/spire/skills/adepts/SKILL.md`, `plugins/spire/skills/adepts/roster.sh` **Commit 2** — `🤖 Update adept agent for tiered layout and handoff protocol` - `plugins/spire/agents/adept.md` **Commit 3** — `🤖 Wire Igor to use adept roster for discovery and spawning` - `plugins/spire/skills/igor/SKILL.md`, `plugins/spire/agents/igor.md`, `plugins/spire/skills/igor/references/journal-template.md` **Commit 4** — `🤖 Update init templates and supporting files for adept discovery` - `plugins/spire/skills/init/SKILL.md`, `plugins/spire/skills/workpad/SKILL.md`, `plugins/spire/skills/igor/references/project.md`, `plugins/spire/skills/curator/SKILL.md` --- ## Fact-Check Items ### From the design (questions 6-10) **FC-1 (Q6)**: Nested `CLAUDE.md` auto-loading — does the harness load `/CLAUDE.md` when a subagent reads files under `` via Read? Underpins the "keep CLAUDE.md short" length pressure. **FC-2 (Q7)**: Skill shell injection with a script path — does `` !`bash "${CLAUDE_SKILL_DIR}/roster.sh"` `` work with `allowed-tools: Bash(bash:*)`? Does `${CLAUDE_SKILL_DIR}` resolve for plugin skills at agent-startup preload time? Behavior under `disableSkillShellExecution`? **FC-3 (Q8)**: Workpad resolution in the script — does the resolution chain cover the external-tickets-folder case? **FC-4 (Q9)**: `Skill("spire:adepts")` from a subagent — can an adept invoke a plugin skill on demand? **FC-5 (Q10)**: `git log` with glob pathspecs — does `git log --oneline ..HEAD -- src/middleware/auth*` work correctly, or does shell expansion interfere? Should the handoff template quote the paths? ### Additional items from planning **FC-6**: `sed` frontmatter parsing robustness — handles values with colons? Multiline arrays? Files with no frontmatter? **FC-7**: `ls` vs. `find` for journal enumeration — behavior when `journal/` doesn't exist? Does `2>/dev/null` on `ls` swallow both arguments' output? **FC-8**: `CLAUDE_SKILL_DIR` for the adepts skill — resolves to `plugins/spire/skills/adepts/` (or cached equivalent), not the invoking skill's directory? --- ## Design Adjustments (from planner) 1. **`roster.sh` should grep `.claude/spire/project.md` for the workpad path** as an additional fallback for the external-tickets-folder case. 2. **Keep `covers:` parsing out of `roster.sh`** — it's consumed by the drift check in `handoff.md`, not by the roster. The roster only needs `summary`, `status`, and `related`. 3. **Phase parallelism**: Phases 1, 2, and 5 have no dependencies and can be worked in parallel. Phase 3 depends on Phase 1. Phase 6 depends on Phase 2. --- ## Risks and Mitigations 1. **`roster.sh` fragility** — shell parsing of YAML frontmatter with `sed` is brittle. Mitigation: only extract four single-line fields; "unmigrated" fallback for unparseable frontmatter; convention note that frontmatter values must be single-line. 2. **`handoff.md` overwrite breaks git merge** — parallel sessions in same domain. Mitigation: accepted (Q5); rare, short file, `branch:` field helps resolution. 3. **Large change surface** — many files change across the plugin. Mitigation: commit strategy isolates additive roster skill from behavior changes; each commit independently verifiable. 4. **Backward compatibility** — existing adept folders see "unmigrated" in roster. Mitigation: by design; lazy migration via next adept spawn.