# nagent Review v2: 2026-06-08 → 2026-06-12 Updates

**Track:** `nagent_review_20260608`
**Date:** 2026-06-12
**Author:** Tier 1 Orchestrator
**Companion to:** `report.md` (v1, 2026-06-08), `comparison_table.md`, `decisions.md`, `nagent_takeaways_20260608.md`
**Purpose:** Document what's new in Mike Acton's nagent repo since the v1 review and identify what in the v1 artifacts needs updating (without deleting them).

> **Reading note.** v1 reviewed nagent at commit `28a6a87c` ("Fix conversation delegation and token accounting," 2026-06-08 06:41:39 UTC). v2 reviews it at commit `eb6be32a` ("Remove resolved issue files," 2026-06-12 00:25:50 UTC). That's **8 commits and 4 days of work**. The README has been completely restructured (14 sections → 7 Parts with 14 numbered sections, but reorganized into a teaching arc). A new major pattern (**knowledge harvest**) has been added. A new provider (**claude-code**) has been added. New sub-commands (`--compact`, `--branch-conversation`) are now first-class. Prompt caching is now explicit. The 12-step Build Your Own list is now 13 steps.
>
> This is a **focused delta report**, not a full re-review. Sections of the v1 report that haven't changed materially are noted in §5 ("What is still correct in v1"). Sections that need updates are noted in §4 ("Staleness in v1").

---

## 0. TL;DR

| New in nagent | Manual Slop equivalent | Verdict | New future-track candidate? |
|---|---|---|---|
| **Knowledge harvest** (`nagent-gc` → `~/.nagent/knowledge/` with provenance, sha256 ledger, bounded digest) | `src/rag_engine.py` (ChromaDB, no provenance, not user-editable) | **GAP (Application). Manual Slop's RAG is fuzzy + opaque; nagent's knowledge store is exact + editable + provenance-aware.** | **YES** — Candidate 11 |
| **Prompt caching with stable-to-volatile context ordering** (`--cache-prefix-chars` to `nagent-llm-text`, anthropic splits at offsets) | `src/ai_client.py:_add_history_cache_breakpoint`, `_send_anthropic` already uses `cache_control` blocks | **PARTIAL (Application). Caching is in place; stable-to-volatile context ORDERING is not enforced.** | **YES** — Candidate 12 |
| **Conversation compaction** (`--compact` with `prompts/compact-conversation.md` editable guidance) | `src/gui_2.py:4252` `Compress` button → `app_controller._handle_compress_discussion:3357` → `ai_client.run_discussion_compression` | **GAP (Application). Manual Slop has summarization, not behavior-preserving compaction.** | **YES** — Candidate 13 |
| **Project context files** (`context.yaml`/`context.md` at git toplevel, injected install → project → root) | `manual_slop.toml` per-project + `paths.py` per-project overrides | **PARITY (DIFFERENT MECHANISM). Manual Slop uses TOML; nagent uses markdown/YAML. Same intent, different syntax.** | **MAYBE** — Candidate 14 (if user wants markdown) |
| **claude-code provider** (subscription auth via Claude Agent SDK, `default` model = local config) | `src/ai_client.py:_send_gemini_cli` (similar pattern: local CLI auth) | **PARITY.** Same pattern (local-subprocess/subscription auth) as Gemini CLI. | No — already covered by MiniMax follow-up |
| **Per-file knowledge notes** (`knowledge/files/{file_id}.md`, mirrored from harvest) | `models.FileItem` (no notes field) | **GAP (Application). FileItem has 9 fields; no free-form notes per file.** | Bundle with Candidate 11 |
| **"Delete to turn off" feature flags** (`delete digest.md` → injection stops) | `[ai_settings.toml]` toggles, GUI checkboxes | **PARITY (DIFFERENT MECHANISM).** Manual Slop uses config; nagent uses file presence. | No — design pattern note, not a track |
| **Save-with-graceful-summary-failure** (summary LLM fails → save still completes, `(summary unavailable)` marker) | `ai_client.run_discussion_compression` — behavior on LLM failure unknown without source read | **UNKNOWN.** Needs source read. | Maybe — bundle with Candidate 13 |
| **Delegation reframed as "context management, not parallelism"** | `src/multi_agent_conductor.py` (already does this implicitly via subprocess + Context Amnesia) | **PARITY (NEW FRAMING).** | No — design pattern note |

**Verdict in one sentence:** The v2 nagent changes add **one major new pattern (knowledge harvest)** that competes with Manual Slop's RAG, **three smaller patterns (prompt-cache ordering, conversation compaction, per-file notes)** that have direct Manual Slop equivalents or gaps, and **one structural change (claude-code provider)** that mirrors the existing Gemini CLI pattern. The original 14-section deep-dive is *still mostly correct* — the changes are additions, not contradictions. The most actionable update is adding the knowledge-harvest pattern to the future-track candidate list.

---

## 1. The 8 new commits (chronological)

From `https://api.github.com/repos/macton/nagent/commits?per_page=30`, the 8 new commits since v1:

| # | Date (UTC) | Commit | Subject |
|---|---|---|---|
| 1 | 2026-06-11 03:32:50 | `2c3c78b` | Add conversation compaction and restore initial context on load. |
| 2 | 2026-06-11 23:09:57 | `67a3ea5` | Add knowledge harvest, tag parser, and claude-code provider. |
| 3 | 2026-06-11 23:10:12 | `d86bce8` | Add CLAUDE.md importing the shared data-oriented design rules. |
| 4 | 2026-06-11 23:10:12 | `ee72cb4` | Rewrite README prompt around a teaching arc and regenerate README. |
| 5 | 2026-06-12 00:17:34 | `0b9d1a2` | Ignore scratch files. |
| 6 | 2026-06-12 00:17:34 | `5e269ca` | Add project context, prompt caching, and conversation direction. |
| 7 | 2026-06-12 00:17:34 | `99e1270` | Regenerate README for project context, caching, and conversation direction. |
| 8 | 2026-06-12 00:25:50 | `eb6be32` | Remove resolved issue files. |

The 4 substantive commits are #1, #2, #6, and #4. Commits #3, #5, #7, #8 are companion/cleanup work.

### 1.1 The 4 substantive commits (long-form messages)

**Commit `2c3c78b` — Add conversation compaction and restore initial context on load** (2026-06-11 03:32:50)
> Introduce `--compact` with compaction guidance, preserve initial_context through edit flows, and ensure loaded conversations regain protocol preamble when missing.
> Co-authored-by: Cursor

**Commit `67a3ea5` — Add knowledge harvest, tag parser, and claude-code provider** (2026-06-11 23:09:57) — **the big one**
> - `nagent-gc`: classify dead artifacts; harvest facts/decisions/tasks/questions/playbooks into `~/.nagent/knowledge/` with provenance and a sha256 ledger gate; inject a bounded digest into initial context; dry-run by default (design: issues/gc-knowledge-harvest.md)
> - `nagent_tags.py`: explicit parser for the tag protocol replacing regex parsing; block helpers remove re.sub escape hazards
> - claude-code provider via the Claude Agent SDK using the local Claude Code login; omitted model or "default" means Claude Code's configured model
> - Install context: load context.yaml/context.md from the nagent folder before root context; ship `context/data-oriented-design.md` via repo context.yaml
> - Fix re.sub escape corruption in `refresh_initial_context`, O(n^2) splitter scoring (13.6s → 0.008s on a 100KB cpp file), binary reads crashing the loop, pid drift between nagent and nagent-file-edit, and write-path expanduser mismatch
> - Save-conversation indexes the copy even when the summary LLM fails; fresh conversations build initial context once; compact prompt resolves root-first; edit/compact roll up child token stats; gc progress spinner and per-item status lines

**Commit `5e269ca` — Add project context, prompt caching, and conversation direction** (2026-06-12 00:17:34) — **the second big one**
> - Initial context restructured stable-to-volatile: role instructions and the tag protocol (with inline per-tag guidance) lead; instance facts and environment trail, so request prefixes stay byte-identical across conversations of the same mode
> - Protocol rules stated outright: raw bodies, first-close-wins, nothing outside tags, the loop contract (results appended, never fabricate), and errors-as-data
> - New conversations-as-data block directs the model to reuse named workers (`conversation-file="name"`), resume saved conversations, author worker briefings under /tmp, and hand off to a fresh sub-conversation when its own context grows noisy
> - Project context: a `context.yaml`/`context.md` at the git toplevel of the working directory is injected between install and root context, deduplicated when the project is the install or root directory
> - Provider prompt caching: `call_llm` passes stable prefix boundaries via `--cache-prefix-chars`; the anthropic provider splits the message into cache_control blocks at those offsets; cached prompt tokens fold back into reported input counts (issues/provider-prompt-caching.md)

