Design, plan, fact-check report, and athanor implementation report for the adept discovery and tiered knowledge folders feature. Also captures the harness behavior investigation as an open goal.
223 lines
11 KiB
Markdown
223 lines
11 KiB
Markdown
# 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-<topic>.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 `<dir>/CLAUDE.md` when a subagent reads files under `<dir>` 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 <sha>..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.
|