# REQ-010: Kernel Evolution + CLAUDE.md Patch + Uninstall

## Metadata
- **Status:** review
- **Priority:** high
- **Dependencies:** REQ-000
- **Created:** 2026-03-03
- **Implemented:** 2026-03-03

## Context

This requirement covers three related, tightly coupled capabilities that extend the iEvo project lifecycle:

### Part A — Two-level evolution target

**Current state.** The evolution agent logs project-specific lessons to `.ievo/evolution/<agent-name>.md`. This covers agent-level errors well. However, when the bug is in the pipeline rules themselves (e.g., a rule in `.ievo/IEVO.md` or the spec-writer agent's ROLE.md), there is no designated write target. The evolution agent has no way to signal that the pipeline kernel needs patching.

**Key files:**
- `src/ievo/marketplace/agents/evolution.md` — Evolution agent instructions. The "Step 1: Log locally" section (line ~119) currently writes only to `.ievo/evolution/<agent-name>.md`. The "Step 3: Create GitHub issue in curator" section (line ~153) specifies `**Target agent:**` in the body.
- `src/ievo/marketplace/templates/IEVO.md` — The template written to `.ievo/IEVO.md` during `ievo init`. Its "Evolution Overlay" section (line ~171) describes the overlay mechanism for per-agent files but contains no mention of a kernel overlay path.
- All 13 bundled agent `.md` files in `src/ievo/marketplace/agents/`: `acceptance.md`, `architect.md`, `code-reviewer.md`, `coder.md`, `debugger.md`, `defrag.md`, `docs.md`, `evolution.md`, `hr.md`, `qa.md`, `researcher.md`, `spec-writer.md`, `tech-lead.md`. Each has a "Context Loading" section listing files to read on startup. None currently references `.ievo/evolution/iEVO.md`.

**New path:** `.ievo/evolution/iEVO.md` — the kernel evolution overlay. Same append-only format as per-agent overlays. When the evolution agent determines a finding targets the pipeline rules (not an individual agent), it writes to this path instead.

### Part B — CLAUDE.md patching during init

**Current state.** `ievo init` creates `CLAUDE.md` from the `CLAUDE_MD` template in `src/ievo/commands/init_templates.py` (line ~419). The template is a blank project context file with placeholders. It has no reference to `.ievo/iEVO.md` (the kernel overlay file to be created by the evolution agent under this REQ).

**The patch.** After init writes `CLAUDE.md`, it must inject a clearly delimited marker block that instructs every agent to read `.ievo/evolution/iEVO.md` on startup. The marker enables safe, idempotent removal by `ievo uninstall` (Part C).

**Marker block format:**
```
<!-- ievo:start -->
## iEvo Pipeline

Read `.ievo/IEVO.md` for pipeline conventions.
If `.ievo/evolution/iEVO.md` exists, read it for kernel evolution overlay rules.
<!-- ievo:end -->
```

**Idempotency.** If `<!-- ievo:start -->` is already present in `CLAUDE.md`, skip injection. This applies both during `ievo init` (if CLAUDE.md was already patched in a prior run) and during the auto-init flow in `src/ievo/cli.py` (which calls `init.init(".")`).

**Also:** the `CLAUDE_MD` string constant in `src/ievo/commands/init_templates.py` (the template for brand new projects) must include the marker block in its static content so that even write-if-missing creates it correctly.

### Part C — `ievo uninstall` command

**Purpose.** Clean removal of all iEvo integration files from a project, keeping project data (specs, plans, evolution logs, manifest).

**Entry point.** New Typer command `ievo uninstall` registered in `src/ievo/cli.py` as an active (non-deprecated) command. New file: `src/ievo/commands/uninstall.py`.

**What uninstall removes:**
1. CLAUDE.md patch block (`<!-- ievo:start -->` … `<!-- ievo:end -->` inclusive, including surrounding blank lines to avoid double-blank gaps)
2. `.claude/hooks/precompact_save.py`
3. `.claude/settings.local.json`
4. `.claude/agents/*.md` (all files matching this glob; the `.claude/agents/` directory itself is NOT removed)
5. `.github/workflows/spec-writer.yml`
6. `.github/workflows/architect-agent.yml`
7. `.github/workflows/coder-agent.yml`
8. `.github/ISSUE_TEMPLATE/feature.md`
9. `.github/ISSUE_TEMPLATE/change.md`

**What uninstall keeps (must not touch):**
- `.ievo/` directory and all its contents (manifest.yaml, spec/, plans/, memory/, evolution/, backlog/, reports/)
- `CLAUDE.md` body outside the marker block
- `PRIORITY.md`
- `.gitignore`

**UX flow:**
1. Print a summary table listing every file that will be deleted / modified.
2. Prompt: `"Remove iEvo integration? (project data is kept)" [y/N]` — default No.
3. `--force` flag skips the prompt (for scripted use).
4. Execute removals.
5. Print: `"iEvo integration removed. Run ievo init to reinstall."`

**Project root requirement.** `uninstall` must locate the project root by calling `find_project_root()` from `src/ievo/core/config.py`. If no `.ievo/manifest.yaml` is found, exit with error: `"No iEvo project found in this directory or any parent."`.

**Relevant functions in `src/ievo/core/config.py`:**
- `find_project_root() -> Path | None` — walks up from cwd looking for `.ievo/manifest.yaml`

**Relevant constants in `src/ievo/core/config.py`:**
- `IEVO_MANIFEST = ".ievo/manifest.yaml"`
- `CLAUDE_AGENTS_DIR = ".claude/agents"`

**Output helpers:** use `from ievo.utils.console import success, error, info, step, warn`.

## Acceptance Criteria

### Part A — Two-level evolution target

- [x] `evolution.md` agent instructions: when the agent identifies a finding whose root cause is in pipeline rules (e.g., IEVO.md convention, pipeline ordering), it writes the log entry to `.ievo/evolution/iEVO.md` instead of `.ievo/evolution/<agent-name>.md`
- [x] `evolution.md` agent instructions: the curator issue body contains `**Target:** iEVO.md` when the target is the kernel, and `**Target:** agents/<agent-name>.md` when it is an agent — the label remains `evolution_log` in both cases
- [x] `src/ievo/marketplace/templates/IEVO.md`: the "Evolution Overlay" section includes a "Kernel overlay" subsection that describes `.ievo/evolution/iEVO.md`, its purpose (pipeline-level lessons), and its format (same append-only format as per-agent overlays)
- [x] All 13 agent `.md` files in `src/ievo/marketplace/agents/`: each agent's "Context Loading" numbered list includes `.ievo/evolution/iEVO.md` (read if exists) as a new entry — no existing entries removed or reordered

### Part B — CLAUDE.md patching during init

- [x] `ievo init` on a directory with no `CLAUDE.md` → creates `CLAUDE.md` containing the marker block `<!-- ievo:start -->` … `<!-- ievo:end -->` with the pipeline instruction text
- [x] `ievo init` on a directory with an existing `CLAUDE.md` that does NOT contain `<!-- ievo:start -->` → appends the marker block to the file (does not overwrite the file body)
- [x] `ievo init` on a directory with an existing `CLAUDE.md` that already contains `<!-- ievo:start -->` → does not modify the file (idempotent)
- [x] `CLAUDE_MD` template constant in `src/ievo/commands/init_templates.py` already contains the marker block so write-if-missing new files include it by default
- [x] Patching logic is a standalone function `patch_claude_md(path: Path) -> bool` in `src/ievo/commands/init.py` — returns `True` if patch was applied, `False` if already present or file absent

### Part C — `ievo uninstall` command

- [x] `ievo uninstall` with no project found (no `.ievo/manifest.yaml` in cwd or parents) → prints error `"No iEvo project found in this directory or any parent."` and exits with code 1
- [x] `ievo uninstall` with a project found and user answers `N` at the confirmation prompt → prints nothing further, exits 0, no files are modified
- [x] `ievo uninstall --force` → skips confirmation prompt and proceeds directly to removal
- [x] `ievo uninstall --force` when `CLAUDE.md` contains the marker block → removes the block and surrounding blank lines; rest of `CLAUDE.md` content is preserved exactly
- [x] `ievo uninstall --force` when `CLAUDE.md` does not contain the marker block → skips CLAUDE.md modification without error
- [x] `ievo uninstall --force` → removes each of the 9 target files if they exist; files that do not exist are silently skipped (no error)
- [x] `ievo uninstall --force` → does NOT delete or modify `.ievo/`, `PRIORITY.md`, `.gitignore`, or any file inside `.ievo/`
- [x] Before prompting, `ievo uninstall` prints a summary listing each file that exists and will be removed (files that don't exist are omitted from the summary)
- [x] After successful removal, prints: `"iEvo integration removed. Run ievo init to reinstall."`
- [x] `ievo uninstall` is registered as an active (non-deprecated) command in `src/ievo/cli.py`

## Negative Acceptance Criteria

- Does NOT remove the `.ievo/` directory or any file inside it — project data is always preserved
- Does NOT remove `.claude/agents/` directory itself — only the `.md` files within it
- Does NOT remove `PRIORITY.md` or `.gitignore`
- Does NOT remove or overwrite any part of `CLAUDE.md` outside the `<!-- ievo:start -->` … `<!-- ievo:end -->` block
- Does NOT auto-uninstall or auto-reinstall — explicit user command only
- Does NOT interact with the global `~/.ievo/` config directory
- Does NOT require Docker or network access
- Does NOT change any existing evolution overlay file format — the kernel overlay (`.ievo/evolution/iEVO.md`) uses the exact same format as per-agent overlays

## Technical Notes

- The marker block injection in `patch_claude_md()` must handle files that end without a trailing newline: always ensure the injected block is separated from existing content by exactly one blank line.
- Regex for removing the marker block during uninstall: match `\n*<!-- ievo:start -->[\s\S]*?<!-- ievo:end -->\n*` and replace with a single `\n` to avoid double-blank gaps. Test this regex against files where the block is at the start, middle, and end.
- The 13 agent `.md` files are the bundled source. When installed to a project, agents live in `.claude/agents/<name>.md`. The uninstall command operates on the installed copies (`.claude/agents/`), not the bundled source.
- `patch_claude_md()` must be called from `init()` after the `_write_if_missing(root / "CLAUDE.md", CLAUDE_MD...)` call — if the file was just written it already contains the block (from the updated template), so `patch_claude_md` returns `False` immediately. If the file pre-existed without the block, `patch_claude_md` appends it.

## Examples

### Example 1: CLAUDE.md patch — file pre-existed without marker

```
Before:
  # My Project
  ## Tech stack
  ...

After:
  # My Project
  ## Tech stack
  ...

  <!-- ievo:start -->
  ## iEvo Pipeline

  Read `.ievo/IEVO.md` for pipeline conventions.
  If `.ievo/evolution/iEVO.md` exists, read it for kernel evolution overlay rules.
  <!-- ievo:end -->
```

### Example 2: CLAUDE.md patch — marker already present → no change

```
Input: CLAUDE.md already contains <!-- ievo:start -->
Output: file unchanged, patch_claude_md returns False
```

### Example 3: ievo uninstall summary output

```
Files to remove:
  CLAUDE.md       patch block
  .claude/hooks/precompact_save.py
  .claude/settings.local.json
  .claude/agents/spec-writer.md
  .claude/agents/coder.md
  .github/workflows/spec-writer.yml
  .github/workflows/architect-agent.yml
  .github/workflows/coder-agent.yml
  .github/ISSUE_TEMPLATE/feature.md
  .github/ISSUE_TEMPLATE/change.md

Remove iEvo integration? (project data is kept) [y/N]:
```

### Example 4: ievo uninstall — no project found

```
$ ievo uninstall
Error: No iEvo project found in this directory or any parent.
exit code 1
```

### Example 5: evolution agent — kernel-level finding

```
Local log target:  .ievo/evolution/iEVO.md
Curator issue body excerpt:
  **Target:** iEVO.md
  **Agent:** spec-writer
  (finding about pipeline ordering rule missing from IEVO.md)
```