**Commit `ee72cb4` — Rewrite README prompt around a teaching arc and regenerate README** (2026-06-11 23:10:12)
> The prompt now organizes the README as a progression: build it, rename it, own the data, exploit the files, name the principles, the data structures that fall out (neighborhoods, context and large files, per-file conversations), and the framework comparison. Coverage updated for knowledge harvest, install context, the shared tag parser, compaction/branching, and the claude-code provider. README regenerated from the revised prompt.

**Implication of the README restructuring.** The v1 report mapped nagent's 14 sections to Manual Slop features in a 1:1 fashion. v2 nagent's README re-frames the same 14 patterns as a *teaching arc* (build → rename → own → exploit → name → apply → compare). The new organization emphasizes **consequences** of the data-oriented stance (harvest, compaction, project context, prompt caching) over the original 14-as-a-list framing. The substance is mostly the same; the *framing* has shifted toward "what files buy you."

---

## 2. The new patterns (deep-dive)

### 2.1 Knowledge harvest (`nagent-gc`) — THE major new pattern

**nagent's claim.** Dead conversations accumulate, and deleting them loses what was learned. Therefore: distill, then delete — and feed the distillate back in. This is the strongest version of the "files create opportunities" argument. Session state that other tools discard becomes compounding, user-editable knowledge.

**nagent's implementation** (from the README's new §8, "Harvest Knowledge, Reclaim Space"):

1. `nagent-gc` scans the nagent root and classifies every artifact:
   - **Live conversations** (still in use)
   - **User-kept saves** (named, kept explicitly)
   - **Prunable** (stale splits, dead index entries)
   - **Harvest candidates** (conversation archives, delegated sub-conversations, per-file conversations whose target file is gone)
   - **Unknown** is *kept, never deleted*
2. For each harvest candidate, an LLM pass driven by the user-editable `prompts/harvest-conversation.md` extracts:
   - **Facts**
   - **Decisions**
   - **Completed tasks**
   - **Open tasks**
   - **Open questions**
   - **Playbooks**
3. Output goes to category files under `~/.nagent/knowledge/`. **Every bullet carries provenance** (`[from: conversation, date]`).
4. Notes tied to a specific file mirror into `knowledge/files/{file_id}.md`.
5. **Deletion is gated** on a sha256 entry in `knowledge/ledger.json` proving the harvest happened.
6. **Identical content never pays the LLM twice** (the sha256 ledger gate).
7. A bounded `digest.md` (open tasks and questions first, newest first) regenerates from the category files — never from raw conversations, so the user's edits to the category files propagate.
8. The digest is injected into every conversation's initial context as a `{knowledge}` block.
9. **Delete `digest.md` → injection turns off. That is the whole switch.**
10. **Dry run is the default** and prints the classification table plus the estimated harvest cost in tokens before anyone pays it.

**The CLI surface** (from the README's "Common Commands"):
```bash
nagent-gc                       # dry run: classify, estimate cost
nagent-gc --apply               # harvest into ~/.nagent/knowledge/, reclaim
nagent-gc --apply --no-harvest  # reclaim only, no LLM pass
```

**The key design properties** (the things that make this pattern a Manual Slop candidate):

| Property | How it works | Why it matters |
|---|---|---|
| **Provenance** | Every bullet has `[from: conversation, date]` | Auditable, traceable, user can verify |
| **User-editable** | The category files are plain markdown, not a vector store | User can correct wrong "facts" before any model sees them |
| **Bounded digest** | The `digest.md` is byte-capped before injection | Caching-friendly (stable prefix); context-budget-friendly |
| **Delete to turn off** | `rm digest.md` → no injection | Zero-config opt-out; the file is the switch |
| **sha256 ledger gate** | Deletion requires proof of harvest | Lossless: you cannot delete a conversation that hasn't been distilled |
| **Dry run default** | `nagent-gc` without `--apply` does nothing destructive | Safe by default |
| **Per-file mirror** | Notes about a specific file go to `knowledge/files/{file_id}.md` | Per-file memory becomes first-class (extends §13 of v1) |
| **Digest regenerates from category files, not raw** | Edits to category files propagate to digest on next regen | The "knowledge" is a layer, not a snapshot |

**Manual Slop's current state** (RAG, the closest existing pattern):

| Aspect | `src/rag_engine.py` (Manual Slop) | `nagent-gc` (knowledge harvest) |
|---|---|---|
| Storage | ChromaDB (vector store) | `~/.nagent/knowledge/*.md` (markdown files) |
| Provenance | Path + chunk (no conversation-of-origin) | `[from: conversation, date]` per bullet |
| User-editable | No (the vector store is opaque) | Yes (markdown is a text file) |
| Opt-out | GUI toggle (`rag_enabled` setting) | `rm digest.md` |
| Cost control | Embedding + vector storage | sha256 ledger gate; identical content is free |
| Update mechanism | Re-index on mtime change | Manual edit + regenerate digest |
| Deduplication | No explicit dedup | sha256 ledger prevents re-harvest of identical content |
| Auditability | Low (vector similarity, no source-link UI) | High (every bullet has provenance) |
| Per-file notes | None (FileItem has no `notes` field) | `knowledge/files/{file_id}.md` |
| Pattern: "knowledge" is a *layer*, not a *snapshot* | No (each indexing is fresh) | Yes (digest regenerates from category files) |

**Verdict.** **GAP (Application).** Manual Slop's RAG is *useful* but is the wrong shape for "what did we learn from past sessions that we want to inject as stable knowledge." RAG is for *semantic retrieval at query time*; the knowledge harvest is for *durable, auditable, user-editable knowledge* that gets injected as a stable prefix. The two are *complementary*, not substitutable, but Manual Slop has only the first.

**Domain tag:** Both (Application for the user-facing knowledge store; Meta-Tooling for the harvest/regen cycle that external agents could trigger).

**Effort:** Large (3-5 phases). The RAG engine is 384 lines; the knowledge store would be ~200-400 lines + the harvest/regen CLI + a new GUI panel. The audit/integrity story is non-trivial.

**Recommended priority:** **HIGH (re-rank from v1).** This is the single most important new pattern in v2 nagent. The user has not yet seen it; surfacing it as a Candidate 11 in `decisions.md` is the v2 report's primary actionable output.

**Cross-references:**
- v1 §6 (Per-File Memory) — the per-file knowledge notes (`knowledge/files/{file_id}.md`) are a *new dimension* of per-file memory that v1 didn't capture. Could be bundled with Candidate 11.
- v1 §7 (Repository History) — the knowledge harvest covers conversations; the git history covers code. Both are "durable, explicit inputs" — same pattern, different data.
- `data_oriented_error_handling_20260606` — the knowledge harvest is data-oriented in the Fleury sense (no control flow; the LLM extraction is a transformation over files).

---

### 2.2 Prompt caching with stable-to-volatile context ordering

**nagent's claim.** Context windows are a budget, but cache hit rate is the multiplier. The initial context's *ordering* determines cache effectiveness: stable prefix + volatile suffix means providers that cache on block boundaries (Anthropic) can reuse the shared context across conversations of the same mode.

**nagent's implementation** (from the commit message of `5e269ca` and the new README's §1, §2, §3):
- `build_initial_context()` assembles context in **stable-to-volatile order**: role instructions and tag protocol first, context-management rules, discovered tool descriptions, install context, project context, root context, knowledge digest, and instance facts and environment *last*.
- "Stable-to-volatile on purpose: request prefixes stay byte-identical across conversations of the same mode."
- `call_llm` passes stable prefix boundaries via `--cache-prefix-chars` to `nagent-llm-text`.
- The Anthropic provider splits the message into `cache_control` blocks at those offsets.
- **Cached prompt tokens fold back into reported input counts** ("accounting still means 'tokens sent'").

**The "stable-to-volatile" ordering pattern in detail.** The context is layered like an onion:

```
[stable] role instructions
[stable] tag protocol (with inline per-tag guidance)
[stable] context-management and write rules
[stable] discovered tool descriptions
[stable] install context (nagent's own context.yaml)
[stable] project context (repo's context.yaml)
[stable] root context (~/.nagent/context.yaml)
[stable] knowledge digest (regenerates on gc, but is stable within a gc cycle)
[volatile] instance facts
[volatile] environment
[volatile] conversation history (changes every turn)
```

The first ~6 layers are stable across conversations of the same mode (same persona, same provider, same model = same conversation mode). The volatile suffix is per-conversation. Anthropic's `cache_control` breakpoints are placed at the boundary between stable and volatile, so the entire stable prefix is cached.

**Manual Slop's current state** (per `src/ai_client.py:2883` summary):

| Aspect | Manual Slop | nagent v2 |
|---|---|---|
| `cache_control` use | `_add_history_cache_breakpoint`, `_strip_cache_controls`, `_build_chunked_context_blocks` exist | `--cache-prefix-chars` + `cache_control` blocks |
| Stable prefix optimization | NOT explicit (the history-breakpoint approach is *temporal*, not *spatial*) | Explicit (stable layers first, volatile last) |
| Cached token accounting | Likely not folded back into input count | Folded back: "accounting still means 'tokens sent'" |
| System prompt + tool description | These go early in `_send_anthropic` calls but order is not formally enforced | Formally enforced by `build_initial_context` |

**Verdict.** **PARTIAL (Application).** Manual Slop has the cache control *mechanism* (Anthropic ephemeral caching, Gemini explicit caching per `docs/guide_ai_client.md`) but does not have the stable-to-volatile *ordering discipline* that nagent makes explicit. The cost: cache hit rate depends on whether the *first N tokens* are stable across turns, which is currently incidental rather than designed.

**The Anthropic detail** (worth a deep read): `src/ai_client.py` has `_ANTHROPIC_CHUNK_SIZE`, `_ANTHROPIC_MAX_PROMPT_TOKENS`, `_build_chunked_context_blocks`. These suggest Manual Slop's anthropic path *does* chunk content into multiple blocks (likely for prompt-size management), but whether those chunks align with stable/volatile boundaries — and whether the `cache_control` markers are at the *right* offsets — needs source verification.

**Domain tag:** Application (the AI client is the Application's main AI entry point).

**Effort:** Small (1-2 phases) IF the current cache_control calls are mostly correct. Medium (2-3 phases) if the ordering needs refactoring across the 5 providers.

**Recommended priority:** **MEDIUM.** Real cost savings; depends on whether current Manual Slop usage actually achieves good cache hit rate (would need a measurement pass first).

**Cross-references:**
- `docs/guide_ai_client.md` §"Anthropic ephemeral + Gemini explicit caching" — the existing pattern.
- v1 report §5 (The Loop) — the loop's "append, call, parse, act, repeat" pattern is the same shape as a cache-stable prefix + volatile suffix; the loop is the volatility.
- `qwen_llama_grok_followup_20260611` — added the `send_openai_compatible()` helper, which is the right shape for a provider-agnostic cache_control injection point.

---

### 2.3 Conversation compaction (`--compact`)

**nagent's claim.** Summarization loses detail. Compaction rewrites the conversation against user-editable guidance, *preserving* the relevant content. Different tool, different purpose.

**nagent's implementation** (from the commit `2c3c78b` and the README's new §6):
- `--compact` is `--edit-conversation` driven by the user-editable `prompts/compact-conversation.md`.
- The compaction prompt is **user-editable** at the install level (`~/.nagent/prompts/compact-conversation.md` overrides the shipped version, root-first resolution).
- "Edit/compact roll up child token stats" — the compaction output preserves the recursive token rollup from sub-conversations (so the child runs are still auditable in the parent's accounting).
- Compaction preserves `initial_context` through edit flows — so the stable prefix stays stable.
- "Loaded conversations regain protocol preamble when missing" — the load path re-injects the preamble if it's been stripped.

**The distinction from summarization:**
- **Summarize** = produce a short description of the conversation (one-way; lossy)
- **Compact** = rewrite the conversation to be shorter, *preserving* the same shape and intent (lossy on word count, lossless on structure)
- nagent's `--compact` is closer to "edit the conversation file to be smaller while keeping the reasoning intact."

**Manual Slop's current state** (`src/gui_2.py:4252` `Compress` button):
> "Compress" button → `app_controller._handle_compress_discussion:3357` → `ai_client.run_discussion_compression`

The button calls `ai_client.run_discussion_compression(disc_text)` and replaces the discussion with the LLM's compressed version. This is **summarization, not compaction** — it's a one-shot LLM call that produces a shorter text, but the shape is "a single string from the LLM" rather than "a rewritten conversation that preserves the structure."

**Verdict.** **GAP (Application).** Manual Slop has summarization; it does not have behavior-preserving compaction.

**The "behavior-preserving" distinction matters** because:
- A summary loses the *back-and-forth* shape of the discussion. The LLM sees one long string instead of turn-by-turn messages.
- A compaction would re-render the conversation with shorter turns, preserving the multi-turn structure that the LLM's chat completion API expects.
- A summary can be regenerated; a compaction cannot (it is the conversation).

**Domain tag:** Application. The Compress button is in the GUI; the underlying call is in the AI client.

**Effort:** Small (1 phase) if the existing `run_discussion_compression` is restructured to produce a compacted multi-turn shape. Medium (2 phases) if a user-editable prompt is added (parallel to the harvest-compaction prompt in nagent).

**Recommended priority:** **MEDIUM.** Worth doing; not as urgent as Candidate 11 (knowledge harvest).

**Cross-references:**
- v1 takeaways §6 (Visible retry on protocol failure) — the "self-correction entry as a System role" pattern could be combined with compaction (compaction adds a "compaction marker" entry).
- v1 §3 (Editable State) — the editable conversation guidance is a v2 nagent pattern that v1 didn't capture.

---

### 2.4 Project context files

**nagent's claim.** Per-project context travels with the repo. When you `cd` into a project, nagent picks up the project's `context.yaml`/`context.md` automatically. Different projects can have different "personality" without forking the nagent install.

**nagent's implementation** (from the README's new §6):
- `load_root_context()` reads `~/.nagent/context.yaml` or `context.md`; YAML can be a list or `{ "paths": [...] }`; nested `context.yaml` files expand recursively.
- **Install context** from the nagent folder itself (the parent of `bin/`) — this repository ships `context.yaml` pointing at `context/data-oriented-design.md`, the operating rules every conversation starts with.
- **Project context**: when nagent runs inside a git repository, a `context.yaml`/`context.md` at that repository's toplevel is included — per-project instructions that travel with the repo.
- **Injection order: install → project → root.** "The more personal context can override the more general; when the project toplevel *is* the install or root directory (e.g. running nagent from its own checkout), the file is included once, not twice."

**Manual Slop's current state** (per `docs/paths.py` and `src/paths.py`):
- Per-project `manual_slop.toml` is the source of truth (per the *Comprehensive Path Mapping & Tooling* track).
- `paths.py` supports `[conductor].dir` override for project-specific conductor paths.
- Project context is *configuration* (TOML), not *operating rules* (markdown).

**Verdict.** **PARITY (DIFFERENT MECHANISM).** Manual Slop has project-scoped configuration (TOML); nagent has project-scoped operating rules (markdown/YAML). Same intent, different syntax and different scope:
- nagent's `context.yaml` injects *prompt text* (operating rules, persona directives, knowledge)
- Manual Slop's `manual_slop.toml` injects *config* (paths, presets, hooks)

**The gap** is that Manual Slop doesn't have a project-level prompt-injection mechanism. If the user wants a project's `manual_slop_context.md` to add "always be terse; prefer 200-line responses; focus on file X" — there is no current way to do that without editing the system prompt preset.

**Domain tag:** Both (the file format is per-project; the renderer is in the App's prompt assembly).

**Effort:** Small (1 phase) — a new `[context_files]` section in `manual_slop.toml` (or a `manual_slop_context.md` file at the project toplevel) read by `aggregate.py:run` at discussion start.

**Recommended priority:** **LOW (but easy).** Could be done in a few hours as a follow-on to Candidate 12 (caching) since both touch `aggregate.py:run` ordering.

**Cross-references:**
- v1 §1 (Durable Work) — the "data is the thing" philosophy says project context should be a file, not a GUI setting. nagent v2 makes this explicit.

---

### 2.5 claude-code provider (5th provider, subscription auth)

**nagent's claim.** A user with a Claude Code subscription should be able to use that subscription in nagent, not require a separate API key. The "claude-code" provider is a thin wrapper around the Claude Agent SDK that delegates auth to the local Claude Code install.

**nagent's implementation** (from the README's new "Setup" section):
- Providers: `openai`, `anthropic`, `google`, `cursor`, **`claude-code`**.
- The `claude-code` provider runs prompts through the locally installed Claude Code via the Claude Agent SDK, so authentication is whatever Claude Code is logged in as (subscription or API key).
- The `default` model — same as omitting `--model` — means Claude Code's own configured model; any Claude model id or alias (`sonnet`, `opus`, `haiku`) overrides it.
- Tools are disabled for plain text generation; `nagent-llm-upload` permits only the Read tool so Claude Code can read the file locally.

**The provider table now reads:**
| Provider | Default model | Credential |
|---|---|---|
| `openai` | `gpt-5.5` | `OPENAI_API_KEY` |
| `anthropic` | `claude-sonnet-4-6` | `ANTHROPIC_API_KEY` |
| `google` | `gemini-2.5-flash` | `GOOGLE_API_KEY` or `GEMINI_API_KEY` |
| `cursor` | `composer-2.5` | `CURSOR_API_KEY` |
| `claude-code` | `default` | **None** — uses local Claude Code login |

**Manual Slop's current state** (per `src/ai_client.py:2883`):
- Providers in `ai_client.py`: `_send_anthropic`, `_send_gemini`, `_send_gemini_cli`, `_send_deepseek`, `_send_grok`, `_send_minimax`, `_send_qwen`, `_send_llama`, `_send_llama_native`. That's **8 send paths** (some have native vs shared-helper variants).
- The Gemini CLI path (`_send_gemini_cli`) is the **direct analog** of nagent's claude-code provider: it uses a local subprocess (the `gemini` CLI) with whatever auth the user has on their local install.

**Verdict.** **PARITY.** Manual Slop already has the local-CLI subscription-auth pattern (Gemini CLI). The pattern nagent is adding for Claude Code is the same shape. No new Manual Slop work needed for this *pattern*; the question is whether to add a Claude Code provider specifically. That would be a new provider addition, not a new *pattern*.

**Domain tag:** Application. The provider list lives in the AI client.

**Effort:** Medium (a new provider is ~200-400 lines: SDK setup, message adapter, error classification, tool loop integration). nagent's `claude-code` is small because nagent has no GUI; Manual Slop's would be larger because of the multi-provider abstraction layer.

**Recommended priority:** **LOW.** Not a track; a provider addition that fits into a future "more providers" follow-up if the user wants Claude Code integration.

**Cross-references:**
- v1 §2 (Text In, Text Out) — the nagent llm-text primitive now has 5 providers; Manual Slop's `send()` has 8. Same shape.
- `qwen_llama_grok_followup_20260611` — the OpenAI-compatible shared helper makes adding a new OpenAI-compatible provider easy (Ollama, Grok, etc.). Claude Code's SDK is *not* OpenAI-compatible, so it would need a new adapter, not just a new entry in the helper.

---

### 2.6 Per-file knowledge notes (`knowledge/files/{file_id}.md`)

**nagent's claim.** When you know things about a specific file, those notes should live next to the file's identity (inode), not next to a conversation or a session. Then, the next time the file is in scope, the notes come back automatically.

**nagent's implementation** (from the README's new §8):
- "Notes tied to a specific file mirror into `knowledge/files/{file_id}.md`."
- This is the "harvest" output's per-file projection.
- File identity is `st_dev:st_ino` (per v1 §6) — stable across renames.
- The notes are part of the per-file "neighborhood" alongside the file history, current summary, and co-edited files (per v1 §8).

**Manual Slop's current state:**
- `src/models.py:510` `FileItem` schema has 9 fields: `path`, `auto_aggregate`, `force_full`, `view_mode`, `selected`, `ast_signatures`, `ast_definitions`, `ast_mask`, `custom_slices`. **No `notes` field.**
- `ContextPreset` is a saved set of `FileItem`s — also no notes propagation.
- The closest existing pattern is `custom_slices[].annotation` (free-form text per slice) and `ast_mask[].comment` (free-form per-symbol), but these are tied to structural slices/masks, not to a "what I learned about this file" note.

**Verdict.** **GAP (Application).** FileItem has no notes field; the per-file knowledge dimension is absent.

**Domain tag:** Application.

**Effort:** Small (1 phase) — add `notes: str = ""` to `FileItem`, add a "Notes" text area to the Structural File Editor (`src/gui_2.py:render_structural_file_editor`), add a `notes_section` to the file-edit initial context (in `aggregate.py:run`).

**Recommended priority:** **LOW** (small but niche) — bundle with Candidate 11 (knowledge harvest) as a sub-task.

**Cross-references:**
- v1 §6 (Per-File Memory) — the FileItem + ContextPreset pair is Manual Slop's *curation* per-file memory; the notes field would add a *knowledge* per-file memory. Same identity, different dimension.
- v1 §8 (Neighborhoods) — nagent's "neighborhood" is `{file-history} + {file-summary} + {per-file knowledge} + {co-edited files}`. Manual Slop has parts of this; per-file knowledge notes is the missing piece.

---

### 2.7 "Delete to turn off" feature flags

**nagent's claim.** Feature flags should be data, not config. If a feature is gated by the presence of a file, the user can turn it off by deleting the file. No GUI toggle, no env var, no `config.toml` edit. Just `rm`.

**nagent's implementation** (from the README's new §8):
- "A bounded digest.md (open tasks and questions first, newest first) regenerates from the category files — never from raw conversations, so your edits to the category files propagate — and is injected into every conversation's initial context as a {knowledge} block. **Delete digest.md and injection turns off. That is the whole switch.**"

**The pattern generalized:** A feature is on iff a file exists. The file is the config. The user can flip the switch with `rm` and `touch`.

**Manual Slop's current state:**
- `[ai_settings.toml]` toggles: `rag_enabled`, `auto_aggregate`, `force_full`, etc.
- GUI checkboxes for many of the same.
- Per-project `manual_slop.toml` settings.

**Verdict.** **PARITY (DIFFERENT MECHANISM).** Manual Slop uses config files + GUI checkboxes; nagent uses file presence. Both are valid. The nagent pattern is more discoverable in the file tree (you can `ls ~/.nagent/knowledge/` and see "oh, digest.md is here, so the knowledge injection is on"); the Manual Slop pattern is more discoverable in the GUI.

**Domain tag:** Both (this is a design pattern, not a feature).

**Effort:** N/A (this is a design pattern, not a track). Worth noting in `conductor/product-guidelines.md` §"AI-Optimized Compact Style" or as a new styleguide.

**Recommended priority:** **LOW** (design pattern note).

**Cross-references:**
- The "Live State Inspector" candidate from v1 takeaways §1 (State visibility) — combining the inspector with a "feature presence map" would surface which features are on/off based on file presence.

---

### 2.8 Save-with-graceful-summary-failure

**nagent's claim.** A save operation should not fail because a non-essential post-step (like an LLM-generated summary) failed. Degrade gracefully: save the artifact, mark the missing piece visibly.

**nagent's implementation** (from the commit `67a3ea5`):
> "Save-conversation indexes the copy even when the summary LLM fails; fresh conversations build initial context once; compact prompt resolves root-first; edit/compact roll up child token stats"

And from the README's §6:
> "`--save-conversation NAME` copies the conversation and records it, with an LLM-generated summary, in a saved-conversations index. **If the summary fails (no credentials, provider down), the save still completes — the index gets a visible '(summary unavailable)' marker instead of losing the entry.**"

**The pattern.** Critical operation completes; non-critical post-step is best-effort. The marker (`(summary unavailable)`) is visible and explicit. The user can re-run the summary later if they want.

**Manual Slop's current state:**
- `ai_client.run_discussion_compression(disc_text)` is the equivalent of `--summarize` in nagent.
- The Compress button in the GUI calls this; on LLM failure, the discussion is *not* replaced (presumably — needs source verification).
- The current behavior on LLM failure is unknown without reading the source.

**Verdict.** **UNKNOWN** without reading the source. If Manual Slop's `run_discussion_compression` raises on LLM failure, that's a gap (a failed Compress should not destroy the original). If it returns the original on failure, parity.

**Domain tag:** Application.

**Effort:** Small (1 phase) IF the current behavior is "raise on failure." Trivial (just a test) IF the current behavior is "fall back to original."

**Recommended priority:** **MEDIUM** (or maybe HIGH if the current behavior is destructive). Needs verification.

**Cross-references:**
- `data_oriented_error_handling_20260606` — the "errors are just cases" framework means `run_discussion_compression` should return a `Result[str, ErrorInfo]`, not raise. If the current code raises, that's a pre-existing bug that this v2 finding surfaces.

---

### 2.9 Delegation reframed as "context management, not parallelism"

**nagent's claim.** "Delegation is context management before it is parallelism." The reason to spawn a sub-conversation is to keep the parent's context clean. The fact that the child runs concurrently (sometimes) is incidental.

**nagent's implementation** (from the README's new §12):
> "And hand off when noisy: when its own conversation is mostly stale tool output, distill goal, state, and decisions into a fresh sub-conversation and delegate the rest — compaction semantics through the one mechanism the model already has, without racing the live file."

The reframing table:
| Long-lived agent abstractions | Disposable workers |
|---|---|
| Identity is central | Output artifact is central |
| Shared context gets noisy | Child context is isolated |
| Parent absorbs all exploration | Parent gets a concise result |
| Delegation implies personality | Delegation is context management |

**Manual Slop's current state:**
- `src/multi_agent_conductor.py:run_worker_lifecycle` already does this implicitly: each MMA Tier 3 worker is a fresh subprocess with Context Amnesia.
- The "disposable worker" pattern is already the MMA pattern.
- The reframing as "context management" is *new phrasing*, not new behavior.

**Verdict.** **PARITY (NEW FRAMING).** Manual Slop's MMA already does the right thing; the new framing is a *philosophical* addition. Useful for the next design discussion about *why* MMA has subprocesses, not whether it should.

**Domain tag:** Both (philosophical; the design pattern is documented, not implemented).

**Effort:** N/A (design pattern note).

**Recommended priority:** **LOW** (documentation update, not a track).

**Cross-references:**
- v1 §9 (Sub-conversations) — the user's explicit want for 1:1 sub-conversations.
- `docs/guide_mma.md` §"Token Firewalling" — the existing framing is "firewall the token budget," not "manage the parent's context." Both are true; the latter is the better framing for the SubConversationRunner design.

---

## 3. The 13-step "Build Your Own" list — what changed

The v1 report's Appendix A cited the 12-step Build Your Own list. v2 nagent's list has **13 steps** (the new step is **#10: Harvest dead conversations into a knowledge store; inject a bounded digest**).

| # | v1 (12 steps) | v2 (13 steps) | Change |
|---|---|---|---|
| 1 | `generate_text(file) -> str` | Same | Unchanged |
| 2 | Growing conversation document | Same | Unchanged |
| 3 | Initial context that states the contract | Same | Unchanged |
| 4 | Output format and a small strict parser | Same | Unchanged |
| 5 | Handlers that append results back into state | Same | Unchanged |
| 6 | Loop after actions | Same | Unchanged |
| 7 | Visible retry on malformed output | Same | Unchanged |
| 8 | Save/load/branch/edit/compact for conversation maintenance | Same | Unchanged (`compact` is new; `branch` is new) |
| 9 | Repository history → context blocks | Same | Unchanged |
| 10 | (n/a) | **Harvest dead conversations into a knowledge store; inject a bounded digest** | **NEW** |
| 11 | Per-artifact memory with stable ids and bounded write authority | Same | Unchanged |
| 12 | Split/index/patch for large files | Same | Unchanged |
| 13 | Child loops for delegation | Same | Unchanged |

**The implication for v1's Appendix A**: it's now stale by one step. The 12-step list should become 13. The new step 10 is the most important Manual Slop candidate (Candidate 11).

---

## 4. Staleness in v1 artifacts

This is the actionable section. For each v1 artifact, what needs updating?

### 4.1 `report.md` (v1) — staleness map

| Section | Staleness | Action needed |
|---|---|---|
| §1 (Durable Work) | Partially stale (no mention of knowledge harvest or stable-to-volatile ordering) | Append a paragraph on knowledge harvest as a "what files buy you" consequence |
| §2 (Text In, Text Out) | Mostly correct; one detail: 5 providers now (was 4) | Note the 5th provider (claude-code) in the comparison |
| §3 (Conversations Are Editable State) | Stale — no mention of `--compact`, `--branch-conversation`, or compaction guidance | Add a new sub-section on compaction as distinct from summarization |
| §4 (Visible Output Protocol) | Still correct, but nagent has a new `nagent_tags.py` explicit parser | Note the parser refactor (was regex; now explicit) |
| §5 (The Loop) | Still correct | None |
| §6 (Per-File Memory) | Stale — no mention of per-file knowledge notes (`knowledge/files/{file_id}.md`) | Add a paragraph on per-file notes as a *new* dimension |
| §7 (Repository History) | Still correct | None |
| §8 (Neighborhoods) | Stale — no mention of the new "everything else files buy you" expansion in §9 of v2 README | Add cross-reference to the new §9 |
| §9 (Sub-Conversations) | Stale — no mention of the new "delegation as context management" reframing or the new `conversation-file="name"` worker reuse pattern | Add a paragraph on the reframing and the worker-reuse pattern |
| §10 (Controlled Writes) | Still correct | None |
| §11 (Large Files) | Still correct (the splitter O(n²) → O(n) fix is performance, not semantic) | Note the perf fix in passing |
| §12 (Tool Discovery) | Still correct | None |
| §13 (Differences from Frameworks) | Stale — the v2 README reframes this as "Own the Inputs" (Part VII §14) | Update title to "Own the Inputs" and note the new framing |
| §14 (Build Your Own) | Stale — 12 steps is now 13 | Bump to 13, add the knowledge harvest step |
| §15 (The 6 Pitfalls) | Stale — no mention of "no knowledge harvest" or "no stable-to-volatile ordering" or "no behavior-preserving compaction" | Add 3 new pitfalls (or replace 3 of the 6 with the new ones) |
| Appendix A (Cross-reference table) | Stale — `bin/nagent-llm-text` now has 5 providers, not 4 | Update provider count |
| Appendix B (Citations) | Stale — missing the v2 commit SHAs and the new `nagent-gc`, `nagent_tags.py`, `context/data-oriented-design.md` files | Update citations |

**Net:** 9 of 16 sections need updates. The v1 report is not *wrong* — the 14-section structure is still correct — but it's missing the v2 additions. A v3 (or v1-revised) report would add ~150-200 lines covering the new patterns.

### 4.2 `comparison_table.md` (v1) — staleness map

| Row | Staleness | Action needed |
|---|---|---|
| §3 (Editable State) | Stale — no mention of `--compact` or `--branch-conversation` | Add column for "compaction" |
| §6 (Per-File Memory) | Stale — no mention of per-file notes | Add column for "notes" |
| §8 (Neighborhoods) | Still correct | None |
| §9 (Sub-Conversations) | Stale — no mention of worker-reuse or compaction-via-handoff | Add column for "context management" |
| §11 (Large Files) | Mostly correct (the perf fix is a detail) | Add a row about prompt caching (nagent's `--cache-prefix-chars`) |
| §12 (Tool Discovery) | Still correct | None |
| §14 (Build Your Own) | Stale (12 steps → 13) | Update step count |
| **NEW ROW** | n/a | Add row for "Knowledge Harvest" (nagent §8) — Manual Slop verdict: GAP (RAG is not the same shape) |
| **NEW ROW** | n/a | Add row for "Prompt Caching Strategy" (nagent §1) — Manual Slop verdict: PARTIAL (mechanism present, ordering not enforced) |
| **NEW ROW** | n/a | Add row for "Compaction vs Summarization" (nagent `--compact`) — Manual Slop verdict: GAP (Compress button is summarize, not compact) |
| **NEW ROW** | n/a | Add row for "Per-File Knowledge Notes" (nagent `knowledge/files/{file_id}.md`) — Manual Slop verdict: GAP (FileItem has no notes field) |

**Net:** 4 existing rows need updates, 4 new rows needed. The flat table grows from 14 rows to 18 rows.

### 4.3 `decisions.md` (v1) — staleness map

| Candidate | Staleness | Action needed |
|---|---|---|
| 1 (SubConversationRunner) | Mostly correct, but v2 adds: return value should include knowledge updates, not just string artifact | Update return-type description to include `knowledge_updates: list[KnowledgeBullet]` |
| 2 (RAG pre-staging) | Stale — knowledge harvest might be a *better* answer to the same problem (the user wants "I prep before I run"; nagent's harvest is the same intent, but for already-completed runs, not pre-runs) | Add a paragraph noting the overlap and recommending Candidate 11 (knowledge harvest) as the primary answer, with Candidate 2 (RAG pre-staging) as a special case for *upcoming* runs |
| 3 (Stateless LLMClient) | Stale — must now support stable-to-volatile context ordering as a design constraint | Add design constraint: the LLMClient constructor takes a "context builder" that emits layers in stable-to-volatile order |
| 4 (Intent DSL) | Still correct | None |
| 5 (Self-describing tools) | Still correct | None |
| 6 (git_history) | Still correct | None |
| 7 (Per-file conversation log) | Stale — per-file knowledge notes (Candidate 11) might be a better answer (the user has the notes dimension, not the conversation-log dimension) | Re-rank: knowledge notes are simpler and more durable; conversation log is heavier |
| 8 (coedited_files) | Still correct | None |
| 9 (split/patch lib) | Still correct (and the O(n²) → O(n) perf fix in nagent is a hint that this is worth doing if/when needed) | Note the perf fix |
| 10 (raw-transcript persistence) | Still correct | None |
| **NEW 11** | n/a | **Knowledge Harvest** (per §2.1 above) — HIGH priority |
| **NEW 12** | n/a | **Stable-to-Volatile Context Ordering for Caching** (per §2.2 above) — MEDIUM priority |
| **NEW 13** | n/a | **Conversation Compaction** (per §2.3 above) — MEDIUM priority |
| **NEW 14** | n/a | **Project Context File** (per §2.4 above) — LOW priority (small but easy) |
| **NEW 15** | n/a | **Save-with-Graceful-Summary-Failure** (per §2.8 above) — needs source verification; possibly HIGH if current behavior is destructive |

**Net:** 4 existing candidates need updates; 5 new candidates needed. The decisions list grows from 10 to 15.

### 4.4 `nagent_takeaways_20260608.md` (v1) — staleness map

| Takeaway | Staleness | Action needed |
|---|---|---|
| §1 (State visibility) | Still correct | None |
| §2 (Readable conversation log) | Stale — nagent v2's `--compact` is a third option (rewrite to preserve structure) | Add a paragraph on compaction as option C |
| §3 (Sub-agents for 1:1) | Stale — should mention the v2 reframing ("delegation is context management") and the new `conversation-file="name"` worker reuse | Update the design constraint section |
| §4 (File identity) | Still correct | None |
| §5 (One loop, one file) | Stale — the v2 stable-to-volatile ordering is the "one loop" insight refined | Add a paragraph on the ordering insight |
| §6 (Visible retry) | Still correct | None |
| §7 (Prompts vs function calls) | Stale — nagent v2 added a stricter explicit parser (`nagent_tags.py`) | Note the parser refactor |
| §8 (Self-describing tools) | Still correct | None |
| §9 (Edit the input, not the output) | Stale — the v2 compaction is "rewrite the input to be smaller while preserving intent" | Add a paragraph on compaction as "edit the input" |
| §10 (Sub-agent return type) | Stale — the v2 example shows the return type is `<nagent-conversation-result conversation="..." tokens_in="..." tokens_out="...">`, with no knowledge update | Update the return type to include knowledge updates |
| **NEW** | n/a | **Knowledge Harvest** (10-15 lines, per §2.1) — HIGH priority actionable |
| **NEW** | n/a | **Stable-to-Volatile Context Ordering** (10-15 lines, per §2.2) — MEDIUM priority actionable |
| **NEW** | n/a | **Conversation Compaction** (10-15 lines, per §2.3) — MEDIUM priority actionable |

**Net:** 6 of 10 takeaways need updates; 3 new takeaways needed. The takeaways doc grows from 10 to 13.

---

## 5. What is still correct in v1

For completeness — what's *not* stale:

- **All 14 v1 sections are still structurally correct.** The 14 patterns (durable work, text-in-text-out, editable state, visible protocol, the loop, per-file memory, repo history, neighborhoods, sub-conversations, controlled writes, large files, tool discovery, differences from frameworks, build your own) are *all still there* in the v2 README. The v2 README re-organizes them into 7 Parts with a teaching-arc structure, but the substance is the same.
- **The 6 v1 pitfalls are still real.** None of them have been "solved" by the v2 changes. The 3 new pitfalls in v2 (no knowledge harvest, no stable-to-volatile ordering, no behavior-preserving compaction) are *additions*, not corrections.
- **The 4 Application features (per file:line) that v1 said are strong are still strong.** FileItem + ContextPreset + Fuzzy Anchors + UISnapshot have not been deprecated or replaced.
- **The Application vs Meta-Tooling distinction is still load-bearing.** v2 nagent is still a Meta-Tooling reference; the Application's choices (provider-native function calling, GUI, long-lived state) are still the right ones for the Application domain.
- **The 10 future-track candidates are all still real candidates.** 4 of them need updates; none are obsoleted.
- **The "Application is intentionally not nagent" claim is still true.** v2 nagent's new features (knowledge harvest, compaction, prompt caching) are *more* reason to keep the Application's choices — these patterns would add complexity that the Application doesn't need at its current scale.

---

## 6. New future-track candidates (formal proposals)

### Candidate 11: Knowledge Harvest & Store (HIGH priority)

**User signal:** Not yet surfaced (the v1 review didn't see this; v2 surfaces it for the first time).

**Why it matters.** RAG is the wrong shape for "what did we learn from past sessions that we want to inject as stable knowledge." RAG is for *semantic retrieval at query time*; knowledge harvest is for *durable, auditable, user-editable knowledge* injected as a stable prefix. Manual Slop's RAG (`src/rag_engine.py:1-384`) and nagent's knowledge harvest (nagent `nagent-gc` + `~/.nagent/knowledge/`) solve different problems:
- RAG: "given a query, find similar chunks in the corpus" (vector similarity, fuzzy, opaque)
- Knowledge harvest: "given a corpus, distill durable facts into a user-editable store with provenance" (markdown files, exact, auditable)

**What it would do.** A new `src/knowledge_store.py` module + companion `src/knowledge_harvest.py`:
- `KnowledgeStore` class with `add_bullet(category, text, provenance)`, `get_digest(budget_chars)`, `regenerate_digest()`, `delete_digest()` (turn-off switch)
- `KnowledgeHarvester` class with `harvest_conversation(discussion) -> list[KnowledgeBullet]` (LLM call against an editable `prompts/harvest-conversation.md`)
- A `src/harvest_cli.py` (or GUI panel) that does the dry-run → apply cycle, like `nagent-gc`
- A bounded `{knowledge}` block injected into `aggregate.py:run` initial context (the *stable* position — it's cache-friendly)
- A "Knowledge" panel in the GUI (similar to the Logs Management panel) for browsing, editing, pruning
- Per-file knowledge notes in `~/.manual_slop/knowledge/files/{file_id}.md` (parallel to `FileItem.notes` Candidate 11.1)

**Where it lives.** Application. The knowledge store is user-editable; the harvest is an in-process LLM call.

**Depends on.** `data_oriented_error_handling_20260606` (the `Result`/`ErrorInfo` pattern for the harvest LLM call's return type).

**Effort.** **Large.** 3-5 phases: (1) KnowledgeStore + digest regeneration, (2) KnowledgeHarvester + harvest-conversation prompt, (3) GUI panel + file picker, (4) aggregate.py integration + cache-position verification, (5) per-file notes + FileItem extension. ~500-800 lines + tests.

**Recommended priority.** **HIGH** — re-ranks above Candidates 4, 6, 7, 8, 9, 10. The user has not yet seen this; surfacing it as the v2 report's primary output is the right next step.

**Cross-references:**
- v1 §6 (Per-File Memory) — adds a *knowledge* dimension alongside the *curation* dimension.
- v1 §7 (Repository History) — git history is a *kind* of "preserved work" that nagent now has a second instance of (knowledge harvest) to complement.
- `data_oriented_error_handling_20260606` — the harvest LLM call is the first use case that benefits from a `Result[str, list[KnowledgeBullet], ErrorInfo]` return type.

---

### Candidate 12: Stable-to-Volatile Context Ordering for Caching (MEDIUM priority)

**User signal:** Not yet surfaced. Anthropic caching is in place (per `docs/guide_ai_client.md`); the *ordering discipline* is not.

**Why it matters.** Anthropic's `cache_control` markers work on *block boundaries*. The cost benefit comes from the stable prefix being *byte-identical* across turns. If the order of context layers changes per turn (e.g., per-discussion system prompt, per-discussion tool list, per-turn diff), the cache hit rate drops.

**What it would do.** A refactor of `src/ai_client.py:_get_combined_system_prompt` and the Anthropic-specific call site to enforce stable-to-volatile ordering:
- **Stable layers** (in order, identical across turns of the same mode):
  1. Role instructions (the model + provider)
  2. Tag protocol / tool protocol / function-calling schema
  3. Discovered tool descriptions
  4. System prompt (the user's chosen preset)
  5. Persona profile (if any)
  6. Project context (per `manual_slop.toml` — Candidate 14)
  7. Knowledge digest (if Candidate 11 is built)
- **Volatile layers** (per-turn, not cached):
  8. Instance facts (current discussion, current file items)
  9. Tool-call results from prior turns
  10. The user message

**Where it lives.** Application. The `ai_client.py` refactor.

**Depends on.** None directly. Could leverage `qwen_llama_grok_followup_20260611`'s `send_openai_compatible()` helper for the Anthropic-specific call site.

**Effort.** **Small to medium.** 1-2 phases if the existing `_build_chunked_context_blocks` already does the right thing (it might, just not formally). 2-3 phases if the chunks need to be re-positioned.

**Recommended priority.** **MEDIUM.** Real cost savings on Anthropic-heavy usage. Should be preceded by a measurement pass: log the cache hit rate before and after, so the win is quantified.

**Cross-references:**
- `docs/guide_ai_client.md` §"Anthropic ephemeral + Gemini explicit caching" — the existing pattern.
- v1 §5 (The Loop) — the loop's append/parse/act structure is the volatility; the cache lives in the stable prefix.

---

### Candidate 13: Conversation Compaction (MEDIUM priority)

**User signal:** Not yet surfaced. The Compress button is summarization; the user might prefer compaction for "I want this conversation shorter but still multi-turn."

**Why it matters.** Summarization loses the multi-turn shape that the LLM's chat completion API expects. Compaction rewrites the conversation in place, preserving the structure but reducing word count.

**What it would do.** A new `ai_client.run_discussion_compaction(disc_text, prompt_path="~/.manual_slop/prompts/compact-discussion.md")` that:
- Reads an editable compaction prompt (root-first: `~/.manual_slop/prompts/compact-discussion.md` overrides the shipped version)
- Calls the LLM to produce a compacted multi-turn rendering of the conversation
- Validates the output: must be a `list[dict]` with the same role/content/collapsed shape as the input
- Falls back to the original on parse failure (graceful, per nagent v2's save pattern)

A new `gui_2.py` button "Compact" (next to the existing "Compress") that calls this instead of `run_discussion_compression`.

**Where it lives.** Application.

**Depends on.** None.

**Effort.** **Small to medium.** 1-2 phases. The existing `run_discussion_compression` is a starting template.

**Recommended priority.** **MEDIUM.** Worth doing; not as urgent as Candidate 11 or 12.

**Cross-references:**
- v1 §3 (Editable State) — the "compaction guidance is user-editable" pattern parallels nagent v2's `prompts/compact-conversation.md`.
- v1 §15.2 (Provider-specific history in process globals) — compaction might be a stepping stone to the Stateless LLMClient refactor (Candidate 3): if the conversation is compacted to a known shape, the projection of `disc_entries` to provider history becomes trivial.

---

### Candidate 14: Project Context File (LOW priority, but small)

**User signal:** Not yet surfaced.

**Why it matters.** `manual_slop.toml` is project config; it's the right shape for paths, presets, and hooks. But it is not the right shape for "operating rules that travel with the repo" (e.g., "always be terse; prefer 200-line responses; focus on file X"). A `manual_slop_context.md` at the project toplevel would inject as a `{project-context}` block in the initial context, just before the volatile layers.

**What it would do.** A new `[context_files]` section in `manual_slop.toml` (or a top-level `manual_slop_context.md` file) read by `aggregate.py:run` at discussion start.

**Where it lives.** Application. `aggregate.py:run` is the consumer.

**Depends on.** None.

**Effort.** **Small.** 1 phase. ~100 lines + a documentation note.

**Recommended priority.** **LOW** (small but niche). Could be done as a small follow-on to Candidate 12 (both touch `aggregate.py:run` ordering).

**Cross-references:**
- v1 §1 (Durable Work) — the "data is the thing" philosophy says project context should be a file.
- Candidate 12 (Stable-to-Volatile Ordering) — the project context is a *stable* layer in the new ordering; adding Candidate 14 first makes Candidate 12's design simpler.

---

### Candidate 15: Save-with-Graceful-Summary-Failure (priority TBD, needs source read)

**User signal:** Not yet surfaced.

**Why it matters.** nagent v2 makes this an explicit principle: critical operations complete; non-essential post-steps are best-effort. Manual Slop's `run_discussion_compression` is the candidate for verification.

**What it would do.** (PENDING VERIFICATION) — read `src/ai_client.py:run_discussion_compression` and the `_handle_compress_discussion:3357` path to see if a failed LLM call destroys the original discussion.

**Where it lives.** Application.

**Depends on.** None.

**Effort.** **Small** (1 phase) IF the current behavior is "raise on failure." Trivial (just a test) IF the current behavior is "fall back to original."

**Recommended priority.** **TBD** — MEDIUM if the current behavior is destructive (it would be a latent bug). LOW if not. Verification first.

**Cross-references:**
- `data_oriented_error_handling_20260606` — the `Result` pattern means a failed LLM call returns `Result.error`, not raises. If the current code raises, that's a pre-existing bug.

---

## 7. Impact on existing future-track candidates

| Candidate | v1 priority | v2 priority change | Why |
|---|---|---|---|
| 1 (SubConversationRunner) | HIGH | HIGH (unchanged) | The v2 `conversation-file="name"` pattern is a *new* use case for the runner; return type should include `knowledge_updates` |
| 2 (RAG pre-staging) | HIGH | MEDIUM (down) | The knowledge harvest (Candidate 11) is a better answer to the "I prep before I run" intent. RAG pre-staging remains useful for *upcoming* runs (where harvest is post-hoc) but is no longer the primary pattern |
| 3 (Stateless LLMClient) | MEDIUM | MEDIUM (unchanged) | Now must support stable-to-volatile ordering as a design constraint |
| 4 (Intent DSL) | LOW | LOW (unchanged) | No change |
| 5 (Self-describing tools) | LOW | LOW (unchanged) | No change |
| 6 (git_history) | MEDIUM | MEDIUM (unchanged) | No change |
| 7 (Per-file conversation log) | LOW | LOW (down to LOW-bundle) | Per-file knowledge notes (Candidate 11) are a simpler, more durable answer to the same intent. Conversation log is heavier and overlaps with `disc_entries` |
| 8 (coedited_files) | LOW | LOW (unchanged) | No change |
| 9 (split/patch lib) | DEFER | DEFER (unchanged) | No change (nagent v2's O(n²) → O(n) perf fix is a hint, not a trigger) |
| 10 (raw-transcript persistence) | LOW | LOW (unchanged) | No change |
| **NEW 11** | n/a | **HIGH** | The single most important v2 finding |
| **NEW 12** | n/a | MEDIUM | Real cost savings on Anthropic-heavy usage |
| **NEW 13** | n/a | MEDIUM | Worth doing; not urgent |
| **NEW 14** | n/a | LOW | Small but easy |
| **NEW 15** | n/a | TBD | Needs source verification |

---

## 8. Verification needs (what to read before the next review)

The v2 report's claims are grounded in the new README and commit messages. The following Manual Slop internals were not read in full and would benefit from a Tier 2 Tech Lead source read before any of the new candidates (11-15) are scoped:

1. **`src/aggregate.py:run`** (1-518) — verify the current context-builder ordering. Is it stable-to-volatile? Where do tool descriptions, system prompt, and project context sit relative to the volatile layers? *(Needed for Candidates 12 and 14.)*

2. **`src/ai_client.py:run_discussion_compression`** — verify the failure mode. Does it raise, return None, or return the original? *(Needed for Candidate 15.)*

3. **`src/ai_client.py:_send_anthropic`** — verify the cache_control block placement. Are the markers at stable/volatile boundaries, or just at chunk-size boundaries? *(Needed for Candidate 12.)*

4. **`src/ai_client.py:_get_combined_system_prompt`** (referenced in summary) — verify the order of layers in the system prompt. The v1 report assumed "system prompt + tool list first" but the actual order may differ. *(Needed for Candidate 12.)*

5. **`src/ai_client.py:run_subagent_summarization`** (referenced in v1) — verify the retry budget. nagent's `SUMMARY_MAX_ATTEMPTS = 2` is a fixed cap; Manual Slop's budget may differ. *(Needed for any future work on summarization.)*

6. **`src/rag_engine.py:RAGEngine.search`** (1-384) — verify the `mtime` invalidation and the ChromaDB persistence path. The knowledge harvest is *not* a replacement for RAG; the two coexist. Understanding the existing RAG's failure modes is needed to scope Candidate 11 (what does the knowledge harvest *not* need to do because RAG already does it?).

7. **`src/paths.py`** — verify the per-project override path. The "project context file" pattern (Candidate 14) needs to be resolved at the project level; the existing `paths.py` API is the right shape. *(Needed for Candidate 14.)*

8. **`src/models.py:FileItem`** (around line 510) — verify the existing schema. Adding a `notes` field is a non-breaking change, but the migration story (existing `manual_slop.toml` files) needs to be defined.

These reads can be done in a single Tier 2 source-read pass (1-2 hours); they don't require a full track. The output is a revised Candidates 11-15 with concrete file:line references and effort estimates.

---

## 9. Recommended next steps (for the user)

The user (the product owner) said: "After we'll look into updating upcoming tracks and documentation related to it, along with the agent workflow docs." The v2 report's recommendations, in priority order:

1. **Surface Candidate 11 (Knowledge Harvest) to the user.** This is the single most important v2 finding. The user has not seen this pattern. If the user wants to pursue it, the v1 `decisions.md` should be updated to add it as Candidate 11 with HIGH priority, bumping the existing list.

2. **Verify Candidate 15 first (Save-with-Graceful-Summary-Failure).** This is potentially a latent bug; verification is cheap (one source read); if the bug exists, it's the highest-priority fix in the entire v2 report.

3. **Update v1's `decisions.md` and `comparison_table.md` to reflect the 4 stale sections and 5 new candidates.** This is a documentation update, not a code change. The user mentioned "documentation related to it" as the next step after the report.

4. **Update v1's `nagent_takeaways_20260608.md` to add 3 new actionable patterns** (knowledge harvest, stable-to-volatile ordering, conversation compaction) and update 6 of the 10 existing takeaways with the v2 insights.

5. **Update v1's `report.md` to add new sub-sections on knowledge harvest, stable-to-volatile ordering, and conversation compaction.** A v1.1 update is appropriate; the v1 file is not deleted.

6. **Update the agent workflow docs** (`AGENTS.md`, `conductor/workflow.md`, `conductor/product-guidelines.md`) to incorporate the v2 patterns as design principles:
   - The "knowledge is data" pattern (provenance, user-editable, delete-to-turn-off) → add to `product-guidelines.md` §"AI-Optimized Compact Style" or as a new styleguide `conductor/code_styleguides/knowledge_artifacts.md`
   - The stable-to-volatile ordering for caching → add to `conductor/tech-stack.md` §"ai_client" or as a new styleguide `conductor/code_styleguides/cache_friendly_context.md`
   - The "compaction vs summarization" distinction → add to `conductor/code_styleguides/llm_workflow.md` (new styleguide)
   - The "delegation is context management, not parallelism" framing → update `docs/guide_mma.md` §"Token Firewalling" to use the new framing

7. **Schedule a Tier 2 source-read pass** to verify the 8 items in §8 above, and produce a revised `decisions.md` with concrete file:line references for Candidates 11-15.

8. **Consider whether to bump the v1 review's track to "completed" once the v2 follow-up is integrated.** The v1 review's track is currently `active` (per `state.toml`); the v2 report is a natural follow-up. After the user reviews the v2 report and confirms which new candidates to pursue, the v1 review can be marked completed and a new track (or several) can be initialized for the chosen candidates.

---

## 10. References (v2-specific)

- **nagent source:** https://github.com/macton/nagent (at commit `eb6be32a`, 2026-06-12 00:25:50 UTC)
- **nagent v2 README:** https://github.com/macton/nagent/blob/main/README.md (regenerated 2026-06-12)
- **v2 commit log:** https://api.github.com/repos/macton/nagent/commits?per_page=30 (4 substantive commits: `2c3c78b`, `67a3ea5`, `5e269ca`, `ee72cb4`)
- **v1 review artifacts (preserved, not deleted):**
  - `report.md` — v1 14-section deep-dive
  - `comparison_table.md` — v1 flat reference
  - `decisions.md` — v1 10 future-track candidates
  - `nagent_takeaways_20260608.md` — v1 10 actionable patterns
  - `spec.md` — v1 track wrapper
  - `state.toml` — v1 track state
  - `metadata.json` — v1 track metadata

## Appendix A. Cross-reference: v1 sections → v2 README sections

| v1 section | v2 location (Part + §) | New content in v2? |
|---|---|---|
| 1. Durable Work | Part II §5 (You Did Not Build an Agent) | Reframed (no new content) |
| 2. Text In, Text Out | Part I §1 | claude-code provider added |
| 3. Editable State | Part III §6 | --compact, --branch-conversation, user-editable compaction prompt |
| 4. Visible Protocol | Part I §2 | nagent_tags.py explicit parser (was regex) |
| 5. The Loop | Part I §3 | Caching integration; stable-to-volatile ordering |
| 6. Per-File Memory | Part VI §13 | Per-file knowledge notes (knowledge/files/{file_id}.md) |
| 7. Repository History | Part IV §7 | Unchanged |
| 8. Neighborhoods | Part VI §11 | Per-file knowledge notes joined to neighborhood |
| 9. Sub-Conversations | Part VI §12 | "Delegation is context management, not parallelism"; `conversation-file="name"` worker reuse |
| 10. Controlled Writes | Part I §3 (in-loop) | Unchanged |
| 11. Large Files | Part VI §12 | O(n²) → O(n) perf fix in splitter |
| 12. Tool Discovery | Part I §4 | nagent-gc added to tool list |
| 13. Differences from Frameworks | Part VII §14 | Reframed as "Own the Inputs" |
| 14. Build Your Own | (end of README) | 12 → 13 steps (knowledge harvest added) |
| **NEW** | Part IV §8 | **Harvest Knowledge, Reclaim Space** (the big new pattern) |
| **NEW** | Part IV §9 | **Everything Else Files Buy You** (case-study enumeration) |
| **NEW** | Part V §10 | **Data-Oriented Design** (formal name for the principles) |
| **NEW** | Setup | claude-code provider documented |

**Net:** 3 new parts (IV, V, VI explicit in v2; was a flat 14 in v1), 4 new numbered sections (8, 9, 10, and the new 11/12/13 expansions), 13-step Build Your Own (was 12).

---

End of v2 report.
