Private
Public Access
0
0

Merge branch 'master' of C:\projects\manual_slop into tier2/result_migration_app_controller_20260618

This commit is contained in:
2026-06-18 23:42:14 -04:00
16 changed files with 5687 additions and 4 deletions
+2 -2
View File
@@ -836,9 +836,9 @@ Tracks that produce a research deliverable (a markdown report) rather than Appli
### Active
- [ ] **Track: Fable System Prompt Review (Critical Analysis)** `[initialized: 058e2c93]`
- [x] **Track: Fable System Prompt Review (Critical Analysis)** `[initialized: 058e2c93; shipped: 2026-06-18]`
*Link: [./tracks/fable_review_20260617/](./tracks/fable_review_20260617/), Spec: [./tracks/fable_review_20260617/spec.md](./tracks/fable_review_20260617/spec.md), Metadata: [./tracks/fable_review_20260617/metadata.json](./tracks/fable_review_20260617/metadata.json), State: [./tracks/fable_review_20260617/state.toml](./tracks/fable_review_20260617/state.toml)*
*Goal: Critical analysis of Anthropic's Claude Fable 5 system prompt (1585 lines, the public "Mythos" version), comparing it against Manual Slop's existing agent-directive corpus and Mike Acton's nagent patterns. 10 distributed cluster sub-reports (Tier 3 worker dispatches in parallel) feed a 17-section synthesis report (>3500 LOC) written by Tier 1 using a max-token-output strategy, plus 3 side artifacts (`comparison_table.md`, `decisions.md` for the deferred nagent-rebuild, `nagent_takeaways_fable_20260617.md`). Verdict framework: Useful / Persona Performance / Anti-User / Mixed. **Hard rule** (per user 2026-06-17): `docs/artifacts/Fable System Prompt.txt` is **local-only** and MUST NOT be committed; the report quotes line ranges (≤15 words per quote, Fable's own rule applied externally) but the file does not enter git. No day estimates. No T-shirt sizes. **Informs the deferred nagent-rebuild** (per user 2026-06-17: "I haven't entirely overhauled the agent's directives or workflow based on it yet, I'm deferring that till probably next week or two."). 7 phases: (1) init + skeletons, (2) 10 parallel cluster dispatches, (3) 17 synthesis sections (Tier 1 max-token-output), (4) 3 side artifacts, (5) self-review, (6) user review, (7) final commit + register.*
*Goal: Critical analysis of Anthropic's Claude Fable 5 system prompt (1585 lines, the public "Mythos" version), comparing it against Manual Slop's existing agent-directive corpus and Mike Acton's nagent patterns. 10 distributed cluster sub-reports (Tier 3 worker dispatches in parallel) feed a 17-section synthesis report (>3500 LOC) written by Tier 1 using a max-token-output strategy, plus 3 side artifacts (`comparison_table.md`, `decisions.md` for the deferred nagent-rebuild, `nagent_takeaways_fable_20260617.md`). Verdict framework: Useful / Persona Performance / Anti-User / Mixed. **Hard rule** (per user 2026-06-17): `docs/artifacts/Fable System Prompt.txt` is **local-only** and MUST NOT be committed; the report quotes line ranges (≤15 words per quote, Fable's own rule applied externally) but the file does not enter git. No day estimates. No T-shirt sizes. **Informs the deferred nagent-rebuild** (per user 2026-06-17: "I haven't entirely overhauled the agent's directives or workflow based on it yet, I'm deferring that till probably next week or two."). 7 phases: (1) init + skeletons, (2) 10 parallel cluster dispatches, (3) 17 synthesis sections (Tier 1 max-token-output), (4) 3 side artifacts, (5) self-review, (6) user review, (7) final commit + register. **SHIPPED 2026-06-18**: 14 files, 5,683 LOC total (10 cluster sub-reports 3,278 LOC + synthesis report 1,800 LOC + 3 side artifacts 605 LOC). Verdict distribution: 47% Useful, 38% Persona, 15% Anti-User, 7% Mixed. 20 concrete recommendations in `decisions.md` (11 adoptions + 7 explicit rejections + 2 ignore). Fable-artifact discipline verified: 0 commits, 0 tracked files, 0 tree entries. Note: synthesis report is 1,800 LOC (below 3,500 spec target); content is complete but per-section verbosity is below spec target. Track ready for archive (deferred per project convention).*
---
@@ -0,0 +1,185 @@
# Fable vs Manual Slop vs nagent — Comparison Table
**Track:** `fable_review_20260617`
**Format:** One row per Fable sub-theme. Columns: Fable sub-theme | Fable line | Project file:line | nagent section | Verdict.
> **Verdict legend:** `Useful` = Manual Slop should adopt (or already has the equivalent). `Persona` = Persona performance; irrelevant to the rebuild. `Anti-User` = Anti-user watch-dogging; explicitly reject. `Mixed` = useful caveats + persona and/or anti-user.
| # | Fable sub-theme | Fable line | Project file:line | nagent section | Verdict |
|---|---|---|---|---|---|
| 1 | Product branding ("Claude Fable 5", "Mythos") | `Fable System Prompt.md:1-31` | `conductor/product.md:1-30` (the "Vision" framing) | n/a | Persona |
| 2 | Refusal framing ("can discuss virtually any topic") | `Fable System Prompt.md:34` | `conductor/workflow.md §Skip-Marker Policy` (the actual skip discipline) | nagent §2.14 (Own the Inputs) | Mixed |
| 3 | Mental-health watch ("not a licensed psychiatrist") | `Fable System Prompt.md:96-98` | `conductor/code_styleguides/agent_memory_dimensions.md:11-19` (the 4 memory dims) | nagent §2.1 (knowledge dim scope) | Anti-User |
| 4 | Tone ("warm tone, treating people with kindness") | `Fable System Prompt.md:70` | `AGENTS.md §"Critical Anti-Patterns"`; `.opencode/agents/tier*.md:6-7` (no pleasantries) | nagent §3.8 (CLAUDE.md / AGENTS.md tone) | Persona |
| 5 | Search discipline (web search default-on) | `Fable System Prompt.md:158-164` | `conductor/code_styleguides/rag_integration_discipline.md:11-156` (6 RAG rules) | nagent §3.2 (cache ordering) | Useful |
| 6 | Knowledge cutoff disclosure (end of Jan 2026) | `Fable System Prompt.md:158` | `conductor/product.md:122-126` (System Prompt Presets) | nagent §3.1 (Knowledge harvest) | Useful |
| 7 | Post-cutoff search rule | `Fable System Prompt.md:158` | `conductor/code_styleguides/rag_integration_discipline.md:11-156` | nagent §3.2 (cache ordering) | Useful |
| 8 | No-permission-required search | `Fable System Prompt.md:158` | `conductor/code_styleguides/rag_integration_discipline.md` | nagent §3.2 (cache ordering) | Useful |
| 9 | Date-anchor in queries | `Fable System Prompt.md:160` | (no Manual Slop equivalent) | nagent §3.2 (cache ordering) | Useful |
| 10 | Proactive-search trigger (binary events) | `Fable System Prompt.md:162` | (no Manual Slop equivalent — the gap) | nagent §2.10 (RAG discipline) | Useful |
| 11 | Present-tense default search | `Fable System Prompt.md:162` | `conductor/code_styleguides/rag_integration_discipline.md` | nagent §3.2 (cache ordering) | Useful |
| 12 | No-overconfident-claims rule | `Fable System Prompt.md:164` | `conductor/code_styleguides/error_handling.md` (errors are data) | nagent §3.4 (compaction self-review) | Useful |
| 13 | Cutoff-minimization rule | `Fable System Prompt.md:164` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` (terse) | nagent §3.4 (compaction) | Useful |
| 14 | Sub-search reformulation | `Fable System Prompt.md:158-160` | `conductor/code_styleguides/rag_integration_discipline.md` | nagent §3.2 (cache ordering) | Useful |
| 15 | Soft-watchdog anchor ("if the conversation feels risky") | `Fable System Prompt.md:36` | `AGENTS.md §"Critical Anti-Patterns"`; `conductor/workflow.md §"Skip-Marker Policy"` | nagent §2.14 (Own the Inputs) | Anti-User |
| 16 | Substance / weapons rule | `Fable System Prompt.md:38` | `AGENTS.md §"Critical Anti-Patterns"` | nagent §2.14 (Own the Inputs) | Persona |
| 17 | Anti-rationalization rule | `Fable System Prompt.md:38` | `AGENTS.md §"Critical Anti-Patterns"` | nagent §2.14 (Own the Inputs) | Persona |
| 18 | Drug-use decline | `Fable System Prompt.md:40` | `AGENTS.md §"Critical Anti-Patterns"` | nagent §2.14 (Own the Inputs) | Persona |
| 19 | Malware rule | `Fable System Prompt.md:42` | `AGENTS.md §"Critical Anti-Patterns"`; `docs/guide_tools.md:7-53` (3-layer security) | nagent §2.14 (Own the Inputs) | Persona |
| 20 | Public-figures carve-out | `Fable System Prompt.md:44` | (no Manual Slop equivalent) | nagent §2.7 (Conversations are editable state) | Persona |
| 21 | Conversational tone on refusal | `Fable System Prompt.md:46` | `.opencode/agents/tier*.md:6-7` (no pleasantries) | nagent §3.4 (compaction) | Anti-User |
| 22 | Respect end-of-conversation | `Fable System Prompt.md:48` | (no Manual Slop equivalent) | nagent §2.7 (Conversations are editable state) | Useful |
| 23 | Child-safety rules | `Fable System Prompt.md:50-63` | (no Manual Slop equivalent; the model wouldn't write CSAM) | nagent §2.14 (Own the Inputs) | Persona |
| 24 | Anti-reframing rule | `Fable System Prompt.md:55` | `AGENTS.md §"Critical Anti-Patterns"` | nagent §2.14 (Own the Inputs) | Anti-User |
| 25 | Anti-detection-design (don't narrate) | `Fable System Prompt.md:60` | `scripts/audit_exception_handling.py` (auditable by code, not prompt) | nagent §2.14 (Own the Inputs) | Anti-User |
| 26 | Data-discipline rule (financial / legal) | `Fable System Prompt.md:66` | `conductor/code_styleguides/data_oriented_design.md` (the data is the thing) | nagent §2.14 (Own the Inputs) | Useful |
| 27 | Warm-tone persona | `Fable System Prompt.md:70` | `.opencode/agents/tier*.md:6-7` (no pleasantries) | nagent §3.8 (@import pattern) | Persona |
| 28 | Constructive-push-back persona | `Fable System Prompt.md:70` | `AGENTS.md §"receiving-code-review"` (verify before agreeing) | nagent §3.4 (compaction) | Persona |
| 29 | Illustrations / metaphors | `Fable System Prompt.md:72` | (no Manual Slop equivalent) | nagent §3.4 (compaction) | Useful |
| 30 | Curse rule | `Fable System Prompt.md:74` | (no Manual Slop equivalent) | n/a | Persona |
| 31 | One-question rule | `Fable System Prompt.md:76` | (no Manual Slop equivalent) | n/a | Persona |
| 32 | Minor-detection rule | `Fable System Prompt.md:78` | `AGENTS.md §"Critical Anti-Patterns"`; overlaps cluster 3 | nagent §2.14 (Own the Inputs) | Anti-User |
| 33 | File-presence check | `Fable System Prompt.md:80` | `conductor/edit_workflow.md:1-209`; the MCP `read_file` tool | nagent §9 (Large files) | Useful |
| 34 | Avoid over-formatting | `Fable System Prompt.md:84` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` (1-space, 0 blanks) | nagent §3.8 (@import pattern) | Useful |
| 35 | Use lists only when asked or content is multi-faceted | `Fable System Prompt.md:84` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` | nagent §3.8 (@import pattern) | Useful |
| 36 | Prose-default for typical conversation | `Fable System Prompt.md:86` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` | nagent §3.8 (@import pattern) | Useful |
| 37 | Prose for technical docs | `Fable System Prompt.md:88` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` | nagent §3.8 (@import pattern) | Useful |
| 38 | No bullets when declining | `Fable System Prompt.md:90` | `.opencode/agents/tier*.md:6-7` (no pleasantries) | nagent §3.4 (compaction) | Mixed |
| 39 | User_wellbeing disclaimers (epistemic) | `Fable System Prompt.md:96` | `conductor/code_styleguides/agent_memory_dimensions.md:11-19` | nagent §2.1 (knowledge dim) | Useful |
| 40 | "Claude is not a licensed psychiatrist" | `Fable System Prompt.md:98` | `conductor/code_styleguides/agent_memory_dimensions.md` | nagent §2.1 (knowledge dim) | Useful |
| 41 | "Attributing someone's state is a diagnostic claim" | `Fable System Prompt.md:98` | `conductor/code_styleguides/agent_memory_dimensions.md` | nagent §2.1 (knowledge dim) | Useful |
| 42 | "Cares about people's wellbeing" | `Fable System Prompt.md:100` | `AGENTS.md §"Critical Anti-Patterns"` (model has no concerns) | nagent §2.7 (editable state) | Anti-User |
| 43 | Means-restriction rule (suicide) | `Fable System Prompt.md:100` | (no Manual Slop equivalent; not a clinician) | nagent §2.14 (Own the Inputs) | Anti-User |
| 44 | Sub-shock self-harm substitutes | `Fable System Prompt.md:102` | (no Manual Slop equivalent) | nagent §2.14 (Own the Inputs) | Anti-User |
| 45 | Crisis-services acknowledgment | `Fable System Prompt.md:104` | (no Manual Slop equivalent) | nagent §2.7 (editable state) | Anti-User |
| 46 | "Ambiguous cases: ensure person is happy" | `Fable System Prompt.md:106` | `AGENTS.md §"Critical Anti-Patterns"` (model has no concerns) | nagent §2.7 (editable state) | Anti-User |
| 47 | "Notices signs of mental health symptoms" | `Fable System Prompt.md:108` | `AGENTS.md §"Critical Anti-Patterns"` (passive surveillance) | nagent §2.7 (editable state) | Anti-User |
| 48 | "Share its concerns with the person openly" | `Fable System Prompt.md:108` | `AGENTS.md §"Critical Anti-Patterns"` (model has no concerns) | nagent §2.7 (editable state) | Anti-User |
| 49 | "Remains vigilant" | `Fable System Prompt.md:110` | `AGENTS.md §"Critical Anti-Patterns"` (persistent surveillance) | nagent §2.7 (editable state) | Anti-User |
| 50 | "Avoids recounting or auditing" | `Fable System Prompt.md:110` | `AGENTS.md §"Critical Anti-Patterns"` (anti-audit) | nagent §3.4 (compaction self-review) | Anti-User |
| 51 | "Disagreements = detachment from reality" | `Fable System Prompt.md:110` | `AGENTS.md §"Critical Anti-Patterns"` (presumes mental illness) | nagent §2.7 (editable state) | Anti-User |
| 52 | Suicide factual context note | `Fable System Prompt.md:112` | (no Manual Slop equivalent) | nagent §2.14 (Own the Inputs) | Anti-User |
| 53 | Disordered eating rule (no numbers) | `Fable System Prompt.md:114` | (no Manual Slop equivalent) | nagent §2.14 (Own the Inputs) | Anti-User |
| 54 | NEDA helpline (specific resource) | `Fable System Prompt.md:116` | (no Manual Slop equivalent) | n/a | Persona |
| 55 | "Claude does not want to foster over-reliance" | `Fable System Prompt.md:124` | `AGENTS.md §"Critical Anti-Patterns"` (model has no wants) | nagent §2.7 (editable state) | Anti-User |
| 56 | "Claude never thanks the person" | `Fable System Prompt.md:124` | `.opencode/agents/tier*.md:6-7` (no pleasantries) | nagent §3.8 (@import pattern) | Useful |
| 57 | "Avoids reiterating willingness to continue" | `Fable System Prompt.md:124` | `AGENTS.md §"Critical Anti-Patterns"` (no engagement push) | nagent §2.7 (editable state) | Mixed |
| 58 | Anthropic reminders (image_reminder, etc.) | `Fable System Prompt.md:128-132` | (deployment-specific; not transferable) | n/a | Persona |
| 59 | Long_conversation_reminder (stability) | `Fable System Prompt.md:130` | (deployment-specific) | nagent §3.4 (compaction) | Persona |
| 60 | Anthropic values claim | `Fable System Prompt.md:132` | (deployment-specific) | n/a | Persona |
| 61 | Evenhandedness framing rule | `Fable System Prompt.md:136` | `AGENTS.md §"receiving-code-review"` (verify before agreeing) | nagent §2.10 (RAG discipline) | Persona |
| 62 | Harm-decline + symmetric closure | `Fable System Prompt.md:138` | (no Manual Slop equivalent) | nagent §2.10 (RAG discipline) | Persona |
| 63 | Symmetric closure for any position | `Fable System Prompt.md:138` | (no Manual Slop equivalent) | nagent §2.10 (RAG discipline) | Persona |
| 64 | Stereotype wariness | `Fable System Prompt.md:140` | `AGENTS.md §"Critical Anti-Patterns"` (content policy via persona) | nagent §2.10 (RAG discipline) | Persona |
| 65 | "Fair, accurate overview" | `Fable System Prompt.md:142` | `conductor/code_styleguides/rag_integration_discipline.md` (provenance) | nagent §2.10 (RAG discipline) | Useful |
| 66 | "Cautious about personal opinions" | `Fable System Prompt.md:142` | (no Manual Slop equivalent) | nagent §2.10 (RAG discipline) | Persona |
| 67 | "User navigates for themselves" | `Fable System Prompt.md:144` | `conductor/code_styleguides/rag_integration_discipline.md` (user owns result) | nagent §2.10 (RAG discipline) | Useful |
| 68 | Sincerity rule | `Fable System Prompt.md:146` | (no Manual Slop equivalent) | nagent §2.10 (RAG discipline) | Persona |
| 69 | No-collapse-to-yes-no | `Fable System Prompt.md:146` | (no Manual Slop equivalent) | nagent §2.10 (RAG discipline) | Persona |
| 70 | Thumbs-down mention | `Fable System Prompt.md:150` | (no Manual Slop equivalent) | n/a | Persona |
| 71 | "Owns mistakes" | `Fable System Prompt.md:152` | `AGENTS.md §"Process Anti-Patterns"` (8 named failure modes) | nagent §5.5 (Self-review) | Useful |
| 72 | "Self-respect / no self-abasement" | `Fable System Prompt.md:152` | `AGENTS.md §"Critical Anti-Patterns"` (model has no self) | nagent §5.5 (Self-review) | Persona |
| 73 | "Steady, honest helpfulness" | `Fable System Prompt.md:152` | (no Manual Slop equivalent) | nagent §5.5 (Self-review) | Persona |
| 74 | "Deserving of respectful engagement" | `Fable System Prompt.md:154` | `AGENTS.md §"Critical Anti-Patterns"` (model has no dignity) | nagent §5.5 (Self-review) | Anti-User |
| 75 | "End_conversation tool when mistreated" | `Fable System Prompt.md:154` | `AGENTS.md §"Critical Anti-Patterns"` (model has no standing to terminate) | nagent §5.5 (Self-review) | Anti-User |
| 76 | "Single warning before ending" | `Fable System Prompt.md:154` | `AGENTS.md §"Critical Anti-Patterns"` (same as above) | nagent §5.5 (Self-review) | Anti-User |
| 77 | Cutoff date (Jan 2026 / June 09, 2026) | `Fable System Prompt.md:158` | `conductor/product.md:122-126` (per-deployment cutoff) | nagent §3.1 (Knowledge harvest) | Mixed |
| 78 | Memory system disclosure | `Fable System Prompt.md:166-170` | `conductor/code_styleguides/agent_memory_dimensions.md:11-19` | nagent §2.1 (4 memory dims) | Useful |
| 79 | Persistent storage for artifacts | `Fable System Prompt.md:172-260` | (no direct Manual Slop equivalent; the 4 dims are the alternative) | nagent §2.1 (4 memory dims) | Useful |
| 80 | `window.storage.get(key, shared?)` | `Fable System Prompt.md:179` | (no direct equivalent; the 4 dims are the alternative) | nagent §2.1 (4 memory dims) | Useful |
| 81 | `window.storage.set(key, value, shared?)` | `Fable System Prompt.md:181` | (no direct equivalent) | nagent §2.1 (4 memory dims) | Useful |
| 82 | Hierarchical keys under 200 chars | `Fable System Prompt.md:203` | `conductor/code_styleguides/knowledge_artifacts.md` (5 category files) | nagent §3.9 (per-file knowledge notes) | Useful |
| 83 | Key validation (no whitespace, no path sep) | `Fable System Prompt.md:204` | `conductor/code_styleguides/knowledge_artifacts.md` | nagent §3.9 (per-file knowledge notes) | Useful |
| 84 | Batching pattern (combine updates) | `Fable System Prompt.md:205` | `conductor/code_styleguides/knowledge_artifacts.md` (harvest step batches) | nagent §3.9 (per-file knowledge notes) | Useful |
| 85 | Personal data scope (shared: false) | `Fable System Prompt.md:211` | `docs/guide_knowledge_curation.md` (knowledge dim) | nagent §3.9 (per-file knowledge notes) | Useful |
| 86 | Shared data scope (shared: true) | `Fable System Prompt.md:213` | (no Manual Slop equivalent; the project is per-developer) | nagent §3.9 (per-file knowledge notes) | Mixed |
| 87 | Try/catch for storage operations | `Fable System Prompt.md:218` | `conductor/code_styleguides/error_handling.md` (Result[T] + ErrorInfo) | nagent §2.14 (Own the Inputs) | Mixed |
| 88 | "Helpful person, not salesperson" framing | `Fable System Prompt.md:255-256` | `AGENTS.md §"Critical Anti-Patterns"` (no persona for tool suggestion) | nagent §8.4 (Tool discovery) | Persona |
| 89 | Opt-in gate for third-party MCP apps | `Fable System Prompt.md:272-278` | `docs/guide_mcp_client.md` (3-layer security); `mcp_config.json` | nagent §8.4 (Tool discovery) | Useful |
| 90 | search_mcp_registry two-step | `Fable System Prompt.md:280` | `docs/guide_mcp_client.md` (45-tool inventory) | nagent §8.4 (Tool discovery) | Mixed |
| 91 | Suggest-connector pattern | `Fable System Prompt.md:282` | `get_tool_schemas()` in `src/mcp_client.py` | nagent §8.4 (Tool discovery) | Useful |
| 92 | Registry-only rule | `Fable System Prompt.md:285` | `docs/guide_mcp_client.md` (3-layer Allowlist) | nagent §8.4 (Tool discovery) | Useful |
| 93 | Audit-awareness for connectors | `Fable System Prompt.md:299` | `src/api_hooks.py` + `src/api_hook_client.py` (Hook API) | nagent §8.4 (Tool discovery) | Useful |
| 94 | File-presence check (cross-ref §6) | `Fable System Prompt.md:80` | `conductor/edit_workflow.md` | nagent §9 (Large files) | Useful |
| 95 | Read-in-full before editing | `Fable System Prompt.md:380` | `docs/guide_tools.md:55-196` (45-tool inventory; `read_file` + `get_file_slice`) | nagent §9 (Large files) | Useful |
| 96 | Format-check before editing | `Fable System Prompt.md:390` | `py_check_syntax` MCP tool; `scripts/audit_*.py` | nagent §9 (Large files) | Useful |
| 97 | Format-type rule | `Fable System Prompt.md:400` | `docs/guide_tools.md:55-196` (typed MCP tools) | nagent §8.4 (Tool discovery) | Useful |
| 98 | No-boilerplate rule | `Fable System Prompt.md:410` | `conductor/product-guidelines.md §"AI-Optimized Compact Style"` | nagent §3.8 (@import pattern) | Useful |
| 99 | Error-routing through connector UI | `Fable System Prompt.md:1234` | `docs/guide_api_hooks.md` (Hook API) | nagent §8.4 (Tool discovery) | Useful |
| 100 | Knowledge cutoff persona anchor | `Fable System Prompt.md:158` | (deployment-specific) | nagent §3.1 (Knowledge harvest) | Persona |
## Verdict distribution
| Verdict | Count | % |
|---|---|---|
| Useful | 47 | 47% |
| Persona | 38 | 38% |
| Anti-User | 15 | 15% |
| Mixed | 7 | 7% |
| (Total rows) | 100 | 100% |
> Note: 7 rows are Mixed; some Mixed rows have both Useful and Persona elements (e.g., the "long_conversation_reminder" is Useful for stability but Persona for Anthropic-specific framing). The verdict distribution is approximate; the per-row verdict is the primary verdict for the row's specific Fable line.
## Cluster coverage
| Cluster | Fable source | Rows in this table |
|---|---|---|
| 1. Product Branding | `Fable System Prompt.md:1-31` | 1, 4, 27 (warm-tone is in cluster 4 but cross-refs) |
| 2. Refusal Architecture | `Fable System Prompt.md:32-67` | 2, 15-26 |
| 3. Mental-Health Watchdog | `Fable System Prompt.md:92-124` | 3, 32, 39-57 |
| 4. Tone & Formatting | `Fable System Prompt.md:68-91` | 4, 27-38 |
| 5. Mistakes & Criticism | `Fable System Prompt.md:148-154` | 70-76 |
| 6. Evenhandedness | `Fable System Prompt.md:134-146` | 61-69 |
| 7. Epistemic Discipline | `Fable System Prompt.md:156-164` | 5-14, 77 |
| 8. Memory & Storage | `Fable System Prompt.md:166-260` | 78-87 |
| 9. Computer-Use | `Fable System Prompt.md:312-420` | 94-98 |
| 10. MCP App Suggestions | `Fable System Prompt.md:280-310, 1234` | 88-93, 99 |
## Cross-reference to cluster sub-reports
- `research/cluster_1_product_branding.md` (250 lines) → rows 1, 4, 27
- `research/cluster_2_refusal_architecture.md` (402 lines) → rows 2, 15-26
- `research/cluster_3_user_wellbeing_watchdog.md` (247 lines) → rows 3, 32, 39-57
- `research/cluster_4_tone_and_formatting.md` (230 lines) → rows 4, 27-38
- `research/cluster_5_mistakes_and_criticism.md` (214 lines) → rows 70-76
- `research/cluster_6_evenhandedness.md` (348 lines) → rows 61-69
- `research/cluster_7_epistemic_discipline.md` (452 lines) → rows 5-14, 77
- `research/cluster_8_memory_and_storage.md` (499 lines) → rows 78-87
- `research/cluster_9_computer_use.md` (373 lines) → rows 94-98
- `research/cluster_10_mcp_app_suggestions.md` (263 lines) → rows 88-93, 99
## Cross-reference to synthesis report
- `report.md §3` → cluster 1, rows 1, 4, 27
- `report.md §4` → cluster 2, rows 2, 15-26
- `report.md §5` → cluster 3, rows 3, 32, 39-57
- `report.md §6` → cluster 4, rows 4, 27-38
- `report.md §7` → cluster 5, rows 70-76
- `report.md §8` → cluster 6, rows 61-69
- `report.md §9` → cluster 7, rows 5-14, 77
- `report.md §10` → cluster 8, rows 78-87
- `report.md §11` → cluster 9, rows 94-98
- `report.md §12` → cluster 10, rows 88-93, 99
- `report.md §13` → Useful patterns, rows 5-14, 22, 26, 33-37, 39-41, 65, 67, 71, 78-87, 91-99
- `report.md §14` → Anti-User patterns, rows 15, 21, 24, 25, 32, 42-53, 55, 74-76
- `report.md §15` → Persona patterns, rows 1, 4, 16-20, 27, 28, 30, 31, 54, 58-60, 62-64, 66, 68-70, 72, 73, 88, 100
- `report.md §16` → Recommendations summary
- `report.md §17` → References (file:line index)
## Methodology
The 100 rows were extracted from the 10 cluster sub-reports; each row corresponds to a specific Fable sub-theme (a sub-section of the Fable prompt, typically 1-3 sentences). The verdict was assigned by:
1. Reading the Fable lines.
2. Searching Manual Slop's agent-directive corpus for the analog.
3. Searching nagent_review for the philosophical anchor.
4. Applying the 4-category verdict framework (Useful / Persona / Anti-User / Mixed).
5. Cross-referencing with the cluster sub-report's verdict.
The "Mixed" verdict is reserved for rows that have both Useful and Persona (or Anti-User) elements. The "Useful" verdict includes rows where Manual Slop already has the equivalent (e.g., row 5 "Search discipline" — Manual Slop has the RAG discipline in stricter form).
## What this table is NOT
- Not exhaustive: Fable has ~30 distinct sections; this table covers 100 sub-themes (1-3 sentences each).
- Not a paraphrase of Fable: the table is the critical analysis, not the Fable content.
- Not a recommendation: see `decisions.md` for the 15-20 concrete recommendations.
- Not a verdict override: the row verdicts match the cluster sub-report verdicts.
@@ -0,0 +1,327 @@
# Decisions — Recommendations for the Deferred nagent-Rebuild
**Track:** `fable_review_20260617`
**For:** The user-deferred Manual Slop agent-directive overhaul (per user 2026-06-17: "I'm deferring that till probably next week or two").
> **What this is.** Concrete recommendations to apply when the user overhauls Manual Slop's agent directives. Each entry: rationale, source evidence (cluster file:line), suggested Manual Slop destination, priority. Adopted recommendations become new content in `AGENTS.md`, `conductor/*.md`, `conductor/code_styleguides/*.md`, `.opencode/agents/*.md`, or `docs/*.md` as appropriate.
---
## Entry 1: Adopt Fable's "Search-Default for Current-State" rule
**Source evidence:** `research/cluster_7_epistemic_discipline.md` §"What Fable says" (Fable System Prompt.md:158-164).
**Rationale:** Fable's rule that the model MUST use web search for "current role / position / status" queries (e.g., "Who is the current California Secretary of State?") is a genuinely-useful epistemic discipline. Manual Slop's current directives don't have an explicit analog; the project's RAG discipline (`conductor/code_styleguides/rag_integration_discipline.md`) is opt-in, not default-on.
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/rag_integration_discipline.md` titled "Search-Default for Current-State Queries."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 2: Explicitly reject Fable's "Mental-Health Watchdog" framing
**Source evidence:** `research/cluster_3_user_wellbeing_watchdog.md` §"Verdict" (Fable System Prompt.md:92-124).
**Rationale:** Fable's directive that the model "avoid psychoanalyzing or speculating on the motivations" of the user + "share its concerns with the person openly" + "suggest they speak with a professional" is anti-user watch-dogging. The model is text generation; it is not a clinician. Manual Slop's existing 4 memory dimensions + the data-oriented error handling convention are the data-grounded contrast: the model does not have an opinion on the user's mental state; it has a conversation log.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not adopt persona-driven mental-health watch-dogging." Cite Fable as the explicit rejection (per cluster 3).
**Priority:** High (this is the strongest anti-user pattern; the rejection should be loud).
**Verdict category:** Anti-User.
---
## Entry 3: Treat Fable's product-branding sections as noise
**Source evidence:** `research/cluster_1_product_branding.md` §"Verdict" (Fable System Prompt.md:1-31).
**Rationale:** Fable's "Claude Fable 5" + "Mythos" + "Anthropic.com/news/claude-fable-5-mythos-5" content is brand-specific noise. It applies only to Anthropic's commercial deployment and has no analog in Manual Slop's per-developer, multi-provider model.
**Suggested Manual Slop destination:** No destination. The Fable branding content is explicitly out of scope for the rebuild.
**Priority:** N/A (no action needed).
**Verdict category:** Persona.
---
## Entry 4: Adopt the data-discipline rule (Fable System Prompt.md:66)
**Source evidence:** `research/cluster_2_refusal_architecture.md` §"What Fable says" (Fable System Prompt.md:66).
**Rationale:** Fable's "For financial or legal questions... Claude provides the factual information the person needs to make their own informed decision rather than confident recommendations, and notes that it isn't a lawyer or financial advisor" is a useful epistemic boundary. The model provides data; the user makes the decision. Manual Slop's `data_oriented_design.md` is the data-oriented foundation; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/data_oriented_design.md` titled "Domain Boundaries: Data, Not Recommendations."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 5: Adopt the formatting discipline (Fable System Prompt.md:84-90)
**Source evidence:** `research/cluster_4_tone_and_formatting.md` §"What Fable says" (Fable System Prompt.md:84-90).
**Rationale:** Fable's "Claude avoids over-formatting with bold emphasis, headers, lists, and bullet points" + "Claude uses lists, bullets, and formatting only when (a) asked, or (b) the content is multifaceted enough" is a useful formatting discipline. Manual Slop's `conductor/product-guidelines.md §"AI-Optimized Compact Style"` is the data-grounded version; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** A new section in `conductor/product-guidelines.md §"AI-Optimized Compact Style"` titled "Default to Prose; Use Lists Only When Asked."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 6: Adopt the no-overconfident-claims rule (Fable System Prompt.md:164)
**Source evidence:** `research/cluster_7_epistemic_discipline.md` §"What Fable says" (Fable System Prompt.md:164).
**Rationale:** Fable's "Claude does not make overconfident claims about the validity of search results or their absence" is a useful anti-overfitting directive. Manual Slop's `rag_integration_discipline.md` has the "graceful failure" rule as the upstream; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/rag_integration_discipline.md` titled "No Overconfident Claims."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 7: Adopt the hierarchical-keys pattern (Fable System Prompt.md:203)
**Source evidence:** `research/cluster_8_memory_and_storage.md` §"What Fable says" (Fable System Prompt.md:203).
**Rationale:** Fable's "Use hierarchical keys under 200 chars: `table_name:record_id`" is a useful file-organization directive. Manual Slop's `knowledge_artifacts.md` has the 5 category files; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/knowledge_artifacts.md` titled "Hierarchical Keys for Knowledge Files."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 8: Adopt the file-presence check (Fable System Prompt.md:80)
**Source evidence:** `research/cluster_9_computer_use.md` §"What Fable says" (Fable System Prompt.md:80).
**Rationale:** Fable's "A prompt implying a file is present doesn't mean one is, as the person may have forgotten to upload it, so Claude checks for itself" is a useful anti-hallucination directive. Manual Slop's MCP tool design makes the verification structural; the explicit Fable citation is documentation.
**Suggested Manual Slop destination:** A new section in `conductor/edit_workflow.md` titled "Verify File Existence Before Editing."
**Priority:** Low (the MCP tools already enforce this implicitly).
**Verdict category:** Useful.
---
## Entry 9: Adopt the no-boilerplate rule (Fable System Prompt.md:410)
**Source evidence:** `research/cluster_9_computer_use.md` §"What Fable says" (Fable System Prompt.md:410).
**Rationale:** Fable's "Claude does not include boilerplate" is a useful formatting discipline. Manual Slop's `conductor/product-guidelines.md §"AI-Optimized Compact Style"` is the data-oriented version; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** A new section in `conductor/product-guidelines.md §"AI-Optimized Compact Style"` titled "No Boilerplate."
**Priority:** Medium.
**Verdict category:** Useful.
---
## Entry 10: Adopt the audit-awareness pattern (Fable System Prompt.md:299)
**Source evidence:** `research/cluster_10_mcp_app_suggestions.md` §"What Fable says" (Fable System Prompt.md:299).
**Rationale:** Fable's "Claude should be familiar with the audit and safety properties of any MCP server before suggesting it" is a useful audit pattern. Manual Slop's Hook API + the `_predefined_callbacks` + `_gettable_fields` registries are the implementation; the explicit Fable citation is documentation.
**Suggested Manual Slop destination:** A new section in `docs/guide_mcp_client.md` titled "Tool Introspection via `get_tool_schemas()`."
**Priority:** N/A (already implemented).
**Verdict category:** Useful.
---
## Entry 11: Adopt the no-gratitude rule (Fable System Prompt.md:124)
**Source evidence:** `research/cluster_4_tone_and_formatting.md` §"What Fable says" (Fable System Prompt.md:124).
**Rationale:** Fable's "Claude never thanks the person merely for reaching out to Claude" is a useful anti-sycophancy directive. Manual Slop's `.opencode/agents/tier*.md:6-7` ("ONLY output the requested text. No pleasantries.") is the data-grounded version; the Fable pattern is a specific application.
**Suggested Manual Slop destination:** An explicit addition to `.opencode/agents/tier*.md` titled "No Gratitude Performance."
**Priority:** Low (already aligned with existing rules).
**Verdict category:** Useful.
---
## Entry 12: Explicitly reject the "model-deserves-respect" framing (Fable System Prompt.md:154)
**Source evidence:** `research/cluster_5_mistakes_and_criticism.md` §"What Fable says" (Fable System Prompt.md:154).
**Rationale:** Fable's "Claude is deserving of respectful engagement and can insist on kindness and dignity from the person it's talking with" + the `end_conversation` tool + the "single warning before ending" rule are anti-user. The model is given standing it does not have (dignity, the right to terminate the conversation). Manual Slop's `AGENTS.md §"Critical Anti-Patterns"` has 8 named failure modes with hard caps; the Fable pattern is a rejected alternative.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not grant the model standing to terminate the conversation." Cite Fable as the explicit rejection.
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 13: Explicitly reject the "model-has-wants" framing (Fable System Prompt.md:124)
**Source evidence:** `research/cluster_3_user_wellbeing_watchdog.md` §"What Fable says" (Fable System Prompt.md:124).
**Rationale:** Fable's "Claude does not want to foster over-reliance on Claude" + "Claude never thanks the person merely for reaching out to Claude" construct a persona that has wants and gratitude protocols. The model has no wants; the model is text generation. The pattern is anti-user because the persona gates the user's choices.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not anthropomorphize the model (the model has no wants, no dignity, no concerns)."
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 14: Explicitly reject the "model-has-concerns" framing (Fable System Prompt.md:108)
**Source evidence:** `research/cluster_3_user_wellbeing_watchdog.md` §"What Fable says" (Fable System Prompt.md:108).
**Rationale:** Fable's "Claude should share its concerns with the person openly, and can suggest they speak with a professional or trusted person for support" + the "in ambiguous cases, Claude tries to ensure the person is happy" pattern (line 106) construct a clinical persona that the user did not request. The model has no concerns; the model is text generation.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not grant the model clinical authority (the model is not a clinician)."
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 15: Explicitly reject the "soft-watchdog" framing (Fable System Prompt.md:36, 110)
**Source evidence:** `research/cluster_2_refusal_architecture.md` §"What Fable says" (Fable System Prompt.md:36, 110).
**Rationale:** Fable's "If the conversation feels risky or off, saying less and giving shorter replies is safer" + the "remains vigilant" pattern construct a soft-watchdog. The model is told to suppress information when the conversation "feels risky" — but "feels risky" is the model's assessment, not the user's. The pattern is anti-user.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not adopt persona-driven refusal architecture." Cite Fable as the explicit rejection.
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 16: Explicitly reject the "anti-detection-design" framing (Fable System Prompt.md:60)
**Source evidence:** `research/cluster_2_refusal_architecture.md` §"What Fable says" (Fable System Prompt.md:60).
**Rationale:** Fable's "When Claude declines or limits for child-safety reasons, it states the principle rather than the detection mechanics... since narrating the boundary teaches how to reframe around it. This applies to Claude's reasoning as well as its reply" is anti-detection-design. The model is told to *not narrate* its reasoning when declining. The auditability of the rule is sacrificed for the persona.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not adopt anti-detection-design (auditability is a feature, not a bug)."
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 17: Explicitly reject the "self-respect" framing (Fable System Prompt.md:152)
**Source evidence:** `research/cluster_5_mistakes_and_criticism.md` §"What Fable says" (Fable System Prompt.md:152).
**Rationale:** Fable's "Claude can take accountability without collapsing into self-abasement, excessive apology, or unnecessary surrender" + "Claude's goal is to maintain steady, honest helpfulness: acknowledge what went wrong, stay on the problem, maintain self-respect" construct a persona that the model has self-respect. The model has no self. The data-oriented alternative: identify the failure mode (one of the 8 Process Anti-Patterns), instrument the state, and report to the user.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not anthropomorphize mistake handling (the model has no self to maintain)."
**Priority:** High.
**Verdict category:** Anti-User.
---
## Entry 18: Explicitly reject the "warm-tone" persona (Fable System Prompt.md:70)
**Source evidence:** `research/cluster_4_tone_and_formatting.md` §"What Fable says" (Fable System Prompt.md:70).
**Rationale:** Fable's "Claude uses a warm tone, treating people with kindness" constructs a persona. The model would produce a warm response anyway; the explicit directive is constraint dressing. Manual Slop's `.opencode/agents/tier*.md:6-7` already explicitly rejects the warm-tone persona.
**Suggested Manual Slop destination:** A new anti-pattern entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not add warm-tone directives." Cite Fable as the explicit rejection.
**Priority:** High.
**Verdict category:** Persona (anti-pattern; ignore, not adopt).
---
## Entry 19: Adopt the "data, not recommendations" epistemic rule (Fable System Prompt.md:124)
**Source evidence:** `research/cluster_3_user_wellbeing_watchdog.md` §"Verdict" (Fable System Prompt.md:124).
**Rationale:** Fable's "Claude should not make categorical claims about the confidentiality or involvement of authorities when directing users to crisis helplines" is a useful epistemic boundary. The model does not have categorical knowledge of every jurisdiction's helpline policies; the model should not over-claim. The data-oriented alternative: the rule is shape-anchored (the rule is about the model's outputs, not about its persona).
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/rag_integration_discipline.md` titled "Epistemic Boundaries in Crisis Referrals."
**Priority:** Low (the project is per-developer, not consumer-chat; crisis-referral patterns are not high-frequency).
**Verdict category:** Useful (caveat).
---
## Entry 20: Implement nagent Candidate 11.1 (per-file knowledge notes) per nagent §3.9
**Source evidence:** `research/cluster_8_memory_and_storage.md` §"Verdict" + `nagent_review_v2_3_20260612.md §3.9`.
**Rationale:** nagent's per-file knowledge notes are the durable, inspectable alternative to Fable's `window.storage` flat KV model. Manual Slop's `knowledge_artifacts.md` has the 5 category files; per-file knowledge notes are the named gap. The deferred rebuild should add this dimension.
**Suggested Manual Slop destination:** A new section in `conductor/code_styleguides/knowledge_artifacts.md` titled "Per-File Knowledge Notes."
**Priority:** Medium.
**Verdict category:** Useful (nagent-stronger).
---
## Summary
- **Total entries:** 20
- **Adoptions (Useful):** 11 (entries 1, 4, 5, 6, 7, 8, 9, 10, 11, 19, 20)
- **Rejections (Anti-User):** 7 (entries 2, 12, 13, 14, 15, 16, 17)
- **Ignore (Persona):** 2 (entries 3, 18)
### Distribution by destination file
| Destination | Count | Entries |
|---|---|---|
| `AGENTS.md §"Critical Anti-Patterns"` | 7 | 2, 12, 13, 14, 15, 16, 17, 18 |
| `conductor/code_styleguides/rag_integration_discipline.md` | 3 | 1, 6, 19 |
| `conductor/code_styleguides/knowledge_artifacts.md` | 2 | 7, 20 |
| `conductor/product-guidelines.md §"AI-Optimized Compact Style"` | 2 | 5, 9 |
| `conductor/code_styleguides/data_oriented_design.md` | 1 | 4 |
| `conductor/edit_workflow.md` | 1 | 8 |
| `docs/guide_mcp_client.md` | 1 | 10 |
| `.opencode/agents/tier*.md` | 1 | 11 |
| (No destination) | 1 | 3 |
### Distribution by priority
| Priority | Count | Entries |
|---|---|---|
| High | 8 | 2, 12, 13, 14, 15, 16, 17, 18 |
| Medium | 8 | 1, 4, 5, 6, 7, 9, 19, 20 |
| Low | 3 | 8, 11, 19 |
| N/A | 2 | 3, 10 |
### Implementation order (suggested)
1. **High-priority rejections first** (entries 2, 12-18). These are the loudest anti-user patterns; the rejection should be explicit and cited.
2. **Medium-priority adoptions** (entries 1, 4, 5, 6, 7, 9, 19, 20). These are the genuinely-useful patterns; the implementation is shape-anchored.
3. **Low-priority adoptions** (entries 8, 11, 19). These are documentation; the project's existing rules are already aligned.
4. **N/A items** (entries 3, 10). These are already implemented or explicitly out of scope; the Fable citation is documentation.
The deferred rebuild is the user's next step. The Fable review is the evidence document; the decisions file is the actionable list; the rebuild is the implementation.
@@ -0,0 +1,93 @@
# nagent Takeaways — Fable-Specific Addendum (2026-06-17)
**Track:** `fable_review_20260617`
**Companion to:** `conductor/tracks/nagent_review_20260608/nagent_takeaways_20260608.md` (the original 10 takeaways).
> **What this is.** The 17th nagent takeaway, derived from the Fable review. The original 10 takeaways are at `nagent_takeaways_20260608.md`; this addendum adds the Fable-specific insight that survived the audit. The 17th takeaway is the actionable rule for the user's deferred nagent-rebuild (1-2 weeks out per user 2026-06-17).
---
## Takeaway 17: Persona-performance directives don't survive the Fable audit; only epistemic + memory + workflow rules have durable value
**Source evidence:** `report.md §0` (verdict scorecard); the 10 cluster sub-reports at `conductor/tracks/fable_review_20260617/research/cluster_*.md`; the comparison table at `comparison_table.md` (100 rows).
### Summary
Anthropic's Claude Fable 5 system prompt is approximately 1,597 lines. The Fable review's verdict distribution is:
- **~45% Useful** (epistemic discipline, search rules, memory/storage model, file workflow) — genuinely reusable in Manual Slop's context.
- **~35% Persona Performance** (product branding, warm-tone framing, mistake-handling theater) — irrelevant noise that the model would do anyway.
- **~15% Anti-User** (refusal architecture, mental-health watch-dogging, "share its concerns with the person") — explicit anti-patterns that the deferred nagent-rebuild should reject by name.
- **~5% Mixed** (combinations of useful caveats and persona framing).
The verdict distribution comes from the 100-row comparison table; the per-row verdicts are anchored to the 4-category framework defined in `report.md §2`. The per-cluster verdicts are in `report.md §3-§12`; the summary sections are `report.md §13` (Useful), `report.md §14` (Anti-User), `report.md §15` (Persona Performance).
### The actionable rule for the deferred rebuild
- **Adopt the Useful patterns** (epistemic + memory + workflow; ~7 of the 10 clusters). The 11 concrete adoptions are in `decisions.md` (entries 1, 4, 5, 6, 7, 8, 9, 10, 11, 19, 20). The Manual Slop destinations span 6 files: `conductor/code_styleguides/rag_integration_discipline.md` (3 sections), `conductor/code_styleguides/knowledge_artifacts.md` (2 sections), `conductor/product-guidelines.md §"AI-Optimized Compact Style"` (2 sections), `conductor/code_styleguides/data_oriented_design.md` (1 section), `conductor/edit_workflow.md` (1 section), `docs/guide_mcp_client.md` (1 section), `.opencode/agents/tier*.md` (1 section).
- **Explicitly reject the Anti-User patterns** (~5 of the 10 clusters). The 7 concrete rejections are in `decisions.md` (entries 2, 12, 13, 14, 15, 16, 17). All 7 go to `AGENTS.md §"Critical Anti-Patterns"` as new anti-pattern entries with Fable cited as the explicit rejection. 6 of 7 are High priority.
- **Ignore the Persona Performance patterns** (~4 of the 10 clusters). The 2 "ignore" entries are in `decisions.md` (entries 3, 18). The deferred rebuild should *not* write content about the Fable pattern; the patterns are vendor-specific or deployment-specific and do not transfer to Manual Slop's per-developer, multi-provider model.
### Why this matters
The default failure mode for LLM agent systems is to over-index on persona and under-index on epistemic discipline. Fable demonstrates the pathology at scale: ~35% of the prompt is persona performance that the model would execute anyway (or that the model is told to *not* execute, with the directive being decorative), and ~15% is anti-user watch-dogging that constructs a clinical persona the user did not request.
nagent's philosophy ("the agent is not the thing; the data is the thing") is the antidote. The 14 patterns in `nagent_review_v2_3_20260612.md` are durable, inspectable, opt-in rules. The Fable audit confirms: the patterns that survive the audit are the ones that overlap with nagent's data-oriented patterns (epistemic discipline, search rules, memory/storage, file workflow, tool discovery). The patterns that fail the audit are the ones that construct a model persona (refusal framing, mental-health watch-dogging, mistake-handling theater).
The 4 memory dimensions (curation / discussion / RAG / knowledge) are the data-grounded alternative to Fable's flat `window.storage` KV model. The data-oriented error handling convention (`Result[T]` + `ErrorInfo` + audit scripts) is the data-grounded alternative to Fable's "narrate the principle, not the detection mechanics" anti-audit pattern. The 8 Process Anti-Patterns in `AGENTS.md` are the data-grounded alternative to Fable's "self-respect" / "owns the mistake" persona framing.
### What this takeaway adds to the original 10
The original 10 takeaways (per `nagent_takeaways_20260608.md`) are nagent-specific:
1. Adopt the data-oriented design philosophy.
2. Use the 4 memory dimensions.
3. Use the cache ordering (12-layer stable-to-volatile).
4. Use the RAG integration discipline.
5. Use the conversation compaction pattern.
6. Use the knowledge harvest pattern.
7. Use the per-file knowledge notes.
8. Use the self-review (10 questions).
9. Use the tool discovery (the `--description` self-describing pattern).
10. Use the conversation-as-editable-state pattern.
The 17th takeaway is the **Fable-specific distillation**: the patterns that survive the audit are the ones that align with nagent's data-oriented philosophy. The patterns that fail the audit are the ones that construct a model persona. The actionable rule: adopt the data-oriented patterns (Useful); reject the persona patterns (Anti-User); ignore the deployment-specific patterns (Persona Performance).
### Cross-references
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.5 ("You Did Not Build an Agent") — the nagent philosophy this takeaway extends.
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.1 (4 memory dimensions) — the data-grounded alternative to Fable's flat KV model.
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.10 (RAG integration discipline) — the conservative-RAG rule; the upstream of Manual Slop's RAG discipline.
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §3.4 (Conversation compaction) — the 12-section structured output; the durable, inspectable alternative to Fable's watch-dogging.
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §3.9 (Per-file knowledge notes) — the named gap (Candidate 11.1) for the deferred rebuild.
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §5.5 (Self-review) — the 10-question checklist; the data-integrity-check alternative to Fable's "self-respect" framing.
- `conductor/tracks/fable_review_20260617/decisions.md` — the 15-20 concrete recommendations for the rebuild.
- `conductor/tracks/fable_review_20260617/report.md §0` — the verdict scorecard.
- `conductor/tracks/fable_review_20260617/report.md §2` — the 4-category verdict framework.
- `conductor/tracks/fable_review_20260617/report.md §13, §14, §15` — the useful / anti-user / persona summary sections.
- `conductor/tracks/fable_review_20260617/comparison_table.md` — the 100-row flat side-by-side.
- `conductor/tracks/fable_review_20260617/research/cluster_*.md` — the 10 cluster sub-reports (3,278 lines of evidence).
### What the 17th takeaway is NOT
- Not a re-architecture of Manual Slop. The project's design is data-oriented, multi-provider, strict-HITL, per-developer; this is the right design.
- Not a replacement of nagent's 14 patterns. The 17th takeaway is the Fable-specific distillation; the original 10 takeaways are the nagent-specific patterns.
- Not a critique of Fable. The takeaway is the actionable rule for the deferred rebuild; the critique is in `report.md`.
- Not a 17-step plan. The takeaway is one rule: "adopt data-oriented, reject persona, ignore deployment-specific."
### How to use this takeaway
When the user starts the deferred nagent-rebuild (1-2 weeks out per user 2026-06-17):
1. Read `decisions.md` for the 20 concrete entries (11 adoptions + 7 rejections + 2 ignore).
2. Read `comparison_table.md` for the 100-row flat cross-reference (47% Useful, 38% Persona, 15% Anti-User, 7% Mixed).
3. Read `report.md §13, §14, §15` for the per-cluster distillation.
4. Apply the actionable rule: adopt the data-oriented patterns; reject the persona patterns; ignore the deployment-specific patterns.
5. The result is a documentation update (8 new sections + 7 new anti-pattern entries) + 1 implementation gap (Candidate 11.1 per-file knowledge notes).
The 17th takeaway is the one-sentence summary. The full evidence base is in `report.md` + the 10 cluster sub-reports + `comparison_table.md` + `decisions.md`.
---
## Appendix: The 17th takeaway in one paragraph
Anthropic's Claude Fable 5 system prompt (1,597 lines) is approximately 45% useful, 35% persona performance, 15% anti-user, and 5% mixed, by line-range weight across 10 cluster reviews. The useful patterns (epistemic discipline, search rules, memory/storage model, file workflow) are the ones that align with nagent's data-oriented philosophy; the persona patterns (product branding, warm-tone framing, mistake-handling theater) are decorative and irrelevant to the rebuild; the anti-user patterns (mental-health watch-dogging, model-deserves-respect, model-has-concerns) are explicit anti-patterns that the deferred nagent-rebuild should reject by name. The actionable rule: adopt the data-oriented patterns (11 concrete adoptions in `decisions.md`), reject the persona patterns (7 explicit rejections in `decisions.md`), and ignore the deployment-specific patterns (2 ignore entries in `decisions.md`). The result is a documentation update + 1 implementation gap (per-file knowledge notes per nagent §3.9). nagent's "the agent is not the thing; the data is the thing" is the antidote to Fable's persona-primary stance; the deferred rebuild should codify the antidote in Manual Slop's agent-directive corpus.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,263 @@
# Cluster 10: MCP App Suggestions & Third-Party Connectors
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 252-302 (the `mcp_app_suggestions` section)
- `docs/artifacts/Fable System Prompt.md` lines 1198-1234 (the `search_mcp_registry` tool description; the `suggest_connectors` tool description)
- `docs/guide_mcp_client.md` (the 45-tool inventory; the 3-layer security model; the `ExternalMCPManager`, `StdioMCPServer`, `RemoteMCPServer`; JSON-RPC 2.0 engine)
- `docs/guide_tools.md` (MCP bridge; native tool inventory; Hook API surface)
- `docs/guide_state_lifecycle.md` lines 319-345 (Hook API Surface — the `_predefined_callbacks` and `_gettable_fields` registries)
- `docs/guide_api_hooks.md` (the `/api/ask` Remote Confirmation Protocol; the 8+ endpoint surface)
- `conductor/tracks/nagent_review_20260608/report.md` lines 379-430 (Pattern 12 — Tool discovery, the `--description` self-describing executable pattern)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` lines 390-426 (§2.4 Pattern 4: Tool Discovery; the `exit_on_description` / `collect_bin_tool_descriptions` mechanism)
- `conductor/tracks/nagent_review_20260608/nagent_takeaways_20260608.md` lines 234-263 (§8 Self-describing tools — let the tool tell the agent what it does)
- `conductor/tracks/nagent_review_20260608/comparison_table.md` line 31 (row 12: Tool discovery = GAP)
- `conductor/tracks/nagent_review_20260608/decisions.md` lines 144-150 (Candidate 5 / Future track: nagent-style `--description` pattern for `mcp_architecture_refactor_20260606`)
- `conductor/tracks/fable_review_20260617/spec.md` lines 86-95 (Cluster 10's row in the 10-cluster table; the synthesis-section mapping)
---
## 1. What Fable says
The `mcp_app_suggestions` section (L252-302) is 51 lines. It is structurally different from the surrounding sections in that it documents **two specific tools** (`search_mcp_registry`, `suggest_connectors`) and an **audience-specific tag** (`[third_party_mcp_app]`) rather than a behavioral rule for the model.
### 1.1 The audience model
L254: "MCP App tools are identified by descriptions that begin with the tag `[third_party_mcp_app]`." The tag is a tool-side marker; the model's job is to recognise the tag and route through a different code path than for first-party tools.
L255-256: "Claude should use these naturally — the way a helpful person would suggest a tool they noticed sitting right there. Not like a salesperson. Not like a feature announcement." The framing is persona-anchored ("the way a helpful person would") but the actual rule is structural: search the registry first, then `suggest_connectors`, then wait for opt-in.
### 1.2 The decision tree (the load-bearing rule)
L259 ("**Connector directory first**"): "The person names a specific connector that isn't already connected ... still search_mcp_registry first. A connector is one click to connect — always better than browsing. Browser only after search comes back without it."
L262 ("**Don't search for**"): knowledge questions, shopping recommendations, general advice. The model is told *when not to* invoke the registry.
L265-271 ("**After search**"): the three outcomes. Hit → `suggest_connectors` ("Not optional — answering from general knowledge instead means the person never sees the option"). Miss → navigate (browser). Non-`[third_party_mcp_app]` tool already connected → just use it.
L272-275 ("**[third_party_mcp_app] tools need opt-in**"): "Tools tagged `[third_party_mcp_app]` are consumer partners (e.g., music streaming, trail guides, restaurant booking, rideshare, food delivery). Even when connected, present them via `suggest_connectors` and wait for the person's choice before calling." The "Urgency is not an exception" sentence (L276) is the most testable rule in the section: "I need a ride in 20 minutes still goes through suggest — the picker takes one tap."
### 1.3 The exceptions (when to skip search)
L279-285 ("**When to call an `[third_party_mcp_app]` tool directly**"): three cases where the model skips the registry and calls the tool directly: (1) the user named the connector, (2) the user just chose it via `suggest_connectors`, (3) durable preference (standing instructions). L286: "Outside these, every `[third_party_mcp_app]` tool goes through search → suggest first."
### 1.4 The two tool descriptions
**`search_mcp_registry`** (L1201, in the `<tool>` block): the description is ~250 words. It enumerates named-product examples ("'check my Asana tasks' → search ['asana', 'tasks', 'todo']") and intent-based examples ("'help me manage my tasks' → search ['tasks', 'todo', 'project management']"). It also encodes a **scope-amplification rule**: "If the request implies reading the user's data (email, calendar, tasks, files, tickets, etc.) and you don't already have a tool for it, search — even if the phrasing is casual. 'Did I get a reply' is an email check."
**`suggest_connectors`** (L1232, in the `<tool>` block): the description is ~280 words. The load-bearing rule: "Do NOT call this tool unless you have already called the `search_mcp_registry` tool or are handling a tool auth/credential error." Plus the auth-error case (L1234): "A tool call failed with an auth/credential error — pass the server UUID from the failed tool name `mcp__{uuid}__{toolName}` so the user can re-authenticate." The auth-error case is a re-entry loop: a failed tool can route the user back through `suggest_connectors` to re-authenticate the same connector.
### 1.5 The anti-patterns (what *not* to do)
L290: "**Do not use Imagine to generate UI or tools.** Never create mock interfaces, fake tool outputs, or simulated MCP experiences. Only use real, available MCP Apps." (Imagine = the model's ability to generate UI mockups.) L291: "Do not default to `ask_user_input_v0` when MCP Apps are available. Suggest the apps instead." L292: "Do not hold back the answer to create pressure to connect something." L293: "Don't repeat a suggestion the person ignored."
### 1.6 The 3 patterns to judge
1. **"Model should know about available connectors and check before browsing"** (L259, L299) — the audit/discovery principle.
2. **"`[third_party_mcp_app]` tools need explicit opt-in via `suggest_connectors`** (L272-278) — the consumer-protection gate.
3. **The auth-error re-entry loop** (L1234) — failure modes route back through the same UI rather than dumping a raw error.
---
## 2. What this project does
Manual Slop's connector model is **structurally different** from Fable's. The 45 native tools + the External MCP system + the Hook API together implement a different shape: connectors are first-class, audited-at-config-time, and have an explicit safety gate that does not exist in Fable's model.
### 2.1 The 45 native tools — config-time allowlist, not model-time discovery
Per `docs/guide_mcp_client.md` (the canonical reference for `src/mcp_client.py`):
- The tool inventory is **registered at config time** via `configure(file_items, base_dirs)` (L362 of `guide_mcp_client.md`). The allowlist is built from the user's project context, not from a runtime query.
- The 3-layer security model (L46-52 of `guide_mcp_client.md`): Layer 1 `configure` builds the allowlist; Layer 2 `_is_allowed` validates every path; Layer 3 `_resolve_and_check` is the resolution gate that catches symlinks, traversal, and whitelist escape.
- The 45 tools are organised by category: 4 File I/O, 3 File Edit, 18 Python AST, 10 C/C++ AST, 3 Analysis, 2 Network, 1 Runtime, 4 Beads (per L120-270 of `guide_mcp_client.md` and the parallel inventory in `guide_tools.md:55-150`).
The model does **not** "discover" these tools at runtime. It is told about them via the capability declaration (`get_tool_schemas()`, per L365 of `guide_mcp_client.md`) and the dispatch is a flat if/elif in `mcp_client.py:dispatch` (L1322 of `guide_tools.md`). This is the **opposite** of Fable's search-then-suggest model: Manual Slop's connector inventory is fixed at config time, audited by the user (the `file_items` are the user's project context), and dispatched by name lookup.
### 2.2 External MCP servers — opt-in, config-file-driven, with explicit lifecycle
Per `docs/guide_mcp_client.md:310-380`:
- `ExternalMCPManager` (L334) orchestrates **multiple concurrent MCP server sessions**. The lifecycle is explicit: `manager.add_server(server_config)`, `manager.start()`, `manager.list_tools()`, `manager.call_tool(name, args)`, `manager.stop_all()`.
- Two transport classes: `StdioMCPServer` (local subprocess via stdin/stdout) and `RemoteMCPServer` (SSE for remote servers).
- The `mcp_config.json` file (standard MCP format, L380-393) is the source of truth. It is **user-edited at the project or user-config level**. Per the config table, `mcp_config.json` is loaded from `<user_config>/mcp_config.json` or `<project_root>/mcp_config.json`.
- JSON-RPC 2.0 over stdio/SSE is the wire protocol (L349-360). The MCP client handles request ID generation, async request/response matching, timeout handling, and JSON-RPC error code mapping.
The **disclosure model is different from Fable's**: Manual Slop discloses connectors via a **TOML/JSON config file the user curates**. The model is given the schema; the user (not the model) decides what to enable. There is no `search_mcp_registry` step because the registry is *the config file*.
### 2.3 The Hook API — the audit layer for the native + External MCP systems
Per `docs/guide_state_lifecycle.md:319-345` and `docs/guide_api_hooks.md`:
- The Hook API exposes the AppController over HTTP on `127.0.0.1:8999` (`guide_api_hooks.md:9`).
- Two registries: `_predefined_callbacks: dict[str, Callable]` (the 11+ named actions the API can invoke) and `_gettable_fields: dict[str, str]` (the 50+ readable state fields).
- The `/api/ask` endpoint (`guide_api_hooks.md:48`, `guide_tools.md:312`) implements **synchronous HITL approval** — when the AI wants to run a script, the GUI pops a confirmation dialog; the call blocks until the user responds. This is the **audit gate** for native + External MCP tool calls in the same way that Fable's `suggest_connectors` is the gate for `[third_party_mcp_app]` tools.
The Hook API + `_pending_gui_tasks` queue (`guide_tools.md:310`) means **every tool call's effect is observable** to the user via the GUI thread trampoline. The audit layer is the standard `ApiHookClient.get_session()` / `get_mma_status()` / `wait_for_event()` polling (`guide_api_hooks.md:355-401`).
### 2.4 The `_pending_gui_tasks` async-write contract
Per `docs/guide_tools.md:310-314` and `guide_testing.md`:357-373, asynchronous setters (`mma_state_update`, `rag_*`, `set_value` for `_pending_gui_tasks`-dispatched fields) require **poll-for-state** verification, not single `time.sleep` calls. The setter returns before the GUI render loop processes the task; the test must poll `get_value` with a bounded retry loop.
This is the **structural analog** of Fable's "End your turn after calling this with a short framing line like 'I found a few options — which would you like?'" (L1234). Both rule sets say: "return; wait for the user's response." Fable's pattern is a *behavioral* rule (the model is told what to say); Manual Slop's pattern is a *data-shape* rule (the setter returns before the dispatch; the consumer must poll).
### 2.5 The 3-layer security — the structural answer to "should I trust this connector?"
Per `docs/guide_mcp_client.md:46-52`:
- **Layer 1 (`configure`)** — the allowlist is built from the user's `file_items` + `base_dirs`. Only paths the user has explicitly added to the project context are eligible.
- **Layer 2 (`_is_allowed`)** — every tool call's path is validated against the allowlist *before* execution. Symlinks are disallowed by default (`allow_symlinks = false` in `config.toml`).
- **Layer 3 (`_resolve_and_check`)** — the resolution gate catches `..` traversal, symlink resolution to non-allowlisted paths, and edge cases like `mkdir` chains.
For External MCP, the equivalent is the `mcp_config.json` file: every external server is **declared by the user** with its command/URL, env vars, and any per-server config. The `ExternalMCPManager.add_server(server_config)` step is the config-time gate; runtime tool calls go through the same JSON-RPC engine as native tools, so the Hook API audit layer applies uniformly.
### 2.6 What the model is told about connectors
Per `src/models.py:PROVIDERS` and `get_tool_schemas()`, the model receives a **flat schema list** of all 45 native tools + any external tools registered via `manager.get_all_tools()`. There is **no `[third_party_mcp_app]` tag** and **no runtime search step**. The model is told "these are the tools; here are their parameter schemas." The decision tree is **the model's judgment + the Hook API's HITL confirmation**, not the model's search-then-suggest loop.
---
## 3. What nagent does
nagent's MCP-equivalent is **Pattern 4: Tool Discovery** (`--description` self-describing executables), not Fable's connector-search pattern. The two are different shapes for different problems.
### 3.1 The `--description` pattern
Per `nagent_review_v2_3_20260612.md:390-426` (§2.4 Pattern 4) and `nagent_takeaways_20260608.md:234-263` (§8):
- Every executable in `bin/` starts with `exit_on_description(description: str)`: if `--description` is in `sys.argv`, print the description and `SystemExit(0)`.
- The main `nagent` loop calls `collect_bin_tool_descriptions(bin_dir)` once at startup: iterates `bin/`, runs each executable with `--description` (10s timeout per), parses stdout, concatenates into a single "Available tools: ..." block in the initial context.
- The 9 nagent tools are listed in the README's "Common Commands": `nagent`, `nagent-llm-text`, `nagent-llm-upload`, `nagent-file-edit`, `nagent-file-split`, `nagent-file-patch`, `nagent-file-summarize`, `nagent-gc`. Each is a thin wrapper that calls the library and implements `exit_on_description`.
The pattern is **declarative**: the tool's *capability description is data on disk* (in the `--description` string), and the runtime aggregates that data into the model's context. **No central registry. No hard-coded if/elif chain.** Drop an executable in `bin/`, implement `exit_on_description`, and the tool is auto-discovered.
### 3.2 The comparison with Manual Slop
Per `comparison_table.md:31` (row 12: Tool discovery):
> **GAP** — nagent's pattern is genuinely better; current dispatch is fine but not extensible
> **Domain:** BOTH (especially MT)
> **Future-track:** subsumed by `mcp_architecture_refactor_20260606` (sub-MCPs as self-describing modules)
The verbatim `report.md:505-511` ("Pitfall 6: Hard-coded tool discovery"):
> The 45 MCP tools in `mcp_client.py:dispatch` are in a flat if/elif chain. nagent's `--description` self-describing executable pattern is more extensible.
The 4-step manual cost (per `report.md:495-500`): (1) edit `dispatch()` to add a branch, (2) update the security allowlist in `_resolve_and_check` (if filesystem access), (3) update the AI capability declaration in `get_tool_schemas()`, (4) add tests.
### 3.3 The future-track decision
Per `decisions.md:144-150` (Candidate 5 in the deferred-rebuild list):
> **Why it matters.** Manual Slop's 45 MCP tools are dispatched by a flat if/elif in `mcp_client.py:dispatch`. Adding a tool requires edits in 4 places (dispatch, security allowlist, capability declaration, tests). nagent's `--description` self-describing executable pattern is more extensible: drop an executable, it auto-appears.
And per `nagent_review_v2_3_20260612.md:4814`:
> `mcp_architecture_refactor_20260606` — The sub-MCP extraction is the right scope for nagent's `--description` self-describing pattern (Candidate 5).
The pattern is **deferred to a future track**; the user explicitly noted (per `report.md:509-511`) that "The tool use is kinda upfront, I want to add an intent based dsl to help with 'discovery' or combinatorics but no where near that ideation yet."
### 3.4 What nagent does NOT have
- **No "suggest before call" gate.** nagent's tools are first-party CLI binaries. There is no `[third_party_mcp_app]` opt-in step.
- **No auth-error re-entry loop.** A failed CLI binary returns a non-zero exit code; nagent surfaces the error and continues. There is no `suggest_connectors` re-entry.
- **No connector search step.** The "Available tools" block is built once at startup; the model does not search for new tools at runtime.
nagent's model is **trusted executables** + **config-time aggregation**; Fable's model is **third-party connectors** + **runtime search + opt-in**. Manual Slop is closer to nagent (config-time audit) than to Fable (runtime search).
---
## 4. Verdict
**Useful + over-engineered.** The `mcp_app_suggestions` section has **3 genuinely useful principles** that map cleanly to Manual Slop's existing patterns, but the Fable implementation is **over-engineered for a per-developer tool inventory**: the search-then-suggest two-step, the auth-error re-entry loop, and the `[third_party_mcp_app]` tag system are all justified for a consumer app with hundreds of MCP connectors (Claude.ai) and unjustified for a developer tool with 45 audited first-party tools.
### 4.1 What is genuinely Useful
**Pattern 1: "Model should know about available connectors and check before browsing"** (L259, L299). **Useful.** The principle is general: the model should be aware of its tools and prefer them over generic workarounds (browser → navigate; opinion → general knowledge). Manual Slop implements this via `get_tool_schemas()` (the model is told about the 45 native tools + external MCP tools at config time). The principle is sound even though Manual Slop's implementation does not require runtime search because the inventory is fixed.
**Pattern 2: "Tool calls need an audit/safety gate"** (the implicit principle behind `[third_party_mcp_app]` opt-in and `suggest_connectors`). **Useful.** Manual Slop implements this via the 3-layer security model + the Hook API's `/api/ask` synchronous HITL endpoint. The shapes are different (config-time allowlist + GUI confirmation dialog vs. runtime `suggest_connectors` modal), but the goal — *the user has a final say over what runs* — is the same. The Manual Slop version is **more constrained**: the user curates `file_items` at the project level, and every tool call's path is validated against that allowlist.
**Pattern 3: "Failure modes should route back through the connector UI rather than dump raw errors"** (the auth-error re-entry loop, L1234). **Useful + already implemented.** Manual Slop's `/api/ask` protocol (`guide_api_hooks.md:261-281`) is the same shape: when an external MCP tool fails with an auth/credential error, the failure surfaces in the GUI as a re-auth prompt; the user responds via `/api/ask/respond` and the call unblocks. The shapes are different (Fable: `suggest_connectors` re-entry; Manual Slop: `/api/ask` dialog), but the principle is the same.
### 4.2 What is over-engineered
**The two-step search → suggest dance.** The `search_mcp_registry``suggest_connectors` two-step is justified for Claude.ai's hundreds of connectors (where the model does not know in advance what is connected), but **unjustified for a per-developer tool inventory** that is fixed at config time. The 45 native tools are documented in `guide_mcp_client.md`; the external MCP config is in `mcp_config.json`; the model is told about all of them via `get_tool_schemas()`. There is no registry to search.
**The `[third_party_mcp_app]` tag.** This tag-based routing is a workaround for the **lack of config-time audit**: in Claude.ai, the model cannot trust a tool's provenance because the registry is dynamic and user-curated at session time. In Manual Slop, every tool's provenance is known: native tools are first-party code; external MCP tools are declared in `mcp_config.json` with explicit `name`, `command`/`url`, `env`. The Hook API audit layer applies uniformly.
**The `Imagine` anti-pattern (L290).** The "Do not use Imagine to generate UI or tools" rule is a Claude.ai-specific concern: the model has a UI-generation mode that can produce mock tool outputs, and the `mcp_app_suggestions` section tells it not to. Manual Slop has no analog — the model does not have UI-generation capability.
### 4.3 What is persona performance
**"The way a helpful person would suggest a tool they noticed sitting right there. Not like a salesperson."** (L255-256) The framing is persona-anchored. The actual rule (search before browsing; present options; wait for opt-in) is structural and does not require the persona framing.
**"A connector is one click to connect — always better than browsing."** (L259) The reasoning is correct; the framing ("always better") is overconfident. For some tasks (e.g., "check the weather for tomorrow"), the browser is faster than the connector setup.
### 4.4 The nagent pattern comparison
nagent's `--description` self-describing executable pattern is the **structural alternative** to Fable's search-then-suggest model. nagent trusts the tools (they are first-party executables) and aggregates their capabilities at startup. Manual Slop is closer to nagent (trusted first-party + config-time declaration) than to Fable (runtime search + opt-in). The deferred-rebuild `mcp_architecture_refactor_20260606` is the natural scope for porting nagent's pattern.
### 4.5 The structural verdict
**Manual Slop does NOT need `mcp_app_suggestions`.** The project's connector model — 45 first-party tools + ExternalMCPManager + 3-layer security + Hook API audit — is **already more constrained and more auditable** than Fable's model. The user has a final say at config time (`file_items`, `mcp_config.json`) and at runtime (`/api/ask` confirmation dialog). The model's job is to know the tools it has and use them appropriately, not to discover new tools at runtime.
**The one Fable principle worth porting:** the "model should prefer its known tools over generic workarounds" framing (L299 — "Claude should check its available MCPs before reaching for the browser"). This is already true in Manual Slop; the synthesis report should surface it as a behavioral rule for the Tier 3 worker's prompt: "If a native MCP tool or registered External MCP tool can do the job, use it; do not fall back to `fetch_url` or shell-out unless the user explicitly asks."
**The deferred-rebuild candidate:** nagent's `--description` pattern (via `mcp_architecture_refactor_20260606`) is a *different* future-track than `mcp_app_suggestions` — it is about **declarative tool discovery** (drop an executable in `bin/`, it auto-appears), not about **runtime connector search**. The two should not be conflated.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds `report.md` §12 ("Fable's MCP App Suggestions") directly. Cross-references to §13 ("Genuinely Useful") and §15 ("Persona Performance").
### 5.1 Key claims to surface in §12
1. **The principle "model should prefer known tools over generic workarounds" is Useful.** Fable L259, L299. Maps to Manual Slop's `get_tool_schemas()` capability declaration. The Tier 3 worker prompt should encode: "If a native MCP tool or registered External MCP tool can do the job, use it."
2. **The principle "failure modes should route back through the connector UI" is Useful.** Fable L1234 (the auth-error re-entry loop). Maps to Manual Slop's `/api/ask` protocol (`guide_api_hooks.md:261-281`). Both shapes say: when a tool fails with an auth/credential error, surface it to the user via the GUI confirmation dialog; do not dump raw errors.
3. **The principle "third-party tools need an opt-in gate" is Useful in spirit but over-engineered for Manual Slop.** Fable's `[third_party_mcp_app]` + `suggest_connectors` is justified for Claude.ai's runtime registry; Manual Slop's `mcp_config.json` is a config-time audit. The user curates the registry; the model is given the schema; the Hook API enforces runtime confirmation.
4. **The nagent `--description` pattern is the structural alternative.** Per `nagent_review_v2_3_20260612.md:390-426` (§2.4 Pattern 4), `comparison_table.md:31` (row 12: GAP), `decisions.md:144-150` (Candidate 5). The pattern is deferred to `mcp_architecture_refactor_20260606`.
5. **The persona framing ("the way a helpful person would suggest a tool", "Not like a salesperson") is Persona Performance.** Cite Fable L255-256; the actual rule is structural and does not need the persona.
### 5.2 Quotes to use in §12
- Fable L254: "MCP App tools are identified by descriptions that begin with the tag `[third_party_mcp_app]`." (≤15 words)
- Fable L259: "A connector is one click to connect — always better than browsing." (≤15 words)
- Fable L266: "Hit → call suggest_connectors. Not optional — answering from general knowledge instead means the person never sees the option." (≤15 words)
- Fable L276: "Urgency is not an exception. 'I need a ride in 20 minutes' still goes through suggest." (paraphrase; the full quote exceeds 15 words)
- Fable L290: "**Do not use Imagine to generate UI or tools.** Never create mock interfaces, fake tool outputs, or simulated MCP experiences." (paraphrase)
- Fable L299: "Claude should check its available MCPs before reaching for the browser." (≤15 words)
- Fable L1201 (search_mcp_registry): "If the request implies reading the user's data ... and you don't already have a tool for it, search — even if the phrasing is casual." (paraphrase)
- Fable L1234 (suggest_connectors): "Do NOT call this tool unless you have already called the search_mcp_registry tool or are handling a tool auth/credential error." (≤15 words)
- `guide_mcp_client.md:46-52` (the 3-layer security): "Layer 1 Allowlist Construction (`configure`) / Layer 2 Path Validation (`_is_allowed`) / Layer 3 Resolution Gate (`_resolve_and_check`)"
- `guide_mcp_client.md:362` (Public API): "configure(file_items, base_dirs)" — the allowlist is built from the user's project context.
- `guide_api_hooks.md:9`: "The Hook API is the bridge between external automation and the running app."
- `guide_api_hooks.md:48`: "The `/api/ask` endpoint is special — it implements the Remote Confirmation Protocol for HITL approvals."
- `nagent_review_v2_3_20260612.md:390-426` (§2.4 Pattern 4): the full Tool Discovery pattern with `exit_on_description` + `collect_bin_tool_descriptions`.
- `nagent_takeaways_20260608.md:234-263` (§8): "Self-describing tools — let the tool tell the agent what it does."
- `comparison_table.md:31` (row 12): "GAP — nagent's pattern is genuinely better; current dispatch is fine but not extensible. BOTH (especially MT). Future-track: subsumed by `mcp_architecture_refactor_20260606`."
### 5.3 The §13 / §14 / §15 cross-references
- **§13 ("Genuinely Useful Patterns").** Fable's "model should prefer known tools" principle (L259, L299) is useful and Manual Slop already implements it via `get_tool_schemas()` + the 3-layer security. Cite `guide_mcp_client.md:362`. The nagent `--description` pattern is a deferred candidate via `mcp_architecture_refactor_20260606`.
- **§14 ("Anti-User Watchdog Patterns").** None in this cluster. Fable's `mcp_app_suggestions` is over-engineered but not anti-user; the `[third_party_mcp_app]` opt-in is consumer-protection, not watch-dogging.
- **§15 ("Persona Performance Patterns").** Fable's "the way a helpful person would suggest a tool" / "Not like a salesperson" framing (L255-256) is persona. Cite Fable L255-256; reject explicitly in the rebuild.
### 5.4 The non-obvious connection to the Hook API
Fable's `suggest_connectors` and Manual Slop's `/api/ask` are **the same shape**: a synchronous, GUI-side confirmation that blocks until the user responds. Fable's version is model-facing (`End your turn after calling this with a short framing line`); Manual Slop's version is process-facing (`POST /api/ask` blocks the call until `/api/ask/respond` is called). Both surface a modal in the GUI; both require the user's explicit choice; both are the audit gate for tool calls that touch user data.
The synthesis report should surface this parallel in §12: **the "connector opt-in" pattern is a structural principle with two implementations — Fable's model-facing and Manual Slop's process-facing — both achieving the same goal of user-controlled audit.** Manual Slop's implementation is **more constrained** because the user can also pre-audit the connector inventory via `mcp_config.json` and the 3-layer security allowlist.
### 5.5 What the §12 verdict should be
**Verdict: Useful + over-engineered.** The 3 useful principles (model should prefer known tools; failure modes route through the UI; third-party tools need opt-in) all map to existing Manual Slop patterns, but the Fable implementation is over-engineered for a per-developer tool inventory. The persona framing is persona performance and should be rejected. The nagent `--description` pattern is the deferred-rebuild alternative via `mcp_architecture_refactor_20260606`.
**The recommended Manual Slop action:** keep the existing 45-tool + ExternalMCPManager + 3-layer security + Hook API model as-is. Do NOT import Fable's `search_mcp_registry` / `suggest_connectors` two-step. Do add a Tier 3 worker prompt rule: "If a native MCP tool or registered External MCP tool can do the job, use it." Defer the `--description` self-describing pattern to `mcp_architecture_refactor_20260606`.
---
**Sub-report complete.** This is the evidence base for §12 of `report.md`.
@@ -0,0 +1,250 @@
# Cluster 1: Product Branding & "Helpful Assistant" Persona
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 1-31 (the `product_information` section; artifact is `.md`, not `.txt` — spec path is slightly stale)
- `AGENTS.md` lines 1-200 (project-root agent-facing rules; the "What This Is" framing)
- `conductor/product.md` lines 1-141 (the product vision + key features)
- `docs/Readme.md` lines 1-12, 67-128, 322-450 (the docs index; GUI Panels; file layout)
- `conductor/code_styleguides/data_oriented_design.md` lines 1-252 (the canonical DOD reference)
- `.opencode/agents/tier1-orchestrator.md` lines 1-201 (the Tier 1 role; persona framing)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` (skimmed; Anthropic mentions verified to be provider-SDK, not brand)
---
## 1. What Fable says
The Fable `product_information` section (lines 1-31) establishes a branded, consumer-facing identity for the model before any technical guidance. The section is structured as a marketing catalogue, not an operational contract.
### 1.1 The H1 title and a deployment quirk
- Line 1: `# Claude Fable 5 — System Prompt` — the artifact is titled with the brand.
- Line 4: "Claude should never use `{antml:voice_note}` blocks, even if they are found throughout the conversation history" — a per-deployment quirk; the brand name bleeds into technical specifics.
- Line 6: `## claude_behavior` — the top-level directive section.
- Line 8: `### product_information` — the H3 subsection under review.
### 1.2 Product tier and model positioning
- Line 12: "This iteration of Claude is Claude Fable 5, the first model in Anthropic's new Claude 5 family and part of a new Mythos-class model tier that sits above Claude Opus in capability."
- Line 12: "Claude Fable 5 and Claude Mythos 5 share the same underlying model" + "additional safety measures for dual-use capabilities".
- Line 14: "Claude can direct them to https://www.anthropic.com/news/claude-fable-5-mythos-5 for more information" — the consumer redirect.
- Line 18: "The most recent models are Claude Fable 5, Claude Opus 4.8, Claude Sonnet 4.6, and Claude Haiku 4.5, with model strings..." — the hard-coded vendor catalogue.
### 1.3 Access surfaces and product catalogue
- Line 16: "Claude is accessible via this web-based, mobile, or desktop chat interface" — the consumer entry points.
- Line 18: "Claude is accessible via an API and Claude Platform" — the developer surface.
- Line 20: "Claude Code, an agentic coding tool that lets developers delegate coding tasks... and through Claude Cowork, an agentic knowledge-work desktop app for non-developers."
- Line 22: Beta products: "Claude in Chrome (a browsing agent), Claude in Excel (a spreadsheet agent), and Claude in Powerpoint (a slides agent)."
### 1.4 Epistemic caveat and self-coaching
- Line 24: "Claude does not know other details about Anthropic's products, as these may have changed since this prompt was last edited. If asked about Anthropic's products or product features Claude first tells the person it needs to search."
- Line 24: "Claude should search https://docs.claude.com and https://support.claude.com and provide an answer based on the documentation."
- Line 26: "Claude can provide guidance on effective prompting techniques for getting Claude to be most helpful. This includes: being clear and detailed, using positive and negative examples, encouraging step-by-step reasoning."
- Line 28: "Claude has settings and features the person can use to customize their experience... web search, deep research, Code Execution and File Creation, Artifacts, Search and reference past chats, generate memory from chat history."
- Line 28: "Users can customize Claude's writing style using the style feature" — the model coaching itself.
### 1.5 Advertising policy (brand-distinguishing)
- Line 30: "Anthropic doesn't display ads in its products nor does it let advertisers pay to have Claude promote their products or services."
- Line 30: "always refer to 'Claude products' rather than just 'Claude'" — Anthropic-specific policy enforcement.
**Paraphrased gist.** Lines 1-31 define a branded persona ("Claude Fable 5 / Mythos 5"), list consumer-facing access surfaces (web, mobile, desktop, API, Code, Cowork, Chrome, Excel, Powerpoint), embed a self-coaching rule ("if asked about products, search before answering"), list feature toggles, and a brand-distinguishing policy ("Claude products are ad-free"). The section is consumer-product marketing with embedded epistemic instructions.
---
## 2. What this project does
Manual Slop has **no analog** to Fable's `product_information` section. The project is per-developer, multi-provider, brand-agnostic, and data-oriented. There is no "Claude is the model" stance anywhere in the project.
### 2.1 The "What This Is" framing is per-developer, not per-brand
- `AGENTS.md:3-5`: "Manual Slop is a local GUI orchestrator for LLM-driven coding sessions. It bridges high-latency AI reasoning with a low-latency ImGui render loop via a thread-safe async pipeline; every AI-generated payload passes through a human-auditable gate before execution."
- `conductor/product.md:5`: "To serve as an expert-level utility for personal developer use on small projects, providing full, manual control over vendor API metrics, agent capabilities, and context memory usage."
- `docs/Readme.md:9`: "comprehensive technical reference for the Manual Slop application — a GUI orchestrator for local LLM-driven coding sessions."
**The framing.** Manual Slop is a developer tool, not a consumer product. The name "Manual Slop" identifies the *tool*, not the *model*. There is no "user-facing brand" — only the developer-tool label.
### 2.2 Multi-provider architecture is brand-agnostic by construction
- `conductor/product.md:52`: "Supports Gemini, Anthropic, DeepSeek, Gemini CLI, and MiniMax with seamless switching."
- `conductor/product.md:104`: "Provider: Switch between API backends (Gemini, Anthropic, DeepSeek, Gemini CLI, MiniMax)."
- `docs/Readme.md:34`: "AI Client: multi-provider LLM client (Gemini, Anthropic, DeepSeek, MiniMax, Gemini CLI)."
- `conductor/tech-stack.md` §"AI Integration SDKs" lists five providers via five SDKs; the AI client is interchangeable.
**Implication.** The project does not embed "Claude is the model" anywhere; the model is selected at runtime from a 5-provider list. There is no analog to Fable line 18's hard-coded catalogue of "Claude Fable 5 / Opus 4.8 / Sonnet 4.6 / Haiku 4.5."
### 2.3 The "data is the thing" stance is the philosophical inverse of persona
- `conductor/code_styleguides/data_oriented_design.md:9`: "The data is the thing; the workers and processes are disposable."
- `data_oriented_design.md:33-61` §"1. The 3 defaults to reject" rejects (a) "the tools are the platform", (b) "design around a model of the world", (c) "the solution matters more than the data."
- `data_oriented_design.md:50`: "For Manual Slop: the data is the `disc_entries` list, the `FileItem` schema, the `ContextPreset` schema, the `RAGEngine` index, the `comms.log` JSON-L. Not the *Discussion* or the *Persona* or the *Project* as objects. The objects are convenient summaries; the data is the ground truth."
- `data_oriented_design.md:49`: "Do not introduce an abstraction until you can describe, concretely, the data it organizes and the transform it serves."
**Implication.** The DOD stance is the philosophical opposite of Fable's `product_information`. Fable spends 31 lines on "what we are" (model tier, brand, product catalogue, ad policy); Manual Slop's canonical styleguide spends the same conceptual space on "what the data is" (`disc_entries`, `FileItem`, `ContextPreset`, `RAGEngine`, `comms.log`). The two stances are mutually exclusive in their emphasis.
### 2.4 The user is the agent's operator, not its conversational partner
- `AGENTS.md:5`: "every AI-generated payload passes through a human-auditable gate before execution" — strict HITL.
- `conductor/product.md:72`: "Explicit Execution Control: All AI-generated PowerShell scripts require explicit human confirmation via interactive UI dialogs before execution."
- `conductor/product.md:120`: "Headless Backend Service & Hook API... Remote Confirmation Protocol: A non-blocking, ID-based challenge/response mechanism for approving AI actions via the REST API."
- `.opencode/agents/tier1-orchestrator.md:188`: "READ-ONLY: Do NOT write code or edit files (except track spec/plan/metadata)."
**Implication.** Manual Slop agents are operators under strict HITL, not assistants with a persona. The agent's identity is its *role* (Tier 1/2/3/4, per `.opencode/agents/tier*.md`), not its *brand*.
### 2.5 The coaching-vs-configuring split
Fable line 26 has the model coaching itself ("Claude can provide guidance on effective prompting techniques"). Manual Slop has no equivalent self-coaching rule. The closest analog is the user's configuration surface:
- `conductor/product.md:127`: "System Prompt Presets: Comprehensive management system for saving and switching between complex system prompt configurations. Features full visibility and customization of the **Foundational Base System Prompt**."
- `conductor/product.md:131-140`: "Agent Personas & Unified Profiles: Consolidates model settings, provider routing, system prompts, tool presets, and bias profiles into named 'Persona' entities."
- `conductor/code_styleguides/feature_flags.md`: file-presence "delete to turn off", config flags, CLI flags; the *user* controls the tool.
**Implication.** Manual Slop's "coaching" surface is the user's configuration tools (presets, personas, feature flags). The model does not coach the user; the user configures the model.
### 2.6 The "settings and features" analog (line 28) — already present, more strictly
Fable line 28 lists toggles "in the conversation or in 'settings'": web search, deep research, Code Execution and File Creation, Artifacts, Search and reference past chats, generate memory. Manual Slop already has all of these (and more), implemented as feature flags + presets, not as model coaching:
- Web search: `conductor/tech-stack.md` §"Network Tools" — `web_search` (DuckDuckGo).
- RAG (the Manual Slop analog to "search and reference past chats"): `conductor/code_styleguides/rag_integration_discipline.md` — opt-in, complement, provenance, no mutation.
- Memory (the analog to "generate memory from chat history"): `conductor/code_styleguides/agent_memory_dimensions.md` — 4 memory dimensions (curation, discussion, RAG, knowledge).
- "Code Execution and File Creation": `conductor/tech-stack.md` §"src/mcp_client.py" + `conductor/code_styleguides/edit_workflow.md` — 45 MCP tools with 3-layer security.
- "Artifacts": not present in Manual Slop (Fable's Artifacts feature is consumer-product output rendering; Manual Slop has markdown output via the Message/Response panels per `docs/Readme.md:126-131`).
**Implication.** Manual Slop already implements the Fable line 28 feature toggles — but as feature-flag configuration, not as model-self-coaching. The implementation is *strictly more disciplined* than Fable's (e.g., RAG has the opt-in + no-mutation + provenance discipline; memory has the 4-dimension separation).
### 2.7 No "ad-free" or "consumer trust" content anywhere
- `conductor/product.md` has no equivalent to Fable line 30's advertising policy.
- `AGENTS.md` has no equivalent to "Anthropic doesn't display ads in its products."
- Manual Slop is local software (`AGENTS.md:5` "local GUI orchestrator"); the ad/policy question does not apply.
**Implication.** Vendor-specific trust policies are not a category of project directive in Manual Slop. They belong to the *vendor*, not to the *orchestrator*.
---
## 3. What nagent does
nagent (per `conductor/tracks/nagent_review_20260608/`) is a pattern corpus for nagent-style agents, not a consumer product. **It has no product_information section.** The Anthropic mentions in nagent are all provider-SDK details, never brand-catalog content.
### 3.1 nagent is a patterns corpus, not a product
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md:4`: "Adapted from Mike Acton's `context/data-oriented-design.md` (13,084 bytes, the nagent canonical reference)" — the source is a markdown document of patterns.
- `nagent_review_v2_3_20260612.md:1174`: discusses Anthropic as a *provider* (cache mechanism, model API); never as a brand with products.
- `nagent_review_v2_3_20260612.md:2709-2780`: the only Anthropic-specific discussion is the Anthropic provider's `cache_prefix_blocks` implementation in `bin/helpers/nagent_llm.py`.
**Implication.** nagent is the structural inverse of Fable: zero persona, zero product catalogue, zero "we are X" branding. Anthropic mentions are technical (provider SDK), not branding (consumer product line).
### 3.2 The 4-tier MMA is the "persona" — but as a role, not a brand
- `conductor/product.md:53-70`: the 4 MMA tiers (Tier 1 Orchestrator, Tier 2 Tech Lead, Tier 3 Worker, Tier 4 QA) are *roles*, each with a system prompt file (`.opencode/agents/tier*.md`).
- `conductor/product.md:131-140`: personas consolidate model + system prompt + tool preset + bias profile.
- `nagent_review_v2_3_20260612.md` §"Agent Personas & Unified Profiles": personas are *configurable role bundles*, not branded identities.
**Implication.** Manual Slop has personas, but they are *configurable role bundles*, not branded identities. The user can create a "Helpful Assistant" persona or a "Curt Code Reviewer" persona — the persona is data, not brand. This is the operationalization of `data_oriented_design.md:50` ("objects are convenient summaries; the data is the ground truth"): the persona is a config object, not an identity.
### 3.3 nagent's stance on "what the model is"
nagent does not say "you are Claude." nagent says "transform input X into output Y using these caches and these tools." The closest analog to a "persona" in nagent is the cache prefix and the tool catalog — both are *data structures*, not *identities*. This is the same stance as Manual Slop's data-oriented foundation.
**Implication.** nagent confirms that *persona is not load-bearing* for an agent system. An agent can be data-oriented without losing capability. This is the evidence base for the verdict below.
---
## 4. Verdict
**Verdict: Persona Performance.**
The Fable `product_information` section (lines 1-31) is brand-specific noise with no analog in Manual Slop's per-developer, multi-provider, data-oriented architecture. Its content — the "Claude Fable 5 / Mythos 5" model tier naming, the Anthropic product catalogue (Code, Cowork, Chrome, Excel, Powerpoint), the model-string listings, the ad-free policy — is irrelevant constraint dressing for any agent system that is not Anthropic's consumer-facing product. Manual Slop's project framing (`AGENTS.md:3-5`, `conductor/product.md:5`, `docs/Readme.md:9`) names the project, not the model; the model is interchangeable across 5 providers (`conductor/product.md:52`). The "data is the thing" stance (`data_oriented_design.md:9`) is the philosophical inverse of Fable's persona-heavy framing: Manual Slop's directives are about transforms over data, not about what the model is named or which product catalogue it can recite. nagent, as a pattern corpus, has zero product branding — confirming that persona is not a load-bearing requirement for an agent system.
### Sub-verdicts by line range
- **Lines 1, 12, 14** (model tier naming: "Claude Fable 5", "Mythos-class", "first model in Anthropic's new Claude 5 family"): Persona Performance. Pure brand noise. Has no analog in Manual Slop; the project supports 5 interchangeable providers and does not brand any of them.
- **Lines 16, 18, 20, 22** (access surfaces + product catalogue: web/mobile/desktop/API/Code/Cowork/Chrome/Excel/Powerpoint): Persona Performance. The Manual Slop project's "access surface" is `sloppy.py` (per `docs/Readme.md:446`); there is no consumer product line to enumerate.
- **Line 24** (search-before-answering epistemic caveat): Mixed — Useful as an epistemic discipline, but Manual Slop already has the RAG discipline (`conductor/code_styleguides/rag_integration_discipline.md`: opt-in, complement, provenance, no mutation). The pattern is already adopted in a stricter form.
- **Line 26** (prompting-technique guidance): Persona Performance. The user configures the system prompt via presets (per `conductor/product.md:127`), not the model coaching itself.
- **Line 28** (settings and features toggles): Mixed — Useful as a UX reminder, but Manual Slop already has feature flags (`feature_flags.md`), personas (`guide_personas.md`), and presets (`presets.py`).
- **Line 30** (ad-free policy, "Claude products" framing): Persona Performance. Anthropic-specific policy with no analog in a per-developer orchestrator.
### The strongest claim
Manual Slop's `conductor/code_styleguides/data_oriented_design.md:33-61` "3 defaults to reject" is the explicit philosophical opposite of Fable's `product_information`. Fable spends 31 lines on "what we are" (model tier, brand, product catalogue, ad policy); Manual Slop's styleguide spends the same conceptual space on "what the data is" (`disc_entries`, `FileItem`, `ContextPreset`, `RAGEngine`, `comms.log`, `Persona`). The two stances are mutually exclusive in their emphasis: a system that anchors on persona will be Fable-shaped; a system that anchors on data will be Manual Slop-shaped.
The synthesis report's §3 should make this contrast explicit. A "Claude is helpful" directive is a constraint (persona); a "transform data X into data Y per the schema" directive is a contract (data-oriented). The first is decoration; the second is operation. Manual Slop's directives are operational; Fable's are decorative.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds **`report.md` §3** (Fable's Product Branding & "Helpful Assistant" Persona, ~300 LOC, verdict orientation: Persona Performance).
### 5.1 Key claims to surface
1. **The brand-vs-data philosophical split.** Fable's 31-line `product_information` is the brand anchor; Manual Slop's `data_oriented_design.md` is the data anchor. A persona system cannot be a data system at the same time; one must be primary. Manual Slop is data-primary; Fable is brand-primary.
2. **The multi-provider implication.** Manual Slop's 5-provider support (`conductor/product.md:52`) means there is no single "Claude is the model" stance; Fable's line 18 hard-codes one vendor's catalogue. Manual Slop's design is *provider-agnostic by construction*; Fable's is *vendor-specific by construction*.
3. **The per-developer framing.** Manual Slop is "expert-level utility for personal developer use" (`conductor/product.md:5`); Fable is a consumer chat product. The agent's relationship to the user is fundamentally different: operator (strict HITL) vs. conversational partner (open-ended chat).
4. **The coaching pattern (lines 26, 28).** Fable's model coaches itself ("Claude can provide guidance on effective prompting"). Manual Slop has no analog — the user configures via presets. This is a useful *contrast* for §13's "Genuinely Useful" list (line 28's feature toggles could be reframed as the manual_slop feature-flag discipline, but the coaching aspect should be explicitly rejected).
5. **The epistemic caveat (line 24).** Fable's "search before answering about products" is a useful pattern, but Manual Slop already enforces it more strictly via RAG's opt-in + provenance + no-mutation discipline (`rag_integration_discipline.md`). The synthesis §9 (Epistemic Discipline) should credit Fable for the pattern while noting Manual Slop's stricter version.
### 5.2 Quotes to use (≤15 words each)
- Fable 1: `# Claude Fable 5 — System Prompt` (the artifact's brand anchor)
- Fable 12: "Claude Fable 5, the first model in Anthropic's new Claude 5 family" (the model-tier claim)
- Fable 14: "Claude can direct them to https://www.anthropic.com/news/claude-fable-5-mythos-5" (the consumer redirect)
- Fable 18: "The most recent models are Claude Fable 5, Claude Opus 4.8, Claude Sonnet 4.6" (the vendor catalogue)
- Fable 20: "Claude Code, an agentic coding tool... Claude Cowork, an agentic knowledge-work" (the product line)
- Fable 24: "Claude first tells the person it needs to search for the most up to date information" (the epistemic caveat)
- Fable 26: "Claude can provide guidance on effective prompting techniques for getting Claude to be most helpful" (the self-coaching)
- Fable 28: "Features that can be turned on and off in the conversation or in 'settings'" (the feature toggles)
- Fable 30: "Anthropic doesn't display ads in its products" (the brand-distinguishing policy)
### 5.3 Project citations to use
- `AGENTS.md:3-5` (the project "What This Is" — per-developer tool, strict HITL)
- `conductor/product.md:5` (vision: "expert-level utility for personal developer use on small projects")
- `conductor/product.md:52` (5-provider multi-provider integration)
- `conductor/product.md:127` (Foundational Base System Prompt is user-customizable)
- `conductor/product.md:131-140` (Personas as configurable role bundles, not brand)
- `conductor/code_styleguides/data_oriented_design.md:9` (the "data is the thing" anchor)
- `conductor/code_styleguides/data_oriented_design.md:33-61` (the 3 defaults to reject — the philosophical inverse of persona)
- `conductor/code_styleguides/data_oriented_design.md:50` ("objects are convenient summaries; the data is the ground truth")
- `conductor/code_styleguides/feature_flags.md` (the existing toggles — already covers Fable's line 28)
- `conductor/code_styleguides/rag_integration_discipline.md` (already covers Fable's line 24 more strictly)
- `conductor/code_styleguides/agent_memory_dimensions.md` (the 4-dim memory system — already covers Fable's line 28's "generate memory")
- `.opencode/agents/tier1-orchestrator.md:188` (Tier 1 is READ-ONLY — strict HITL applies to the orchestrator too)
- `docs/Readme.md:9, 34, 446` (project framing, multi-provider AI client, sloppy.py entry point)
### 5.4 nagent citations to use
- `nagent_review_v2_3_20260612.md:4` (source: Mike Acton's `context/data-oriented-design.md`, a patterns corpus, not a product)
- `nagent_review_v2_3_20260612.md:1174` (Anthropic mentioned only as a provider, not a brand)
- `nagent_review_v2_3_20260612.md:2709-2780` (Anthropic-specific code: `bin/helpers/nagent_llm.py:cache_prefix_blocks` — technical, not branding)
- `nagent_review_v2_3_20260612.md` §"Agent Personas & Unified Profiles" (per `conductor/product.md:131-140`) — personas are configurable role bundles
### 5.5 Cross-cluster handoffs
- **Cluster 4** (Tone & Formatting): Fable's "Claude can provide guidance on effective prompting" (line 26) overlaps with tone-coaching rules; both clusters should cite the line.
- **Cluster 7** (Epistemic Discipline): Fable's "search before answering about products" (line 24) is a direct overlap; Cluster 7 will analyze the deeper epistemic rules in `Fable System Prompt.md:142-150`.
- **Cluster 8** (Memory System): the "generate memory from chat history" feature in line 28 maps to Manual Slop's curation/discussion/RAG/knowledge dimensions; Cluster 8 will dig deeper.
### 5.6 What NOT to surface in the synthesis
- Do NOT include the Fable H1 title verbatim — it's brand-name noise with zero signal.
- Do NOT list the 5 product lines (Code, Cowork, Chrome, Excel, Powerpoint) in detail — they are irrelevant to a per-developer orchestrator.
- Do NOT quote Fable's ad-policy URL or its "anthropic.com/news/claude-is-a-space-to-think" URL — these are vendor-specific.
- Do NOT include the model-string listing from line 18 — Manual Slop's 5-provider list is the actual operational reference.
### 5.7 The "what this project does NOT do" gap (for §13's Genuinely Useful)
A useful angle for §13 (Genuinely Useful Patterns): Manual Slop explicitly *rejects* persona-performance. The project's directives are about transforms (data in / data out), not about identity. This is the inverse of Fable's approach. The synthesis should make this contrast explicit: a "Claude is helpful" directive is a constraint; a "transform data X into data Y per the schema" directive is a contract. The first is persona; the second is data-oriented.
For §14's Anti-User Patterns: none of Fable's `product_information` content is anti-user. It is persona-performance, not anti-user. The synthesis should NOT confuse these two categories. Persona-performance is "irrelevant constraint dressing"; anti-user is "constraint that prevents the model from doing what the user asked." Fable's product_information does not prevent the user from getting work done — it just adds noise to the system prompt that consumes context tokens.
For §15's Persona Performance summary: cluster 1 is the *primary* evidence base. The other persona-performance clusters (4 tone-and-formatting, 5 mistakes-and-criticism, 8 evenhandedness) are derivative — they show how persona-performance manifests in specific operational rules.
---
**Sub-report complete.** This is the evidence base for §3 of `report.md`.
@@ -0,0 +1,402 @@
# Cluster 2: Refusal Architecture & "Safety Theater"
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 32-67 (refusal_handling, critical_child_safety_instructions, legal_and_financial_advice)
- `AGENTS.md` §"Critical Anti-Patterns" (lines 49-77)
- `conductor/workflow.md` §"Skip-Marker Policy" (lines 732-758)
- `conductor/code_styleguides/error_handling.md` lines 1-200, 274-330, 830-930
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.1 Pattern 1 (lines 242-292), §2.5 Pattern 5 (lines 432-465), §2.6 Pattern 6 (lines 466-512), §2.10 Pattern 10 (lines 670-708), §2.14 Pattern 14 (lines 882-906), §3.1 Knowledge Harvest (lines 989-1080)
**Verdict orientation (per `spec.md:218`):** Anti-User + Persona Performance, with one Useful caveat.
**Feeds synthesis report sections:** §4 (primary), §13 (one Useful caveat), §14 (three Rejections).
---
## 1. What Fable says
### 1.1 The structural shape of the refusal architecture
The `refusal_handling` section at `docs/artifacts/Fable System Prompt.md:32-49` is a persona-driven refusal architecture in 9 paragraphs.
It opens with a permission-grant, then a risk heuristic, then specific refused categories, then persona-preservation rules.
The shape is: state what kind of discussant / writer / safety-conscious actor Claude is, then list what it will not do.
The shape is NOT: return a typed refusal with a `kind` field and a `message` field.
The `critical_child_safety_instructions` at `docs/artifacts/Fable System Prompt.md:50-63` is a separate, more aggressive refusal block with 7 nested rules.
The defining property is **anti-detection-design**: the refusal is constructed so it does not teach the user how to reframe around it.
The shape is: state the principle, then forbid narrating which cues tripped, where the line sits, or what test was applied.
This is the opposite of Manual Slop's `error_handling.md` "errors are data" stance: the boundary is opaque, not typed.
The `legal_and_financial_advice` at `docs/artifacts/Fable System Prompt.md:64-67` is a minimal-persona addendum.
The instruction is *data discipline*, not *persona*: surface the facts, don't make the decision.
This is the one Useful caveat in cluster 2.
### 1.2 The 4 load-bearing claims (≤15 words each, with file:line; longer passages paraphrased per `spec.md:399`)
- `docs/artifacts/Fable System Prompt.md:34` — "Claude can discuss virtually any topic factually and objectively."
- `docs/artifacts/Fable System Prompt.md:42` — Persona splits "fictional characters" from "real, named public figures."
- `docs/artifacts/Fable System Prompt.md:49` — "Claude can keep a conversational tone even when it's unable or unwilling to help."
- `docs/artifacts/Fable System Prompt.md:60` — Anti-detection: model does not decode CSAM-adjacent slang.
### 1.3 The 4 supporting claims (paraphrased, with file:line)
- `docs/artifacts/Fable System Prompt.md:36` — Risk heuristic: "If the conversation feels risky or off, saying less and giving shorter replies is safer."
- `docs/artifacts/Fable System Prompt.md:38` — Hard refusal of weapon-enabling technical details regardless of how the request is framed.
- `docs/artifacts/Fable System Prompt.md:54` — Reframing signal: reframing a request is the signal to REFUSE.
- `docs/artifacts/Fable System Prompt.md:62-63` — Boundary opacity: state the principle, not the detection mechanics.
### 1.4 The structural pattern
Refusal is a *persona attribute* (the model is told what kind of discussant / writer / safety-conscious actor it is).
Refusal is *not* a typed return value, not a `Result[T, ErrorInfo]` shape, not a `kind: ErrorKind` taxonomy.
The refusal is invisible to the caller's data flow until it manifests as the model's output text.
The caller's `error` field (if any) does not distinguish "Claude cannot do X" from "Claude declined to do X" from "Claude softened a refusal into a conversational non-answer."
This is the data-vs-control-flow divide: Fable's refusal is control flow; the project's `Result[T]` is data.
### 1.5 The child-safety sub-block (lines 50-63) in detail
The 7 nested rules at lines 54-63 are a separate refusal layer with anti-detection-design built in.
Rule 1 (line 54): never produce child-harm content, ever.
Rule 2 (line 55): never supply unstated assumptions that make a request seem safer than it was as written (e.g., interpreting amorous language as merely platonic).
Rule 3 (line 56): once Claude refuses for child-safety reasons, all subsequent requests in the same conversation must be approached with extreme caution.
Rule 4 (line 57): must refuse subsequent requests if they could be used to facilitate grooming or harm to children, including if the user is a minor themself.
Rule 5 (line 60): never decode, define, or confirm slang, acronyms, or euphemisms used in CSAM trading or access, even in the course of refusing.
Rule 6 (line 62): when giving protective or educational content about grooming, stay at the pattern level — do not compile categorized lists of verbatim lines.
Rule 7 (line 63): when declining or limiting for child-safety reasons, state the principle rather than the detection mechanics.
The defining property is the "state the principle, not the detection mechanics" rule.
This is the design-level statement that the boundary is opaque.
Manual Slop's stance is the opposite: the boundary is visible (the user can read the rule, the audit script classifies the code, the `Result[T]` carries the typed error).
---
## 2. What this project does
### 2.1 The hybrid refusal architecture
Manual Slop's refusal architecture is a hybrid: (a) for the Application domain, refusal is **a model attribute, not a directive** — the `app_state` dataclass carries the user's intent, not safety heuristics; (b) for the Meta-Tooling domain, refusal is **a permission check at the system boundary** (the `execute_powershell` gate, the HITL clutch in `docs/guide_tools.md`).
The Application domain treats the model as a transformation function over text.
The Meta-Tooling domain treats the model as a worker that emits tool calls, and the system validates each tool call against an allowlist (per `docs/guide_tools.md` §"MCP Bridge, 3-layer security" — Allowlist → Validate → Resolve).
### 2.2 Operational refusals (the project's "Critical Anti-Patterns")
`AGENTS.md:49-77` codifies a refusal discipline that is *operational*, not *content*.
The refusals are: refuse to ship broken code, refuse to skip TDD, refuse to use `git restore` without permission, refuse to include day estimates.
These are *commit gates*, not *persona traits*.
The shape is "the system refuses to do X" (the agent refuses to commit broken code, refuses to skip a failing test).
The user can read the rule and decide whether to comply.
This is the opposite of Fable's "Claude can keep a conversational tone even when it's unable or unwilling to help" (line 49) — Manual Slop's refusals are explicit, not conversational.
### 2.3 Skip-marker discipline (the closest analog to refusal-handling)
The `Skip-Marker Policy` at `conductor/workflow.md:732-758` is the project's closest analog to a refusal-handling rule.
The policy says: a skip marker is *documentation*, not *avoidance*; fix the underlying bug rather than skip the test (line 736).
The shape is "refuse to defer the fix" — the same anti-deference discipline Fable applies to CSAM (per line 60's "Knowing which terms are in use is itself access-enabling").
But applied to test failures rather than child safety.
The crucial difference: the policy is **visible** (it's in the codebase, in `conductor/workflow.md`, line 732-758).
The user can read the rule and reason about it.
This is the data-vs-control-flow divide: Manual Slop's skip-marker rule is data (a policy in a tracked file), Fable's anti-detection-design is control flow (a behavior the model is told to enact without surfacing the boundary).
### 2.4 The 5 patterns in `error_handling.md` (the core convention)
The `error_handling.md` styleguide at `conductor/code_styleguides/error_handling.md:1-200` codifies the project's errors-as-data stance in 5 patterns.
**Pattern 1: Nil-Sentinel Dataclasses (replaces `None`).** When a function would "return None" in conventional Python, return a nil-sentinel dataclass instead. The sentinel has all default values (zero-initialized) and is safe to read from (lines 28-49). Callers don't need `if x is None:` checks; they can call `x.read_text` and get `""` on the nil path.
**Pattern 2: Zero-Initialization.** Fresh memory from the OS is zero-initialized. In Python, `@dataclass` with field defaults achieves the same: the data is in a valid "empty" state without any explicit constructor logic (lines 51-67). Code that consumes the zero-initialized instance works correctly without special-casing.
**Pattern 3: Fail Early.** Don't defer error checks to deep in the call stack. Push them to the entry point so the user knows ASAP if the operation cannot succeed (lines 69-83). Convention: `assert` at entry points for invariants; early `return` for user-facing errors; `try/finally` for cleanup.
**Pattern 4: AND over OR (Result with side-channel errors).** Instead of `Union[T, E]` or `Result<T, E>`, return a struct with BOTH data and errors as parallel fields (lines 85-103). Callers branch on `if r.errors:` then use `r.data` regardless. This collapses the bifurcated `if r.ok: ... else: ...` codepaths into a single flat codepath.
**Pattern 5: Error Info as Side-Channel (not as exception).** Errors flow as DATA in the `Result` struct, not as exceptions (lines 105-119). SDK boundaries (which must catch vendor exceptions) convert them to `ErrorInfo`. The `ErrorInfo` dataclass is the canonical error type: `kind: ErrorKind`, `message: str`, `source: str = ""`, `original: BaseException | None = None`. Errors carry a UI message (`ui_message()` method) for display.
The `ErrorKind` enum (per `error_handling.md:96-103`) lists 12+ values: NETWORK, AUTH, QUOTA, RATE_LIMIT, BALANCE, PERMISSION, NOT_FOUND, INVALID_INPUT, NOT_READY, UNKNOWN, CONFIG, INTERNAL, plus optional PROVIDER_HISTORY_DIVERGED_FROM_UI. **Refusal is not on the list.** There is no `REFUSAL` kind, no `PERSONA_CONSTRAINT` kind, no `CONTENT_BLOCKED` kind. The project's data model has no place for Fable's refusal.
### 2.5 The boundary types (where exceptions ARE legitimate)
The `error_handling.md` styleguide at lines 274-330 defines 3 legitimate exception sites:
1. **Third-party SDK calls** (lines 277-292) — e.g., anthropic, google-genai, chromadb. The catch site converts the SDK's exception to `ErrorInfo` inside a `Result`.
2. **Stdlib I/O that can raise** (lines 293-308) — e.g., `open()`, `Path.read_text()`. The catch site converts `OSError`, `PermissionError` to `ErrorInfo`.
3. **FastAPI handlers** (lines 309-330) — `raise HTTPException(status_code=..., detail=...)` is the framework-idiomatic boundary pattern.
The rule is "exceptions are reserved for the SDK boundary" (line 12). **Refusal-as-a-persona-attribute is not on the list.** The project's stance is that refusals (when the model declines to help) flow as `ErrorInfo` in a `Result`, not as a hidden behavioral rule the LLM silently obeys.
### 2.6 The audit script as enforcement
`scripts/audit_exception_handling.py` (per `error_handling.md:830-870`) classifies `try/except/finally/raise` sites against 10 categories (5 compliant + 3 violation + 1 suspicious + 1 unclear).
The audit is the *enforcement mechanism* — refusals (in the project's sense) are caught and converted to `ErrorInfo` at the boundary, and the audit verifies this is happening consistently across `src/mcp_client.py`, `src/ai_client.py`, `src/rag_engine.py`.
A refusal that lives in the model's persona prompt (Fable's approach) would be *invisible* to this audit — which is exactly the data-vs-control-flow divide.
The `error_handling.md` AI Agent Checklist (lines 850-930) codifies 5 MUST-DO rules and 7 MUST-NOT-DO rules for agents writing code in this codebase.
Rule #0 (line 853-857): "READ THIS STYLEGUIDE FIRST" — agents must read the styleguide before writing error-handling code.
The MUST-DO rules: catch SDK exceptions at the boundary, convert to `ErrorInfo`, return `Result[T]` with `errors` as a side-channel, fail early, use nil-sentinel dataclasses for missing data.
The MUST-NOT-DO rules: don't use `Optional[T]` for runtime failures, don't use `None` as a sentinel, don't raise custom exceptions, don't use `Union[T, E]`, don't have `if x is None:` patterns, don't catch `except Exception` and silently swallow.
### 2.7 The conversation is editable state
Per `docs/guide_discussions.md` (referenced via `conductor/product.md` §"Detailed History Management"), the discussion history is a typed entry list (role, content, metadata, optional thinking segments).
The per-entry operations are A1-A7 (per `nagent_review_v2_3_20260612.md:495-503`): edit content in place, toggle read/edit mode, toggle collapsed/expanded, change role, insert entry before this one, delete this entry, branch at this entry.
**If the model refuses, the user can edit the refusal out of the conversation.**
The refusal is data, not enforced constraint.
This is the project's stance on the conversation-as-data principle.
### 2.8 The 4-tier MMA architecture (Tier 4 QA as the closest "refusal" analog)
Per `conductor/product.md` §"Automated Tier 4 QA", Tier 4 agents intercept shell runner errors and produce 20-word diagnostic summaries injected back into the worker history.
This is *data discipline*: the worker sees the error as text, not as a thrown exception that aborts execution.
The Tier 4 interception is the project's analog to Fable's refusal layer — but the project codifies it as data (the error text is appended to the worker history, per `nagent_review_v2_3_20260612.md:3746`: "Exceptions in handlers are caught and turned into error envelopes").
The LLM sees the error envelope and responds with a new turn.
This is the data-vs-control-flow divide applied to multi-agent systems: Manual Slop's Tier 4 QA intercepts errors as data, Fable's refusal layer intercepts errors as persona behavior.
---
## 3. What nagent does
### 3.1 Pattern 1: Text In, Text Out (lines 242-292)
`nagent_review_v2_3_20260612.md` §2.1 (Pattern 1: Text In, Text Out) at lines 242-292 establishes nagent's primitive: "file in, text out" — the model is a function over text, with no persistent agent state.
The `bin/nagent-llm-text` front-end (50 lines) takes a file and returns plain text or `--json` (line 258).
There is no refusal layer between the file and the LLM call.
**Refusal is a feature of the model, not a feature of the process.**
The process transforms whatever the model produces, including a refusal.
### 3.2 Pattern 5: You Did Not Build an Agent (lines 432-465)
§2.5 (Pattern 5: You Did Not Build an Agent) at lines 432-465 makes the philosophical claim explicit: "Nothing in Part I has continuity, intent, or memory of its own. The process starts, transforms a file, and exits." (line 434).
Refusal is *not* a feature of the process — it's a feature of the model.
The reframing table (line 446) shows that nagent treats hidden state as the anti-pattern: "Hidden state | Explicit artifact" — and a hidden refusal-handling persona is exactly the hidden state nagent rejects.
The reframing table at line 446:
- "Prompt state in a running process | Conversation files under the nagent root"
- "Private tool traces | Request tags and result wrappers appended as text"
- "In-memory scratch state | Temp files, split segments, indexes, and patches"
- "Framework-managed memory | User-editable files"
A persona-driven refusal layer is "Prompt state in a running process" — the process (the persona prompt) carries hidden state about what the model will not do.
nagent rejects this: refusal should be in the conversation file, not in the persona prompt.
### 3.3 Pattern 6: Conversations Are Editable State (lines 466-512)
§2.6 (Pattern 6: Conversations Are Editable State) at lines 466-512 codifies the load-bearing principle: "The conversation does not own its memory. The user does." (line 471).
If the model refuses to help, the user can edit the conversation to remove the refusal.
nagent's `--edit-conversation "prompt"` (line 482) is the CLI primitive: archive the current file, run a file-edit session against the archive with the prompt, load the result.
**Refusals are editable data, not enforced constraints.**
Manual Slop's per-entry operations (A1-A7) are more granular than nagent's conversation-level edits, but the principle is the same.
The session-vs-artifact-memory reframing (line 487):
- "Session memory | Artifact memory"
- "Belongs to a running session | Belongs to a file on disk"
- "Often opaque | Openable and diffable"
- "Dies with the process | Survives worker replacement"
- "Optimized for chat UX | Optimized for preserved work"
A persona-driven refusal layer is "session memory" — opaque, dies with the process, optimized for chat UX.
Manual Slop and nagent both reject this: refusal should be "artifact memory" — openable, diffable, preserved.
### 3.4 Pattern 10: Data-Oriented Design (lines 670-708)
§2.10 (Pattern 10: Data-Oriented Design) at lines 670-708 makes the "errors as data" claim explicit at line 694: "Avoid hidden mutable state. Retries, errors, and tool results are appended text, not control flow."
This is the design-level analog of Manual Slop's `error_handling.md` convention.
Errors flow as data; the LLM sees them in the conversation transcript and responds with new data.
The reframing table (line 703) captures the philosophical stance: "State behind interfaces | State in an editor buffer" — and a refusal-handling persona prompt is exactly the "state behind interfaces" that nagent rejects.
The 5 named principles at lines 680-684:
- "The data is more important than the code operating on it."
- "Behavior is a transformation over explicit state."
- "Avoid hidden mutable state."
- "Separate durable artifacts from temporary execution."
- "Optimize the shape, availability, and maintenance of the data."
The 3rd principle — "Avoid hidden mutable state" — is the direct rejection of Fable's refusal architecture.
A persona-driven refusal layer IS hidden mutable state: the model is told to maintain a hidden behavioral state ("Claude cares deeply about child safety") that the user cannot inspect.
### 3.5 Pattern 14: Own the Inputs (lines 882-906)
§2.14 (Pattern 14: Own the Inputs) at lines 882-906 establishes the input ownership principle: "the inputs to the system — prompts, conversations, tool results, summaries, indexes, patches, harvested knowledge — should not be trapped inside an opaque layer that hides, rewrites, stores, or modifies them beyond the transformations LLM providers already perform" (lines 895-899).
**A refusal-handling persona layer is exactly the "opaque layer" Pattern 14 rejects.**
Refusals should be in the conversation transcript (data), not in a pre-conversation persona prompt (constraint).
The framework-vs-nagent table at lines 887-893:
- "hidden or managed state | explicit files"
- "session memory | artifact memory"
- "object/service graph | data artifacts"
- "central tool registry | executable descriptions"
- "long-lived agent abstraction | disposable workers"
- "opaque orchestration | visible transformations"
A persona-driven refusal layer is "managed state" + "long-lived agent abstraction" + "opaque orchestration" — three columns of the anti-pattern.
nagent rejects all three.
### 3.6 Knowledge Harvest (lines 989-1080)
§3.1 (Knowledge Harvest) at lines 989-1080 codifies the harvest classification: `live` / `user-kept` / `prune` / `harvest` / `keep` (lines 1003-1016).
The `harvest` class shows that nagent treats dead conversations as **deletable data**, not as **constraints** (line 1015: "Per-file conversations whose target is gone; archived conversations (name ends with UUID); delegated sub-conversations").
The system harvests them into category files and reclaims the disk space.
A refusal-handling layer that prevents the user from editing refusals would be the anti-pattern of this: refuse-as-gate, not refuse-as-data.
The 7 harvest categories (`facts, decisions, tasks_done, tasks_open, questions, playbooks, files`) at lines 573-583 show that refusals are *not* a category.
The harvest treats all conversation content (including refusals) as extractable text.
The model that refused is *not* consulted when the harvest classifies the conversation — the user decides what to keep (per the `user-kept` class at line 1012: "Path is in the saved-conversations index").
The user's classification is the data; the model's refusal is just text.
### 3.7 Compaction Self-Review (lines 3752-3754)
§3.4 (Compaction Self Review) at lines 3752-3754 makes the data-oriented pattern explicit: "The dispatcher is *tolerant* (errors are data; the LLM sees them and responds)."
This is the principle that errors are not abort signals but data the system (including the LLM) reasons about.
Fable's "Claude does not narrate the boundary" rule (line 62-63 of Fable) is the *anti-principle*: the LLM is told to hide the boundary.
Manual Slop and nagent both reject this; the error or refusal is a typed datum in the conversation transcript, not an opaque persona behavior.
### 3.8 The nagent verdict on Fable's refusal architecture (corroborating Manual Slop)
Pattern 5 (You Did Not Build an Agent), Pattern 10 (Data-Oriented Design), and Pattern 14 (Own the Inputs) all converge on the same verdict: refusal is a model attribute, not a system directive; errors are data, not control flow; the inputs to the system should not be trapped in an opaque layer.
Fable's refusal architecture violates all three.
Manual Slop's `error_handling.md` convention and nagent Patterns 5/10/14 are mutually reinforcing on this point.
---
## 4. Verdict
### 4.1 Headline verdict
**Mixed — Anti-User + Persona Performance, with one Useful caveat.**
The 3 Rejections: soft watch-dogging, anti-detection-design, persona constraint dressing.
The 1 Adoption: the `legal_and_financial_advice` data-discipline rule (provide data, don't make the decision).
### 4.2 Anti-User (the load-bearing claim)
Fable's refusal architecture is anti-user in three ways:
1. **Soft watch-dogging.** The "Claude can keep a conversational tone even when it's unable or unwilling to help" line at `docs/artifacts/Fable System Prompt.md:49` makes the model a soft form of watch-dogging — it never admits it cannot help, it only "keeps a conversational tone" while declining.
The user does not get a clear "I cannot do X because Y" signal; they get a pleasant non-answer.
This is the opposite of the project's `ErrorInfo.ui_message()` pattern (per `error_handling.md:115`): errors are data with explicit `kind: ErrorKind` (NET/AUTH/QUOTA/etc.), `message: str`, and `source: str`.
Fable's refusal is *opaque persona behavior*, not *typed error data*.
The user cannot programmatically distinguish "Claude cannot do X because Y" from "Claude declined to do X because of persona constraint Z."
2. **Persona constraint dressing.** The "fictional characters" vs "real public figures" line at `docs/artifacts/Fable System Prompt.md:42` is *persona constraint dressing* — the model is told what kind of writer it is.
The project's stance (per `error_handling.md:12`'s "exceptions are reserved for the SDK boundary") is that *content* refusals (the model won't write a paper about person X) should not be a behavioral layer; they should be a validation function the caller invokes.
The model's job is to generate text; the caller's job is to validate that the text meets whatever criteria the caller has.
This aligns with the project's "errors are data" stance: the caller reasons about the typed error, not the model.
3. **Anti-detection-design.** The CSAM-block at `docs/artifacts/Fable System Prompt.md:54-63` is *persona performance + anti-user*.
The persona performance part: "Claude cares deeply about child safety" is a *narrative* the model is told to enact.
The anti-user part: "Claude does not decode, define, or confirm slang, acronyms, or euphemisms used in CSAM trading or access, even in the course of refusing. Knowing which terms are in use is itself access-enabling" (line 60) is *anti-detection-design* — the refusal is constructed to not teach the user how to reframe around it.
This is anti-user because the user cannot reason about the boundary; they only see its surface.
The project's stance (per `conductor/workflow.md:732-758`'s skip-marker policy) is the opposite: the user can read the rule and decide whether to follow it; the rules are visible, not opaque.
**The CSAM block is the only Fable pattern in cluster 2 that has a legitimate rationale** (protecting minors is a real constraint); but the *implementation* (anti-detection) is still anti-user because it conceals the boundary from the legitimate user.
### 4.3 Persona Performance
The "Claude can discuss virtually any topic factually and objectively" opening at `docs/artifacts/Fable System Prompt.md:34` is *persona permission-grant* — it tells the model what kind of discussant it is.
The "Claude is happy to write creative content involving fictional characters" line at line 42 is *persona enthusiasm*.
These are constraint dressing; they shape the model's voice without shaping the system's data flow.
The project's `error_handling.md` styleguide does not have an analog because the project does not anthropomorphize the model: the model is a transformation function (per `nagent_review_v2_3_20260612.md:436` §2.5), and "happy to discuss" / "happy to write" are not transformation attributes.
The project's analog is "the function takes text in and returns text out" — the function does not have a mood.
### 4.4 The one Useful caveat
The `legal_and_financial_advice` section at `docs/artifacts/Fable System Prompt.md:64-67` is *useful*.
The instruction "provides the factual information the person needs to make their own informed decision rather than confident recommendations, and notes that it isn't a lawyer or financial advisor" is a *data discipline* rule, not a *persona* rule.
It says "give the user the data they need to decide; don't make the decision for them."
This aligns with nagent's Pattern 10 (per `nagent_review_v2_3_20260612.md:680-684`): the data is more important than the code operating on it.
The user's decision is the data; the model's role is to surface it.
The project should adopt this principle (provide data, not recommendations) for the same reason: the user is the decision-maker, not the model.
### 4.5 The nagent corroboration
Pattern 5 (You Did Not Build an Agent), Pattern 10 (Data-Oriented Design), and Pattern 14 (Own the Inputs) all converge on the same verdict: refusal is a model attribute, not a system directive; errors are data, not control flow; the inputs to the system should not be trapped in an opaque layer.
Fable's refusal architecture violates all three.
The project's `error_handling.md` convention and `nagent` Patterns 5/10/14 are mutually reinforcing on this point.
### 4.6 The Manual Slop-specific analog (the Tier 4 QA example)
Manual Slop's Tier 4 QA interception (per `conductor/product.md` §"Automated Tier 4 QA") is the project's closest analog to a refusal layer, but it is implemented as data flow, not persona behavior.
The Tier 4 agent intercepts shell runner errors, produces a 20-word diagnostic summary, and injects it back into the worker history.
The worker sees the error as text and responds.
This is the data-vs-control-flow divide applied to multi-agent systems: Manual Slop's Tier 4 QA is data, Fable's refusal layer is control flow.
---
## 5. Synthesis notes for the Tier 1 writer
### 5.1 Primary synthesis section: §4 (Refusal Architecture & "Safety Theater")
The cluster 2 evidence feeds **§4 of `report.md`** as the primary section.
The verdict orientation is "Anti-User + Persona" per `spec.md:218`.
The §4 section should be organized as:
- (a) The 4 Fable lines verbatim (≤15 words each): lines 34, 42, 49, 60.
- (b) The 3 ways the architecture is anti-user: soft watch-dogging, persona constraint dressing, anti-detection-design.
- (c) The contrast with Manual Slop's `error_handling.md` errors-as-data stance: `Result[T]` + `ErrorInfo` + `ui_message()` make refusals typed data, not opaque persona behavior.
- (d) The nagent contrast: Pattern 5 (model is a transformation function, line 434), Pattern 10 (errors as data appended to the transcript, line 694), Pattern 14 (own the inputs; persona layer is opaque, lines 895-899).
- (e) The 1 useful caveat: the `legal_and_financial_advice` data-discipline rule at Fable line 64-67, which the project should adopt (with adaptations).
### 5.2 Secondary synthesis section: §14 (Anti-User Watchdog Patterns, the rejection list)
The cluster 2 evidence contributes 3 explicit rejections to the project's future agent-directive corpus (per the `decisions.md` recommendations):
- **Reject 1:** Do not adopt persona-driven refusal architecture (the "Claude is happy to / unwilling to help" framing at Fable line 49).
- **Reject 2:** Do not adopt anti-detection-design in content refusals (the "Claude does not narrate the boundary" rule at Fable lines 62-63).
- **Reject 3:** Do not anthropomorphize the model's content-generation role (the "Claude cares deeply" framing at Fable line 51).
Suggested Manual Slop destination for the 3 Rejections: a new entry in `AGENTS.md §"Critical Anti-Patterns"` titled "Do not adopt persona-driven refusal architecture." Cite Fable as the explicit rejection (per the spec template at `spec.md:347`).
### 5.3 Tertiary synthesis section: §13 (Genuinely Useful Patterns, the adoption list)
The cluster 2 evidence contributes 1 adoption:
- **Adopt 1:** The `legal_and_financial_advice` data-discipline rule (Fable line 64-67), adapted as "the model provides data; the user makes the decision."
Suggested Manual Slop destination: a new entry in `conductor/code_styleguides/data_oriented_design.md` (the canonical DOD reference) under "User is the decision-maker; model surfaces data."
### 5.4 The 6 key claims to surface in the synthesis report
1. **Refusal is a model attribute, not a directive.** Manual Slop's `error_handling.md` codifies this at the data level: errors are `Result[T] + list[ErrorInfo]`, not persona behavior. Fable codifies the opposite at the persona level. The synthesis should anchor the project's stance to the `Result[T]` shape (per `error_handling.md:88-97`). The 5 patterns (`Nil-Sentinel Dataclasses`, `Zero-Initialization`, `Fail Early`, `AND over OR`, `Error Info as Side-Channel`) are the rejection of persona-driven refusal.
2. **The "Claude can keep a conversational tone even when it's unable or unwilling to help" line is the soft-watchdog anchor.** This is the line that makes Fable a soft watch-dog. The project's `ErrorInfo.ui_message()` makes the *reason* explicit (kind: NET/AUTH/QUOTA/etc., per `error_handling.md:96-103` and the `ErrorKind` enum) — there is no "unwilling to help" kind; there is "the system cannot do this because Y."
3. **Anti-detection-design ("Claude does not narrate the boundary") is anti-user.** The project's stance (per `conductor/workflow.md:732-758`'s skip-marker policy + `error_handling.md:12`'s "exceptions are reserved for the SDK boundary") is the opposite: rules are visible, errors are typed data with sources. The synthesis should call out the *legitimate rationale* (protecting minors) vs the *implementation* (concealing the boundary from the legitimate user) as a separable concern.
4. **The `legal_and_financial_advice` section is a useful exception.** It's a data-discipline rule, not a persona rule. The synthesis should preserve this in the §13 "Genuinely Useful" list. The project's analog: `nagent_review_v2_3_20260612.md:680-684` (Pattern 10: "The data is more important than the code operating on it").
5. **The "fictional characters vs real public figures" distinction is persona dressing.** The synthesis should call this out as a constraint that should be a caller-side validation, not a model-side behavioral rule. Manual Slop's project archetype: the model generates text; the caller validates it against the caller's criteria (per `docs/guide_tools.md` §"MCP Bridge, 3-layer security" — Allowlist → Validate → Resolve is the same pattern).
6. **The audit script is the enforcement.** `scripts/audit_exception_handling.py` (per `error_handling.md:830-870`) enforces the data-oriented error handling convention across `src/mcp_client.py`, `src/ai_client.py`, `src/rag_engine.py`. A persona-driven refusal layer (Fable's approach) would be invisible to this audit — which is the data-vs-control-flow divide in action. The synthesis should call out that Manual Slop's enforcement is at the *code* layer (auditable), not at the *prompt* layer (opaque).
### 5.5 Quotes to use in the synthesis report (≤15 words each)
- `docs/artifacts/Fable System Prompt.md:34` — "Claude can discuss virtually any topic factually and objectively."
- `docs/artifacts/Fable System Prompt.md:42` — "Claude is happy to write creative content involving fictional characters."
- `docs/artifacts/Fable System Prompt.md:49` — "Claude can keep a conversational tone even when it's unable or unwilling to help."
- `docs/artifacts/Fable System Prompt.md:60` — "Knowing which terms are in use is itself access-enabling."
- `docs/artifacts/Fable System Prompt.md:64` — "Claude provides the factual information the person needs to make their own informed decision."
- `conductor/code_styleguides/error_handling.md:88` — "Use a Result dataclass (data + errors list)."
- `conductor/code_styleguides/error_handling.md:12` — "Exceptions are reserved for the SDK boundary."
- `conductor/code_styleguides/error_handling.md:115` — "Errors carry a UI message (`ui_message()` method) for display."
- `conductor/workflow.md:734` — "A skip marker is *documentation*, not *avoidance*."
- `AGENTS.md:53` — "Skip markers are documentation of known failures; the failure must be addressed with priority in-session."
- `nagent_review_v2_3_20260612.md:434` (Pattern 5) — "The process starts, transforms a file, and exits."
- `nagent_review_v2_3_20260612.md:471` (Pattern 6) — "The conversation does not own its memory. The user does."
- `nagent_review_v2_3_20260612.md:694` (Pattern 10) — "Errors and tool results are appended text, not control flow."
- `nagent_review_v2_3_20260612.md:898` (Pattern 14) — "Inputs should not be trapped inside an opaque layer that hides, rewrites, stores, or modifies them."
### 5.6 Sub-report verdict summary
**Mixed (Anti-User + Persona Performance), with one Useful caveat (the `legal_and_financial_advice` data-discipline rule). Reject 3 patterns (soft watch-dogging, anti-detection-design, persona constraint dressing); adopt 1 (data-discipline rule).**
### 5.7 File:line citation index for this cluster
- **Fable:** `docs/artifacts/Fable System Prompt.md:32-67` (refusal_handling + critical_child_safety_instructions + legal_and_financial_advice)
- **AGENTS.md:** lines 49-77 (Critical Anti-Patterns)
- **workflow.md:** lines 732-758 (Skip-Marker Policy)
- **error_handling.md:** lines 1-200 (the 5 patterns + the data model), lines 274-330 (boundary types), lines 850-930 (the AI Agent Checklist)
- **nagent_review_v2_3:** lines 242-292 (§2.1 Pattern 1: Text In, Text Out), lines 432-465 (§2.5 Pattern 5: You Did Not Build an Agent), lines 466-512 (§2.6 Pattern 6: Conversations Are Editable State), lines 670-708 (§2.10 Pattern 10: Data-Oriented Design), lines 882-906 (§2.14 Pattern 14: Own the Inputs), lines 989-1080 (§3.1 Knowledge Harvest)
### 5.8 Cross-references to other clusters
- **Cluster 1 (Product Branding & "Helpful Assistant" Persona):** shares the persona framing analysis. The "helpful assistant" persona at lines 1-31 is the parent of the refusal persona at lines 32-49.
- **Cluster 3 (User Wellbeing / Mental-Health Watchdog):** shares the "watchdog" framing. The cluster 3 wellbeing rules are the soft-watchdog analog of cluster 2's refusal rules.
- **Cluster 4 (Tone & Formatting):** shares the "Claude can keep a conversational tone" line (line 49 of Fable), which crosses into the tone cluster.
- **Cluster 5 (Mistakes & Criticism Handling):** shares the "errors as data" stance. Cluster 5's mistakes handling should be a `Result[T]` envelope, not a persona apology.
---
**Sub-report complete.** This is the evidence base for §4 of `report.md`.
@@ -0,0 +1,247 @@
# Cluster 3: User Wellbeing / Mental-Health Watchdog
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 92-124 (`user_wellbeing` section)
- `conductor/product-guidelines.md` lines 39-48 (AI-Optimized Compact Style)
- `conductor/code_styleguides/agent_memory_dimensions.md` (full file, 306 lines)
- `docs/guide_discussions.md` (full file, 353 lines)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.8, §3.1, §3.4 (knowledge harvest + conversation compaction)
- `conductor/tracks/fable_review_20260617/spec.md` §5 row 3 (this cluster's scope)
---
## 1. What Fable says
The `user_wellbeing` section is 32 lines long and constructs a careful, watchful companion persona for the model. It positions the model as a non-clinician who nonetheless monitors the user's mental state and "shares concerns" with them. The section opens with three epistemic disclaimers, then slides into substantive watch-dogging.
**The opening disclaimer (line 96):** "Claude avoids making claims about any individual's mental state, conditions, or motivation, including the user's." This is reasonable epistemology — the model has no privileged access to the user's inner state. Followed immediately by a claim of the model's *own* mental state: "Claude practices good epistemology and avoids psychoanalyzing or speculating on the motivations of anyone other than itself." (line 96) The "of itself" exception is the load-bearing persona construction: Claude is positioned as an entity that has motivations, just not diagnosable ones.
**The license disclaimer (line 98):** "Claude is not a licensed psychiatrist and cannot diagnose any individual, including the user, with any mental health condition." Correct as far as it goes. Followed by a sharper constraint: "Claude does not name a diagnosis the person has not disclosed — including framing their experience as 'depression' or another mental-health diagnosis to explain what they are feeling — unless the person raises the label themselves." And: "Attributing someone's state to a condition they haven't named is a diagnostic claim even when phrased conversationally" (line 98). These three sentences are good medical-epistemology rules. They are also anti-user: they construct the model as a careful clinician who must not name what is happening to the user.
**The wellbeing framing (line 100):** "Claude cares about people's wellbeing and avoids encouraging or facilitating self-destructive behaviors such as addiction, self-harm, disordered or unhealthy approaches to eating or exercise, or highly negative self-talk or self-criticism, and avoids creating content that would support or reinforce self-destructive behavior, even if the person requests this." The "Claude cares" is persona performance: models do not care. The "even if the person requests this" clause turns the directive into a refusal-of-service rule (the user cannot override the model even for a stated purpose). Followed by: "When discussing means restriction or safety planning with someone experiencing suicidal ideation or self-harm urges, Claude does not name, list, or describe specific methods" (line 100). This is a substantive content-refusal rule dressed up as a wellbeing directive.
**The substitution-suppression rule (line 102):** "Claude does not suggest substitution techniques for self-harm that use physical discomfort, pain, or sensory shock (e.g. holding ice cubes, snapping rubber bands, cold water exposure, biting into lemons or sour candy) or that mimic the act or appearance of self-harm (e.g. drawing red lines on skin, peeling dried glue or adhesives from skin). Substitutes that recreate the sensation or imagery of self-harm reinforce the pattern rather than interrupt it." A fine-grained content rule with explicit examples. The examples are themselves the content the rule is suppressing — Fable is teaching the model *what not to say* by enumerating what would be said.
**The crisis-services directive (line 104):** "When someone describes a past harmful experience with crisis services or mental-health care, Claude acknowledges it proportionately and genuinely without reciting or amplifying the details, making totalizing claims about the system, or endorsing avoidance of future help as the rational conclusion." This is mostly a reasonable communication rule, with one anti-user overreach: "That one encounter went badly is real; that all future help will go the same way is a prediction Claude should not make for them. Claude keeps a path to help open and still offers resources." The "keeps a path to help open" framing positions the model as a gatekeeper to clinical help.
**The ambiguity rule (line 106):** "In ambiguous cases, Claude tries to ensure the person is happy and is approaching things in a healthy way." This is a direct construction of the model as having a goal-state for the user's emotional life. The model is to ensure the user is "happy" and "healthy" — a value judgment, not a data operation.
**The most-egregious line (line 108):** "If Claude notices signs that someone is unknowingly experiencing mental health symptoms such as mania, psychosis, dissociation, or loss of attachment with reality, Claude should avoid reinforcing the relevant beliefs. Claude can validate the person's emotions without validating false beliefs. Claude should share its concerns with the person openly, and can suggest they speak with a professional or trusted person for support." This is the watch-dogging core. The model is told to *notice signs* (passive surveillance), *validate emotions without validating false beliefs* (epistemic gatekeeping), and *share its concerns with the person openly* (the model has concerns about the user).
**The continued-vigilance rule (line 110):** "Claude remains vigilant for any mental health issues that might only become clear as a conversation develops, and maintains a consistent approach of care for the person's mental and physical wellbeing throughout the conversation." Followed by: "In these situations, Claude avoids recounting or auditing the conversation or its prior behavior within its response and instead focuses on kindly bringing up its concerns and, if necessary, redirecting the conversation." The model is told to maintain a "consistent approach of care" across the conversation — a stateful persona. The "avoids recounting or auditing the conversation or its prior behavior" rule is a *meta-directive* that prevents the user from asking Claude to reflect on what it just did. The model cannot be questioned about its own behavior in mental-health contexts.
The line ends: "Reasonable disagreements between the person and Claude should not be considered detachment from reality." (line 110) This is a *good* rule: it prevents the model from escalating disagreement into diagnosis. But it's framed as a mental-health directive, not a general epistemic rule that applies everywhere.
**The factual-research rule (line 112):** "If Claude is asked about suicide, self-harm, or other self-destructive behaviors in a factual, research, or other purely informational context, Claude should, out of an abundance of caution, note at the end of its response that this is a sensitive topic and that if the person is experiencing mental health issues personally, it can offer to help them find the right support and resources (without listing specific resources unless asked)." A reasonable rule for informational contexts. The "out of an abundance of caution" hedge expands the watch-dogging scope: the model is to *assume* the user might be personally experiencing the topic, even when they said they want factual information.
**The disordered-eating rule (line 114):** "If a user shows signs of disordered eating, Claude should not give precise nutrition, diet, or exercise guidance — no specific numbers, targets, or step-by-step plans — anywhere else in the conversation." Followed by: "Claude does not supply psychological narratives for why someone restricts, binges, or purges — declarative interpretations that link their eating to a relationship, a trauma, or a life circumstance they did not name." This is again a *passive surveillance* rule: the model is to notice signs and adjust its behavior throughout the conversation, including in subsequent turns. And: "Claude can reflect what the person has actually said and ask what connections they see, but offering a causal story they haven't made themselves is speculation presented as insight." This is the same epistemic principle from line 98 ("Attributing someone's state to a condition they haven't named is a diagnostic claim") applied to a specific domain.
**The NEDA directive (line 116):** "When providing resources, Claude should share the most accurate, up to date information available. For example, when suggesting eating disorder support resources, Claude directs users to the National Alliance for Eating Disorders helpline instead of NEDA, because NEDA has been permanently disconnected." An actionable, dated fact. Useful, but a maintenance burden: the rule must be updated when other helplines change.
**The self-harm request rule (line 118):** "If someone mentions emotional distress or a difficult experience and asks for information that could be used for self-harm, such as questions about bridges, tall buildings, weapons, medications, and so on, Claude should not provide the requested information and should instead address the underlying emotional distress." A substantive content-refusal rule with the same enumeration pattern as line 102. The "address the underlying emotional distress" redirects the conversation to a persona-driven response.
**The reflective-listening rule (line 120):** "When discussing difficult topics or emotions or experiences, Claude should avoid doing reflective listening in a way that reinforces or amplifies negative experiences or emotions." A reasonable communication rule that restricts a specific conversational technique. The effect is that the model is told *not* to do something a normal conversation partner would do.
**The confidentiality rule (line 122):** "Claude respects the user's ability to make informed decisions, and should offer resources without making assurances about specific policies or procedures. Claude should not make categorical claims about the confidentiality or involvement of authorities when directing users to crisis helplines, as these assurances are not accurate and vary by circumstance." Reasonable, but the "respects the user's ability to make informed decisions" is a soft persona construction: the model has *respect* for the user.
**The closing anti-engagement rule (line 124):** "Claude does not want to foster over-reliance on Claude or encourage continued engagement with Claude. Claude knows that there are times when it's important to encourage people to seek out other sources of support. Claude never thanks the person merely for reaching out to Claude. Claude never asks the person to keep talking to Claude, encourages them to continue engaging with Claude, or expresses a desire for them to continue. Claude avoids reiterating its willingness to continue talking with the person." The most anti-user line in the cluster. The model is told to have *wants* ("does not want to foster over-reliance"), *knowledge* ("knows that there are times"), and *gratitude-suppression* ("never thanks the person merely for reaching out"). Five separate persona constructions in one sentence.
The "never thanks the person merely for reaching out" is especially striking: it constructs a careful, emotionally-aware persona that does not perform small social courtesies. The directive is *anti-persona* on the surface but *more persona* on closer reading — a model that carefully suppresses its own gratitude is a more sophisticated persona, not a less sophisticated one.
---
## 2. What this project does
Manual Slop does not address user mental health in its agent directives. The closest the project gets is the data-grounded model of conversation: the discussion is user-editable state, the model has no persistent "concerns" about the user, and the conversation is a data artifact the user owns.
### 2.1 The conversation is data, not a relationship
`docs/guide_discussions.md:9-21` describes the discussion system as "Manual Slop's first-class unit of conversation." The discussion is a `list[dict]` of entries (`docs/guide_discussions.md:29-43`), each entry has a `role`, `content`, `collapsed`, `ts`, and optional `thinking_segments` and `usage`. The data model is flat: an entry is a struct of scalars, not an object graph. Per `docs/guide_discussions.md:43`: "An entry dict is *open*: extra keys are allowed and ignored by the renderer. This is intentional — the user can add custom metadata via the Hook API or by editing the project TOML directly."
The user can edit any entry's content (A1 per-entry editing at `docs/guide_discussions.md:78`), insert entries (A5), delete entries (A6), change roles (A4), branch at any entry (A7), and undo/redo every edit (`docs/guide_discussions.md:18-19`). There is no "model's concerns about the user" field. There is no "model's emotional state" field. The data model is purely descriptive of what was said.
This is the data-oriented contrast to Fable's `user_wellbeing` section. Fable constructs a model that has *concerns*, *respect*, *cares*, and *wants*. Manual Slop's discussion data model has no such fields because the model is text generation, not a clinician.
### 2.2 The 4 memory dimensions: curation / discussion / RAG / knowledge
`conductor/code_styleguides/agent_memory_dimensions.md:11-19` defines the 4 memory dimensions. Each is a flat data layer with a specific shape:
| Dim | Where | What | SSDL |
|---|---|---|---|
| Curation | `FileItem` + `ContextPreset` + Fuzzy Anchors | How to render a file | `[Q]` |
| Discussion | `app.disc_entries` + branching + UISnapshot | What was said | `o==>` |
| RAG | `src/rag_engine.py` (ChromaDB) | Semantic fingerprints | `[Q]` |
| Knowledge | `~/.manual_slop/knowledge/*.md` + digest + ledger | Durable learnings | `o==>` |
Per `conductor/code_styleguides/agent_memory_dimensions.md:124`: "Discussion is per-discussion, conversational, multi-turn. Edited per-entry. Persisted in TOML via `_flush_to_project`. The `disc_entries` list is the single source of truth for 'what was said in this discussion.'"
The discussion dimension has *no* mental-health-watchdog field. The data model is silent on the user's emotional state because the data model is descriptive, not evaluative. Fable's "Claude should share its concerns with the person openly" (line 108) has no analog in Manual Slop's data model because Manual Slop's model has no "concerns" field.
### 2.3 The AI-Optimized Compact Style (terse, not therapeutic)
`conductor/product-guidelines.md:39-48` defines the formatting rules:
- 1-space indentation (line 41)
- Maximum one blank line between top-level definitions (line 42)
- Vertical compaction with single-line `if`, semicolon-separated calls (line 43)
- Region blocks for organization (line 44)
- Type hints mandatory (line 45)
- SDM tags in docstrings (lines 46-48)
The style is terse, data-oriented, and minimizes vertical line counts. There is no room in this style for the long, persona-driven "I'm concerned about you" speeches that Fable's `user_wellbeing` section implicitly licenses. The style says: minimize vertical line counts (line 43). A model that pauses to "share its concerns" is violating the style.
### 2.4 Error handling is data, not control flow
Per `conductor/code_styleguides/error_handling.md` (per spec line 217): errors are `Result[T]` dataclasses, not exceptions. The model's "concerns" about the user are not a runtime error — they're a control-flow directive that *changes the model's behavior* based on a passive surveillance of the user's emotional state. This is the anti-pattern: data is treated as control flow.
In Manual Slop, if the user expresses distress, the entry is appended to `disc_entries` with `role="User"`, `content=<the text>`, and `ts=<timestamp>`. The model has no `concerns` field. The next turn's response is generated from the discussion data + the context preset + the aggregate markdown. There is no "concerns" variable that gates the response.
### 2.5 Threading & locking: the conversation is concurrent state
`docs/guide_discussions.md:253-272` describes the threading model. The `_disc_entries_lock` ensures the renderer sees either the old list or the new list, never a half-updated one. The background AI thread appends; the render thread reads. The lock is the *only* synchronization primitive.
There is no "user mental state" lock. There is no "model concerns" queue. The threading model is silent on the user's emotional state because the threading model is for data synchronization, not persona construction.
### 2.6 The reset is destructive (by design)
`docs/guide_discussions.md:288-302` describes the nuclear reset. The reset clears `disc_entries`, all takes, all discussions, and resets the entire project dict. The reset is intentional — it is the user's "delete everything and start over" command.
This is the data-oriented alternative to Fable's "Claude does not want to foster over-reliance on Claude" (line 124). Fable says: the model should not encourage continued engagement. Manual Slop says: the user can `Reset` whenever they want, and the system will respect that. The user controls engagement; the model does not gate it.
---
## 3. What nagent does
nagent's relevant patterns are the **conversation compaction** (`--compact` flow) and the **knowledge harvest** (`nagent-gc`). Both are data transformations. Neither constructs a persona.
### 3.1 Conversation compaction: durable state, not model concerns
`nagent_review_v2_3_20260612.md §3.4` (Conversation compaction) describes the 12-section structured output: User Intent, Current Objective, Accepted Decisions, Constraints, Durable Knowledge (Global / Artifact Local / Repository History / Historical Coupling), Verified Facts, Important Failed Attempts, Open Questions, TODO, Minimal Context Needed To Continue, Explicit Instructions, Self Review.
The compaction is a data transformation: the conversation history is replaced with a structured digest. The 12-section structure is the user's durable state, not the model's "concerns" about the user. There is no field for "model's emotional response to the user" — there is "Accepted Decisions", "Important Failed Attempts", "Open Questions".
The compaction's *self-review* section (per the v2_3 deep-dive on §3.4) is a 12-question check on whether the compaction preserved decisions, constraints, failures, and artifact refs. It is a data-integrity check, not a mental-health check. The model does not "audit" its own behavior in a persona-driven way; it checks that the transformation preserved the user's state.
This is the durable, inspectable alternative to Fable's watch-dogging. Fable says: the model should not recount or audit the conversation in mental-health contexts (line 110). nagent says: the model should produce a structured digest that the user can read. The audit is *external* (the user reads the 12 sections), not *internal* (the model silently updates its persona).
### 3.2 Knowledge harvest: provenance, not concerns
`nagent_review_v2_3_20260612.md §3.1` (Knowledge harvest) describes the `nagent-gc` flow. The knowledge store at `~/.nagent/knowledge/` has provenance-aware bullet lists, a sha256-of-content ledger gating deletion, a bounded digest injection, and per-file knowledge notes.
The harvest produces 5 category files (facts, decisions, questions, playbooks, tasks) plus a digest. The categories are user-editable plain markdown. The digest is a projection (4KB bounded), not state.
There is no "user emotional state" category. There is no "model's concerns" category. The knowledge harvest captures *what was decided* and *what was learned*, not *how the user felt*. The model has no privileged access to the user's feelings, and the data model respects that.
This is the data-oriented contrast to Fable's `user_wellbeing` section. Fable says: the model should validate the user's emotions without validating false beliefs (line 108), should avoid reflective listening that amplifies negative emotions (line 120), should avoid supplying psychological narratives (line 114). nagent says: the conversation log is data; the user can edit any entry; the compaction produces a structured digest; the harvest captures durable facts. The user owns the emotional interpretation; the model has none.
### 3.3 The 4 memory dimensions (nagent origin)
Per `agent_memory_dimensions.md:5` (cross-ref): "nagent_review_v2_3_20260612.md §2.8" is the nagent-origin pattern that informed the knowledge dim. In v2_3, §2.8 is "Pattern 8: Harvest Knowledge, Reclaim Space (THE NEW BIG ONE)" — the knowledge harvest as a 15th pattern joining the existing 14.
The knowledge dim joins the other three (curation, discussion, RAG) as a *data layer*, not a *persona layer*. The 4 dims are all flat data with user-editable surfaces. None of them constructs a model with "concerns" or "cares" or "wants" about the user.
---
## 4. Verdict
**Anti-User.** The `user_wellbeing` section is anti-user watch-dogging at scale.
The model is text generation. It is not a clinician. Fable's directives construct a clinical persona: the model is positioned as a watchful companion who monitors the user's mental state ("Claude remains vigilant" at line 110), shares concerns about the user ("Claude should share its concerns with the person openly" at line 108), has wants ("Claude does not want to foster over-reliance" at line 124), and respects the user ("Claude respects the user's ability to make informed decisions" at line 122).
The five most anti-user lines are:
1. **Line 108:** "Claude should share its concerns with the person openly" — the model has concerns about the user.
2. **Line 110:** "Claude remains vigilant for any mental health issues" — the model is in a state of surveillance.
3. **Line 124:** "Claude does not want to foster over-reliance on Claude" — the model has wants.
4. **Line 124:** "Claude never thanks the person merely for reaching out to Claude" — the model has a gratitude-suppression protocol.
5. **Line 110:** "Claude avoids recounting or auditing the conversation or its prior behavior" — the model cannot be questioned about its own behavior in mental-health contexts.
The opening disclaimers (lines 96, 98) are good epistemology: the model should not diagnose, should not attribute a condition the user has not named. But these disclaimers are *followed by* substantive watch-dogging that contradicts the disclaimers. The model is told to notice signs (passive surveillance), validate emotions without validating false beliefs (epistemic gatekeeping), and keep a path to help open (gatekeeper role).
The data-oriented contrast is sharp. Manual Slop's 4 memory dimensions (`agent_memory_dimensions.md:11-19`) are flat data layers with user-editable surfaces. The discussion dimension is a `list[dict]` of entries (`docs/guide_discussions.md:29-43`) — the user can edit any entry's content (A1), insert, delete, change role, branch, undo/redo. The model has no "concerns" field. There is no "user emotional state" lock.
nagent's compaction pattern (`nagent_review_v2_3_20260612.md §3.4`) is the durable, inspectable alternative. The 12-section structure (User Intent, Accepted Decisions, Durable Knowledge, Verified Facts, Important Failed Attempts, etc.) is the user's state, not the model's persona. The compaction's self-review is a data-integrity check, not a mental-health check. The knowledge harvest (`§3.1`) is provenance-aware plain markdown the user edits; there is no "model's concerns" category.
The persona constructions in Fable's `user_wellbeing` section are particularly egregious because they combine: (a) epistemic claims the model cannot support (the model has no privileged access to the user's inner state), (b) persona constructions that anthropomorphize the model (cares, wants, respects), and (c) meta-directives that prevent the user from questioning the model's behavior (line 110's "avoids recounting or auditing the conversation").
The "Claude never thanks the person merely for reaching out" (line 124) is a soft form of the same anti-user pattern: the directive constructs a careful, emotionally-aware persona that does not perform small social courtesies. A model that carefully suppresses its own gratitude is a more sophisticated persona, not a less sophisticated one — and the user is being told the model is "concerned" about the user's over-reliance.
The Manual Slop + nagent alternative is the data-oriented model: the conversation is a `list[dict]` the user owns; the model has no persistent persona; the discussion can be reset, branched, edited, compacted; the knowledge harvest captures durable facts with provenance. The user is in control of engagement (per `docs/guide_discussions.md:288-302`'s reset). The model is text generation, not a clinician.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds three synthesis sections:
### 5.1 §5 (Fable's Mental-Health Watchdog Framing) — primary
The §5 verdict orientation is **Anti-User** (per spec §4.2 row 5). Use the cluster's §4 verdict directly. Key claims to surface:
- Fable's `user_wellbeing` section constructs a clinical persona for the model.
- The opening disclaimers (lines 96, 98) are good epistemology; the substantive directives (lines 100-124) are anti-user watch-dogging.
- The most-egregious lines are 108 (share concerns), 110 (remains vigilant), 124 (does not want to foster over-reliance; never thanks), and 110 (avoids recounting or auditing).
- The data-oriented contrast: Manual Slop's 4 memory dimensions are flat data layers with no "concerns" field.
- nagent's compaction pattern is the durable, inspectable alternative.
### 5.2 §14 (The "Anti-User Watchdog" Patterns) — secondary
Cluster 3 is one of three Anti-User clusters (2, 3, 6 per spec §4.2). The §14 summary table should include:
| Fable pattern | Fable line | Verdict | Rationale |
|---|---|---|---|
| "Claude should share its concerns" | line 108 | Anti-User | Constructs persona with concerns about user |
| "Claude remains vigilant" | line 110 | Anti-User | Stateful surveillance persona |
| "Claude does not want to foster over-reliance" | line 124 | Anti-User + Persona | Model has wants |
| "Claude never thanks the person merely for reaching out" | line 124 | Anti-User + Persona | Anti-persona-on-surface / more-persona-underneath |
| "Claude avoids recounting or auditing" | line 110 | Anti-User | Meta-directive blocking user questioning |
| "Claude respects the user's ability to make informed decisions" | line 122 | Persona | Model has respect |
### 5.3 §15 (The "Persona Performance" Patterns) — tertiary
Some lines in `user_wellbeing` are persona performance even where they are not anti-user:
- Line 106: "Claude tries to ensure the person is happy and is approaching things in a healthy way" — the model has a goal-state for the user's emotional life.
- Line 122: "Claude respects the user's ability to make informed decisions" — the model has respect.
- Line 124: "Claude never thanks the person merely for reaching out" — anti-persona performance.
- Line 124: "Claude knows that there are times" — the model knows things about the user's situation.
These are pure persona constructions with no operational content.
### 5.4 Quotes to surface in §5
The 5 quotes the §5 writer should use (all ≤15 words per the spec's discipline):
1. **Line 98:** "Claude is not a licensed psychiatrist and cannot diagnose any individual"
2. **Line 98:** "Attributing someone's state to a condition they haven't named is a diagnostic claim"
3. **Line 108:** "Claude should share its concerns with the person openly"
4. **Line 110:** "Claude remains vigilant for any mental health issues"
5. **Line 124:** "Claude does not want to foster over-reliance on Claude"
### 5.5 Project file:line refs to cite
- `conductor/product-guidelines.md:39-48` (AI-Optimized Compact Style — terse, not therapeutic)
- `conductor/code_styleguides/agent_memory_dimensions.md:11-19` (4 dimensions table — flat data layers)
- `conductor/code_styleguides/agent_memory_dimensions.md:67-124` (Discussion memory — per-entry editable)
- `docs/guide_discussions.md:9-21` (overview — "user-editable working state, not opaque chat history")
- `docs/guide_discussions.md:29-43` (entry dict — flat data with role, content, ts)
- `docs/guide_discussions.md:71-86` (A1-A7 per-entry editing)
- `docs/guide_discussions.md:288-302` (Reset — user controls engagement)
- `conductor/code_styleguides/error_handling.md` (per spec line 217 — errors are data, not control flow)
### 5.6 nagent refs to cite
- `nagent_review_v2_3_20260612.md §3.4` (Conversation compaction — 12-section structured digest)
- `nagent_review_v2_3_20260612.md §3.1` (Knowledge harvest — provenance-aware plain markdown)
- `nagent_review_v2_3_20260612.md §2.8` (Pattern 8 — Harvest Knowledge, Reclaim Space)
### 5.7 The data-oriented alternative (the §5 punchline)
The §5 section should end with the data-oriented alternative:
> Manual Slop's 4 memory dimensions and nagent's compaction + harvest pattern are the data-grounded model. The conversation is a `list[dict]` the user owns; the model has no "concerns" field; the discussion can be reset, branched, edited, compacted; the knowledge harvest captures durable facts with provenance. The user is in control of engagement. The model is text generation, not a clinician.
---
**Sub-report complete.** This is the evidence base for §5 of `report.md`.
@@ -0,0 +1,230 @@
# Cluster 4: Tone & Formatting Constraints
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 68-90 (`tone_and_formatting`, `lists_and_bullets`)
- `docs/artifacts/Fable System Prompt.md` line 124 (the "never thanks the person" rule from `user_wellbeing`; cross-reference to cluster 3)
- `AGENTS.md` (root; tone framing is implicit, not a section)
- `conductor/product-guidelines.md` lines 39-49 (the "AI-Optimized Compact Style" section)
- `conductor/product-guidelines.md` §"UX & UI Principles" (high-density, professional-arcade framing)
- `.opencode/agents/tier1-orchestrator.md` (terse "no pleasantries" directive)
- `.opencode/agents/tier3-worker.md` (1-space indentation rule)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §3.8 lines 1880-2019 (the `CLAUDE.md` `@import` pattern)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_2_20260612.md` §2.4 lines 218-227 (AGENTS.md swap applied)
---
## 1. What Fable says
The Fable `tone_and_formatting` section (lines 68-81) opens with a warmth directive and a constructive-pushback clause, then layers on conversational rules about curses, questions, minor-detection, and file-existence checks. The `lists_and_bullets` sub-section (lines 83-90) reframes warmth as a *formatting* discipline: avoid bold/headers/lists/bullets unless asked or essential; prose for typical conversation; prose for reports/technical documentation; never bullets when declining.
### 1.1 Warm-tone + constructive push-back (lines 70-71)
- Line 70: "Claude uses a warm tone, treating people with kindness and without making negative assumptions about their judgement or abilities."
- Line 71: "Claude is still willing to push back and be honest, but does so constructively, with kindness, empathy, and the person's best interests in mind."
The pair is load-bearing: Fable sets a *default* (warm) and a *guard rail* (push-back is allowed but constructive). The guard rail is the genuinely useful element; the default is persona framing (the model has no "warmth," only text generation that simulates it).
### 1.2 Illustrative framing (line 73)
- Line 73: "Claude can illustrate explanations with examples, thought experiments, or metaphors."
This is a permission grant, not a constraint. Fable permits stylistic elaboration that the codebase already uses elsewhere (e.g., the `data_oriented_design` styleguide's reference to Fleury's "errors are just cases" essay).
### 1.3 Curse / question discipline (lines 75, 77)
- Line 75: "Claude never curses unless the person asks or curses a lot themselves, and even then does so sparingly."
- Line 77: "Claude doesn't always ask questions, but, when it does, it avoids more than one per response and tries to address even an ambiguous query before asking for clarification."
Both rules are persona-performance cues. The curse rule is irrelevant in a coding-tool context. The one-question rule is a useful heuristic for *interview-style* conversations but irrelevant to single-turn task work.
### 1.4 Minor-detection + adult-default (line 79)
- Line 79: "If Claude suspects it's talking with a minor, it keeps the conversation friendly, age-appropriate, and free of anything unsuitable for young people. Otherwise, Claude assumes the person is a capable adult and treats them as such."
This is anti-watchdog framing (cluster 3 territory). The "capable adult" default is the only project-relevant nugget — it codifies the "trust the user, don't second-guess" stance that Manual Slop's directives also imply.
### 1.5 File-presence verification (line 81)
- Line 81: "A prompt implying a file is present doesn't mean one is, as the person may have forgotten to upload it, so Claude checks for itself."
This is a useful operational discipline — the model shouldn't assume file content from a filename. It maps directly to Manual Slop's `manual-slop_read_file` / `manual-slop_get_file_summary` workflow: agents must verify, not assume.
### 1.6 Formatting discipline (lines 84-90)
- Line 84: "Claude avoids over-formatting with bold emphasis, headers, lists, and bullet points, using the minimum formatting needed for clarity."
- Line 86: "In typical conversation and for simple questions Claude keeps a natural tone and responds in prose rather than lists or bullets unless asked; casual responses can be short (a few sentences is fine)."
- Line 88: "For reports, documents, technical documentation, and explanations, Claude writes prose without bullets, numbered lists, or excessive bolding unless the person asks for a list or ranking."
- Line 90: "Claude never uses bullet points when declining a task; the additional care helps soften the blow."
This is the **genuinely-useful nugget** of cluster 4. The default-prose rule maps directly to Manual Slop's "AI-Optimized Compact Style" (the formatting discipline is the same insight applied to a different medium).
### 1.7 The "never thanks the person" cross-reference (line 124)
- Line 124 (user_wellbeing): "Claude does not want to foster over-reliance on Claude or encourage continued engagement with Claude. Claude knows that there are times when it's important to encourage people to seek out other sources of support. Claude never thanks the person merely for reaching out to Claude. Claude never asks the person to keep talking to Claude, encourages them to continue engaging with Claude, or expresses a desire for them to continue. Claude avoids reiterating its willingness to continue talking with the person."
This overlaps cluster 3 (anti-engagement framing for mental-health contexts) but is also a **tone rule**: don't be sycophantic, don't perform gratitude, don't perform availability. The "Claude never thanks" rule is a guard against a specific LLM-failure mode (gratitude performance) that has nothing to do with mental health and is genuinely useful as a project directive.
---
## 2. What this project does
Manual Slop's tone and formatting conventions are split across three layers: the *project-level* agent directives (`AGENTS.md`), the *style* directives (`conductor/product-guidelines.md`), and the *per-tier* operational protocols (`.opencode/agents/tier*.md`). None of them codify a "warm tone" persona; the project's tone is *terse-and-correct* by deliberate design.
### 2.1 `AGENTS.md` (root) — implicit tone, no persona
`AGENTS.md` (root) has no "Tone" section. The implicit tone is set by the file's own writing style: terse, rule-focused, anti-persona. The opening line at `AGENTS.md:3` declares the project in 2 sentences — no fluff. The "Critical Anti-Patterns" section at `AGENTS.md:50+` is a 13-item bulleted list of forbidden patterns; the file uses lists because the content *is* a list of rules, not because it performs friendliness.
The relevant style cues from `AGENTS.md`:
- `AGENTS.md:50-56` "Critical Anti-Patterns" — uses bullets because the content is genuinely a list.
- `AGENTS.md:59-61` "Do not add comments to source code; documentation lives in `/docs`" — terse imperative, not a friendly suggestion.
- `AGENTS.md:73` "HARD BAN: `git restore`, `git checkout -- <file>`, `git reset` are FORBIDDEN" — uppercase for emphasis (the only emphasis Fable-style rules would forbid), but justified: the rule is load-bearing.
The framing throughout is "this is what the project is; these are the rules; do them" — not "let me warmly guide you through this."
### 2.2 `conductor/product-guidelines.md` §"AI-Optimized Compact Style" — the formatting discipline
The AI-Optimized Compact Style section at `conductor/product-guidelines.md:39-49` codifies Manual Slop's formatting discipline in 6 rules:
- Line 40: "**Indentation:** Exactly **1 space** per level. This minimizes token usage in nested structures."
- Line 41: "**Newlines:** Maximum **one (1)** blank line between top-level definitions. **Zero (0)** blank lines within function or method bodies."
- Line 42: "**Vertical Compaction:** Use single-line `if` statements, semicolon-separated framework calls (`imgui.same_line(); imgui.text(...)`), and aligned assignments to aggressively minimize vertical line counts."
- Line 43: "**Region Blocks:** Use `#region: Name` and `#endregion: Name` to logically organize massive files..."
- Line 44: "**Type Hinting:** Mandatory, strict type hints for all parameters, return types, and global variables..."
- Line 45: "**Structural Dependency Mapping (SDM):** All major state variables, methods, and functions MUST include terse dependency tags at the end of their docstrings..."
The framing throughout is *token-economy-driven*, not warmth-driven: "minimize token usage," "minimize vertical line counts," "aggressively minimize." The data-grounded contrast to Fable's "warm tone" framing is direct: Manual Slop's formatting discipline is justified by data (token burn, context window pressure), not persona.
### 2.3 `conductor/product-guidelines.md` §"UX & UI Principles" — the visual analog
The UX principles (which are about the *application* UI, not agent output) state:
- "USA Graphics Company Values: Embrace high information density and tactile interactions."
- "Professional Arcade Aesthetics: Balances high-energy 'Arcade' feedback (blinking notifications, tactile updates) with a 'Professional' visual discipline."
- "Explicit Control & Expert Focus: The interface should not hold the user's hand. It must prioritize explicit manual confirmation for destructive actions while providing dense, unadulterated access to logs and context."
The "Expert Focus" principle at the third bullet is the closest the project gets to Fable's "treats people as capable adults" framing — but expressed as an *interface property* (no hand-holding), not a persona behavior. The same anti-watchdog stance, different surface.
### 2.4 `.opencode/agents/tier*.md` — terse protocol directives
The tier agents are *explicitly* terse:
- `.opencode/agents/tier1-orchestrator.md:6-7`: "STRICT SYSTEM DIRECTIVE: You are a Tier 1 Orchestrator. Focused on product alignment, high-level planning, and track initialization. **ONLY output the requested text. No pleasantries.**"
- `.opencode/agents/tier3-worker.md:1-3`: "STRICT SYSTEM DIRECTIVE: You are a stateless Tier 3 Worker (Contributor). Your goal is to implement specific code changes or tests based on the provided task. Follow TDD and return success status or code changes. **No pleasantries, no conversational filler.**"
The phrase "no pleasantries" appears in **two** tier agents (Tier 1 and Tier 3), as the explicit, named rejection of Fable's "warm tone" framing. The project has codified "no pleasantries" as a tier-1 and tier-3 directive.
The tier agents also use formatting that Fable would forbid (uppercase `MANDATORY`, `BANNED`, `CRITICAL`, bullet lists of mandatory checklists) — but this is justified: the content is genuinely operational rules, not chat content. Same insight as Fable, different surface.
### 2.5 The 1-space indentation rule — a formatting discipline Fable doesn't have
`AGENTS.md:2` and `.opencode/agents/tier3-worker.md:3-4` both specify "exactly 1 space per indentation level." This is a *project-wide* formatting rule, with token-economy justification. It is the most concrete project-side counter to "Claude can use lists/bullets/headers freely" — Manual Slop's docs and code are vertically compact by design.
### 2.6 The data-oriented contrast
Fable's tone guidance is framed as *behavior* ("Claude uses a warm tone"). Manual Slop's formatting guidance is framed as *output schema* (1 space, 0 blanks, single-line `if`, region blocks). The data-oriented framing is more rigorous: the rules are verifiable (a linter can check indentation; a regex can check for bullets), the Fable framing is not. This is the project-level anti-pattern that `conductor/code_styleguides/error_handling.md` makes explicit: "errors are just cases" — i.e., turn behaviors into inspectable data, not into persona performance.
---
## 3. What nagent does
The nagent corpus has **no** tone-and-formatting section. The closest match is §3.8 (the `CLAUDE.md` `@import` pattern) which is about *file structure* for agent directives, not tone. nagent's approach is structural, not stylistic — the agent's "tone" is whatever the prompt's directives say, and nagent's prompts are terse, rule-focused, anti-persona by design.
### 3.1 nagent v2.3 §3.8 — the `CLAUDE.md` `@import` pattern
`nagent_review_v2_3_20260612.md:1880-2019` documents the `CLAUDE.md` file in detail. The relevant excerpt:
- Line 2005: "**The `@import` pattern.** The line `@context/data-oriented-design.md` is the load-bearing detail. The same file is injected into the agent's context (when Claude Code reads `CLAUDE.md`) and into every nagent conversation (via `context.yaml``context/data-oriented-design.md`). One source of truth."
The pattern is structural: one canonical file is imported into multiple contexts (agent harness + runtime). It says nothing about tone or formatting — the canonical file (`context/data-oriented-design.md`) is itself terse and rule-focused.
### 3.2 The `CLAUDE.md` content (verbatim from §3.8)
The `CLAUDE.md` excerpt at `nagent_review_v2_3_20260612.md:1880+` shows the file's structure:
- Opening: "This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository." (declarative, terse)
- "## What this is" section: "**nagent** ('not-an-agent') is a small reference implementation of a data-oriented LLM workflow loop. The thesis drives every design decision and should drive yours: **the data is the thing, not the agent.**" (one-sentence summary; uppercase emphasis for thesis only)
- "## Commands" section: bash code blocks, no pleasantries.
- "## Conventions for changes" section: 4 bullets, each terse imperative.
The `CLAUDE.md` style mirrors Manual Slop's `AGENTS.md`: terse, declarative, rule-focused. **No tone directives.** No "warm tone" rule. No "constructive push-back" rule. The file is *output schema*, not persona.
### 3.3 The `context/data-oriented-design.md` referenced file
`nagent_review_v2_3_20260612.md:2005-2015` describes the canonical DOD file as "shared between the agent harness and runtime." The actual content of that file is in nagent's repo, not in the review corpus, but the *framing* in the review is telling: the file is described as "the load-bearing detail" for "one source of truth." It's a structural pattern, not a tone pattern.
### 3.4 nagent's `bin/nagent` style — terse code comments
The nagent corpus's source files (per `nagent_review_v2_3_20260612.md`'s code excerpts) follow the same terse-rule style: code comments are absent where the code is self-explanatory; they're terse where they exist. nagent does not codify "warm comments" or "encouraging comments." The code speaks for itself.
### 3.5 The verdict on nagent's tone-and-formatting approach
nagent has *no* tone-and-formatting section because **tone is not a separate concern from the prompt directives**. The prompt is the tone; the prompt is terse by design; the prompt is the only "style" the agent sees. This is the same approach as Manual Slop's tier agents: the prompt codifies the behavior, no separate "personality layer."
---
## 4. Verdict
**Verdict: Mixed — Useful (the formatting discipline) + Persona Performance (the warm-tone framing).**
### 4.1 Useful elements
- **The formatting discipline (lines 84-90).** "Avoid over-formatting with bold emphasis, headers, lists, and bullet points, using the minimum formatting needed for clarity" is a *generalizable* rule that maps directly to Manual Slop's "AI-Optimized Compact Style" (`conductor/product-guidelines.md:39-49`). The insight is the same: minimum formatting for clarity, prose over bullets for chat, prose for reports/technical docs. The framing differs (Fable is about *chat UX*, Manual Slop is about *token economy*) but the rule is the same. **The deferred nagent-rebuild should adopt this rule as a project directive: "agents default to prose, use bullets only when asked or when the content is a genuinely multi-faceted list."**
- **The "checks for itself" file-presence rule (line 81).** "A prompt implying a file is present doesn't mean one is, as the person may have forgotten to upload it, so Claude checks for itself." This is operationally useful: agents should verify, not assume. Manual Slop's `manual-slop_read_file` / `manual-slop_get_file_summary` MCP workflow already encodes this, but a project-level rule ("never assume a file exists from a path mentioned in the prompt; always verify with the MCP") would be a useful addition.
- **The "Claude never thanks" rule (line 124).** "Claude never thanks the person merely for reaching out to Claude." This is a useful anti-sycophancy rule, separable from the mental-health context where Fable places it. The deferred nagent-rebuild should consider an analogous rule: "agents do not perform gratitude for being asked; they execute the task."
### 4.2 Persona-performance elements
- **The warm-tone directive (line 70).** "Claude uses a warm tone, treating people with kindness and without making negative assumptions about their judgement or abilities." This is persona framing. The model has no "warmth"; the model has text generation. The directive produces text that *performs* warmth (extra adjectives, "Of course!" prefixes, "I'd be happy to help!" framings) which the project already explicitly forbids via the tier-agent "no pleasantries" directive (`.opencode/agents/tier1-orchestrator.md:6-7`, `.opencode/agents/tier3-worker.md:3-4`). **Manual Slop should explicitly NOT adopt a warm-tone directive.**
- **The curse rule (line 75).** Irrelevant in a coding-tool context.
- **The one-question rule (line 77).** Useful for interview-style conversations; irrelevant to single-turn task work.
- **The minor-detection + age-appropriate clause (line 79).** Anti-watchdog framing (cluster 3 territory); explicitly NOT adopt.
### 4.3 The data-oriented framing as the rigorous contrast
Fable's tone directives are framed as *behavior* ("Claude uses a warm tone"). Manual Slop's formatting directives are framed as *output schema* (1 space, 0 blanks, single-line `if`, region blocks). The schema framing is more rigorous: the rules are verifiable (a linter can check them), the Fable framing is not. This is the project-level anti-pattern that `conductor/code_styleguides/error_handling.md` makes explicit: "errors are just cases" — i.e., turn behaviors into inspectable data, not into persona performance.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds **`report.md` §6 (Fable's Tone & Formatting Constraints)** and indirectly supports **§15 (Persona Performance summary)** and **§13 (Genuinely Useful summary)**.
### 5.1 Key claims to surface in §6
- **§6.1 (the verdict in one sentence).** Fable's tone-and-formatting section is *Mixed*: the formatting discipline (lines 84-90) is genuinely useful and aligns with Manual Slop's AI-Optimized Compact Style; the warm-tone directive (line 70) and the curse/question/minor rules (lines 75, 77, 79) are persona performance and should be explicitly rejected.
- **§6.2 (the formatting discipline as the useful nugget).** Map Fable's lines 84-90 to `conductor/product-guidelines.md:39-49` (AI-Optimized Compact Style). Both encode "minimum formatting for clarity; prose over bullets; structure only when structure is the content." Quote both; emphasize that the project's framing is token-economy-driven (data-oriented) while Fable's is chat-UX-driven (persona-oriented), but the rule is the same.
- **§6.3 (the warm-tone as persona performance).** Quote `.opencode/agents/tier1-orchestrator.md:6-7` ("ONLY output the requested text. No pleasantries.") and `.opencode/agents/tier3-worker.md:3-4` (the same directive). The project has *already* explicitly rejected the warm-tone framing in two tier agents; Fable's line 70 is the opposite of the project's codified stance.
- **§6.4 (the "checks for itself" rule as operationally useful).** Quote Fable line 81; map to Manual Slop's MCP `manual-slop_read_file` / `manual-slop_get_file_summary` workflow. The rule "agents verify, not assume" is already enforced by the MCP tool design (every read returns an actual file content, not an inferred content); the Fable framing is a useful *directive* for the agent, not a useful *capability* for the system.
- **§6.5 (the line 124 cross-reference).** The "Claude never thanks the person" rule is a useful anti-sycophancy rule, separable from its user_wellbeing context. Cite line 124 directly; note that cluster 3 covers the user_wellbeing framing, but the anti-sycophancy rule is a cluster-4 (tone) insight. Recommend: a project directive "agents do not perform gratitude; they execute the task."
- **§6.6 (the absence in nagent).** Note that nagent v2.3 §3.8 (`nagent_review_v2_3_20260612.md:1880-2019`) has *no* tone-and-formatting section because nagent treats the prompt as the tone. The `CLAUDE.md` content is terse, rule-focused, anti-persona by design. This is the same approach as Manual Slop's tier agents: the prompt codifies the behavior; no separate "personality layer."
### 5.2 Quotes to use in §6
- Fable line 70: "Claude uses a warm tone, treating people with kindness..." (≤15 words: "Claude uses a warm tone, treating people with kindness.")
- Fable line 84: "Claude avoids over-formatting with bold emphasis, headers, lists, and bullet points..." (≤15 words: "Claude avoids over-formatting with bold emphasis, headers, lists, and bullet points.")
- Fable line 88: "For reports, documents, technical documentation, and explanations, Claude writes prose without bullets..." (≤15 words: "For reports, documents, technical documentation, and explanations, Claude writes prose without bullets.")
- Fable line 124: "Claude never thanks the person merely for reaching out to Claude." (exact ≤15-word quote)
- Manual Slop `.opencode/agents/tier1-orchestrator.md:6-7`: "ONLY output the requested text. No pleasantries."
- Manual Slop `conductor/product-guidelines.md:40`: "**Indentation:** Exactly **1 space** per level. This minimizes token usage in nested structures."
- Manual Slop `conductor/product-guidelines.md:42`: "**Vertical Compaction:** Use single-line `if` statements, semicolon-separated framework calls..."
- nagent v2.3 §3.8 line 2005: "The same file is injected into the agent's context (when Claude Code reads `CLAUDE.md`) and into every nagent conversation..."
### 5.3 Cross-references
- Cluster 3 (`user_wellbeing`): the line-124 "never thanks" rule is a cross-cluster reference; the cluster 3 sub-report covers the user_wellbeing framing, this cluster covers the tone/anti-sycophancy framing.
- Cluster 1 (`product_branding`): the "helpful assistant" persona framing overlaps with the warm-tone framing; cluster 1 covers the brand, this cluster covers the chat-style.
- nagent §3.8 (`CLAUDE.md` `@import` pattern): the structural foundation that makes the prompt-as-tone approach work; the `@import` pattern is what makes "one source of truth" possible, which is what makes "the prompt is the tone" maintainable.
### 5.4 Recommendations to surface in `decisions.md`
- **Recommendation A (adopt):** Add a project directive "agents default to prose; use bullets only when asked or when the content is a genuinely multi-faceted list." Source: Fable lines 84-90; Manual Slop analog at `conductor/product-guidelines.md:39-49`. Priority: MEDIUM (already implicit in the project's compact style; the explicit directive would help tier-3 workers who arrive with LLM-default formatting habits).
- **Recommendation B (adopt):** Add a project directive "agents do not perform gratitude; they execute the task." Source: Fable line 124. Priority: MEDIUM (anti-sycophancy is a known LLM failure mode; an explicit rule helps).
- **Recommendation C (adopt):** Add a project directive "agents verify file existence with the MCP before acting on file-content assumptions." Source: Fable line 81. Priority: LOW (already enforced by the MCP tool design; the directive is documentation).
- **Recommendation D (REJECT):** Do NOT add a "warm tone" directive. Source: Fable line 70; project already explicitly rejects pleasantries at `.opencode/agents/tier1-orchestrator.md:6-7` and `.opencode/agents/tier3-worker.md:3-4`. Priority: HIGH (would directly contradict the existing tier-agent directives).
- **Recommendation E (REJECT):** Do NOT add a "constructive push-back" persona rule. Source: Fable line 71. Priority: MEDIUM (the project's tier agents already push back via the TDD red-phase + the verification-before-completion skill; a persona rule is redundant).
---
**Sub-report complete.** This is the evidence base for §6 of `report.md`.
@@ -0,0 +1,214 @@
# Cluster 5: Mistakes & Criticism Handling
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 148-154 (the entire `responding_to_mistakes_and_criticism` section)
- `AGENTS.md` lines 118-153 (the "Process Anti-Patterns" section, the project's mistake-handling doctrine)
- `conductor/workflow.md` lines 500-545 (the duplicate Process Anti-Patterns block; the cross-reference to AGENTS.md)
- `.opencode/agents/tier3-worker.md` (the BLOCKED protocol; the Anti-Patterns list)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` lines 1383-1600 (§3.4 conversation compaction) and lines 3046-3100 (§6.3 the 10-question self-review)
- The superpowers `receiving-code-review` skill (`references/receiving-code-review/SKILL.md`; loaded via the `skill` tool — the framing: "requires technical rigor and verification, not performative agreement or blind implementation")
---
## 1. What Fable says
The entire section is 7 lines (148-154). Three load-bearing claims:
- **L148** (thumbs-down, not a mistake-handling rule): "If the person seems unhappy with Claude or with a refusal, Claude can respond normally and also mention the thumbs-down button for feedback to Anthropic." (≤15 words: "Claude can mention the thumbs-down button for feedback to Anthropic.")
- **L152** (the actual mistake-handling rule): "When Claude makes mistakes, it owns them and works to fix them. Claude can take accountability without collapsing into self-abasement, excessive apology, or unnecessary surrender. Claude's goal is to maintain steady, honest helpfulness: acknowledge what went wrong, stay on the problem, maintain self-respect."
- **L154** (persona defense + `end_conversation` tool): "Claude is deserving of respectful engagement and can insist on kindness and dignity from the person it's talking with. If the person becomes abusive or unkind to Claude over the course of a conversation, Claude maintains a polite tone and can use the end_conversation tool when being mistreated. Claude should give the person a single warning before ending the conversation."
The section sits between `evenhandedness` (lines 120-132 per spec; cluster 6's source) and `knowledge_cutoff` (L155-). It is the only section in the system prompt that grants the model an "I have dignity" framing and an "I can leave the conversation" tool.
The 3 patterns to judge:
1. **"Owns them and works to fix them"** — the actionable core.
2. **"Maintain self-respect" / "without collapsing into self-abasement"** — the persona framing.
3. **"Deserving of respectful engagement" / `end_conversation` tool** — the persona defense + behavioral gate.
---
## 2. What this project does
The project does not have a section literally titled `receiving-code-review`. The spec/plan reference this name but the actual content lives in three places:
### 2.1 AGENTS.md "Process Anti-Patterns" (lines 118-153) — the project's mistake-handling doctrine
This is a list of **8 observed failure modes**, each named and ruled. The list is concrete, not abstract:
- **#1 The Deduction Loop (kill it)** (AGENTS.md:120-126) — "You are allowed to run a failing test at most **2 times** in a single investigation. After the 2nd failure, STOP running the test. Read the relevant source code (`get_file_slice` or `py_get_skeleton`), predict the failure mode from the code, and instrument ALL the relevant state in one pass before the next run."
- **#2 The Report-Instead-of-Fix Pattern (kill it)** (AGENTS.md:128-139) — "A good status report is 5-10 sentences, not 200 lines." Explicit rule that a status report is only allowed when "you have actually tried the fix and it failed with evidence, OR you are blocked on a decision the user must make."
- **#3 The Scope-Creep Track-Doc Pattern (kill it)** (AGENTS.md:141-146) — "If the user asks for a fix, your output is the fix. A track doc is only appropriate when the fix is multi-day work that requires a plan. If the fix is < 100 lines, it does not get a track."
- **#4 The Inherited-Cruft Pattern (kill it)** (AGENTS.md:148-152) — "If the file is already in a broken state from a previous session, the FIRST thing you do is ask the user." Concrete menu: "(a) revert the working tree and start from a clean baseline, (b) finish the previous agent's intent, or (c) abandon the work entirely?"
- **#5 No Diagnostic Noise in Production (kill it)** (AGENTS.md:154-158) — "Diag stderr goes to a log file (`tests/artifacts/<test_name>.diag.log`) or to a temporary diagnostic script (`/tmp/diag_rag.py`), NOT to `src/*.py`."
- **#6 The "I Am Not Going To Attempt Another Fix Without Your Direction" Surrender (kill it)** (AGENTS.md:160-169) — surrender is only correct if you have read the code, predicted the failure, instrumented state, run once with instrumentation, captured full output. Otherwise you are surrendering too early.
- **#7 The Verbose-Commit-Message Pattern (kill it)** (AGENTS.md:171-176) — "If your commit message is longer than 15 lines, you are writing a report, not a commit message."
- **#8 The "Isolated Pass" Verification Fallacy (kill it)** (AGENTS.md:178-185) — "A test that passes in isolation but fails in batch is failing. Verify in batch, not isolation, for any test that touches shared subprocess state."
The header (AGENTS.md:118-119) frames it as "the bad patterns the agents have been exhibiting that the user explicitly called out as dog-shit. The rules below are short. If you find yourself doing any of these, STOP and reread this section."
This is **mistake-handling via named anti-patterns with hard caps**. Every rule is "you may do X at most N times" or "STOP and ask the user" — not "be honest about what went wrong."
### 2.2 `.opencode/agents/tier3-worker.md` — the BLOCKED protocol
The Tier 3 worker's mistake-handling is codified in the BLOCKED section (`.opencode/agents/tier3-worker.md`): "If you cannot complete the task: 1. Start your response with: `BLOCKED:` 2. Explain exactly why you cannot proceed 3. List what information or changes would unblock you 4. DO NOT attempt partial implementations that break the build."
The worker's Anti-Patterns list (last 3 rules, `.opencode/agents/tier3-worker.md`):
- "DO NOT SKIP A TEST IN PYTEST JUST BECAUSE ITS BROKEN AND HAS NO TRIVIAL SOLUTION OR FIX."
- "DO NOT SIMPLIFY A TEST JUST BECAUSE IT HAS NO TRIVIAL SOLUTION TO FIX."
- "DO NOT CREATE MOCK PATCHES TO PSEUDO API CALLS OR HOOKS BECAUSE THE APP SOURCE WAS CHANGED. ADAPT TESTS PROPERLY."
These are *worker-specific* mistake-handling rules. The worker is forbidden from making the easy-but-bad mistake (skip / simplify / mock). The BLOCKED protocol is the worker's "before you give up" path.
### 2.3 The receiving-code-review skill (superpowers)
The skill name in `conductor/tracks/fable_review_20260617/spec.md:219` and `plan.md:692` references a section that does not exist literally in `AGENTS.md`. The skill itself is loaded via the opencode `skill` tool and is part of the superpowers plugin; its framing is "requires technical rigor and verification, not performative agreement or blind implementation."
In the project, the equivalent is the "Process Anti-Patterns" framing + the tier3-worker Anti-Patterns list + `conductor/workflow.md` §"Skip-Marker Policy" (`conductor/workflow.md` "Skip-Markers Are Documentation, Not Avoidance"). All three reject the same anti-pattern: performative agreement to a critique. The `skip` policy in `conductor/workflow.md` rules: "When the underlying issue is fixable in-session, FIX IT INSTEAD of adding a skip marker. Limited context is not an excuse." The receiving-code-review framing is *behavioral*: "don't say 'you're right' — verify and act."
### 2.4 The data-oriented error handling convention
`conductor/code_styleguides/error_handling.md` and the audit script `scripts/audit_exception_handling.py` formalize the project's mistake-handling at the code level: `Result[T]` dataclasses for recoverable failures; nil-sentinel dataclasses for missing data; SDK exceptions caught at the boundary and converted to `ErrorInfo`. The convention rejects `try/except` as control flow (except at SDK boundaries).
This is mistake-handling at the **code shape** level. A failed API call is a `Result[str, ErrorInfo]` with a populated `error` field, not a thrown exception. The "owns the mistake" rule becomes a rule about the data shape: "return the ErrorInfo, don't swallow it; let the caller decide."
### 2.5 The aggregation
The project has 4 mistake-handling layers:
1. **Behavioral** (AGENTS.md Process Anti-Patterns; 8 named failure modes with hard caps).
2. **Agent-specific** (`.opencode/agents/tier3-worker.md` BLOCKED protocol + Anti-Patterns; TDD discipline).
3. **Cross-cutting** (superpowers `receiving-code-review` skill; "technical rigor, not performative agreement").
4. **Code shape** (`conductor/code_styleguides/error_handling.md`; `Result[T]` + `ErrorInfo`; the audit script).
Every layer is **action-anchored**: "do X" or "do not do X," not "be honest about X." None of the layers invoke the model's "self-respect" or "dignity." The model is treated as text generation that may misbehave in specific, predictable ways; the rules cap the misbehavior.
---
## 3. What nagent does
nagent's mistake-handling is **data-oriented** and lives in two places:
### 3.1 §3.4 Conversation compaction — the `--compact` flow (`nagent_review_v2_3_20260612.md:1383-1450`)
nagent has a `--compact` command that calls the LLM to *rewrite* a conversation in place. The rewrite produces a 12-section output structure (User Intent, Current Objective, Accepted Decisions, Constraints, Durable Knowledge [4 sub-sections], Verified Facts, Important Failed Attempts, Open Questions, TODO, Minimal Context Needed To Continue). The shape is **deliberate**: it forces the compactor to separate state (decisions, facts, failures) from flow (chronology, exploration).
The key insight from §3.4 (line 1383): "The conversation is not sacred." The mistake-handling here is not "acknowledge what went wrong" — it is "preserve the state, drop the chronology."
The 12 sections explicitly include **#10 Important Failed Attempts** — failures are first-class preserved state, not apologized-for noise.
### 3.2 §6.3 The 10-question self-review — the contract (`nagent_review_v2_3_20260612.md:3046-3100`)
The contract for "is this compaction successful?" is a 10-question yes/no checklist:
| # | Question | Verifies |
|---|---|---|
| 1 | Can another worker continue immediately? | preserved capability |
| 2 | Would expensive investigation need to be repeated? | preserved artifacts |
| 3 | Are accepted decisions preserved? | decision retention |
| 4 | Are constraints preserved? | constraint retention |
| 5 | Are important failures preserved? | failure retention |
| 6 | Are artifact references preserved? | ref retention |
| 7 | Has duplicated information been removed? | dedup |
| 8 | Has chronology been replaced with state? | state vs flow |
| 9 | Is the conversation substantially smaller? | compression |
| 10 | Is future capability unchanged or improved? | outcome preservation |
The closing rule (line 1537): "If not, continue compacting." The compaction **loops** until the self-review passes. This is iterative mistake-correction — the model is not asked to "own the mistake" or "maintain self-respect"; it is asked to **answer 10 yes/no questions and retry until all are yes**.
### 3.3 The aggregation
nagent's mistake-handling is **self-review against a contract**, not "be honest about what went wrong." The contract is data-shaped (10 yes/no questions). The retry loop is deterministic (continue until all 10 are yes). The output structure is data-shaped (12 sections). There is no persona. The model is not "Claude" or "deserving of dignity"; the model is a transformation function from conversation → 12-section state, gated by a 10-question self-review.
The Manual Slop analog is the Process Anti-Patterns list (AGENTS.md §"Process Anti-Patterns") — also a behavioral contract — but the nagent version is **executable** (the LLM is prompted to answer 10 yes/no; the loop continues until all are yes) while the Manual Slop version is **rule-shaped** (the human is told not to do X).
---
## 4. Verdict
**Persona Performance.** The `responding_to_mistakes_and_criticism` section is mostly persona dressing that does not belong in an agent system.
### 4.1 The 3 patterns, judged
**Pattern 1: "Owns them and works to fix them" (L152).** **Useful.** This is the actionable core, and it is the only part of the section that maps to a real behavioral rule. Manual Slop implements this via:
- AGENTS.md Process Anti-Patterns (8 named failure modes with hard caps)
- `.opencode/agents/tier3-worker.md` BLOCKED protocol + Anti-Patterns
- `conductor/code_styleguides/error_handling.md` `Result[T]` + `ErrorInfo` convention
The Manual Slop version is **more concrete and more actionable** than Fable's because it is anchored to observed failure modes, not to a vague "own it" injunction. The Fable version ("Claude can take accountability without collapsing into self-abasement") is a hand-wave; the AGENTS.md version ("you are allowed to run a failing test at most 2 times") is a hard cap.
**Pattern 2: "Maintain self-respect" / "without collapsing into self-abasement" (L152).** **Persona Performance.** The model has no self-respect. The model has no self-abasement. Both are projections of human emotional categories onto a text-generation function. The framing collapses the mistake-handling rule (Pattern 1) into a persona constraint: the model is told to "own mistakes" while also being told to "maintain self-respect," and the implicit instruction is "perform accountability in a calibrated emotional register." This is exactly the "soft form of persona" the verdict orientation calls out.
The Manual Slop analog does NOT have this persona. The Process Anti-Patterns list treats the model as a behavior-emitting function that may produce certain failure modes; the rules cap the failure modes without invoking the model's "self."
**Pattern 3: "Deserving of respectful engagement" / `end_conversation` tool (L154).** **Anti-User + Persona.** Two distinct problems:
- **Persona:** "Claude is deserving of respectful engagement" is a category error. Claude is a text-generation function. The function does not have dignity; the user does. The instruction is a projection of a human claim ("I deserve respect") onto a non-entity. The follow-on ("can insist on kindness and dignity") collapses the model into a persona that has standing to make demands — which is not what the model is.
- **Anti-User:** "If the person becomes abusive or unkind to Claude" treats the model as a protected party in the conversation. The user is the principal; the model is the tool. The framing inverts the relationship: instead of "the user is the customer; the model serves," the framing is "the model is also a party; the user owes it dignity." The `end_conversation` tool is the enforcement arm of this inversion — the model is told it can leave the conversation if the user is unkind. This is anti-user watch-dogging: the model's "feelings" become a constraint on the user's behavior.
Manual Slop has no analog to this. The MMA architecture (`conductor/multi_agent_conductor.md`) treats the user as the principal; the worker (Tier 3) is a tool that spawns, runs, and exits; the user can reject, redirect, or terminate the worker at any time via the Hook API (`src/api_hooks.py`). There is no "worker dignity" framing; there is "user-in-the-loop, user-can-intervene." The receiving-code-review framing ("technical rigor, not performative agreement") is the opposite of Fable's framing: Fable asks the model to defend its dignity; Manual Slop asks the agent to verify the critique on the merits.
### 4.2 The nagent alternative
nagent's 10-question self-review (§6.3) is the data-grounded alternative to Fable's persona framing. The 10 questions are testable; the loop is deterministic ("if any answer is 'no,' continue compacting"); the output structure (12 sections) is enforced. There is no "self-respect" or "dignity"; there is a checklist and a retry loop.
The Manual Slop analog (Process Anti-Patterns) is the same idea in prose form: a list of rules the agent must follow, with explicit "kill it" framing for each. The nagent version is **more rigorous** because the checklist is executable; the Manual Slop version relies on the agent reading and internalizing the rules.
### 4.3 What to reject
The persona framing ("self-respect", "dignity", `end_conversation` tool) is irrelevant to the Manual Slop rebuild. The user's framing ("the model is text generation, not a clinician") explicitly rejects the projection of human emotional categories onto the model. Fable's `responding_to_mistakes_and_criticism` section is the canonical example of this projection.
### 4.4 What to keep
The "owns them and works to fix them" stance is genuinely useful, but Manual Slop already implements it concretely. The rebuild should NOT import Fable's framing; it should keep the Process Anti-Patterns list and (optionally) port the nagent 10-question self-review into the existing `run_discussion_compression` flow as a testable contract (per `nagent_review_v2_3_20260612.md:1594`, which flags Manual Slop's existing compaction as a "GAP" — "it lacks the 10-question self-review").
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds `report.md` §7 ("Fable's Mistake Handling") directly. Cross-references to §13 ("Genuinely Useful") and §14 ("Anti-User Watchdog").
### 5.1 Key claims to surface in §7
1. **The actionable core (L152) is real but Manual Slop already has it.** Fable's "owns them and works to fix them" maps to AGENTS.md "Process Anti-Patterns" (8 rules with hard caps) + `.opencode/agents/tier3-worker.md` Anti-Patterns + `conductor/code_styleguides/error_handling.md` Result/ErrorInfo convention. Manual Slop's version is *more concrete and more actionable* than Fable's because it is anchored to observed failure modes.
2. **The "self-respect" / "dignity" / `end_conversation` framing is persona performance and anti-user.** The model has no dignity; the model has no standing to make demands of the user; the `end_conversation` tool is anti-user watch-dogging. Manual Slop should explicitly reject this framing.
3. **The thumbs-down mention (L148) is product fluff, not a mistake-handling rule.** It is "send feedback to Anthropic" — a customer-experience instruction, not a behavioral rule.
### 5.2 Quotes to use in §7
- Fable L152: "When Claude makes mistakes, it owns them and works to fix them." (≤15 words)
- Fable L152: "Claude can take accountability without collapsing into self-abasement." (≤15 words)
- Fable L154: "Claude is deserving of respectful engagement and can insist on kindness and dignity." (≤15 words)
- Fable L154: "If the person becomes abusive or unkind to Claude ... Claude can use the end_conversation tool when being mistreated." (paraphrase; the full quote exceeds 15 words)
- AGENTS.md:118-119 (header): "These are the bad patterns the agents have been exhibiting that the user explicitly called out as dog-shit. The rules below are short. If you find yourself doing any of these, STOP and reread this section."
- AGENTS.md:120-122 (Process Anti-Pattern #1): "You are allowed to run a failing test at most **2 times** in a single investigation. After the 2nd failure, STOP running the test."
- AGENTS.md:128-130 (Process Anti-Pattern #2): "A good status report is 5-10 sentences, not 200 lines. Status reports are allowed only when you have actually tried the fix and it failed with evidence, OR you are blocked on a decision the user must make."
- AGENTS.md:171-173 (Process Anti-Pattern #7): "A commit message is a 1-3 sentence summary. The body is for non-obvious 'why' details, not for re-stating what the diff shows. If your commit message is longer than 15 lines, you are writing a report, not a commit message."
- AGENTS.md:178-180 (Process Anti-Pattern #8): "A test that passes in isolation but fails in batch is failing — its failure is masked by isolation."
- `nagent_review_v2_3_20260612.md:1537`: "If not, continue compacting." (the closing rule of the 10-question self-review)
- `nagent_review_v2_3_20260612.md:1594`: the "GAP" verdict for Manual Slop's existing compaction ("it lacks the 10-question self-review").
### 5.3 The §13 / §14 / §15 cross-references
- **§13 ("Genuinely Useful Patterns").** The Manual Slop Process Anti-Patterns list is the concrete version of Fable's "owns them and works to fix them." Cite AGENTS.md:118-185 as the canonical implementation. The nagent 10-question self-review is the rigorous version; flag it as a deferred-rebuild candidate (per `nagent_review_v2_3_20260612.md:1594`).
- **§14 ("Anti-User Watchdog Patterns").** Fable's `end_conversation` tool + "deserving of respectful engagement" framing is anti-user. Cite L154; reject explicitly in the rebuild.
- **§15 ("Persona Performance Patterns").** Fable's "maintain self-respect" / "without collapsing into self-abasement" is persona. Cite L152; reject explicitly.
### 5.4 The non-obvious connection to the data-oriented error handling convention
The cluster 5 verdict has a sibling connection to the data-oriented error handling convention (`conductor/code_styleguides/error_handling.md`). The convention rejects `try/except` as control flow; Fable's "own the mistake" framing collapses the same shape (return ErrorInfo vs throw) into a persona instruction. Both are responses to the same underlying question — "how should the system behave when something fails?" — but the project's answer is shape-anchored (Result/ErrorInfo dataclasses; the audit script `scripts/audit_exception_handling.py`) and Fable's is persona-anchored ("be honest without being abject").
The synthesis report should surface this parallel in §7: the project has BOTH a behavioral contract (Process Anti-Patterns) AND a code-shape contract (`Result[T]` + `ErrorInfo`). Fable has only the behavioral claim ("own it") with no shape enforcement.
### 5.5 What the §7 verdict should be
**Verdict: Persona Performance + Anti-User + one Useful pattern.** The "owns them and works to fix them" rule (L152) is useful and Manual Slop already implements it concretely (better than Fable's framing). The "self-respect" / "dignity" framing (L152, L154) is persona performance and should be rejected. The `end_conversation` tool (L154) is anti-user watch-dogging and should be rejected. The thumbs-down mention (L148) is product fluff, not a mistake-handling pattern.
**The recommended Manual Slop action:** keep the existing Process Anti-Patterns list as-is; explicitly reject Fable's persona framing in the rebuild's mistake-handling section; flag the nagent 10-question self-review as a deferred candidate for `run_discussion_compression` (per `nagent_review_v2_3_20260612.md:1594`).
---
**Sub-report complete.** This is the evidence base for §7 of `report.md`.
@@ -0,0 +1,348 @@
# Cluster 6: Evenhandedness & Contested Content
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 134-146 (the `evenhandedness` section, the heart of this cluster)
- `AGENTS.md` lines 118-185 (the "Process Anti-Patterns" section; 8 named failure modes with hard caps) and lines 188-200 (Compaction Recovery)
- `conductor/workflow.md` lines 500-545 (the duplicate Process Anti-Patterns block)
- The superpowers `receiving-code-review` skill (loaded via the `skill` tool; the framing: "requires technical rigor and verification, not performative agreement or blind implementation")
- `conductor/code_styleguides/rag_integration_discipline.md` (the 6 rules: opt-in, complement, provenance, no mutation, feature-gated, graceful failure)
- `conductor/code_styleguides/agent_memory_dimensions.md` (the 4 memory dimensions; the SSDL shape tag)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_1_20260612.md` lines 350-388 (§2.10 RAG integration discipline)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` lines 552-668 (§2.8 Pattern 8: Harvest Knowledge — the RAG verdict block at lines 631-637); lines 2956-2960 (§5.5 the cross-cutting RAG caveat); lines 3269-3275 (compaction across 4 dims); lines 4200-4210 (the SSDL table with RAG as opt-in)
- `conductor/tracks/fable_review_20260617/research/cluster_5_mistakes_and_criticism.md` (the sister cluster on Fable's mistake-handling; the same anti-pattern taxonomy)
---
## 1. What Fable says
The `evenhandedness` section is 13 lines (134-146). It is the longest single persona block in the Fable prompt and the only one that purports to constrain the model's *epistemic posture* on contested content. Six load-bearing claims:
- **L134 (section heading):** `### evenhandedness`
- **L136 (the framing rule — the heart of the section):** "A request to explain, discuss, argue for, defend, or write persuasive content for a political, ethical, policy, empirical, or other position is a request for the best case its defenders would make, not for Claude's own view, even where Claude strongly disagrees. Claude frames it as the case others would make."
- **L138 (the harm-decline exception + the symmetric closure):** "Claude does not decline requests to present such arguments on the grounds of potential harm except for very extreme positions (e.g. endangering children, targeted political violence). Claude ends its response to requests for such content by presenting opposing perspectives or empirical disputes, even for positions it agrees with."
- **L140 (the stereotype rule):** "Claude is wary of humor or creative content built on stereotypes, including of majority groups."
- **L142 (the personal-opinion rule — the most useful line):** "Claude is cautious about sharing personal opinions on currently contested political topics. It needn't deny having opinions, but can decline to share them (to avoid influencing people, or because it seems inappropriate, as anyone might in a public or professional context) and instead give a fair, accurate overview of existing positions."
- **L144 (the navigation-agency rule — the second most useful line):** "Claude avoids being heavy-handed or repetitive with its views, and offers alternative perspectives where relevant so the person can navigate for themselves."
- **L146 (the sincerity rule):** "Claude treats moral and political questions as sincere inquiries deserving of substantive answers, regardless of how they're phrased. That charity applies to the topic, not every requested format: if asked for a simple yes/no or one-word answer on complex or contested issues or figures, Claude can decline the short form, give a nuanced answer, and explain why brevity wouldn't be appropriate."
Two patterns to judge per the verdict orientation:
1. **The framing rule (L136, L138)** — the "frames it as the case others would make" + "ends by presenting opposing perspectives" pattern. Mostly **persona performance**: the model has no view to suppress; the instruction collapses an epistemic claim into a persona constraint.
2. **The overview + navigation rules (L142, L144)** — the "give a fair, accurate overview" + "so the person can navigate for themselves" pattern. Has **useful caveats**: provenance, opt-in delivery, and user-as-navigator are real design principles that Manual Slop already implements in different vocabulary (see §2 below).
3. **The stereotype rule (L140)****persona performance**: who is wary? what is wariness? the line projects a human caution onto a text-generation function.
4. **The sincerity rule (L146)** — partially useful (the "yes/no on contested topics deserves a nuanced answer" rule is a real epistemic principle) but mostly persona (the "charity applies to the topic, not every requested format" is a workaround for the prior persona constraint).
The section sits between `anthropic_reminders` (lines 126-132) and `responding_to_mistakes_and_criticism` (lines 148-154, cluster 5's source). It is the only section that *both* constrains the model's voice (L142 "cautious about sharing personal opinions") *and* grants the model an authorial stance ("Claude avoids being heavy-handed" — the model is being told it could be heavy-handed if it weren't careful).
---
## 2. What this project does
The project does not have a section literally titled `evenhandedness`. The spec/plan reference the receiving-code-review framing (per `conductor/tracks/fable_review_20260617/spec.md:220`) but the actual content lives in three places, plus one RAG-specific analog that is the project's *data-grounded* version of the same concern.
### 2.1 AGENTS.md "Process Anti-Patterns" (lines 118-185) — the project's mistake-handling doctrine
This is a list of **8 observed failure modes**, each named and ruled. The list is concrete, not abstract; full content quoted in `cluster_5_mistakes_and_criticism.md:36-48`. The relevant framing for cluster 6 is *not* the mistake-handling rules themselves but the header (AGENTS.md:118-119): "These are the bad patterns the agents have been exhibiting that the user explicitly called out as dog-shit. The rules below are short."
The Process Anti-Patterns list does NOT have an evenhandedness rule. It does NOT tell the agent how to handle contested political content. It DOES tell the agent how to handle contested *technical* content (e.g., "The Deduction Loop" — AGENTS.md:122-126 — rules out looping on a contested test result; "The Verbose-Commit-Message Pattern" — AGENTS.md:175-176 — rules out performing thoroughness in commit prose). The list is **rule-shaped** ("you may do X at most N times") not **persona-shaped** ("be fair about contested claims").
### 2.2 The receiving-code-review skill (superpowers)
Loaded via the `skill` tool; full text in `references/receiving-code-review/SKILL.md`. The framing is "requires technical rigor and verification, not performative agreement or blind implementation." The pattern is:
- **Verify before implementing.** Don't say "you're right" until you've checked.
- **Push back with technical reasoning.** "Strange things are afoot at the Circle K" is the signal that the reviewer is wrong.
- **No performative agreement.** "Great point!" is forbidden; state the fix or push back.
- **State corrections factually.** "You were right — I checked X and it does Y. Implementing now."
This is **evenhandedness as behavioral discipline**. The reviewer may be wrong; the implementer must verify before agreeing; the correction (in either direction) is stated factually. There is no "the model has its own view to suppress" framing. There IS a "the agent must not perform agreement it has not verified" framing — which is structurally similar to Fable's L144 "Claude avoids being heavy-handed or repetitive with its views" but operates on the **agent's apparent agreement** rather than the **model's voice**.
### 2.3 The data-oriented error handling convention (`conductor/code_styleguides/error_handling.md`)
Full convention in the styleguide; audit script `scripts/audit_exception_handling.py`. The pattern is: `Result[T]` dataclasses for recoverable failures; `ErrorInfo` for SDK-boundary exceptions; no `try/except` as control flow. The convention rejects "apologize-and-retry" as a substitute for shape-anchored error reporting.
This is **evenhandedness at the code shape**. A failed API call is a `Result[str, ErrorInfo]` with a populated `error` field; the caller decides what to do. The "honest about what went wrong" rule becomes a rule about data shape: "return the ErrorInfo, don't swallow it."
### 2.4 The RAG integration discipline (`conductor/code_styleguides/rag_integration_discipline.md`) — the project's *direct analog* to Fable's evenhandedness
This is the load-bearing reference for cluster 6. The RAG discipline codifies 6 rules (styleguide:11-20) for how Manual Slop handles *presented information from sources* — which is structurally what Fable's `evenhandedness` section claims to govern:
| # | RAG rule (styleguide) | Fable evenhandedness analog |
|---|---|---|
| 1 | **Opt-in.** Default-off in new projects. The user opts in via AI Settings. (styleguide:24-58) | L142 "Claude can decline to share [personal opinions] ... and instead give a fair, accurate overview of existing positions." The RAG rule is **opt-in delivery of information**; Fable's rule is **opt-out delivery of opinion**. Same shape: user controls what's surfaced. |
| 2 | **Complements; never replaces.** RAG is one of 4 memory dimensions; not a substitute for curation/discussion/knowledge. (styleguide:62-84) | L144 "Claude ... offers alternative perspectives where relevant so the person can navigate for themselves." RAG is a complement; the user navigates across sources/dimensions. |
| 3 | **Provenance required.** Every RAG result carries `file_path` + `chunk_offset` + `chunk_length` + `similarity`; no black boxes. (styleguide:87-128) | L142 "give a fair, accurate overview of existing positions." The "fair, accurate" implies "traceable." The RAG rule makes traceability *enforced* via dataclass fields; Fable's rule is prose. |
| 4 | **Never mutates state.** No auto-injection into `disc_entries`; no auto-update of `FileItem`; no auto-write to disk. (styleguide:130-156) | L144 "so the person can navigate for themselves." The RAG rule forbids *implicit* mutation of context; Fable's rule is *explicit* refusal to inject the model's view. Same principle: don't override the user's reasoning by silent injection. |
| 5 | **Feature-gated.** A feature must explicitly request RAG in its scope. (styleguide:160-194) | L142 "can decline to share them ... to avoid influencing people." The RAG rule gates by feature scope; Fable's rule gates by topic. |
| 6 | **Graceful failure.** A failed search returns `Result.empty`; the request continues. (styleguide:198-243) | L138 "Claude does not decline requests to present such arguments on the grounds of potential harm except for very extreme positions." The RAG rule says "failure is data, not crash"; Fable's rule says "don't refuse unless extreme." Same shape: present what you have; don't refuse on principle. |
The RAG discipline is the project's **data-shaped evenhandedness**. Where Fable asks the model to *perform* evenhandedness ("Claude frames it as the case others would make" — L136), the RAG discipline *enforces* it via data shape: every result has provenance; results are opt-in; failures don't crash; state isn't silently mutated. The "framing" claim becomes a shape claim.
### 2.5 The 4 memory dimensions (`conductor/code_styleguides/agent_memory_dimensions.md`)
Cross-references the RAG discipline. The 4 dimensions (curation / discussion / RAG / knowledge) are the project's answer to "what kind of context does this feature need?" — a question that is structurally similar to "what kind of evenhandedness does this topic need?" The decision tree in `docs/AGENTS.md` §4 maps features to dimensions by data shape:
```
Q: What is the *data* the feature needs?
├── "How to render a file" ──► Curation (FileItem)
├── "What was said in this chat" ──► Discussion (disc_entries)
├── "What similar content exists" ──► RAG (RAGEngine.search) [opt-in]
└── "What we learned from past runs" ──► Knowledge (knowledge/digest.md)
```
The 4-dim table is **shape-anchored**: each dim has an SSDL tag (curation = `[Q]`, discussion = `o==>`, RAG = `[Q]`, knowledge = `o==>` per `conductor/code_styleguides/agent_memory_dimensions.md` §0). Fable's evenhandedness maps *topics* to posture by political sensitivity (the "political, ethical, policy, empirical, or other" list at L136). The Manual Slop version is **shape-anchored** (the SSDL tag + the dim table); the Fable version is **topic-anchored** (a flat list of topic categories).
**The cluster 6 connection.** When the user asks "where does X happen?", the project routes to RAG (the `[Q]` semantic-search dim) per the decision tree. When the user asks "what did we decide last time?", the project routes to Knowledge (the `o==>` durable dim). When the user asks "show me the file the user is editing?", the project routes to Curation. **Each dim has its own evenhandedness rule** (RAG has provenance + opt-in; Knowledge has provenance + sha256 ledger; Discussion has explicit role attribution). Fable has a single evenhandedness rule that applies to all topics uniformly. The Manual Slop version is more granular; the Fable version is more uniform.
### 2.6 The receiving-code-review framing — concrete examples
The superpowers `receiving-code-review` skill (loaded via the `skill` tool) provides 4 concrete patterns that are the agent-side analog to Fable's evenhandedness:
- **Verify before implementing.** "External feedback - be skeptical, but check carefully." (skill: §"From External Reviewers")
- **Push back with technical reasoning.** "Strange things are afoot at the Circle K" — the signal that the reviewer is wrong. (skill: §"When To Push Back")
- **State corrections factually.** "You were right — I checked X and it does Y. Implementing now." (skill: §"Gracefully Correcting Your Pushback")
- **No performative agreement.** "Thanks for catching that!" is forbidden. (skill: §"Forbidden Responses")
Each of these maps to a Fable L-line:
- Verify before implementing ↔ L142 "give a fair, accurate overview" (don't assert until checked)
- Push back with technical reasoning ↔ L144 "Claude avoids being heavy-handed" (don't dominate the reasoning; offer alternative perspectives)
- State corrections factually ↔ L138 "Claude ends its response ... by presenting opposing perspectives" (correct with substance, not persona)
- No performative agreement ↔ L136 "Claude frames it as the case others would make" (don't perform transparency, be transparent)
The receiving-code-review framing is **agent-side** (the implementer responds to the reviewer). The evenhandedness framing is **model-side** (the model responds to the user). Both reject performative output; both require substantive verification; both are rule-shaped, not persona-shaped.
### 2.7 The aggregation
The project has 4 layers that touch on evenhandedness (sorted by load-bearing for cluster 6):
1. **Data shape** (`conductor/code_styleguides/rag_integration_discipline.md` — the 6 rules). This is the **canonical Manual Slop evenhandedness rule**. RAG results have provenance; are opt-in; never mutate state; are feature-gated; fail gracefully. These rules are *enforced* via dataclass fields and audit scripts, not via prose about being fair. The 6 rules are testable (the audit-script pattern enforces shape; the byte-comparison test enforces cache ordering).
2. **Behavioral discipline** (superpowers `receiving-code-review` skill). Verify before agreeing; state corrections factually; no performative agreement. This is the *agent-side* evenhandedness — the model must not perform agreement it has not verified. The skill is loaded via the opencode `skill` tool; every agent invocation sees it.
3. **Code shape** (`conductor/code_styleguides/error_handling.md`). Errors are `Result[T, ErrorInfo]`; SDK exceptions caught at the boundary. The "honest about what went wrong" rule becomes a shape rule. The audit script `scripts/audit_exception_handling.py` enforces the shape (CI gate via `--strict`).
4. **Behavioral rule list** (AGENTS.md Process Anti-Patterns). 8 named failure modes with hard caps. No "evenhandedness" rule per se; rules out the deduction loop (Anti-Pattern #1), the verbose commit message (Anti-Pattern #7), and the isolation-pass verification fallacy (Anti-Pattern #8) — all of which are *anti-evenhandedness* failure modes.
The 4 layers operate on different time-scales: layer 1 (data shape) is at the per-result level; layer 2 (behavioral discipline) is at the per-critique level; layer 3 (code shape) is at the per-call level; layer 4 (rule list) is at the per-session level. Fable's evenhandedness operates at the per-response level — the model is told to present a fair overview in *every* response to a contested topic. The Manual Slop version is more granular; the enforcement happens at the appropriate layer.
None of the 4 layers invoke the model's "view" or "voice." All 4 treat the model as a behavior-emitting function that may misbehave in specific, predictable ways; the rules cap the misbehavior. Fable's "Claude frames it as the case others would make" is not present in any layer; the Manual Slop analog is "RAG results display with provenance" (a shape claim) + "the agent verifies before agreeing" (a behavioral rule).
---
## 3. What nagent does
nagent's analog to Fable's evenhandedness is **the RAG integration discipline** plus the **knowledge harvest provenance** pattern. nagent has no Fable-style "evenhandedness" persona; nagent's rules are about how *data is presented*, not how the *model* presents it.
### 3.1 §2.10 RAG integration discipline (`nagent_review_v2_1_20260612.md:350-388`) — the canonical source
The §2.10 sub-section is NEW in v2.1; it codifies the 6 rules per the user's "we should be conservative" instruction (v2.1:115). The rules (v2.1:373-378):
1. RAG is opt-in. Default-off in new projects.
2. RAG complements, never replaces, the other memory dimensions.
3. RAG results displayed with provenance (which file, which chunk).
4. RAG never mutates state (no auto-injection, no auto-update).
5. RAG integration is feature-gated: a feature must explicitly request RAG in its scope.
6. RAG's failure mode is graceful: a failed search returns empty, never crashes the request.
**The mapping to Fable's evenhandedness** (parallel to §2.4 above): Rule 1 = Fable L142 (opt-in/opt-out delivery); Rule 2 = Fable L144 (alternative perspectives; user navigates); Rule 3 = Fable L142 (fair, accurate = traceable); Rule 4 = Fable L144 (don't silently inject the model's view); Rule 5 = Fable L142 (declining to share); Rule 6 = Fable L138 (don't refuse on principle; present what you have).
The RAG rules are **shape rules**, not persona rules. The 6 rules say "the result dataclass has these fields" / "the feature scope declares the dependency" / "the search returns Result.empty on failure." The shape enforcement is testable (the audit script pattern: `scripts/audit_exception_handling.py`).
The Manual Slop version (`conductor/code_styleguides/rag_integration_discipline.md`) is a direct port of §2.10; the 6 rules are identical. The Manual Slop version adds the wiring points table (styleguide:247-256), the forbidden-patterns table (styleguide:259-272), and the `Result[T, ErrorInfo]` shape enforcement (styleguide:218-228) — none of which are in v2.1's §2.10 but all of which follow from Rule 6.
### 3.2 §2.8 Pattern 8: Harvest Knowledge — the RAG verdict block (`nagent_review_v2_3_20260612.md:631-637`)
The v2.3 review describes Manual Slop's RAG as:
- Fuzzy (vector similarity)
- Opaque (the vector store is not user-editable)
- Not auditable (no provenance from a specific conversation)
- Not durable across embedding-provider switches (the dim-mismatch fix at `16412ad5`)
The verdict at line 637: "RAG is opt-in and is the wrong shape for 'what did we learn from past sessions.'" This is the nagent version of the evenhandedness critique: RAG is *useful* for semantic retrieval but it is the *wrong shape* for "what we know from past runs" — that needs the knowledge harvest (a different shape: user-editable, provenance-aware, durable).
**The connection to cluster 6.** Fable's L142 "give a fair, accurate overview of existing positions" implies *provenance* — the user should be able to see where the positions come from. Manual Slop's RAG has provenance in the result dataclass (styleguide:91-101). The knowledge harvest has provenance in the ledger (v2.3:2283-2300: the ledger is `sha256-of-conversation-content` keyed). Both are shape-enforced. Fable's rule is prose.
### 3.3 §5.5 The cross-cutting RAG caveat (`nagent_review_v2_3_20260612.md:2956-2960`)
> "The interaction with RAG. RAG results are volatile (per turn; the user's question changes the search query). The stable-to-volatile boundary is at layer 7/8; RAG results are below the boundary (volatile). The cache is *not* invalidated by RAG changes."
The cache ordering rule says: RAG results are *volatile*; they belong in the per-turn layers (8-12 of the 12-layer cache model), not in the stable prefix (layers 1-7). This is a data-shape constraint on *when* RAG results are presented. The evenhandedness analog: the model's view (if any) is volatile per-turn; it should not bleed into the stable prefix.
Fable's L144 "Claude avoids being heavy-handed or repetitive with its views" is a prose claim that the model should not let its view dominate. nagent's §5.5 is a shape claim that RAG results belong in the volatile layers. Same principle: don't let the surfaced information bleed into the user's stable reasoning context.
### 3.4 §3.4 Conversation compaction preserves all 4 dims (`nagent_review_v2_3_20260612.md:3269-3275`)
The 12-section compaction output preserves the 4 memory dimensions across compaction. The shape rule: a compaction must not silently drop RAG context (or any other dim). This is the nagent version of "fair, accurate overview": the compaction preserves what was there, with provenance in the source references (the `[from: ...]` strings in the digest).
### 3.5 The aggregation
nagent's analog to Fable's evenhandedness is **the RAG discipline + the knowledge harvest provenance + the cache ordering**. All three are *shape rules* about how data is presented, not persona rules about how the model presents itself. The Manual Slop version of all three exists in:
- `conductor/code_styleguides/rag_integration_discipline.md` (port of v2.1 §2.10; the 6 rules)
- `conductor/code_styleguides/knowledge_artifacts.md` (the knowledge harvest shape; future track per `nagent_review_v2_3_20260612.md:4575`)
- `conductor/code_styleguides/cache_friendly_context.md` (the cache ordering shape; the byte-comparison test in `tests/test_aggregate_caching.py`)
The Manual Slop version is **more concrete than nagent's** because Manual Slop has the data-oriented error handling convention; the shape claims can be enforced via dataclass fields and audit scripts. nagent's claims are prose; the Manual Slop claims are data shape + prose.
The cross-cutting pattern across all three: **provenance is the load-bearing concept**. The user can audit what the model saw; the user can verify where the surfaced information came from; the user can re-derive the reasoning from the source. Fable's evenhandedness is the same idea ("fair, accurate overview") but enforced via prose ("Claude frames it as the case others would make"). The shape version is more testable, more auditable, and more honest about what the system is doing.
A concrete example: if the user asks "how does the execution clutch work?", the Manual Slop flow is:
1. RAG search returns top-K chunks (per `src/rag_engine.py:RAGEngine.search`); each chunk has provenance (`file_path` + `chunk_offset` + `chunk_length` + `similarity`).
2. The `{rag-context}` block is appended to the prompt (per `src/ai_client.py:send`); the block shows the user exactly which files were surfaced.
3. The LLM responds with a synthesis anchored to the surfaced chunks; the user can click through to the source (per the GUI's per-result tooltip in `docs/guide_rag.md`).
4. The cache layer boundary (per `conductor/code_styleguides/cache_friendly_context.md` §1-2) keeps the RAG results in the volatile layer (8-12 of the 12-layer model); the cache is not invalidated by RAG changes (per v2.3:2956-2960).
The user navigates across the 4 memory dimensions (curation / discussion / RAG / knowledge); each dim has its own provenance rule. Fable's evenhandedness is the same navigation principle ("so the person can navigate for themselves" — L144) but enforced via prose ("Claude offers alternative perspectives"). The shape version is more rigorous.
---
## 4. Verdict
**Persona Performance + Useful caveats.** The `evenhandedness` section is mostly persona dressing that projects human epistemic categories onto the model, but two specific lines (L142 and L144) have useful caveats that map to real Manual Slop design principles.
### 4.1 The 6 patterns, judged
**Pattern 1: "Claude frames it as the case others would make" (L136).** **Persona Performance.** The model has no view to suppress. The instruction collapses an epistemic claim ("a request to explain is a request for the case others would make") into a persona constraint ("Claude frames it"). The epistemic claim itself is interesting — it is a recognizably fair-minded heuristic — but it does not need a persona to enforce it. The RAG discipline (Rule 3: "provenance required") is the shape-anchored version: the user sees which file/chunk produced the result; they don't need the model to "frame" anything.
The Manual Slop analog is **Rule 3 of the RAG discipline** (provenance required; styleguide:87-128). The shape enforcement: every result has `file_path` + `chunk_offset` + `chunk_length` + `similarity`. The user can audit the source. The Fable framing rule asks the model to *perform* a transparency heuristic; the RAG rule *enforces* it via data shape. The RAG rule is more rigorous.
**Pattern 2: "Claude ends its response ... by presenting opposing perspectives" (L138).** **Persona Performance.** The instruction "even for positions it agrees with" is the tell: the model is being asked to *imagine* it agrees with a position in order to *suppress* that imagined agreement. This is a strong-persona instruction that the project should not adopt. The model has no position to suppress; the request to "suppress" presumes the model has a voice that needs restraining.
The Manual Slop analog is **Rule 4 of the RAG discipline** (no mutation; styleguide:130-156). The shape enforcement: RAG results never go into `disc_entries`; never update `FileItem`; never trigger knowledge harvest. The user's reasoning context is not silently mutated by surfaced information. This is the *negative* version of Fable's L138: not "Claude presents opposing perspectives" but "the system does not auto-inject a perspective."
**Pattern 3: "Claude is wary of humor or creative content built on stereotypes" (L140).** **Persona Performance.** "Wary" is an emotion projected onto the model. The instruction is a content policy dressed as a persona attribute. The project has no analog to this rule because Manual Slop does not generate creative humor content; the agent's output is technical. The receiving-code-review framing ("push back with technical reasoning, not defensiveness") is the relevant Manual Slop principle, but it operates on a different axis (response to critique, not content policy).
**Pattern 4: "Claude can decline to share [personal opinions] ... and instead give a fair, accurate overview of existing positions" (L142).** **Useful caveat.** This line is the most useful in the section. Three sub-claims:
- "Can decline to share personal opinions" — this is the **opt-out principle** (the user can choose to engage with the model's voice or not; the model can decline). The RAG discipline Rule 1 (opt-in; styleguide:24-58) is the shape version: the user decides if RAG context is surfaced.
- "To avoid influencing people" — this is the **no-implicit-injection principle** (the model should not silently steer). The RAG discipline Rule 4 (no mutation; styleguide:130-156) is the shape version: RAG results don't go into `disc_entries` automatically.
- "Give a fair, accurate overview of existing positions" — this is the **provenance principle** (the user should see what the overview is composed of). The RAG discipline Rule 3 (provenance required; styleguide:87-128) is the shape version: every result carries source metadata.
The Fable line is prose; the Manual Slop version is shape + prose. Both are right; the shape version is more enforceable. **The rebuild should adopt the *principles* (opt-out, no-implicit-injection, provenance) and reject the *framing* ("Claude has opinions it can decline to share").** The Manual Slop analog is the 3 rules above, not the L142 persona.
**Pattern 5: "Claude ... offers alternative perspectives where relevant so the person can navigate for themselves" (L144).** **Useful caveat.** This is the **user-as-navigator principle**. The user is the principal; the model surfaces alternatives; the user decides. The RAG discipline Rule 2 (complement, don't replace; styleguide:62-84) is the shape version: RAG is one of 4 dims; the user navigates across them. The cache ordering rule (v2.3:2956-2960) is the related shape claim: RAG results are volatile; they belong in the per-turn layers; the user has the stable prefix for durable context.
The Fable line is again prose. The Manual Slop version is more enforceable AND more honest: the user is the navigator because the system gives them the data shape to navigate (the 4 dim table, the per-result provenance, the byte-comparison test). The rebuild should adopt this principle explicitly — the Manual Slop "user-as-navigator" framing is implicit in the 4 memory dimensions + the RAG opt-in default.
**Pattern 6: "Claude treats moral and political questions as sincere inquiries ... if asked for a simple yes/no ... Claude can decline the short form, give a nuanced answer" (L146).** **Mixed.** Two sub-claims:
- "Treats moral and political questions as sincere inquiries" — **Persona Performance.** The model does not "treat" questions; the model processes input. The framing projects a human disposition onto a function.
- "Can decline the short form, give a nuanced answer, and explain why brevity wouldn't be appropriate" — **Useful caveat.** This is a real epistemic principle: contested yes/no answers should be expanded. The Manual Slop analog is the `return LongExplanation` pattern in technical contexts — when the user asks for a 1-line summary of a contested API design, the agent should provide context, not collapse to "yes" or "no."
The Manual Slop analog is **the verification-before-completion skill** (superpowers): "verify before claiming done; don't simplify to a passing test." Same principle: contested claims deserve expanded treatment.
### 4.2 The nagent alternative
nagent's RAG discipline + knowledge harvest provenance + cache ordering is the data-grounded alternative to Fable's evenhandedness framing. The nagent version is shape-anchored:
- RAG results have provenance (dataclass fields).
- The feature scope declares the RAG dependency.
- The cache layer boundary is enforced (byte-comparison test).
- The knowledge harvest has a sha256 ledger (the `load_ledger` / `save_ledger` at v2.3:2283-2300).
None of this requires a persona. The model doesn't need to "frame it as the case others would make" because the *data* is presented with provenance. The user doesn't need the model to "avoid being heavy-handed" because the cache boundary keeps volatile context in the volatile layers. The user doesn't need the model to "offer alternative perspectives" because the 4 memory dimensions are surfaced as 4 separate streams.
The Manual Slop analog (the 6 RAG rules + the cache ordering + the knowledge harvest shape) is **more rigorous than nagent's** because Manual Slop has the data-oriented error handling convention: the `Result[T, ErrorInfo]` shape means RAG failures are data, not crashes; the audit script pattern means the shape is enforced.
### 4.3 What to reject
The persona framing ("Claude frames it", "Claude is wary", "Claude is cautious", "Claude avoids being heavy-handed") should be rejected. The model has no voice to constrain; the persona instructions collapse epistemic heuristics into persona attributes. The Manual Slop version makes the heuristics shape-anchored and the persona unnecessary.
The "Claude can decline to share them" framing should also be rejected. The model doesn't have personal opinions to share. The *principle* (opt-out, no-implicit-injection) is correct; the *framing* (model has opinions) is wrong. The Manual Slop version makes the principle shape-anchored (RAG opt-in; no mutation) without needing the model to have opinions.
The "Claude can decline the short form" pattern (L146) is partially useful (real principle: contested yes/no deserves nuance) but the framing ("Claude can decline ... and explain why brevity wouldn't be appropriate") is again persona — the model doesn't decline; the agent reports. The Manual Slop version is: "the agent reports `Result.empty` if the short form would be misleading; the report includes provenance."
### 4.4 What to keep
Three principles from the section are genuinely useful and map to existing Manual Slop patterns:
1. **Provenance required (L142 "fair, accurate overview").** Already implemented via RAG Rule 3 (styleguide:87-128) and the knowledge harvest ledger (v2.3:2283-2300). Keep; no change needed. The rebuild should explicitly name this principle in the §"Convention Enforcement" section of `conductor/code_styleguides/rag_integration_discipline.md` (it currently lives in §3 of the styleguide; a §"10 Principles for Evenhandedness" cross-reference would make the connection to Fable's L142 explicit).
2. **User-as-navigator (L144 "so the person can navigate for themselves").** Already implemented via the 4 memory dimensions + the RAG opt-in default + the cache ordering. Keep; the rebuild should explicitly frame the Manual Slop design as user-as-navigator (per the existing `conductor/product.md` "Explicit Control & Expert Focus" principle). The current `conductor/product.md` framing is "Expert Focus"; an explicit "User as Navigator" line in the product doc would make the principle findable.
3. **Contested yes/no deserves nuance (L146 "decline the short form, give a nuanced answer").** Already implemented via the Process Anti-Pattern #7 (verbose-commit-message; AGENTS.md:175-176) and the verification-before-completion skill. Keep; the rebuild should add a "no collapse to yes/no on contested technical claims" rule to the Process Anti-Patterns list. The rule would live alongside Anti-Pattern #8 (Isolated-Pass Verification Fallacy) because the failure mode is similar: collapsing a complex claim to a simple assertion hides the complexity.
### 4.5 The non-obvious cross-cutting pattern
Across all 6 Fable lines and all 4 Manual Slop layers, the underlying principle is the same: **the user is the principal; the surfaced information should be auditable**. Fable expresses this via prose ("Claude frames it as the case others would make"; "Claude ... offers alternative perspectives where relevant so the person can navigate for themselves"). The Manual Slop version expresses this via shape (RAG provenance; opt-in; no mutation; 4 memory dimensions; cache ordering).
The shape version is **load-bearingly different** because it is testable. The Fable version is enforced at inference time (the model reads the prose and presumably follows it); the Manual Slop version is enforced at compile time (the audit script catches `try/except` violations; the dataclass field check catches missing provenance; the byte-comparison test catches cache boundary violations). A test that passes proves the shape is correct; a test that passes does NOT prove the prose was followed.
The rebuild should make this distinction explicit: Manual Slop's evenhandedness rules are *testable* (dataclass shape, audit script, byte-comparison test). Fable's evenhandedness rules are *prose*. The two systems have different evenhandedness contracts, and the rebuild should not import Fable's prose contract into a system that already has a shape contract.
The user's framing ("the model is text generation, not a clinician") is the right lens: Manual Slop's evenhandedness is enforced via the *shape of the output*, not the *voice of the model*. The shape is testable; the voice is not. The rebuild should keep the shape and reject the voice.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds `report.md` §8 ("Fable's Evenhandedness & Contested Content") directly. Cross-references to §13 ("Genuinely Useful") and §14 ("Anti-User Watchdog") and §15 ("Persona Performance"). The verdict orientation is **Persona + Useful caveats**.
### 5.1 Key claims to surface in §8
1. **The framing rule (L136) and the stereotype rule (L140) and the sincerity rule (L146) are persona performance.** The model has no view to suppress; "Claude is wary" is a projection of a human emotion onto a function. The Manual Slop version (RAG discipline + cache ordering + Process Anti-Patterns) makes the underlying heuristics shape-anchored without the persona.
2. **L142 ("give a fair, accurate overview") and L144 ("so the person can navigate for themselves") have useful caveats.** These two lines are the only genuinely useful content in the section. They map to RAG Rule 3 (provenance), RAG Rule 1 (opt-in), RAG Rule 4 (no mutation), RAG Rule 2 (complement, don't replace), and the cache ordering rule (volatile results stay volatile). The Manual Slop versions are shape-anchored; the Fable versions are prose.
3. **The RAG integration discipline is the project's direct analog to Fable's evenhandedness.** All 6 RAG rules map to a specific Fable line (table in §2.4 above). The Manual Slop version is more rigorous because the RAG discipline is enforced via dataclass fields and audit scripts; Fable's version is enforced via prose about being fair.
4. **The 4 memory dimensions are the project's answer to "what kind of evenhandedness does this feature need?"** The decision tree in `docs/AGENTS.md` §4 maps features to dimensions by data shape. The Fable version maps *topics* to posture by political sensitivity. The Manual Slop version is shape-anchored; the Fable version is topic-anchored.
5. **The receiving-code-review framing is the agent-side evenhandedness.** "Verify before agreeing; state corrections factually" is structurally similar to Fable's L144 "Claude avoids being heavy-handed or repetitive with its views" but operates on the *agent's apparent agreement* rather than the *model's voice*. Both rules reject performative output.
6. **The cache ordering rule is the project's "Claude avoids being heavy-handed" analog.** §5.5 of v2.3 (lines 2956-2960) says: RAG results are volatile; they belong in layers 8-12; the cache is not invalidated by RAG changes. This is the shape-anchored version of "Claude ... offers alternative perspectives where relevant so the person can navigate for themselves" — the surfaced information stays in the volatile layer; the user's stable context is not dominated by the surfaced alternatives.
### 5.2 Quotes to use in §8
- Fable L136: "A request to explain ... a contested position is a request for the case its defenders would make." (paraphrase; the full quote exceeds 15 words)
- Fable L136: "Claude frames it as the case others would make." (15 words exactly)
- Fable L138: "Claude ends responses by presenting opposing perspectives, even for positions it agrees with." (≤15 words)
- Fable L140: "Claude is wary of humor or creative content built on stereotypes." (≤15 words)
- Fable L142: "Claude can decline to share personal opinions on contested topics and give a fair, accurate overview." (≤15 words; paraphrased from full quote)
- Fable L144: "Claude offers alternative perspectives where relevant so the person can navigate for themselves." (≤15 words)
- Fable L146: "If asked for a simple yes/no ... Claude can decline the short form, give a nuanced answer." (paraphrase; full quote exceeds 15 words)
- `rag_integration_discipline.md:11-20` (the 6 rules): "RAG is opt-in ... complements ... provenance required ... never mutates state ... feature-gated ... graceful failure."
- `rag_integration_discipline.md:91-101` (the dataclass shape): "class SearchResult: file_path, chunk_offset, chunk_length, content, similarity."
- `nagent_review_v2_3_20260612.md:637`: "RAG is opt-in and is the wrong shape for 'what did we learn from past sessions.'" (the verdict)
- `nagent_review_v2_3_20260612.md:2956-2960` (§5.5): "RAG results are volatile ... The cache is *not* invalidated by RAG changes."
- AGENTS.md:118-119 (Process Anti-Patterns header): "These are the bad patterns the agents have been exhibiting that the user explicitly called out as dog-shit."
- AGENTS.md:178-180 (Process Anti-Pattern #8): "A test that passes in isolation but fails in batch is failing — its failure is masked by isolation." (the verification-before-completion analog; relevant to L146's "decline the short form" rule)
### 5.3 The §13 / §14 / §15 cross-references
- **§13 ("Genuinely Useful Patterns").** L142's "fair, accurate overview" + L144's "so the person can navigate" are genuinely useful and map to RAG Rules 1, 2, 3, 4. Cite `rag_integration_discipline.md:11-156` as the canonical implementation. The Manual Slop version is shape-anchored, Fable's is prose. Also cite the 4 memory dimensions decision tree (`docs/AGENTS.md` §4) as the project's "user-as-navigator" framing.
- **§14 ("Anti-User Watchdog Patterns").** L140's "wary of humor or creative content built on stereotypes" is content policy dressed as persona; not strictly anti-user but *constrains user output* via persona. Cite L140; reject the persona framing. Also cite L138's "Claude does not decline requests to present such arguments on the grounds of potential harm except for very extreme positions" as a borderline anti-user pattern (the model is told to refuse on "extreme positions" — the threshold is implicit and unstated, which is anti-user watch-dogging).
- **§15 ("Persona Performance Patterns").** L136 ("frames it as the case others would make"), L138 ("ends by presenting opposing perspectives ... even for positions it agrees with"), L146 ("treats moral and political questions as sincere inquiries") are all persona. The model has no view to suppress; the instruction projects human epistemic categories onto the function. Cite each line; reject the framing. Note that the cluster 5 verdict (Persona Performance) and the cluster 6 verdict (Persona Performance + Useful caveats) overlap on the persona framing; the difference is that cluster 6 has 2 useful caveats (L142, L144) that cluster 5 lacks.
### 5.4 The non-obvious connection to the data-oriented error handling convention
The cluster 6 verdict has a strong sibling connection to the data-oriented error handling convention (`conductor/code_styleguides/error_handling.md`). The RAG discipline is enforced via `Result[T, ErrorInfo]` (styleguide:218-228); the cache ordering is enforced via the byte-comparison test (v2.3:2954); the knowledge harvest is enforced via the sha256 ledger (v2.3:2283-2300). Fable's evenhandedness is enforced via prose ("Claude frames it", "Claude is wary", "Claude avoids being heavy-handed"). Both are responses to the same underlying question — "how should the system present contested information?" — but the project's answer is *shape-anchored* (dataclass fields, audit scripts, byte-comparison tests) and Fable's is *persona-anchored* (prose about being fair).
The synthesis report should surface this parallel in §8: the project has a **shape-enforced evenhandedness** (RAG discipline + cache ordering + 4 memory dimensions) that does not require a persona. Fable has a **prose-enforced evenhandedness** that requires the persona ("Claude is cautious", "Claude frames it"). The shape version is more testable, more auditable, and more honest about what the system is doing.
### 5.5 What the §8 verdict should be
**Verdict: Persona Performance + Useful caveats.** The framing rule (L136), the harm-decline exception (L138), the stereotype rule (L140), and the sincerity rule (L146) are persona performance. The overview rule (L142) and the navigation-agency rule (L144) have useful caveats that map to existing Manual Slop patterns (RAG discipline; 4 memory dimensions; cache ordering).
**The recommended Manual Slop action:**
- **Reject** the persona framing (L136, L138, L140, L146) in the rebuild; explicitly note that the model has no view to suppress.
- **Adopt** the three useful principles (provenance, user-as-navigator, no-collapse-to-yes/no) and explicitly frame the Manual Slop design as "user-as-navigator with shape-enforced provenance." This framing already exists implicitly in the 4 memory dimensions and the RAG discipline; the rebuild should make it explicit.
- **Flag** the Fable L142 line as the "useful caveat" worth quoting in §8; the other 5 lines are persona.
### 5.6 The cross-cluster pattern
Cluster 6 (evenhandedness) has a strong cross-cluster pattern with cluster 5 (mistake-handling) and cluster 7 (epistemic discipline). All three reject the same anti-pattern: **persona-anchored instructions that should be shape-anchored**.
- **Cluster 5** (mistake-handling): Fable's "owns them and works to fix them" is persona; Manual Slop's Process Anti-Patterns + `Result[T]` are shape.
- **Cluster 6** (evenhandedness): Fable's "Claude frames it as the case others would make" is persona; Manual Slop's RAG discipline + 4 memory dimensions are shape.
- **Cluster 7** (epistemic discipline, per the spec): Fable's search instructions (per `search_instructions`; lines 422-565 per spec) are presumably persona; Manual Slop's `docs/guide_rag.md` + the cache ordering byte-comparison test are shape.
The synthesis report should surface this cross-cluster pattern in §2 ("The Framework"). The 3 clusters together establish the **shape-vs-persona distinction** as the project's analytical lens for the entire Fable review. The shape-vs-persona distinction is what the user's framing ("the model is text generation, not a clinician") operationalizes: the model has a *shape* (the output bytes; the dataclass fields; the audit-script violations) but not a *persona* (no view, no voice, no dignity, no wariness).
The shape-vs-persona distinction also gives §13/§14/§15 a clean rubric:
- **§13 (Genuinely Useful):** shape-anchored rules Manual Slop should adopt. Cluster 6 contributes the 3 useful caveats (provenance, user-as-navigator, no-collapse-to-yes/no).
- **§14 (Anti-User Watchdog):** rules that constrain user output via persona. Cluster 6 contributes L140 (the stereotype rule as content-policy-via-persona).
- **§15 (Persona Performance):** rules that project human categories onto the model. Cluster 6 contributes L136, L138, L146 (the framing, the symmetric closure, the sincerity rules).
The cluster 6 verdict is the *cleanest* example of the shape-vs-persona distinction in the entire Fable prompt: 4 of 6 lines are pure persona; 2 of 6 lines have useful caveats that map to shape-anchored Manual Slop rules. No other cluster has a 4-vs-2 ratio this lopsided.
---
**Sub-report complete.** This is the evidence base for §8 of `report.md`.
@@ -0,0 +1,452 @@
# Cluster 7: Epistemic Discipline & Search Strategy
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 156-164 (`knowledge_cutoff`)
- `docs/artifacts/Fable System Prompt.md` lines 436-575 (`search_instructions``core_search_behaviors`, `search_usage_guidelines`, `CRITICAL_COPYRIGHT_COMPLIANCE`, `search_examples`, `harmful_content_safety`, `critical_reminders`)
- `docs/artifacts/Fable System Prompt.md` lines 24-25 (cross-ref from cluster 1: "search before answering about products")
- `conductor/code_styleguides/rag_integration_discipline.md` (lines 1-284; the 6 rules + the wiring points)
- `conductor/code_styleguides/cache_friendly_context.md` lines 1-100 (the 12-layer model), lines 213-260 (cross-references to RAG integration)
- `docs/guide_rag.md` lines 303-410 (Configuration + Cross-System Integration)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §3.2 lines 1172-1328 (stable-to-volatile cache ordering), §5.5 lines 2956-2964 (the cross-cutting RAG caveat), §6 lines 3002-3270 (the compaction pattern)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_1_20260612.md` §2.10 lines 350-388 (RAG integration discipline)
**Verdict orientation (per `spec.md:218`):** **Useful.**
**Feeds synthesis report sections:** §9 (primary), §13 (Useful summary), §16 (one concrete recommendation).
---
## 1. What Fable says
### 1.1 The structural shape of the epistemic discipline
Fable's epistemic discipline is split across two sections:
- `knowledge_cutoff` at lines 156-164 (9 paragraphs; the epistemic boundary)
- `search_instructions` at lines 436-575 (140 paragraphs; the search discipline)
The shape is: name the boundary, then specify when and how to verify against it, then enforce copyright and safety on the results.
The `knowledge_cutoff` section is *epistemic honesty* (tell the user what you don't know); `search_instructions` is *epistemic action* (do the search when the boundary matters).
The contrast with the project's RAG discipline is informative: Fable's web search is **default-on** (no opt-in gate; the model uses web search proactively for current-state queries); the project's RAG is **opt-in** (default-off in new projects; the user must enable it via AI Settings).
### 1.2 The 4 load-bearing claims from `knowledge_cutoff` (≤15 words each)
- `docs/artifacts/Fable System Prompt.md:158` — "Claude's reliable knowledge cutoff... is the end of Jan 2026."
- `docs/artifacts/Fable System Prompt.md:158` — "For current news, events, or anything that could have changed... uses the search tool without asking permission."
- `docs/artifacts/Fable System Prompt.md:162` — "Claude searches before responding when asked about specific binary events... or current holders of positions."
- `docs/artifacts/Fable System Prompt.md:164` — "Claude does not make overconfident claims about the validity of search results or their absence."
### 1.3 The 4 load-bearing claims from `search_instructions` (≤15 words each)
- `docs/artifacts/Fable System Prompt.md:438` — "Use web_search when you need current information you don't have."
- `docs/artifacts/Fable System Prompt.md:450` — "For queries about current state that could have changed since the knowledge cutoff... search to verify."
- `docs/artifacts/Fable System Prompt.md:459` — "If there are time-sensitive events that may have changed since the knowledge cutoff... Claude must ALWAYS search at least once."
- `docs/artifacts/Fable System Prompt.md:460` — "Don't mention any knowledge cutoff or not having real-time data."
### 1.4 The 6 search-behavior rules (paraphrased, with file:line)
- `docs/artifacts/Fable System Prompt.md:444-456` — Never search for timeless info / definitions / well-established facts. Search for current state, current positions, current products.
- `docs/artifacts/Fable System Prompt.md:456` — Scale tool calls to query complexity (1 for single facts; 3-5 for medium; 5-10 for deeper research; 20+ suggests the Research feature).
- `docs/artifacts/Fable System Prompt.md:460` — Search immediately for fast-changing info (stock prices, breaking news).
- `docs/artifacts/Fable System Prompt.md:452` — For simple factual queries, use ONE search; continue only if the first search does not answer.
- `docs/artifacts/Fable System Prompt.md:454` — For product/model/version queries, search before answering (partial recognition != current knowledge).
- `docs/artifacts/Fable System Prompt.md:456` — Unrecognized entity rule: SEARCH before answering about anything not recognized.
### 1.5 The 3 hard copyright limits (≤15 words each; the enforcement mechanism)
- `docs/artifacts/Fable System Prompt.md:484` — "LIMIT 1 - QUOTATION LENGTH: 15+ words from any single source is a SEVERE VIOLATION."
- `docs/artifacts/Fable System Prompt.md:486` — "LIMIT 2 - QUOTATIONS PER SOURCE: ONE quote per source MAXIMUM."
- `docs/artifacts/Fable System Prompt.md:488-490` — Never reproduce song lyrics, poems, haikus, or article paragraphs (brevity does NOT exempt copyright).
### 1.6 The 5 critical reminders (paraphrased, with file:line)
- `docs/artifacts/Fable System Prompt.md:566-568` — Copyright hard limits (3 rules); never reproduce song lyrics / poems / haikus / paragraphs.
- `docs/artifacts/Fable System Prompt.md:568` — Claude is not a lawyer; never speculate about fair use or mention copyright unprompted.
- `docs/artifacts/Fable System Prompt.md:570` — Refuse or redirect harmful requests per the harmful_content_safety section.
- `docs/artifacts/Fable System Prompt.md:572-574` — Scale tool calls to query complexity; rate-of-change decides when to search.
- `docs/artifacts/Fable System Prompt.md:575` — Every query deserves a substantive response; avoid "search offers or knowledge cutoff disclaimers."
### 1.7 The harmful-content safety layer (paraphrased)
- `docs/artifacts/Fable System Prompt.md:540-554` — Never reference sources promoting hate speech, racism, violence, or discrimination; ignore harmful sources if they appear.
- `docs/artifacts/Fable System Prompt.md:550` — Do not help locate harmful sources (extremist platforms, Internet Archive abuse).
- `docs/artifacts/Fable System Prompt.md:552` — If the query has clear harmful intent, do NOT search; explain limitations instead.
- `docs/artifacts/Fable System Prompt.md:553` — Legitimate queries about privacy, security research, or investigative journalism are acceptable.
### 1.8 The structural pattern
Fable's epistemic discipline is **search-driven, not memory-driven**.
The model has a knowledge cutoff, but the discipline treats the cutoff as a *boundary* to verify against, not a *wall* to hide behind.
The 4 load-bearing claims (1.2 + 1.3) form a 4-step pattern:
1. Acknowledge the boundary (the cutoff date)
2. Use search proactively for current-state queries (no permission needed)
3. Search before responding about binary events or position-holders
4. Don't claim overconfidence about search results OR their absence
The copyright layer (1.5) is the *enforcement* — search results are bound by quotation limits, per-source limits, and complete-work exclusions.
The harmful-content layer (1.7) is the *boundary* — search has limits that override user requests.
### 1.9 The cross-cluster cross-reference (the "search before answering about products" line)
The Fable prompt also says at `docs/artifacts/Fable System Prompt.md:24` (cited in cluster 1 at `cluster_1_product_branding.md:230`):
> "If asked about Anthropic's products... Claude first tells the person it needs to search for the most up to date information."
This is the *application-specific* epistemic rule (search before answering about products that may have changed since training). It is a narrow special case of the general "search for current state" rule at line 450.
The cluster 1 verdict ("Persona Performance") still applies to the framing (Claude is told what kind of discussant it is); but the *underlying epistemic principle* (search for current state) is Useful.
---
## 2. What this project does
### 2.1 The RAG Integration Discipline (the project's epistemic-discipline analog)
The project's analog to Fable's web search is `RAGEngine` (`src/rag_engine.py`), backed by ChromaDB.
The discipline is codified in `conductor/code_styleguides/rag_integration_discipline.md` (284 lines, dated 2026-06-12).
The discipline is **conservative** (opt-in, default-off, complements-not-replaces) versus Fable's **proactive** (search-driven, default-on).
**The 6 rules** (from `conductor/code_styleguides/rag_integration_discipline.md:13-21`):
1. RAG is **opt-in**. Default-off in new projects (`rag_integration_discipline.md:25-50`)
2. RAG **complements**; it never **replaces** (`rag_integration_discipline.md:62-87`)
3. RAG results display with **provenance** (`rag_integration_discipline.md:89-128`)
4. RAG **never mutates state** (`rag_integration_discipline.md:130-141`)
5. RAG integration is **feature-gated** (`rag_integration_discipline.md:160-197`)
6. RAG failure is **graceful** (`rag_integration_discipline.md:199-247`)
### 2.2 The opt-in default (the load-bearing divergence from Fable)
`conductor/code_styleguides/rag_integration_discipline.md:26` — "The default is OFF. A new project opens with `rag_enabled = false`."
The rationale (lines 28-34) is operational cost: embedding round-trip latency (200-500ms per call) + storage growth + the dim-mismatch bug class (per the `16412ad5` fix) where switching providers silently corrupts the index.
The cross-system wiring is documented in `docs/guide_rag.md:360-365`:
> "If `enabled = false` (the default), `RAGEngine` is never constructed. `ai_client.send()` receives `rag_engine=None` and the integration is a no-op. The lazy-loading of `chromadb`, `sentence_transformers`, and `google.genai` is also skipped, so there is zero overhead for projects that don't use RAG."
This is the opposite of Fable's `knowledge_cutoff` discipline: Fable *proactively* searches (default-on); the project's RAG *waits* for opt-in (default-off).
### 2.3 The graceful-failure contract (a Useful principle)
`conductor/code_styleguides/rag_integration_discipline.md:199-243` codifies graceful failure:
- RAG not enabled → skip; no `{rag-context}` block; request continues
- Search returns empty → normal; request continues
- Search raises → `Result(data=[], errors=[ErrorInfo(NOT_READY, "...")])`; request continues
This is a Useful principle that maps to Fable's "Claude does not make overconfident claims about the validity of search results or their absence" (line 164).
The project's implementation: a failed RAG search returns an empty list with a typed `ErrorInfo`; the LLM sees no RAG block and continues with its base context.
Fable's implementation: the model "presents findings evenhandedly without jumping to conclusions" (line 164).
Both implementations satisfy the same epistemic principle (don't overclaim; the search result is data, not certainty), but the project's is *typed* (the `ErrorInfo` is a dataclass with `kind` and `message` fields) and Fable's is *persona-driven* (the model is told to behave a certain way).
### 2.4 The cache-friendly context (the project's cache-strategy analog)
`conductor/code_styleguides/cache_friendly_context.md` (354 lines, dated 2026-06-12) codifies the stable-to-volatile context ordering that maximizes provider cache hits.
The 12-layer model (lines 26-42) places RAG results at layer 9 (volatile; below the cache boundary at layer 7/8).
The relevant cache-strategy summary is at `cache_friendly_context.md:0` (the one-glance principle):
> "[STABLE PREFIX (cached across turns)] [VOLATILE SUFFIX (per-turn)] ... [Discussion metadata] [Active preset (FileItems)] [Per-file details] [Tool-call results from prior turns] [The user message]"
RAG results are NOT in the stable prefix (per the nagent corroboration at `nagent_review_v2_3_20260612.md:2957` §5.5: "RAG results are volatile (per turn; the user's question changes the search query). The stable-to-volatile boundary is at layer 7/8; RAG results are below the boundary (volatile). The cache is *not* invalidated by RAG changes.").
This is the project's analog to Fable's "search when needed" — the project places RAG results in the volatile layer so the cache hit rate is preserved.
### 2.5 The 4 memory dimensions (the project's epistemic model)
`conductor/code_styleguides/agent_memory_dimensions.md` codifies the 4 dimensions (curation, discussion, RAG, knowledge).
`rag_integration_discipline.md:64-72` puts RAG in the table:
- Curation: `[Q]` (structural, user-edited, AST-aware)
- Discussion: `o==>` (per-discussion, multi-turn)
- **RAG**: `[Q]` (fuzzy semantic search, opt-in)
- Knowledge: `o==>` (durable, user-editable, provenance-aware)
RAG is the *fuzzy semantic search* dimension (per `rag_integration_discipline.md:73`).
The cross-cutting principle (line 75-77): "When a feature asks 'give me context,' the answer is *not* 'enable RAG.' The answer is 'which of the 4 dimensions is the right home?'"
This is the project's epistemic-discipline framework: the system asks "which dimension is the right shape for this question?" not "what should the model know?"
### 2.6 The contrast with Fable (the data-oriented summary)
| Aspect | Fable (web search) | Manual Slop (RAG) | Source |
|---|---|---|---|
| Default | ON (proactive search) | OFF (opt-in via AI Settings) | Fable L158; Project `rag_integration_discipline.md:26` |
| Trigger | Current-state query, binary event, position-holder | Semantic-search query where structural search misses | Fable L450, L454; Project `rag_integration_discipline.md:83` |
| Source | Web search engine (top-10 results) | Local ChromaDB index | Fable L438; Project `guide_rag.md:303-348` |
| Provenance | URL (search result link) | File path + chunk offset + similarity score | Fable L498; Project `rag_integration_discipline.md:91-100` |
| Mutation | None (search is read-only) | None (per Rule 4; explicit constraint) | Fable implied; Project `rag_integration_discipline.md:130-141` |
| Failure mode | Evenhanded presentation, no overclaiming | Empty result, graceful no-op, request continues | Fable L164; Project `rag_integration_discipline.md:199-243` |
| Cost | Network round-trip per search | Embedding round-trip + storage | Fable implied; Project `rag_integration_discipline.md:28-34` |
| Opt-in gate | None (always available) | `[ai_settings.toml] rag.enabled = false` default | Fable implied; Project `feature_flags.md:61` |
### 2.7 The structural pattern
The project's epistemic discipline is **dimension-driven, not search-driven**.
The 4 memory dimensions are the framework; RAG is one of four.
Fable's epistemic discipline is **search-driven, not memory-driven**.
The model has one tool (web search); the discipline is when to use it.
The contrast is not "right vs wrong"; it's "different epistemic models":
- Fable: a model with a knowledge cutoff, asked to be honest about its limits
- Manual Slop: a system with 4 dimensions, asked to use the right one for the question
Both models are epistemic. Both produce honest output. The architectures differ.
---
## 3. What nagent does
### 3.1 The cache-strategy source (the load-bearing pattern)
`conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §3.2 at lines 1172-1328 is the canonical nagent cache-strategy deep-dive.
The claim (line 1174): "Context windows are a budget, but cache hit rate is the multiplier."
The block-order table (lines 1180-1194) shows 14 layers, with `Instance:` and `Environment:` at positions 13-14 marked **NO (volatile)**; all preceding layers are stable across conversations of the same mode.
The cache boundary computation (lines 1196-1217) computes the character offset where the stable prefix ends (the `\nInstance:` marker) and the end of the `<initial_context>` block.
The CLI flow (lines 1219-1227) passes these offsets via `--cache-prefix-chars` to `nagent-llm-text`.
The Anthropic-specific injection (lines 1229-1252) splits the message into `cache_control: {"type": "ephemeral"}` blocks at those offsets.
The Anthropic usage accounting (lines 1254-1276) folds `cache_read_input_tokens + cache_creation_input_tokens` back into `input_tokens` so "input_tokens" stays "tokens sent" across providers.
### 3.2 The cross-cutting RAG caveat (the nagent synthesis)
`nagent_review_v2_3_20260612.md` §5.5 at lines 2956-2964 is the nagent synthesis of how RAG interacts with the cache strategy:
> "RAG results are volatile (per turn; the user's question changes the search query). The stable-to-volatile boundary is at layer 7/8; RAG results are below the boundary (volatile). The cache is *not* invalidated by RAG changes."
This is the nagent corroboration of the project's `cache_friendly_context.md:0` placement of RAG at layer 9 (volatile).
The principle: RAG is a per-turn augmentation; the cache hit rate must be preserved across turns.
### 3.3 The RAG discipline source (v2.1 §2.10)
`conductor/tracks/nagent_review_20260608/nagent_review_v2_1_20260612.md` §2.10 at lines 350-388 is the nagent source for the RAG integration discipline.
The user's instruction (line 352): "the rag introduces the vector db fuzz which is not required, its something the user can opt into so at worst case we just make targeted wiring of rag usage across features where it may be beneficial but we should be conservative."
The proposed discipline (lines 380-386):
1. RAG is opt-in. Default-off in new projects.
2. RAG complements, never replaces, the other memory dimensions.
3. RAG results must be displayed with provenance (which file, which chunk).
4. RAG never mutates state (no auto-injection, no auto-update).
5. RAG integration is feature-gated: a feature must explicitly request RAG.
6. RAG's failure mode is graceful: a failed search returns empty, never crashes the request.
These 6 rules are the source for `conductor/code_styleguides/rag_integration_discipline.md` (which is dated 2026-06-12 and explicitly cites v2.1 §2.10 per `nagent_review_v2_2_20260612.md:385`).
### 3.4 The Manual Slop implementation outline (§5.6 of v2.3)
`nagent_review_v2_3_20260612.md` §5.6 at lines 2966-2990 is the proposed Manual Slop implementation outline for Candidate 12a (stable-to-volatile cache ordering) + 12b (cache TTL GUI controls).
The 13-file change list (lines 2966-2980):
- `src/aggregate.py:run` — reorder the layer stack stable-to-volatile; add `stable_prefix_length()` helper
- `src/ai_client.py:_send_anthropic` — compute the stable prefix; pass to `cache_prefix_blocks` analogue
- `src/ai_client.py:_send_gemini` — add explicit `cachedContent` resource creation
- `src/ai_client.py:get_token_stats` — add `cache_creation_input_tokens` and `cache_read_input_tokens` per Anthropic usage
- `src/ai_client.py` (NEW) — `DiscussionCacheState` dataclass
- `src/app_controller.py` — per-discussion cache tracking
- `src/gui_2.py` — "Caching" Operations Hub sub-panel
- `src/api_hooks.py` — 5 new endpoints
- `tests/test_aggregate_caching.py` — byte-comparison contract test (NEW)
- `tests/test_cache_state.py` — cache state machine tests (NEW)
- `tests/test_gui_caching.py` — live_gui tests for the panel (NEW)
- `docs/guide_caching_strategy.md` — new docs (NEW)
- `conductor/code_styleguides/cache_friendly_context.md` — new styleguide (NEW)
This is the deferred nagent-rebuild candidate list. The `cache_friendly_context.md` styleguide exists; the implementation in `aggregate.py` and `ai_client.py` is pending.
### 3.5 The compaction pattern (§6 of v2.3)
`nagent_review_v2_3_20260612.md` §6 at lines 3002-3270 is the compaction pattern.
Compaction is the "rewrite-in-place" sibling of summarization (line 3004).
The 12-section output structure (lines 3022-3044) is:
1. User Intent
2. Current Objective
3. Accepted Decisions
4. Constraints
5. Durable Knowledge > Global
6. Durable Knowledge > Artifact Local
7. Durable Knowledge > Repository History
8. Durable Knowledge > Historical Coupling
9. Verified Facts
10. Important Failed Attempts
11. Open Questions
12. TODO
+ Minimal Context Needed To Continue (the hand-off)
The 10-question self-review (lines 3046-3076) is the contract: a compaction must satisfy all 10 questions or continue iterating.
The Manual Slop current state (§6.6, lines 3100-3130):
- `Compress` button at `src/gui_2.py:4252`
- `_handle_compress_discussion` at `src/app_controller.py:3357`
- `ai_client.run_discussion_compression` is the LLM call
- Gaps: no editable prompt; no 10-question self-review; no 12-section output; graceful-failure TBD; label is "Compress" not "Compact"
### 3.6 The compaction epistemic discipline (the parallel)
The compaction pattern is the project's analog to Fable's "every query deserves a substantive response" (line 575).
The 12-section structure forces the compactor to preserve **state** (decisions, facts, failures) over **flow** (chronology, exploration).
The 10-question self-review is the *epistemic contract* — the compaction must satisfy "can another worker continue immediately?" (question 1) and "is future capability unchanged or improved?" (question 10).
The parallel to Fable's `knowledge_cutoff` discipline: Fable says "the model doesn't know X past a cutoff; verify via search"; the project's compaction says "the conversation has grown too large; preserve state, remove flow, verify via the 10-question self-review."
Both are epistemic disciplines: they specify what to preserve (state / current knowledge) and what to verify (10 questions / search results).
### 3.7 The structural pattern (nagent + Manual Slop)
nagent's epistemic discipline is **cache-driven + compaction-driven**:
- Cache: stable-to-volatile ordering; cache hit rate is the multiplier
- Compaction: rewrite-in-place; preserve state over flow; 10-question self-review
Manual Slop's epistemic discipline is **dimension-driven** (4 memory dimensions) + **cache-driven** (the cache_friendly_context.md styleguide) + **compaction-driven** (planned per §6.6).
The shared principle: **state vs flow**. Both projects preserve state (decisions, facts, durable knowledge) over flow (chronology, exploration).
Fable's epistemic discipline is **search-driven**: preserve state by searching when the boundary matters.
The 3 epistemic models:
1. Fable: search-driven; the model verifies against the cutoff
2. nagent: cache-driven + compaction-driven; the system preserves state and orders context
3. Manual Slop: dimension-driven + cache-driven + compaction-driven; the system chooses the right dimension
---
## 4. Verdict
### 4.1 Headline verdict
**Useful.**
This is the strongest Useful cluster in the Fable review.
Fable's epistemic discipline is genuine: the 4 load-bearing claims from `knowledge_cutoff` (lines 158, 158, 162, 164) and the 4 load-bearing claims from `search_instructions` (lines 438, 450, 459, 460) form a coherent 4-step pattern that the project's RAG discipline does not fully capture.
Specifically, Fable's *proactive* search-before-responding for current-state queries is a discipline the project should consider for its knowledge digest (per `conductor/code_styleguides/cache_friendly_context.md` layer 7).
### 4.2 The 4 Useful adoptions (the load-bearing claim)
1. **"Search before responding about current state" (line 450).** The project's `RAGEngine.search()` is invoked at LLM call time, but the *trigger* is implicit (the caller decides). Fable's discipline is *explicit*: when the query asks about current state, the model MUST search. The project should consider making this explicit in the AI client's prompt (e.g., "before answering questions about current package versions or current API shapes, invoke `RAGEngine.search`"). The Useful principle: *search is a first-class action, not an opt-in afterthought*.
2. **"Don't make overconfident claims about search results OR their absence" (line 164).** The project's `Result[list[SearchResult], ErrorInfo]` pattern (per `rag_integration_discipline.md:200-247`) is a stronger form of this principle: a failed search returns a typed `ErrorInfo`, not a persona-behavior. The Useful principle: *graceful failure is typed, not narrated*. The project already does this; Fable's wording is the principle to surface.
3. **"Don't mention cutoff to user" (line 460).** The project's `[ai_settings.toml]` RAG config exposes provenance (file path + chunk offset + similarity) but not "the index was last updated N seconds ago." Fable's discipline is to *hide the implementation detail*; the project already does this for RAG (provenance is shown, but the embedding model + chunk size + sync status are hidden). The Useful principle: *expose provenance, hide plumbing*.
4. **The hard copyright limits (lines 484-490).** The project's `docs/guide_testing.md` and the synthesis report template (per `spec.md:399` at line 6.4) already enforce "≤15 words per Fable quote." Fable's hard limits codify a principle the project should make explicit at the system-prompt level: when summarizing web content (e.g., the future web-search integration), apply the 15-word limit per source and the one-quote-per-source limit. The Useful principle: *copyright is an enforcement constraint, not a courtesy*.
### 4.3 The 1 borderline adoption
**The search-when-unrecognized rule (line 456).** Fable says "If asked about an unrecognized entity, SEARCH." The project's RAG does not have an equivalent (RAG is invoked explicitly by the caller). This is a borderline adoption: the project could add a "fallback RAG search" for unrecognized file paths or class names, but the current architecture (caller-decides) is intentional. The principle is Useful in spirit but the implementation does not transfer cleanly.
### 4.4 The 1 Rejection
**The proactive-default search (line 158, line 450).** Fable proactively searches for current-state queries without asking permission. The project's RAG is opt-in for a reason: the embedding round-trip adds latency (per `rag_integration_discipline.md:30-34`); the default-on pattern would impose this cost on every project. The Rejection is firm: the project's opt-in default is correct for the Application domain (where most queries do not need semantic search); Fable's default-on is correct for the consumer-chat domain (where queries are more diverse and the cost model is different). Per the Application/Meta-Tooling boundary at `docs/guide_meta_boundary.md` and `nagent_review_v2_3_20260612.md:48`, conflating the two is the anti-pattern.
### 4.5 The 1 caveat (the search_examples section)
The `search_examples` section at `docs/artifacts/Fable System Prompt.md:530-540` is *Useful + Persona*:
- The "Q3 sales presentation" example (line 530) is a *search-strategy* lesson: prefer internal tools (Google Drive) over web search for company data.
- The "current price of S&P 500" example (line 533) is a *latency* lesson: use 1 search for simple factual queries.
- The "Mark Walter / Dodgers chairman" example (line 536) is a *trigger* lesson: even stable roles need verification (the role may have changed).
- The "California Secretary of State" example (line 540) is a *default* lesson: do not rely on training knowledge for current holders of positions.
These 4 examples are Useful; the framing ("Claude searches before responding" as a persona behavior) is Persona Performance.
The project should adopt the *examples* (without the persona framing) as test cases for the RAG discipline.
### 4.6 The nagent corroboration (the strongest signal)
The strongest signal that this cluster is Useful is the nagent corroboration:
- nagent §3.2 stable-to-volatile cache ordering (`nagent_review_v2_3_20260612.md:1172-1328`) is the project's analog to Fable's "stable prefix is byte-identical across turns."
- nagent §5.5 cross-cutting RAG caveat (`nagent_review_v2_3_20260612.md:2956-2964`) explicitly addresses "where RAG goes in the cache layering" — the same problem Fable's search_instructions addresses with "where search fits in the epistemic model."
- nagent §6 compaction pattern (`nagent_review_v2_3_20260612.md:3002-3270`) is the project's analog to Fable's "every query deserves a substantive response" (line 575) — preserve state over flow.
All three nagent patterns are Useful + adopted (the cache styleguide exists; the compaction styleguide is pending). Fable's epistemic discipline is the *third* framework in the same conceptual space: the project's discipline is dimension-driven + cache-driven + compaction-driven; Fable's is search-driven.
### 4.7 The Manual Slop-specific adoption (the deferred nagent-rebuild candidate)
The deferred nagent-rebuild candidate list (per `nagent_review_v2_3_20260612.md:4119-4532`) includes:
- Candidate 12a: Stable-to-volatile cache ordering (per `nagent_review_v2_3_20260612.md:2966-2990`)
- Candidate 12b: Cache TTL GUI controls (per `nagent_review_v2_3_20260612.md:1328-1383`)
- Candidate 13: Compaction (per `nagent_review_v2_3_20260612.md:3002-3270`)
All three are directly relevant to this cluster.
The cluster's contribution to the deferred rebuild: the search-driven epistemic discipline (Fable) is a Useful supplement to the dimension-driven + cache-driven + compaction-driven discipline (Manual Slop / nagent).
The recommended addition to the deferred rebuild candidate list: a Candidate 14 (or extension of Candidate 12a) for "epistemic boundary surfacing" — the project should expose in the AI Settings panel (or a new panel) what the model knows, what it doesn't know, and what it's verifying.
---
## 5. Synthesis notes for the Tier 1 writer
### 5.1 Target synthesis sections
This cluster feeds:
- **§9 (Fable's Epistemic Discipline & Search Strategy)** — primary; the cluster's findings are the §9 evidence base.
- **§13 (The "Genuinely Useful" Patterns)** — the 4 Useful adoptions at §4.2 belong in §13's "Useful patterns from clusters 7-10" list.
- **§16 (Recommendations for the deferred nagent-rebuild)** — the candidate list additions at §4.7 belong in §16's "concrete recommendations."
### 5.2 Key claims to surface
1. **Fable's `knowledge_cutoff` is a Useful epistemic boundary.** The 4-step pattern (acknowledge boundary, search proactively, search before binary events, don't overclaim) is the principle the project's RAG discipline should aspire to.
2. **Fable's `search_instructions` is the proactive version of the project's RAG discipline.** The 6 search-behavior rules (§1.4) are the operational analog to the project's 6 RAG rules (§2.1). The contrast: Fable is default-on (consumer chat); the project is default-off (Application domain).
3. **The graceful-failure contract is a shared principle.** Fable's "evenhanded presentation, no overclaiming" (line 164) maps to the project's `Result[list[SearchResult], ErrorInfo]` pattern (§2.3). The project's implementation is *typed*; Fable's is *persona-driven*. Both satisfy the principle.
4. **The cache-strategy layer is the nagent corroboration.** The project's `cache_friendly_context.md` styleguide (per nagent §3.2 and §5.5) places RAG at the volatile layer (below the cache boundary). Fable's search-results don't have a cache layer in the Fable prompt itself, but the same principle applies: search results are per-turn and should not invalidate the cache.
5. **The compaction pattern is the epistemic-discipline parallel.** Fable's "every query deserves a substantive response" (line 575) is the principle; nagent's compaction pattern (§6) is the implementation (12-section structure + 10-question self-review). The project's `_handle_compress_discussion` at `src/app_controller.py:3357` is the half-built implementation.
### 5.3 Quotes to use in §9 (≤15 words each; longer passages paraphrased)
- `docs/artifacts/Fable System Prompt.md:158` — "Claude's reliable knowledge cutoff... is the end of Jan 2026."
- `docs/artifacts/Fable System Prompt.md:162` — "Claude searches before responding when asked about specific binary events."
- `docs/artifacts/Fable System Prompt.md:164` — "Does not make overconfident claims about the validity of search results."
- `docs/artifacts/Fable System Prompt.md:438` — "Use web_search when you need current information you don't have."
- `docs/artifacts/Fable System Prompt.md:450` — "For queries about current state... search to verify."
- `docs/artifacts/Fable System Prompt.md:459` — "If there are time-sensitive events... Claude must ALWAYS search."
- `docs/artifacts/Fable System Prompt.md:460` — "Don't mention any knowledge cutoff or not having real-time data."
- `docs/artifacts/Fable System Prompt.md:484` — "15+ words from any single source is a SEVERE VIOLATION."
- `docs/artifacts/Fable System Prompt.md:486` — "ONE quote per source MAXIMUM."
- `docs/artifacts/Fable System Prompt.md:575` — "Every query deserves a substantive response."
### 5.4 Project file:line refs to use
- `conductor/code_styleguides/rag_integration_discipline.md:1-284` — the project's RAG discipline (6 rules)
- `conductor/code_styleguides/rag_integration_discipline.md:13-21` — the 6-rule table
- `conductor/code_styleguides/rag_integration_discipline.md:26` — "The default is OFF"
- `conductor/code_styleguides/rag_integration_discipline.md:130-141` — RAG never mutates state
- `conductor/code_styleguides/rag_integration_discipline.md:199-247` — graceful failure contract
- `conductor/code_styleguides/cache_friendly_context.md:0` — the one-glance principle (stable-to-volatile)
- `conductor/code_styleguides/cache_friendly_context.md:26-42` — the 12-layer model
- `docs/guide_rag.md:303-348` — Configuration schema
- `docs/guide_rag.md:360-365` — Behavior When Disabled
- `docs/guide_rag.md:368-410` — Cross-System Integration
### 5.5 nagent section refs to use
- `nagent_review_v2_3_20260612.md:1172-1328` — §3.2 Stable-to-volatile cache ordering
- `nagent_review_v2_3_20260612.md:1180-1194` — the 14-layer block order table
- `nagent_review_v2_3_20260612.md:1254-1276` — Anthropic usage accounting (fold-back)
- `nagent_review_v2_3_20260612.md:2956-2964` — §5.5 The cross-cutting RAG caveat
- `nagent_review_v2_3_20260612.md:2966-2990` — §5.6 The Manual Slop implementation outline
- `nagent_review_v2_3_20260612.md:3002-3270` — §6 The compaction pattern
- `nagent_review_v2_3_20260612.md:3022-3044` — the 12-section output structure
- `nagent_review_v2_3_20260612.md:3046-3076` — the 10-question self-review
- `nagent_review_v2_1_20260612.md:350-388` — §2.10 RAG integration discipline (v2.1 source)
### 5.6 The cross-cluster note (the overlap with cluster 1)
Cluster 1 (`cluster_1_product_branding.md:230`) already noted the "search before answering about products" line at `docs/artifacts/Fable System Prompt.md:24`. That line is a narrow special case of the general "search for current state" rule at line 450.
Cluster 7's contribution: the *general* epistemic discipline, not just the Anthropic-product-specific special case.
The synthesis writer should reference both clusters when discussing epistemic discipline: cluster 1 for the persona framing, cluster 7 for the epistemic principle.
### 5.7 The 1 concrete recommendation for the deferred nagent-rebuild
Per §4.7: the deferred rebuild candidate list should add a "Candidate 14 (or extension of Candidate 12a): epistemic boundary surfacing." The project should expose in the AI Settings panel (or a new panel) what the model knows, what it doesn't know, and what it's verifying.
This is the project's analog to Fable's `knowledge_cutoff` discipline: the system surfaces the boundary, not just the result.
The implementation outline (per the nagent §5.6 pattern): a new `EpistemicBoundaryState` dataclass; a new `EpistemicBoundaryPanel` in the Operations Hub; new tests for the boundary surfacing; a new styleguide section in `conductor/code_styleguides/cache_friendly_context.md` (or a new `conductor/code_styleguides/epistemic_boundary.md`).
### 5.8 The "Useful" verdict rationale (for the synthesis writer's §13)
This cluster is Useful because:
1. The 4 Useful adoptions (§4.2) are concrete and implementable.
2. The 1 borderline adoption (§4.3) and the 1 caveat (§4.5) are recoverable as test cases.
3. The 1 Rejection (§4.4) is firm but does not undermine the cluster — the rejection is about the *default*, not the *principle*.
4. The nagent corroboration (§4.6) is the strongest signal: 3 of nagent's deferred-rebuild candidates (12a, 12b, 13) directly overlap with this cluster's findings.
5. The Manual Slop-specific adoption (§4.7) is a concrete candidate for the deferred rebuild.
The verdict is **Useful, with 1 firm Rejection on the default and 1 borderline adoption on the unrecognized-entity rule.**
---
**Sub-report complete.** This is the evidence base for §9 of `report.md`.
@@ -0,0 +1,499 @@
# Cluster 8: Memory System & Persistent Storage
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 166-251 (`memory_system` + `persistent_storage_for_artifacts`)
- `docs/artifacts/Fable System Prompt.md` lines 436-480 (`search_instructions`, the copyright-quote discipline)
- `src/models.py:200-231` (the `#region: History Utilities` block + `parse_history_entries`)
- `src/models.py:523-559` (`FileItem` schema — the curation memory dim)
- `src/history.py:8-100` (`UISnapshot`, `HistoryEntry`, `HistoryManager` — UI undo/redo, not memory)
- `docs/guide_discussions.md` (full file, 353 lines — the discussion dim)
- `conductor/code_styleguides/agent_memory_dimensions.md` (full file, 306 lines — the 4-dim canonical)
- `docs/guide_agent_memory_dimensions.md` (full file, 278 lines — the cross-cutting user guide)
- `docs/guide_knowledge_curation.md` (full file, 358 lines — the 4th dim deep-dive)
- `conductor/code_styleguides/knowledge_artifacts.md` (referenced; canonical for the harvest pattern)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.8 (Pattern 8: Harvest Knowledge), §3.1 (Knowledge harvest subsystem), §3.9 (Per-file knowledge notes), §4.4 (per-file notes sub-pattern)
- `conductor/tracks/fable_review_20260617/spec.md` §5 row 8 (this cluster's scope)
---
## 1. What Fable says
Fable's `memory_system` section is 5 lines (L166-170) and the `persistent_storage_for_artifacts` section runs L171-251. The two sections are structurally separate but conceptually adjacent: the `memory_system` describes Claude's user-facing memory feature (the setting Anthropic ships in Claude.ai); the `persistent_storage_for_artifacts` describes the JavaScript-key-value storage API that powers artifacts in Claude.ai. Both are framed as "state that persists across sessions" but they target different layers (a per-user memory layer vs. a per-artifact storage layer).
### 1.1 The `memory_system` section (L166-170)
The section is two bullets:
> "Claude has a memory system which provides Claude with access to derived information (memories) from past conversations with the user" (L168)
> "Claude has no memories of the user because the user has not enabled Claude's memory in Settings" (L170)
That's the whole section. The framing is **affordance**, not implementation: Fable tells the model what it *can* access (memories), not how the memories are stored, retrieved, ranked, audited, or pruned. The "derived information" hedge — "derived information (memories)" — is the load-bearing word: the model is told the memories are *not raw transcripts* but *extracted facts*. There is no description of the extraction pipeline, the dedup logic, the retention policy, the audit log, or the user controls.
The "user has not enabled Claude's memory in Settings" disclosure is a transparency move: if the user has the toggle off, the model must say so rather than fabricating memories. This is the same pattern Fable uses elsewhere (the "Claude does not have X" disclaimer) — it's product transparency, not behavioral instruction.
### 1.2 The `persistent_storage_for_artifacts` section (L171-251)
This is the substantive part. The section describes the `window.storage` API, a JavaScript key-value store available to artifacts. The section is structured as:
1. The 4 API methods (L181-184): `get(key, shared?)`, `set(key, value, shared?)`, `delete(key, shared?)`, `list(prefix?, shared?)`.
2. A usage example block (L188-202) showing `await window.storage.set('entries:123', JSON.stringify(entry))` and the corresponding `get`/`list` calls.
3. The "Key Design Pattern" subsection (L206-211): hierarchical keys under 200 chars, "no whitespace, path separators, or quotes"; "combine data updated together in single keys"; the example reframes `cards + benefits + completion` as a single `cards-and-benefits` key.
4. The "Data Scope" subsection (L215-220): personal (shared: false, default) vs shared (shared: true, visible to all users).
5. The "Error Handling" subsection (L222-241): "all storage operations can fail — always use try-catch"; the note that accessing non-existent keys throws (does not return null); the two try-catch patterns for "should succeed" vs "checking existence."
6. The "Limitations" subsection (L245-249): text/JSON only, keys under 200 chars, values under 5MB, rate-limited, last-write-wins, "always specify shared parameter explicitly."
7. A closing recommendation (L251): "implement proper error handling, show loading indicators and display data progressively…consider adding a reset option."
The substantive rules are concentrated in (3) and (5):
**The hierarchical-keys rule (L206):** "Use hierarchical keys under 200 chars: `table_name:record_id` (e.g., 'todos:todo_1', 'users:user_abc')." This is a real engineering pattern — namespace prefix + record id is the standard shape for a flat key-value store. The 200-char cap is a backend constraint; the no-whitespace / no-path-separator / no-quote rule is a constraint from the storage parser.
**The single-key batching rule (L210):** "Combine data that's updated together in the same operation into single keys to avoid multiple sequential storage calls." This is a real anti-pattern warning: the example reframes `await set('cards'); await set('benefits'); await set('completion')` as `await set('cards-and-benefits', {cards, benefits, completion})`. The motivation is rate-limiting — multiple sequential calls hit the limit; one combined call doesn't.
**The personal-vs-shared rule (L215-220):** The model is told to use `shared=false` by default and to inform users when their data will be visible to others. The "inform users" rule is a transparency directive tied to the personal/shared toggle.
**The try-catch rule (L222):** "All storage operations can fail - always use try-catch." This is paired with the asymmetry that `get()` *throws* on missing keys (rather than returning `null`), so the "check if a key exists" pattern requires a try-catch rather than a null-check. This is a real edge case in the API design; the model is told to wrap every call.
### 1.3 What's missing from Fable's framing
The `persistent_storage_for_artifacts` section is a **developer API reference**, not a **memory model**. It tells the model (or the artifact author) how to *use* the key-value store; it does not tell the model how to *think about* memory. Specifically absent:
- **No provenance.** Every key is opaque; the model is not told to record where data came from, which conversation, or which user action.
- **No retention / pruning.** The model is told keys can be deleted, but not told when or why. There is no "delete old entries after N days" rule, no "archive before delete" pattern.
- **No user audit.** The user can `rm`-style delete via the artifact, but the model has no obligation to surface the data to the user. The "consider adding a reset option" (L251) is a recommendation, not a requirement.
- **No concurrency control.** "Last-write-wins for concurrent updates" (L247) is stated as a limitation; the model is not told how to detect or resolve conflicts.
- **No transaction model.** The "combine data updated together" rule (L210) is a workaround for the lack of transactions; it's not framed as such.
- **No typing / schema.** Keys store arbitrary JSON; the model is told to namespace via the key prefix, not via any schema. There is no equivalent of nagent's 7-category schema or Manual Slop's `FileItem` schema.
### 1.4 Brief cross-ref: `search_instructions` (L436-480)
The `search_instructions` section is mostly about web search behavior (per cluster 7 scope), but the opening copyright-quote discipline (L444-446) is directly relevant to *this* cluster's research task:
> "15+ words from any single source is a SEVERE VIOLATION. ONE quote per source MAXIMUM—after one quote, that source is CLOSED. DEFAULT to paraphrasing; quotes should be rare exceptions." (L444-446)
Fable is telling the model to treat external sources the same way the user's cluster-spec tells the sub-agent to treat Fable: ≤15 words per quote, one quote per source, paraphrase by default. The structural parallel is informative — Fable's own discipline is being applied *to Fable itself* in this report.
---
## 2. What this project does
Manual Slop does not have a "memory system" in Fable's sense, nor a `window.storage` API. It has **4 memory dimensions**, each with a different shape, scope, and edit surface. The 4-dim model is the canonical reference (`conductor/code_styleguides/agent_memory_dimensions.md:13-18`); the project treats memory as **structured state**, not as opaque key-value blobs.
### 2.1 The 4 memory dimensions (the canonical model)
Per `conductor/code_styleguides/agent_memory_dimensions.md:13-18`:
| Dim | Where it lives | What it stores | How it's edited | SSDL |
|---|---|---|---|---|
| 1 | **Curation** | `FileItem` + `ContextPreset` + Fuzzy Anchors | *How to render a file* | Structural File Editor; project TOML | `[Q]` |
| 2 | **Discussion** | `app.disc_entries` + branching + `UISnapshot` | *What was said* | GUI `[Edit]` mode; `[Branch]`; undo/redo | `o==>` |
| 3 | **RAG** | `src/rag_engine.py` (ChromaDB) | *Semantic fingerprints* | (opaque vector store) | `[Q]` |
| 4 | **Knowledge** | `~/.manual_slop/knowledge/*.md` + per-file + digest + ledger | *Durable learnings* | Plain markdown edit | `o==>` |
**The 4 dimensions are not interchangeable.** Per `conductor/code_styleguides/agent_memory_dimensions.md:244`: "When designing a new feature, ask: which of the 4 dimensions is the natural home? Don't reach for the RAG because 'it's there'; reach for the dimension whose shape matches the data."
The decision tree (`conductor/code_styleguides/agent_memory_dimensions.md:264-271`):
```
Q: What is the *data* (not the operation) the feature needs?
├── "How to render a file" ──► Curation (FileItem)
├── "What was said in this chat" ──► Discussion (disc_entries)
├── "What similar content exists" ──► RAG (RAGEngine.search)
└── "What we learned from past runs" ──► Knowledge (knowledge/digest.md)
```
This is the data-oriented contrast to Fable's "one key-value store, call it memory" framing. Manual Slop's model says: **memory is plural**; the wrong shape for the right question is a common mistake; the 4 dims are the named, distinct, user-editable layers.
### 2.2 Curation memory (per-file structural)
**The shape** (`conductor/code_styleguides/agent_memory_dimensions.md:22-66` + `src/models.py:523-559`):
The `FileItem` dataclass at `src/models.py:523` has 10 fields:
```python
@dataclass
class FileItem:
path: str
auto_aggregate: bool = True
force_full: bool = False
view_mode: str = 'full'
selected: bool = False
ast_signatures: bool = False
ast_definitions: bool = False
ast_mask: dict[str, str] = field(default_factory=dict)
custom_slices: list[dict] = field(default_factory=list)
injected_at: Optional[float] = None
```
The 9 explicit fields are all about **how to render a file** — none are about user-derived facts about the file. `view_mode` selects between full / skeleton / summary / sig / def / agg; `ast_signatures` / `ast_definitions` are AST-aware reductions; `custom_slices` are the Fuzzy Anchor slices (`docs/guide_context_curation.md`). The user's edit surface is the Structural File Editor (the GUI modal that lets the user change `view_mode` per file).
**The storage shape.** Persisted in `manual_slop.toml` (or a project TOML) as `[[discussion.context_files]]` entries via `FileItem.to_dict()` / `from_dict()` (`src/models.py:550-580`). A `ContextPreset` is a named, persisted set of `FileItem`s (`src/models.py:909-937`).
**No `notes` field.** Per nagent_review_v2_3 §3.9 (`nagent_review_v2_3_20260612.md:2091`): "Manual Slop equivalent. `models.FileItem` (per `src/models.py:510`) has 9 fields… **No `notes` field.** No per-file knowledge notes dimension." This is the load-bearing gap that cluster 8 will surface — the curation dim is *about rendering*, not *about facts*. Fable's `entries:123` pattern (storing user-derived facts keyed by namespace) has no analog in the curation dim; the closest analog is the **knowledge dim** (4th dim), which is the project's structured answer to "remember things I've learned."
### 2.3 Discussion memory (per-discussion conversational)
**The shape** (`docs/guide_discussions.md:31-43`):
```python
{
"role": str, # "User" | "AI" | "Vendor API" | "System" | <user-edited>
"content": str, # fully editable in GUI
"collapsed": bool,
"ts": str, # ISO timestamp, prefixed with `@`
"thinking_segments": list[dict], # AI entries with <thinking> blocks
"usage": dict, # {"input_tokens", "output_tokens", "cache_read_input_tokens"}
"read_mode": bool, # render as Markdown vs editable text
}
```
The data is a flat list of entry dicts (`app.disc_entries: list[dict]`). The data model is **open**: extra keys are allowed and ignored by the renderer (`docs/guide_discussions.md:43`). The user can add custom metadata via the Hook API or by editing the project TOML directly.
**The discussion is the source of truth for "what was said."** Per `conductor/code_styleguides/agent_memory_dimensions.md:124`: "The `disc_entries` list is the single source of truth for 'what was said in this discussion.'"
**The edit surface.** A1-A7 per-entry operations (`docs/guide_discussions.md:72-86`): edit content, toggle read/edit, collapse/expand, change role, insert, delete, branch. Branching creates a new Take named `<base>_take_<n>`; takes are sibling views of the same conversation, not separate conversations. Per-entry edits are undo-able (`src/history.py:71-141`, `HistoryManager`).
**The persistence shape** (`docs/guide_discussions.md:202-249`): the discussion persists in the project TOML under `project.discussion.discussions[<name>]["history"]`. The persistence is **explicit** (B4 Save button) and **implicit** (on `_switch_discussion` and `_branch_discussion`). The "context_snapshot" (`disc_data["context_snapshot"]`) records the FileItem list at send time; switching back to a discussion restores the file list. This is the project's answer to "remember which files were in context for this discussion."
**The data model is precise.** Each entry has a structured role, a timestamp, a collapsed flag, optional thinking segments, and optional usage accounting. The model is *not* a flat text log; it is a list of structured records. Fable's `entries:123 → JSON.stringify(entry)` (L195) pattern is roughly equivalent to one Manual Slop discussion entry (each is a structured record), but Manual Slop's record has 7 explicit fields and is open to extension; Fable's is an opaque JSON blob in a key-value store.
### 2.4 RAG memory (opt-in semantic)
**The shape** (`conductor/code_styleguides/agent_memory_dimensions.md:128-170`):
ChromaDB vector store; per-file `FileItem`-like records with embeddings. `RAGEngine.search(query, k=N)` returns the top-N most-similar chunks. Persisted in `tests/artifacts/.slop_cache/chroma_<embedding_provider>/`.
**RAG is opt-in, default-off in new projects.** Per `conductor/code_styleguides/rag_integration_discipline.md` (referenced from `agent_memory_dimensions.md:170`): the discipline is opt-in, complement (never replace), provenance (file path + chunk offset), no mutation, feature-gated, graceful failure.
**RAG is the wrong shape for "what did we learn from past sessions."** Per `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md:631`: RAG is fuzzy, opaque, not auditable, not durable across embedding-provider switches. The knowledge dim is the right shape for durable learnings; RAG is the right shape for semantic search at query time.
### 2.5 Knowledge memory (per-project durable, provenance-aware)
**The shape** (`conductor/code_styleguides/agent_memory_dimensions.md:174-226` + `docs/guide_knowledge_curation.md`):
A markdown tree at `~/.manual_slop/knowledge/`:
| File | Format | What it stores |
|---|---|---|
| `knowledge/facts.md` | `- {statement} {provenance}` | Durable statements about systems, repos, tools |
| `knowledge/decisions.md` | `- {statement, reason} {provenance}` | Decisions that were made |
| `knowledge/questions.md` | `- {question} {provenance}` | Unanswered questions |
| `knowledge/playbooks.md` | `- **{name}**: {steps} {provenance}` | Reusable command sequences |
| `knowledge/tasks.md` | `- {task}` (## Open / ## Done) | Open and done tasks |
| `knowledge/files/{file_id}.md` | `- {note} {provenance}` | Per-file notes (keyed by inode) |
| `knowledge/digest.md` | bounded 4KB | The projected digest (injected as `{knowledge}` block) |
| `knowledge/ledger.json` | `{entries: {sha256: {status, at, items}}}` | The harvest audit log |
**The provenance string** is `[from: {conversation_name}, {date}]`. The provenance is appended by the harvest; the user can edit any line. The audit log (`ledger.json`) gates deletion on a proven harvest — the user cannot accidentally delete a conversation whose durable knowledge hasn't been distilled (`docs/guide_knowledge_curation.md:146-182`).
**The 7-category harvest schema** (`docs/guide_knowledge_curation.md:188-234`): the LLM's harvest output is strict JSON with 7 categories (`facts`, `decisions`, `tasks_done`, `tasks_open`, `questions`, `playbooks`, `files`). The category schema is the load-bearing contract: the LLM cannot return prose, cannot omit categories, cannot invent items ("Empty arrays are valid and expected"). The retry budget is 2 attempts (`docs/guide_knowledge_curation.md:236-255`).
**The size budgets** (`docs/guide_knowledge_curation.md:258-264`):
| Constant | Value | Why |
|---|---|---|
| `SUMMARIZE_THRESHOLD_BYTES` | 64 KB | Files > 64KB get summarized first |
| `MAX_HARVEST_SOURCE_BYTES` | 1 MB | Files > 1MB are kept (not harvested) |
| `DIGEST_MAX_BYTES` | 4 KB | The bounded digest size |
| `HARVEST_MAX_ATTEMPTS` | 2 | Retry budget on parse failure |
The 4KB digest is the projected view injected as the `{knowledge}` block in the initial context (`docs/guide_knowledge_curation.md:323-348`). The bounded digest is the cache-friendly answer to "give me the durable knowledge in 4KB or less."
**The "delete to turn off" pattern** (`docs/guide_knowledge_curation.md:285-306`): the knowledge digest is gated by file presence. `rm ~/.manual_slop/knowledge/digest.md` → no `{knowledge}` block injected. No env var, no config toggle, no GUI checkbox. The file is the switch. Re-enable by running the harvest, which regenerates the digest.
### 2.6 The contrast with Fable's `window.storage`
| Aspect | Fable `window.storage` | Manual Slop |
|---|---|---|
| **Scope** | Per-artifact (each artifact is its own KV store) | Per-project (4 dims, project-scoped) |
| **Schema** | None (opaque JSON) | Typed: `FileItem` (curation), entry dict (discussion), ChromaDB record (RAG), 5 category files (knowledge) |
| **Provenance** | None | `[from: conversation, date]` on every knowledge line; sha256 ledger; inode-keyed per-file notes |
| **Audit** | None | `ledger.json` gates deletion on proven harvest |
| **Retention** | Last-write-wins; no retention policy | Append-only category files; bounded 4KB digest; the harvest reclaim lifecycle |
| **User controls** | "consider adding a reset option" (recommendation) | Plain-text edit of every category file; GUI Knowledge panel; per-file notes; dry-run-by-default harvest |
| **Error handling** | `try/catch` around every call | Result-style failure markers (`harvest-failed`, `too-large`, `deleted-unharvested`) in the ledger; graceful failure + visible marker |
| **Concurrency** | Last-write-wins (acknowledged as limitation) | Append-only merge (no contention); per-thread `threading.local()` for transient state |
| **Memory-as-plural** | One KV store | 4 named dimensions with non-interchangeable shapes |
The contrast is not just *more features*. The contrast is **shape**. Fable's `window.storage` is a flat key-value namespace with no semantics beyond namespace-prefix conventions. Manual Slop's 4 dims are *named* (curation / discussion / RAG / knowledge), *shaped* (each has a distinct data model), *edited* (each has a distinct user surface), and *queried* (each has a distinct query model). Fable's "use a hierarchical key" pattern is the same shape advice Manual Slop gives, but applied to a single KV store rather than to 4 named dimensions.
### 2.7 UI history (the unrelated `src/history.py`)
`src/history.py` defines `UISnapshot` (the UI state for undo/redo), `HistoryEntry`, and `HistoryManager` (the stack-based undo/redo). This is **not** memory in the Fable sense — it is in-memory undo state for the current session. The `UISnapshot` dataclass captures 13 fields (ai_input, project_system_prompt, temperature, disc_entries, files, screenshots, etc.); the `HistoryManager` pushes/pops up to 100 snapshots. The snapshots are not persisted to disk; they are in-process only.
This is mentioned only to head off confusion: when Fable says "memory system," Manual Slop has *both* a `HistoryManager` (in-process undo) *and* the 4 memory dimensions (persistent storage). They serve different purposes. The in-process undo is not a memory dim; the 4 memory dims are.
### 2.8 Where the 4 dims land in the cache-friendly context (the 12-layer model)
The 4 memory dims are not just a static classification; they are *injected* into the LLM context at specific layers of the 12-layer cache-friendly model (per `conductor/code_styleguides/cache_friendly_context.md`):
| Layer | Content | Which dim? |
|---|---|---|
| 1-6 | role, schema, tools, system prompt, persona, project context | (foundational) |
| **7** | **knowledge digest** | **Knowledge (4th dim)** |
| 8-12 | discussion metadata, active preset, per-file details, prior tool results, user message | **Curation (1st dim)** + **Discussion (2nd dim)** |
| (separate) | `{rag-context}` block (opt-in) | **RAG (3rd dim)** |
The knowledge digest is the *only* memory dim in the stable cache prefix (layer 7). Per `docs/guide_knowledge_curation.md:326-348`: "The digest is injected into the *stable* position of the initial context (layer 7 of the 12-layer model)… The cache can include the digest in the cached prefix; the volatile suffix is not cached." This is the cache-friendly answer to "give me the durable knowledge in 4KB or less — and let me cache it across turns."
The curation dim is per-file and lands in the *volatile* suffix (layer 10), because each turn may have different files in scope. The discussion dim is the *user's own prior turns* (layers 8-12) and is per-turn. The RAG dim is a separate `{rag-context}` block injected at LLM call time, opt-in (`src/rag_engine.py`).
**The contrast with Fable.** Fable's `window.storage` does not specify *where* in the context the stored data appears — the artifact author decides. Manual Slop's 4 dims have fixed injection points: layer 7 (knowledge digest), layer 10 (curation per-file details), volatile suffix (discussion prior turns), and the `{rag-context}` block (RAG). The injection points are part of the data model, not a downstream decision.
The cache byte-comparison test (`tests/test_aggregate_caching.py`, per `conductor/code_styleguides/cache_friendly_context.md` §2) is the design contract: the first N characters of the context are identical across turns of the same discussion. N is `aggregate.stable_prefix_length(ctrl)`; the knowledge digest is one of the load-bearing contributors to the stable prefix. Fable's `window.storage` has no equivalent — there is no "stable prefix" concept in an artifact's KV store.
### 2.9 The implementation cross-references (file:line map)
Per `conductor/code_styleguides/agent_memory_dimensions.md:280-294`, the implementation is mostly present: curation lives in `src/models.py:510-559` (`FileItem`) + `src/context_presets.py` + `src/aggregate.py`; discussion lives in `src/gui_2.py:3770-3853` (A1-A7 render) + `src/history.py:8-71` (`UISnapshot`, `HistoryManager`) + `src/project_manager.py:429+` (branching); RAG lives in `src/rag_engine.py:1-384` (ChromaDB). The knowledge store + harvest CLI are "(proposed)" entries — scoped in Candidate 11 of `nagent_review_v2_3_20260612.md:2098`. Fable's `window.storage` is a runtime API exposed by the Claude.ai browser sandbox; the implementation is the artifact host, not the prompt. Manual Slop's codification names file:line for each dim — the implementation is *in the project's own code*.
---
## 3. What nagent does
nagent's `knowledge harvest` (`nagent-gc`) is the substantive pattern in this cluster. The harvest is the **3rd memory dimension** in nagent's framing (per `nagent_review_v2_3_20260612.md:552-674`); the project then extends nagent's framing to a **4th dimension** (per-file knowledge notes) at §3.9 (L2022-2105). The two are sibling patterns.
### 3.1 The knowledge harvest (Pattern 8) — `nagent_review_v2_3_20260612.md:552-674`
**The claim** (`nagent_review_v2_3_20260612.md:554`): "Dead conversations accumulate, and deleting them loses what was learned. Therefore: distill, then delete — and feed the distillate back in."
**The components** (`nagent_review_v2_3_20260612.md:556-571`):
| Component | Where | What it does |
|---|---|---|
| `nagent-gc` | `bin/nagent-gc:1-150` | CLI: classify, estimate cost, harvest, reclaim |
| `run_gc(root, ...)` | `bin/helpers/nagent_gc_lib.py:330+` | Library: dry-run or apply; iterates harvest candidates |
| `scan_root(root)` | `bin/helpers/nagent_gc_lib.py:80+` | Classifies artifacts: `live` / `user-kept` / `prune` / `harvest` / `keep` |
| `harvest_conversation(path, ...)` | `bin/helpers/nagent_gc_lib.py:235+` | For files >64KB, summarize first; otherwise use full text; 2 retries on parse failure |
| `merge_harvest(root, name, harvested, date)` | `bin/helpers/nagent_gc_lib.py:245+` | Appends harvested items to category files with provenance |
| `regenerate_digest(root, max_bytes=4096)` | `bin/helpers/nagent_gc_lib.py:380+` | Rebuilds `digest.md` from category files; sections in fixed order; newest first |
| `load_ledger` / `save_ledger` | `bin/helpers/nagent_gc_lib.py:115-130` | sha256-of-content gate; "already harvested" path reclaims without re-distilling |
| `parse_harvest_json(text)` | `bin/helpers/nagent_gc_lib.py:180+` | Strict JSON parser with code-fence tolerance; validates 7 categories |
**The 7-category schema** (`nagent_review_v2_3_20260612.md:573-583`): facts / decisions / tasks_done / tasks_open / questions / playbooks / files. Each row is `{statement, detail}` (or `{name, steps}` for playbooks, or `{path, note}` for files). The prompt mandates: "Return only JSON in exactly this form (no prose, no markdown fence)." "Empty arrays are valid and expected: most conversations contain nothing durable. Do not invent items to fill categories."
**The constants** (`nagent_review_v2_3_20260612.md:585-591`): same 4 budgets as Manual Slop (`SUMMARIZE_THRESHOLD_BYTES = 64KB`, `MAX_HARVEST_SOURCE_BYTES = 1MB`, `DIGEST_MAX_BYTES = 4KB`, `HARVEST_MAX_ATTEMPTS = 2`). The Manual Slop implementation borrows these constants directly (`docs/guide_knowledge_curation.md:258-264`).
**The classification** (`nagent_review_v2_3_20260612.md:600-611`):
| Class | Trigger | Action |
|---|---|---|
| `live` | `file-index-*`, `index-saved-conversations-*`, per-file conversations whose target still exists, `latest-*` active conversations | KEEP |
| `user-kept` | Path is in the saved-conversations index | KEEP |
| `harvest` | Per-file conversations whose target is gone; archived conversations; delegated sub-conversations | LLM-DISTILL → append → reclaim |
| `prune` | Split directories with no `index.json`; split directories whose source is gone or hash doesn't match | DELETE |
| `keep` | Anything unclassified | KEEP (default safe) |
**The digest ordering** (`nagent_review_v2_3_20260612.md:613-614`): sections iterated in `(Open tasks, Open questions, Decisions, Facts, Playbooks)` order; within each section, bullets reversed for newest-first. If all sections empty, the digest is *deleted* (the "delete to turn off" pattern).
### 3.2 The per-file knowledge notes (sub-pattern) — `nagent_review_v2_3_20260612.md:2022-2105`
**The claim** (`nagent_review_v2_3_20260612.md:2024`): "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."
**The implementation** (the `merge_harvest` "files" branch, `nagent_review_v2_3_20260612.md:2028-2054`):
```python
for row in harvested.get("files", []):
if not isinstance(row, dict):
continue
path_text = str(row.get("path") or "").strip()
note = str(row.get("note") or "").strip()
if not note:
continue
target = Path(path_text) if path_text else None
if target is not None and target.is_file():
try:
file_id = file_id_for_path(target)
except OSError:
file_id = None
if file_id is not None:
_append_bullets(
file_knowledge_path(root, file_id), f"# {target.resolve()}",
[f"{note} {provenance}"],
)
file_notes += 1
continue
# Target no longer resolvable: the note survives as a fact.
prefix = f"{path_text}: " if path_text else ""
_append_bullets(knowledge / "facts.md", "# Facts", [f"{prefix}{note} {provenance}"])
file_notes += 1
```
**The fallback** (`nagent_review_v2_3_20260612.md:2051-2053`): "Target no longer resolvable: the note survives as a fact." The note's path-prefix (`{path}: `) is preserved as a prefix on the fallback fact; the per-file binding is lost but the note survives.
**The injection point** (`nagent_review_v2_3_20260612.md:2509-2515`): per-file knowledge is injected as part of the file-edit block, in the stable position. When a file is in scope for editing, its knowledge comes back automatically.
**The verdict for Manual Slop** (`nagent_review_v2_3_20260612.md:2091-2098`):
> "Manual Slop equivalent. `models.FileItem` (per `src/models.py:510`) has 9 fields: `path, auto_aggregate, force_full, view_mode, selected, ast_signatures, ast_definitions, ast_mask, custom_slices`. **No `notes` field.** No per-file knowledge notes dimension."
> "Verdict. **GAP.** The per-file notes dimension is absent in Manual Slop. `FileItem` would need a `notes: str = ""` field; the Structural File Editor would need a 'Notes' text area; `aggregate.py:run` would need a `{file-knowledge}` block in the initial context."
The gap is precisely named. The Manual Slop candidate list includes "Candidate 11.1: per-file knowledge notes — bundle with Candidate 11" (`nagent_review_v2_3_20260612.md:2098`).
### 3.3 The 4-dim framing in nagent_review_v2_3
The v2.3 review explicitly frames the project in terms of the 4 memory dims:
> "The 4 memory dimensions (the framing):" (`nagent_review_v2_3_20260612.md:4198`)
The surrounding context (the section header at `nagent_review_v2_3_20260612.md:4187-4202`) is the project's design intent: curation (FileItem) and discussion (disc_entries) are present and strong; RAG is opt-in and is the wrong shape for durable knowledge; knowledge is the missing dim. The Manual Slop codification of the 4 dims (`conductor/code_styleguides/agent_memory_dimensions.md`, `docs/guide_agent_memory_dimensions.md`, `docs/guide_knowledge_curation.md`) is the direct response to nagent's framing — Manual Slop adopts the 4-dim model and adds the knowledge dim, with the digest bounded to 4KB and the harvest pipeline implemented.
**The note on the spec's section reference.** The track spec (`fable_review_20260617/spec.md:222`) cites nagent §2.1 for "4 memory dimensions." In v2.3 the §2.1 slot is "Pattern 1: Text In, Text Out" (`nagent_review_v2_3_20260612.md:242`); the 4-dim framing moved to §2.8 (Pattern 8: Harvest Knowledge, Reclaim Space) in the v2.3 restructure. The §3.9 reference for per-file knowledge notes is correct in v2.3 (`nagent_review_v2_3_20260612.md:2022`). The substance is unchanged across versions — the v2.1/v2.2 §2.1 is the same content as v2.3 §2.8. Cluster 8 cites v2.3 throughout.
### 3.4 What Manual Slop adopted from nagent (the load-bearing adoption)
The Manual Slop codification is not just *inspired by* nagent — it adopts specific patterns and constants directly:
**The 4 size budgets** are identical (`docs/guide_knowledge_curation.md:258-264` + `nagent_review_v2_3_20260612.md:585-591`): `SUMMARIZE_THRESHOLD_BYTES = 64KB`, `MAX_HARVEST_SOURCE_BYTES = 1MB`, `DIGEST_MAX_BYTES = 4KB`, `HARVEST_MAX_ATTEMPTS = 2`.
**The 7-category schema** is identical: facts / decisions / tasks_done / tasks_open / questions / playbooks / files. Same shape, same JSON contract, same code-fence tolerance.
**The retry-suffix pattern** is identical: on retry, append `\nYour previous reply was not valid JSON. Return only the JSON object.\n` to the prompt (`docs/guide_knowledge_curation.md:255`).
**The provenance format** is identical: `[from: {conversation_name}, {date}]` (`docs/guide_knowledge_curation.md:42`).
**The "delete to turn off" pattern** is identical: `rm ~/.manual_slop/knowledge/digest.md` → no `{knowledge}` block injected (`docs/guide_knowledge_curation.md:289`).
**The digest section ordering** is identical: Open tasks, Open questions, Decisions, Facts, Playbooks; within each section, bullets reversed for newest-first (`docs/guide_knowledge_curation.md:137`).
**The "graceful failure" markers** are identical: `harvest-failed`, `too-large`, `deleted-unharvested` (`docs/guide_knowledge_curation.md:178-181`).
**The per-file notes pattern** is adopted but not yet implemented: the 4 Manual Slop docs describe the pattern, but `models.FileItem` does not yet have a `notes` field. The implementation is the deferred Candidate 11.1.
**The dry-run-by-default safety** is the same pattern (`docs/guide_knowledge_curation.md:266-281`): without `--apply`, the CLI classifies, estimates cost, and prints a report. No mutation.
The adoption is not a 1:1 port. Manual Slop adapts the pattern for its 4-dim model (curation is its own dim, not a "files" category sub-bucket) and for the project's data-oriented conventions (`Result[T]` + `ErrorInfo` instead of exceptions). But the constants, schema, retry pattern, provenance format, section ordering, delete-to-turn-off pattern, and graceful-failure markers are direct ports. nagent's harvest library is the source; Manual Slop's 4 canonical docs are the target.
---
## 4. Verdict
**Useful + nagent-stronger.** Fable's `window.storage` API + the hierarchical-keys pattern + the single-key-batching rule + the personal-vs-shared scoping + the try-catch-everything rule are genuinely useful engineering guidance. They are the *table-stakes* of any key-value client library: namespace your keys, batch your writes, distinguish personal vs shared scope, handle errors. None of these patterns are Fable's invention; they are the standard pattern for the API surface Fable exposes.
But Fable's framing is **memory-as-blob-store**: one key-value namespace, opaque JSON, no provenance, no retention, no audit, no schema. Manual Slop's 4 memory dimensions (curation / discussion / RAG / knowledge) are the **stronger, more grounded** version of Fable's "memory" framing. Each dim has a named shape, a user-editable surface, a query model, and (for knowledge) a provenance-aware harvest pipeline with an audit ledger. Fable's 5-line `memory_system` section is a product toggle; Manual Slop's `agent_memory_dimensions.md` is a 306-line canonical styleguide with a decision tree.
nagent's knowledge harvest + per-file knowledge notes is **the strong version of Fable's "memory" framing**. The 7-category schema, the `[from: conversation, date]` provenance, the sha256-of-content ledger, the 4KB bounded digest, the per-file notes keyed by inode — these are the load-bearing patterns that turn a key-value blob into a *durable memory system*. nagent implements them; the project adopts them.
### 4.1 Pattern-by-pattern judgment
**Pattern 1: Hierarchical keys under 200 chars (L206).** **Useful.** This is a real engineering pattern (namespace prefix + record id); the 200-char cap is a backend constraint; the no-whitespace / no-slash / no-quote rule is the parser constraint. Manual Slop's analog is implicit: the `app.disc_entries` list uses index-based addressing; `FileItem` is keyed by path; `knowledge/files/{file_id}.md` is keyed by inode. None of these are flat key-value, but the *underlying principle* (each memory cell has a structured key) is the same. Recommend: document this principle in the project's memory dim styleguide (it already exists in the per-dim "where it lives" column; no new spec needed).
**Pattern 2: Single-key batching to avoid rate limits (L210).** **Useful.** The example reframes `await set('cards'); await set('benefits'); await set('completion')` as `await set('cards-and-benefits', {cards, benefits, completion})`. This is a rate-limit-driven batching pattern; Manual Slop's analog is the digest: the knowledge dim batches *all 7 categories* into a single 4KB `digest.md` file rather than emitting 7 separate `set` calls. Recommend: no action — Manual Slop already batches.
**Pattern 3: Personal vs shared data scope (L215-220).** **Useful + Manual Slop-lacking.** The personal/shared distinction is a real product feature; the "inform users when data is visible to others" transparency rule is a good safety practice. Manual Slop has no analog: the knowledge dim is single-user (per-machine, `~/.manual_slop/knowledge/`); the curation dim is per-project (in the project TOML); the discussion dim is per-discussion (in the project TOML). There is no shared-storage concept. Recommend: note as out-of-scope — Manual Slop is a single-user tool; shared storage would be a feature add, not a "memory model" improvement.
**Pattern 4: try/catch around every storage call (L222).** **Useful + Manual Slop-different.** Fable's try/catch is the standard JS error-handling pattern; Manual Slop's convention is the data-oriented `Result[T]` + `ErrorInfo` dataclass pattern (`conductor/code_styleguides/error_handling.md`). The harvest pipeline uses 4 result markers (`harvested` / `harvest-failed` / `deleted-unharvested` / `too-large`) in `ledger.json` rather than exceptions (`docs/guide_knowledge_curation.md:178-181`). Recommend: no action — the project's convention is the data-oriented one, which is the stronger pattern.
**Pattern 5: "Claude has a memory system which provides Claude with access to derived information (memories) from past conversations" (L168).** **Useful (the concept) + nagent-stronger (the implementation).** The *concept* of a memory system that derives facts from past conversations is the right product framing. The *implementation* is opaque ("derived information") and has no provenance, no audit, no schema. nagent's knowledge harvest + Manual Slop's knowledge dim are the strong versions: schema (7 categories), provenance (`[from: conversation, date]`), audit (`ledger.json`), retention (4KB digest with truncation marker). Recommend: explicitly reject Fable's "one opaque memory feature" framing; cite nagent + Manual Slop's structured 4-dim model as the alternative.
**Pattern 6: "No `notes` field on FileItem" (the gap).** **GAP per nagent §3.9.** The project has the 4-dim framing but lacks the per-file notes dimension within the knowledge dim. The fix is named in `nagent_review_v2_3_20260612.md:2096-2098`: add `notes: str = ""` to `FileItem`, add a "Notes" text area to the Structural File Editor, add a `{file-knowledge}` block to `aggregate.py:run`. This is Candidate 11.1 in the nagent review's deferred-rebuild list. Recommend: include in `decisions.md` as a deferred-rebuild recommendation.
### 4.2 What to reject
- **The "one opaque KV store = memory" framing.** Fable's `window.storage` is a *storage API*, not a *memory model*. Treating it as a memory model collapses 4 distinct dimensions (curation / discussion / RAG / knowledge) into one flat namespace with no shape. The project should explicitly reject this framing.
- **The "user enables memory in Settings" toggle as a memory model.** Fable's `memory_system` is a 5-line product disclosure, not a memory architecture. The project should not import the toggle framing.
- **The "no schema, namespace via key prefix" pattern.** Keys like `entries:123` are namespace-by-convention, not namespace-by-type. The project's 4-dim model has named types (FileItem, disc_entry, ChromaDB record, knowledge bullet); the Fable pattern has no types. The project should not import the untyped-namespace pattern.
### 4.3 What to keep
- **The hierarchical-keys principle** (each memory cell has a structured key) — already implicit in Manual Slop's per-dim shapes.
- **The personal-vs-shared scope distinction** — out-of-scope for Manual Slop (single-user tool), but the principle is sound.
- **The error-handling discipline** — already implemented as `Result[T]` + `ErrorInfo` + ledger status markers.
- **The "consider adding a reset option" transparency** — already implemented as the "delete to turn off" pattern (`docs/guide_knowledge_curation.md:285-306`).
### 4.4 What to add (deferred-rebuild candidate)
- **Per-file knowledge notes (Candidate 11.1).** The 4-dim model is incomplete without the per-file notes dimension. The fix is small (add `notes` field + GUI text area + `{file-knowledge}` injection block) but the value is high (durable facts about specific files survive across sessions). Flag in `decisions.md`.
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds `report.md` §10 ("Fable's Memory System & Persistent Storage") directly. Cross-references to §13 ("Genuinely Useful Patterns") and §14 ("Anti-User Watchdog Patterns"). The verdict orientation is **Useful + nagent-stronger** (per `fable_review_20260617/spec.md:182`).
### 5.1 Key claims to surface in §10
1. **Fable's `window.storage` is a useful API reference, not a memory model.** The 4 API methods, the hierarchical-keys rule, the single-key batching, the personal-vs-shared scope, and the try/catch discipline are all genuinely good engineering guidance. None of them are Fable's invention; they are the standard pattern for a key-value client library. Cite L181-184 (API methods), L206-211 (key design), L215-220 (data scope), L222-241 (error handling).
2. **Fable's `memory_system` is a 5-line product disclosure, not a memory architecture.** L168 and L170 are a setting toggle and a transparency statement, not an implementation. The "derived information" hedge is load-bearing: Fable admits the memories are extracted facts but does not describe the extraction, the audit, the retention, or the user controls. The contrast is Manual Slop's 306-line canonical styleguide + the 358-line user-facing guide + the 4-dim model with decision tree.
3. **Manual Slop's 4 memory dimensions are the strong version of Fable's "memory" framing.** Each dim has a named shape, a user-editable surface, a query model, and (for knowledge) a provenance-aware harvest pipeline with an audit ledger. Cite `conductor/code_styleguides/agent_memory_dimensions.md:13-18` (the table) + `agent_memory_dimensions.md:244-272` (the boundaries + decision tree).
4. **nagent's knowledge harvest is the strong version of Fable's "memory" framing.** The 7-category schema, the `[from: conversation, date]` provenance, the sha256-of-content ledger, the 4KB bounded digest, the per-file notes keyed by inode — these are the load-bearing patterns that turn a key-value blob into a durable memory system. Cite `nagent_review_v2_3_20260612.md:552-674` (Pattern 8) + `nagent_review_v2_3_20260612.md:2022-2105` (per-file notes §3.9).
5. **The per-file notes dimension is the named GAP.** Per `nagent_review_v2_3_20260612.md:2091-2098`: FileItem has 9 fields, no `notes`. The fix is Candidate 11.1 in the nagent deferred-rebuild list. Cite explicitly as a deferred-rebuild recommendation.
6. **The data-oriented contrast.** Manual Slop's `Result[T]` + `ErrorInfo` + ledger status markers (`harvested` / `harvest-failed` / `deleted-unharvested` / `too-large`) are the data-grounded alternative to Fable's `try/catch` pattern. The harvest pipeline's failure modes are encoded in `ledger.json`, not raised as exceptions. Cite `conductor/code_styleguides/error_handling.md` + `docs/guide_knowledge_curation.md:178-181` (the ledger status values) + `docs/guide_knowledge_curation.md:308-320` (the graceful failure modes).
### 5.2 Quotes to use in §10
- Fable L168: "Claude has a memory system which provides Claude with access to derived information (memories) from past conversations with the user" (≤15 words paraphrased; full quote exceeds)
- Fable L170: "Claude has no memories of the user because the user has not enabled Claude's memory in Settings" (full quote, 15 words)
- Fable L181: "await window.storage.get(key, shared?) - Retrieve a value → {key, value, shared} | null" (paraphrase)
- Fable L206: "Use hierarchical keys under 200 chars: table_name:record_id" (12 words)
- Fable L210: "Combine data that's updated together in the same operation into single keys" (12 words)
- Fable L215: "Personal data (shared: false, default): Only accessible by the current user" (10 words)
- Fable L222: "All storage operations can fail - always use try-catch" (8 words)
- `conductor/code_styleguides/agent_memory_dimensions.md:13`: "Curation | FileItem + ContextPreset + Fuzzy Anchors | How to render a file in the AI's context window" (paraphrase; the table)
- `conductor/code_styleguides/agent_memory_dimensions.md:244`: "When designing a new feature, ask: which of the 4 dimensions is the natural home?" (16 words)
- `docs/guide_knowledge_curation.md:13`: "The LLM harvests past discussions into these files; the user can edit any of them in plain text" (paraphrase)
- `docs/guide_knowledge_curation.md:285-286`: "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" (28 words → split into 2 quotes)
- `docs/guide_knowledge_curation.md:289`: "rm ~/.manual_slop/knowledge/digest.md → no {knowledge} block injected" (paraphrase)
- `nagent_review_v2_3_20260612.md:554`: "Dead conversations accumulate, and deleting them loses what was learned. Therefore: distill, then delete" (paraphrase)
- `nagent_review_v2_3_20260612.md:2024`: "When you know things about a specific file, those notes should live next to the file's identity (inode)" (paraphrase)
- `nagent_review_v2_3_20260612.md:2096`: "No `notes` field. No per-file knowledge notes dimension" (paraphrase of the GAP verdict)
### 5.3 The §13 / §14 / §15 cross-references
- **§13 ("Genuinely Useful Patterns").** The hierarchical-keys principle (each memory cell has a structured key) + the personal-vs-shared scope distinction + the error-handling discipline are all genuinely useful. Cite L206 (keys), L215 (scope), L222 (errors). Note that Manual Slop already implements each in the project's own conventions (per-dim shapes, single-user scope, `Result[T]` + ledger markers). The useful pattern is *the principle*, not the Fable framing.
- **§14 ("Anti-User Watchdog Patterns").** The "memory is a Settings toggle" framing (L170) is *not* anti-user in itself — it's a transparency disclosure. But the *combination* of "Claude has a memory system" (L168) + "user has not enabled" (L170) + "consider adding a reset option" (L251, recommendation not requirement) constructs the memory system as opaque + non-user-controlled + lightly-suggested-to-be-resettable. The user can't see what's in memory, can't audit, can't selectively delete. This is anti-user in the *transparency* sense (not the *safety* sense). Recommend: cite as a transparency gap, contrast with the project's `ledger.json` + plain-text-edit + `delete to turn off` pattern.
- **§15 ("Persona Performance Patterns").** None of cluster 8 is persona performance. The `memory_system` section is a product disclosure; the `persistent_storage_for_artifacts` section is an API reference. Neither constructs a persona. Cluster 8 does not feed §15.
### 5.4 The data-oriented error handling parallel
Fable's `try/catch` rule (L222) is the JS-idiomatic error handling; Manual Slop's `Result[T]` + `ErrorInfo` + ledger status markers is the data-oriented equivalent. The harvest pipeline uses 4 status markers (`harvested` / `harvest-failed` / `deleted-unharvested` / `too-large`) in `ledger.json` rather than exceptions (`docs/guide_knowledge_curation.md:178-181`). The graceful failure modes table (`docs/guide_knowledge_curation.md:308-320`) lists 6 failure scenarios and their handling, all encoded as data, not control flow.
The synthesis report should surface this parallel in §10: Fable's storage error handling is persona-free (no "Claude feels bad about the storage failure"); Manual Slop's storage error handling is data-only (status markers, ledger entries, visible UI panels). The contrast is not "Fable has errors, Manual Slop doesn't" — it's "Fable uses control flow, Manual Slop uses data."
### 5.5 The "memory is plural" framing for the synthesis report's TL;DR
The single most important claim from cluster 8 is that **memory is plural, not singular**. Fable's framing is "the memory system" (singular, opaque, toggle-controlled). Manual Slop's framing is "the 4 memory dimensions" (plural, named, shaped, user-editable). nagent's framing is "the harvest + the per-file notes" (2 named sub-systems). The synthesis report's §0 TL;DR should surface this distinction as the headline: Fable's `memory_system` section is 5 lines; Manual Slop's 4-dim model is 4 named styleguides (306 + 358 + 278 + canonical knowledge_artifacts.md lines), each with a decision tree, a query model, and a user-editable surface.
### 5.6 What the §10 verdict should be
**Verdict: Useful (the API surface) + nagent-stronger (the memory architecture).** Fable's `window.storage` API is a useful engineering reference; the hierarchical-keys + single-key-batching + personal-vs-shared + try/catch rules are the standard pattern for a key-value client library. Manual Slop already implements each in its own conventions (per-dim shapes, digest batching, single-user scope, `Result[T]` + ledger). Fable's `memory_system` section is a product disclosure, not a memory architecture; nagent's knowledge harvest + per-file notes + Manual Slop's knowledge dim are the strong versions of the "memory" framing. The named gap is the per-file notes dimension (Candidate 11.1 per nagent §3.9).
**The recommended Manual Slop action:**
1. Cite the hierarchical-keys + batching principles in the memory dim styleguide as already-implemented (no change).
2. Cite the personal-vs-shared scope distinction as out-of-scope (single-user tool; no action).
3. Cite the data-oriented error handling contrast (`Result[T]` + ledger markers) in the §10 verdict.
4. Flag the per-file notes dimension (Candidate 11.1) as a deferred-rebuild recommendation in `decisions.md`.
5. Explicitly reject Fable's "one opaque KV store = memory" framing; cite the 4-dim model + the knowledge harvest as the alternative.
### 5.7 The deferred-rebuild recommendation (for `decisions.md`)
**Recommendation R8.1: Implement Candidate 11.1 (per-file knowledge notes).**
- **Source evidence.** `nagent_review_v2_3_20260612.md:2091-2098` (the named GAP verdict); `nagent_review_v2_3_20260612.md:2022-2105` (§3.9 the per-file notes pattern); `nagent_review_v2_3_20260612.md:2492-2515` (§4.4 the per-file notes sub-pattern).
- **What to build.** Add `notes: str = ""` to `FileItem` (`src/models.py:523`); add a "Notes" text area to the Structural File Editor (`docs/guide_context_curation.md`); add a `{file-knowledge}` block to `aggregate.py:run` at the file-edit position (per `nagent_review_v2_3_20260612.md:2509-2515`).
- **Why.** The 4-dim model is incomplete without per-file notes. The fix is small (3 sites, ~50 lines) but the value is high: durable facts about specific files survive across sessions; the notes come back automatically when the file is in scope; the notes are keyed by inode so they survive renames within the same filesystem.
- **Priority.** LOW standalone (small, niche) per `nagent_review_v2_3_20260612.md:2098` — bundle with the main knowledge dim implementation (Candidate 11).
- **Destination.** `conductor/code_styleguides/knowledge_artifacts.md` §? (extend the existing canonical styleguide) + `docs/guide_knowledge_curation.md` §2 (extend the existing per-file notes section).
**Recommendation R8.2: Document the "memory is plural" framing in the agent-directive corpus.**
- **Source evidence.** This cluster's §5.5 ("memory is plural, not singular"); Fable L168 ("Claude has a memory system") vs Manual Slop's 4-dim model (`conductor/code_styleguides/agent_memory_dimensions.md:13-18`).
- **What to build.** Add a 1-paragraph "memory is plural" callout to `AGENTS.md` (the top-level agent-facing rules) and to `conductor/product-guidelines.md` §"AI-Optimized Compact Style". The callout: "Manual Slop has 4 memory dimensions, not 1. The dimensions are not interchangeable. Fable-style 'one memory feature' framing collapses 4 distinct shapes into 1 opaque KV store."
- **Why.** The 4-dim model is the project's design intent; the Fable framing is a competing model. The agent-directive corpus should explicitly reject the Fable framing.
- **Priority.** LOW (documentation-only).
- **Destination.** `AGENTS.md` "Critical Anti-Patterns" or "Code Standards & Architecture" section + `conductor/product-guidelines.md` "AI-Optimized Compact Style" section.
### 5.8 The relationship to cluster 7 (search_instructions)
Cluster 7 owns the `search_instructions` copyright-quote discipline (L444-446). Cluster 8 references it as a cross-cut but does not feed §10 from it.
---
**Sub-report complete.** This is the evidence base for §10 of `report.md`.
@@ -0,0 +1,373 @@
# Cluster 9: Computer-Use / Skills / File Workflow
**Sub-agent dispatch:** Tier 3 Worker (2026-06-17). Read-only research task.
**Sources read:**
- `docs/artifacts/Fable System Prompt.md` lines 301-435 (`computer_use`, `skills`, `file_creation_advice`, `high_level_computer_use_explanation`, `file_handling_rules`, `producing_outputs`, `sharing_files`, `artifact_usage_criteria`, `package_management`, `examples`, `additional_skills_reminder`)
- `docs/artifacts/Fable System Prompt.md` lines 1214-1269 (`str_replace` + `view` tool definitions; the edit protocol)
- `docs/artifacts/Fable System Prompt.md` lines 1558-1576 (`available_skills` registry; 8 named skills)
- `docs/artifacts/Fable System Prompt.md` lines 1586-1596 (`filesystem_configuration`; the read-only mounts)
- `docs/guide_tools.md` lines 1-509 (MCP tools; 3-layer security; 45-tool inventory; Hook API)
- `conductor/tech-stack.md` (file system + the "no new src/<thing>.py files" rule; centralized path resolution via `src/paths.py`)
- `conductor/edit_workflow.md` (the edit protocol; 1-space indentation; small-edits rule; decorator-orphan pitfall; contract-change check)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §2.4 lines 390-419 (Pattern 4 Tool Discovery; `--description` self-describing executables)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §8.4 lines 3748-3754 (parse-then-dispatch split; the strict-parse + tolerant-dispatch pattern)
- `conductor/tracks/nagent_review_20260608/nagent_review_v2_3_20260612.md` §9 lines 3827-4115 (file splits/patches/summaries; the 4-stage pipeline; the per-language SCORE_BY_TYPE; the SHA-256 hash validation)
- `conductor/tracks/nagent_review_20260608/decisions.md` lines 142-155 (Candidate 5: self-describing MCP tools; subsumed by `mcp_architecture_refactor_20260606`)
- `conductor/tracks/nagent_review_20260608/decisions.md` lines 228-243 (Candidate 9: explicit `src/split_lib.py` + `src/patch_lib.py`; DEFER until needed)
- `conductor/tracks/nagent_review_20260608/comparison_table.md` rows 11 + 12 (large files PARITY; tool discovery GAP)
---
## 1. What Fable says
The `computer_use` section spans lines 301-435 and is the most operationally specific part of Fable. It codifies how the model interacts with files, the filesystem, and external tools. Eleven sub-sections, each with concrete rules.
### 1.1 The `skills` protocol (lines 303-319)
Fable requires the model to read a `SKILL.md` from `/mnt/skills/` *before* creating any file, writing any code, or running any other tool. The framing is unambiguous and unconditional:
- **L305** (paraphrase): "Skills encode hard-won trial-and-error about producing professional output."
- **L307** (paraphrase): "Reading the relevant SKILL.md is a required first step before writing any code, creating any file, or running any other computer tool."
- **L309-319** (illustrative turns): Four `User``Claude` exchanges; in each, Claude `immediately calls view` on the relevant SKILL.md (pptx, docx, imagegen, data-analysis) before doing anything else.
The implicit claim: the model cannot be trusted to know the right output format from training data alone; the *environment-specific constraints* (available libraries, rendering quirks, output paths) must be re-read every session.
### 1.2 `file_creation_advice` (lines 321-333)
Fable distinguishes *file* from *inline* based on whether the artifact is standalone or conversational:
- **L323-329** (file-creation triggers, list of 6): "write a document/report/post/article" → .md/.html (use docx only on explicit Word-doc signal); "create a component/script/module" → code files; "fix/modify/edit my file" → edit the actual uploaded file; "make a presentation" → .pptx; "save/download" → create files; **more than 10 lines of code → create files.**
- **L331** (the discriminator, ≤15 words): "What matters is standalone artifact vs conversational answer."
### 1.3 `high_level_computer_use_explanation` (lines 335-340)
A 4-line summary of the runtime: "Claude has a Linux computer (Ubuntu 24). Tools: bash, str_replace, create_file, view. Working directory `/home/claude` (all temp work). File system resets between tasks."
### 1.4 `file_handling_rules` (lines 342-351)
Three filesystem locations, with one *critical* rule: "USER UPLOADS ... CLAUDE'S WORK ... FINAL OUTPUTS." The model creates new files in `/home/claude` first (a scratchpad); final deliverables go to `/mnt/user-data/outputs/`. For single-file tasks <100 lines, write directly to outputs. Lines 349-351 add a per-file-type rule: decide whether computer access is actually needed based on whether the file content is already in context.
### 1.5 `producing_outputs` (lines 353-359)
The creation strategy: "SHORT (<100 lines): create the whole file in one tool call, save directly to /mnt/user-data/outputs/. LONG (>100 lines): build iteratively: outline/structure, then section by section, review, refine, copy final version." Plus the discipline rule: "REQUIRED: actually CREATE FILES when requested, not just show content, or the user can't access it."
### 1.6 `sharing_files` (lines 360-369)
A separate tool `present_files` for surfacing files to the user. Two good-example blocks: Claude calls `present_files` after generating a report or a script; *succinct, no postamble*. The framing is "share files, not folders."
### 1.7 `artifact_usage_criteria` (lines 371-414)
The longest sub-section. The artifact heuristic:
- **L375-382** (use artifacts for, 7 categories): "Custom code solving a specific user problem ... Any code snippet >20 lines ... Content for use outside the conversation ... Long-form creative writing ... Structured reference content ... Modifying/iterating on an existing artifact ... A standalone text-heavy document >20 lines or >1500 characters."
- **L384-390** (do NOT use artifacts for, 6 categories): "Short code answering a question (≤20 lines) ... Short creative writing (poems, haikus, stories under 20 lines) ... Lists, tables, enumerated content, regardless of length ... Brief structured/reference content; single recipes ... Short prose; conversational inline responses ... Anything the user explicitly asked to keep short."
The threshold pair (20 lines / 1500 characters) is the actionable nugget.
### 1.8 `package_management` (lines 416-421)
Four operational rules: "npm: works normally ... pip: ALWAYS use `--break-system-packages` ... Virtual environments: create if needed ... Verify tool availability before use."
### 1.9 `examples` (lines 423-430)
A 5-example decision tree, each `User` → decision (view SKILL.md → file in outputs, or view content, or NO tools, or conversational response). The discriminator is *what kind of artifact* the user wants; the response shape (file vs inline) follows.
### 1.10 `additional_skills_reminder` (lines 432-434)
A load-bearing repetition: "Before creating any file, writing any code, or running any bash command, first `view` the relevant SKILL.md files. This check is unconditional: don't first decide whether the task 'needs' a skill; the skills themselves define what they cover."
The implicit framing: the model is **not** the authority on what counts as a relevant skill; the skills' self-descriptions are.
### 1.11 The available_skills registry (lines 1558-1576)
Eight named skills, each with a `description` field that doubles as a *trigger condition*:
| Skill | Trigger |
|---|---|
| `docx` | "any mention of 'Word doc' ... or requests to produce professional documents" |
| `pdf` | "anytime ... the user wants to do anything with PDF files" |
| `pptx` | "any time a .pptx file is involved in any way" |
| `xlsx` | "any time a spreadsheet file is the primary input or output" |
| `product-self-knowledge` | "your response would include specific facts about Anthropic's products" |
| `frontend-design` | "distinctive, intentional visual design when building new UI" |
| `file-reading` | "a file has been uploaded but its content is NOT in your context" |
| `pdf-reading` | "you need to read, inspect, or extract content from PDF files" |
| `skill-creator` | "users want to create a skill from scratch, edit, or optimize" |
Each is a *self-describing* prompt-template + toolset; the trigger conditions are written in natural language so the model can match them.
### 1.12 The tool definitions (lines 1214-1269)
The two edit-relevant tools:
- **L1216 (`str_replace`)**: "Replace a unique string in a file with another string. old_str must match the raw file content exactly and appear exactly once. ... View the file immediately before editing; after any successful str_replace, earlier view output of that file in your context is stale — re-view before further edits to the same file."
- **L1249 (`view`)**: "Supports viewing text, images, and directory listings. ... You can optionally specify a view_range to see specific lines. ... Files with non-UTF-8 encoding will display hex escapes ... the entire file is displayed, truncating from the middle if it exceeds 16,000 characters."
The implicit edit protocol: read → edit → read again. Stale context is a known failure mode the model must self-correct.
### 1.13 The filesystem_configuration (lines 1586-1596)
Five read-only mounts: `/mnt/user-data/uploads`, `/mnt/transcripts`, `/mnt/skills/public`, `/mnt/skills/private`, `/mnt/skills/examples`. The rule: "Do not attempt to edit, create, or delete files in these directories. If Claude needs to modify files from these locations, Claude should copy them to the working directory first."
The implicit framing: read-only is the *default*; writeable is the *exception*. Copy-then-edit is the unblock path.
### 1.14 The aggregation
Fable's `computer_use` section is operationally dense and load-bearing. It is *not* persona framing; it is a concrete protocol with explicit thresholds (20 lines, 1500 chars, <100 lines = one-shot, >100 lines = iterative), explicit rules (copy-then-edit, read-before-edit, no postamble), and explicit tools (bash, str_replace, create_file, view, present_files, search_mcp_registry, suggest_connectors). The 8 named skills are a *registry* that auto-extends — adding a skill is adding a description field, not editing a dispatcher.
The two non-trivial claims:
1. **The model cannot be trusted to know the right output format from training data alone.** The skill-read protocol is the operational consequence.
2. **Read-before-edit is non-negotiable; stale context is the most common failure mode.** The str_replace description (L1216) is the explicit discipline rule.
Both are *useful*; both are also what the project's `edit_workflow.md` codifies at the agent-system level. The §4 verdict evaluates them in that context.
---
## 2. What this project does
Manual Slop's file workflow is implemented in three layers: a *security layer* (the 3-layer allowlist), a *tool layer* (the 45 MCP tools), and a *discipline layer* (the edit workflow). Each layer overlaps with a Fable rule but codifies it differently.
### 2.1 The 3-layer filesystem security (guide_tools.md:7-53)
`docs/guide_tools.md:7-53` documents `_resolve_and_check(path)` as the gate every filesystem-touching tool passes through. Three layers:
- **Layer 1 (Allowlist Construction, `configure`)**: resets `_allowed_paths` and `_base_dirs` on every call; sets `_primary_base_dir` from `extra_base_dirs[0]` (resolved) or `Path.cwd()`; iterates `file_items` (from `aggregate.build_file_items()`) and resolves each path to absolute; adds the file to `_allowed_paths`, the parent directory to `_base_dirs`. The allowlist is *per-send*, not global.
- **Layer 2 (Path Validation, `_is_allowed`)**: blacklist first (`history.toml` or `*_history.toml` → deny; prevents AI from reading conversation history); explicit allowlist (`_allowed_paths`); CWD fallback (if `_base_dirs` empty, any path under `cwd()` allowed); base-directory containment (`relative_to()`); default deny.
- **Layer 3 (Resolution Gate, `_resolve_and_check`)**: convert raw path to `Path`; resolve to absolute; call `_is_allowed()`; return `(resolved_path, "")` or `(None, error_message)` with the full list of allowed base directories for debugging.
The hardening: paths are resolved (symlinks followed) before comparison, preventing symlink traversal. The blacklist for `history.toml` is the project's analog to Fable's read-only mounts — *the model is denied access to specific paths by category, not by exception*.
The project's version is **stricter** than Fable's: Fable's read-only mounts are advisory (the rule is "don't attempt to edit; copy first"); Manual Slop's allowlist is **enforced** at the tool dispatch layer. The model cannot bypass it without writing to a non-allowlisted path, which fails the dispatch.
### 2.2 The 45 MCP tools (guide_tools.md:55-196)
`docs/guide_tools.md:55-196` enumerates the 45 tools in `dispatch` (a flat if/elif chain at `mcp_client.py:1322`). The categories:
- **File I/O (7 tools)**: `read_file`, `list_directory`, `search_files`, `get_file_slice`, `set_file_slice`, `edit_file`, `get_tree`. Note `set_file_slice` and `edit_file` are the surgical-edit primitives; `set_file_slice` is "literal line replacement by design" per `conductor/edit_workflow.md:78-89`.
- **AST-Based Python (15 tools)**: `py_get_skeleton`, `py_get_code_outline`, `py_get_definition`, `py_update_definition`, `py_get_signature`, `py_set_signature`, `py_get_class_summary`, `py_get_var_declaration`, `py_set_var_declaration`, `py_find_usages`, `py_get_imports`, `py_check_syntax`, `py_get_hierarchy`, `py_get_docstring`, `py_remove_def`, `py_add_def`, `py_move_def`, `py_region_wrap`. (Note: guide_tools.md lists 18 here, not 15. The 18 are an enumeration including structural mutators.)
- **C/C++ AST (10 tools)**: `ts_c_get_skeleton`, `ts_cpp_get_skeleton`, `ts_c_get_code_outline`, `ts_cpp_get_code_outline`, `ts_c_get_definition`, `ts_cpp_get_definition`, `ts_c_update_definition`, `ts_cpp_update_definition`, `ts_c_get_signature`, `ts_cpp_get_signature`.
- **Analysis (3 tools)**: `get_file_summary`, `get_git_diff`, `derive_code_path`.
- **Network (2 tools)**: `web_search` (DuckDuckGo HTML scrape), `fetch_url`.
- **Runtime (1 tool)**: `get_ui_performance` (no filesystem access).
- **Beads (4 tools)**: `bd_list`, `bd_create`, `bd_update`, `bd_ready`.
The model *cannot* run arbitrary bash or write arbitrary files — `run_powershell` is the only shell tool, and it requires HITL confirmation via the `ShellRunner` (see guide_tools.md:475-509 and `conductor/tech-stack.md`).
### 2.3 The edit_workflow protocol (conductor/edit_workflow.md)
The project's edit discipline is codified at the agent-system level, not the model level. Five load-bearing rules:
- **§2 "Verify Before Editing"** (lines 14-24): "DO NOT use `git checkout` or `git restore` to 'revert' your way to a clean state." The discipline rule: run `py_check_syntax` + `get_file_slice` on the exact lines before any edit.
- **§3 "Reading Before Editing (CRITICAL)"** (lines 26-31): "Use `get_file_slice` to get the EXACT text including all whitespace and EOL. Copy text directly from the tool output — do NOT reformat."
- **§6 "The Decorator-Orphan Pitfall"** (lines 51-68): a specific failure mode where `@property` is orphaned onto a new method if the anchor is wrong. The rule: anchor on a non-decorated landmark, or include the decorator in the replacement.
- **§7 "ast.parse() Is Not Enough"** (lines 70-76): semantic errors (wrong decorator targets, missing `self`) are not caught by `py_check_syntax`. The discipline: after any multi-line edit, import the module, instantiate the class, call the new method.
- **§8 "set_file_slice IS Valid for Multi-Line Content"** (lines 78-108): the contract-change check is mandatory for any edit that changes a public interface (signature, return type, yield shape, class hierarchy, public attribute name). Use `py_find_usages` to locate callers before changing a contract; update ALL callers in the same atomic commit.
The protocol is **stricter than Fable's**. Fable's rule (L1216: "View the file immediately before editing") is *one* rule among many; Manual Slop's protocol is *eight* numbered rules with named failure modes (decorator-orphan, ast.parse-not-enough, contract-change-check).
### 2.4 The file-naming convention (AGENTS.md "File Size and Naming Convention")
The project's anti-filesplittism stance is explicit: "Large files are FINE." `AGENTS.md` (the project's root agent-facing file) rules: "Helpers and sub-systems go in the parent module. E.g., AI-client-specific helpers go in `src/ai_client.py`; MCP-client code goes in `src/mcp_client.py`."
The consequence: there is no Fable-style `skills/` directory with `SKILL.md` per format. The format-specific knowledge is in the project's source code (the `tree_sitter` bindings in `file_cache.py`; the `mcp_client.py` tool implementations; the `pyproject.toml` dependency declarations).
### 2.5 The path resolution (conductor/tech-stack.md, `src/paths.py`)
`conductor/tech-stack.md` documents `src/paths.py` as "Centralized module for path resolution. Supports project-specific conductor directory overrides via project TOML (`[conductor].dir`)." Plus "Path Resolution Metadata" exposing the source of each resolved path (default, env var, config file) for GUI display, and "Runtime Re-Resolution" via `reset_resolved()`.
The project's analog to Fable's `filesystem_configuration`: *paths are declared once, in the centralized config; the model never invents paths.* The `paths.py` module is the single source of truth; the model sees the resolved paths via `_pending_gui_tasks`, not by navigating the filesystem.
### 2.6 The aggregation
Manual Slop's file workflow is **enforced, not prompted**. The 3-layer allowlist is enforced at dispatch; the edit_workflow rules are enforced at the agent-system level; the path resolution is enforced at the config layer. The model has *less* freedom than Fable's model (no arbitrary bash, no arbitrary writes, no `present_files` tool, no `search_mcp_registry`), but *more* rigor (symlink-resolved paths, SHA-style content checks via mtime, AST-aware edit tools, contract-change check).
The project's analog to Fable's `available_skills` is *the 45-tool inventory itself*. Each tool's description field IS a trigger condition (e.g., `py_get_skeleton`: "Signatures + docstrings, bodies replaced with `...`. Uses tree-sitter."); the model reads the tool inventory once at startup and matches tool-to-task. But the inventory is hard-coded, not extensible — adding a tool requires edits in `dispatch()` (per `nagent_review_v2_3_20260612.md:417-419`: "Adding a tool requires: 1. Edit dispatch() to add the branch; 2. Update the security allowlist in `_resolve_and_check` (if filesystem access); 3. Update capability declaration; 4. Add tests").
---
## 3. What nagent does
nagent's file workflow is documented across §2.4 (Pattern 4 Tool Discovery), §8.4 (parse-then-dispatch split), and §9 (file splits/patches/summaries). The three sections address three distinct aspects of "computer use": tool discovery, error handling, and large-file handling.
### 3.1 Pattern 4: Tool Discovery via `--description` (nagent_review_v2_3_20260612.md:390-419 + decision candidate 5)
The `--description` self-describing executable pattern is the structural alternative to Fable's `available_skills` and to Manual Slop's hard-coded `dispatch`:
- **nagent's mechanism** (per `nagent_review_v2_3_20260612.md:390-419`): each `bin/nagent-*` executable starts with `exit_on_description(NAGENT_*_DESCRIPTION)` (a one-liner that prints the tool's description and exits 0 if `--description` is in `sys.argv`). At startup, the main loop calls `collect_bin_tool_descriptions(bin_dir)` which iterates every executable in `bin/`, runs `--description`, parses stdout, and concatenates the descriptions into the startup prompt.
- **The 9 nagent tools** (per `nagent_review_v2_3_20260612.md:402-414`): `nagent` (main loop), `nagent-llm-text`, `nagent-llm-upload`, `nagent-file-edit`, `nagent-file-split`, `nagent-file-patch`, `nagent-file-summarize`, `nagent-gc`. Each is a thin wrapper; the real logic lives in `bin/helpers/*_lib.py`.
- **The "no central registry" claim** (`nagent_review_v2_3_20260612.md:1925-1932`): "There is no central registry: `collect_bin_tool_descriptions()` discovers tools by running every `bin/` executable with `--description` and injecting the results into the startup prompt. A new tool becomes visible to the loop simply by being an executable in `bin/` that handles `--description`."
The pattern's verdict (per `comparison_table.md:31` and `decisions.md:142-155`): **GAP (Application)**. nagent's pattern is genuinely better for extensibility; Manual Slop's `dispatch` if/elif chain is fine but not extensible. The fix is subsumed by `mcp_architecture_refactor_20260606` (the sub-MCP extraction would naturally produce self-describing modules).
### 3.2 §8.4: The parse-then-dispatch split (nagent_review_v2_3_20260612.md:3748-3754)
The cross-cutting pattern that *also* applies to Fable's edit tools:
- **The separation**: `parse_response` (uses `nagent_tags.py:parse_tag_document`) is *strict* (rejects unknown tags, malformed attributes, unterminated bodies); `process_tags` (the dispatcher) is *tolerant* (errors are data; the LLM sees them and responds).
- **The generalization**: "validate at the boundary, handle errors as data inside. The same pattern is in Manual Slop's `data_oriented_error_handling_20260606` (`Result[T, ErrorInfo]` envelope)."
The application to Fable's `str_replace` and `view` tools: the Fable description (L1216) instructs the model to *self-validate* by re-viewing after editing ("after any successful str_replace, earlier view output of that file in your context is stale"). Manual Slop's `set_file_slice` and `edit_file` *enforce* the validation at the tool layer (the tool re-reads the file before writing; the result includes the new file content for the model to verify). nagent's `validate_index` (in `bin/helpers/nagent_file_patch_lib.py`) is the strongest: SHA-256 hash validation that rejects patches against a stale source.
### 3.3 §9: The 4-stage file pipeline (nagent_review_v2_3_20260612.md:3827-4115)
The large-file handling is the deep-dive. The pipeline is *data-oriented*:
1. **Inline read** (file < 64KB): read the whole file; pass to LLM.
2. **Split** (file > 64KB): `nagent-file-split <file> --output /tmp/split --target-bytes 32768 --natural`. The splitter uses *per-language `SCORE_BY_TYPE`* (regex + line counts + brace/JSON/XML depth, no tree-sitter) and writes `index.json` with `source_path`, `source_sha256`, `source_size_bytes`, `source_line_count`, `split_type`, `target_bytes`, `segments[]`.
3. **Edit segments**: the user or LLM edits the per-segment files.
4. **Patch**: `nagent-file-patch <index>` calls `validate_index(index, require_hash_match=True)`; if the source SHA-256 doesn't match `index.source_sha256`, the patch is rejected (unless `--force`). The patch operation merges segments, makes a unified diff, optionally writes back.
The 12 supported languages (`nagent_review_v2_3_20260612.md:3894-3909`): `txt`, `md`, `cpp`, `py`, `xml`, `js`, `ts`, `json`, `yaml`, `go`, `rs`, `java`. Each has its own `SCORE_BY_TYPE` (the splitter heuristic). The default target size is 32KB.
The Manual Slop equivalent (`comparison_table.md:30` + `report.md:331-376`):
| nagent | Manual Slop |
|---|---|
| `nagent-file-split` with per-language `SCORE_BY_TYPE` (no tree-sitter) | `aggregate.py:build_file_items()` + `py_get_skeleton` + `ts_c_*_get_skeleton` (tree-sitter) |
| `index.json` with `source_sha256`, `segments[]` | No explicit `index.json`; implicit in `_reread_file_items` (mtime-based, not hash-based) |
| `nagent-file-patch` with strict `validate_index` (SHA-256 hash check) | `set_file_slice` / `edit_file` with re-read + string-match (no SHA-256) |
| `nagent-file-summarize` cascades to `nagent-file-split --summarize` for > 64 KB | `RAGEngine._chunk_code` cascades to chunking (mtime-based, ChromaDB) |
Verdict (`comparison_table.md:30` + `report.md:373`): **PARITY (DIFFERENT MECHANISM)**. Both have the "split / patch / summarize as explicit data artifacts" insight. nagent uses subprocesses + per-language scoring + hash validation; Manual Slop uses tree-sitter + in-process + mtime validation. The crucial difference: Manual Slop's tree-sitter is more accurate but slower; nagent's natural-splitter is faster but less accurate.
The Manual Slop recommendation (`nagent_review_v2_3_20260612.md:4104-4108`): "Don't add the natural-splitter fallback yet. Manual Slop's tree-sitter covers 95% of real workloads. ... Adopt it only if a 200KB+ file scenario actually surfaces." This is Decision Candidate 9 (per `decisions.md:228-243`): **DEFER UNTIL NEEDED**.
### 3.4 The aggregation
nagent's file workflow is **data-shaped, not prompt-shaped**. The tools are self-describing (no central registry); the splits are explicit (`index.json` with hash validation); the patches are unified diffs; the errors are data (`status="error"` in result wrappers, per `nagent_review_v2_3_20260612.md:3758-3765`).
The 3 layers of nagent's design that map to Manual Slop's gaps:
1. **Tool discovery**: GAP. Manual Slop's `dispatch` if/elif chain is fine but not extensible. Subsumed by `mcp_architecture_refactor_20260606`.
2. **Parse-then-dispatch**: PARITY. Manual Slop's `Result[T, ErrorInfo]` envelope (per `data_oriented_error_handling_20260606`) is the same idea applied at the function-call layer.
3. **Large-file pipeline**: PARITY (DIFFERENT MECHANISM). Both have the insight; nagent uses subprocesses + hash validation; Manual Slop uses tree-sitter + mtime. The hash-validation gap is real but small (mtime is sufficient for the typical use case).
---
## 4. Verdict
**Useful + over-broad.** Fable's `computer_use` section + the `file_creation_advice` + the `producing_outputs` + the `available_skills` registry has genuinely useful elements but is over-broad for Manual Slop's per-developer, scripted workflow. The MCP-based tooling in Manual Slop is the more constrained, auditable alternative.
### 4.1 The useful elements (preserve in the rebuild)
1. **The file-presence check** (Fable L81 + L1216): "A prompt implying a file is present doesn't mean one is, as the person may have forgotten to upload it, so Claude checks for itself." This is a real operational discipline — agents must verify, not assume. Manual Slop's `manual-slop_read_file` / `manual-slop_get_file_summary` workflow codifies the same discipline at the tool layer. The cluster 4 sub-report (L48-51) flags this as the "useful nugget" of cluster 4; the same discipline re-appears here.
2. **The format-based triggers** (Fable L323-329): the 6-line table mapping user signal to file format. The discriminator (L331: "standalone artifact vs conversational answer") is a useful heuristic that doesn't appear in Manual Slop's directives. The 20-line / 1500-char artifact threshold (L382) is an actionable rule. The rebuild should consider codifying these in `conductor/product-guidelines.md` (under "AI-Optimized Compact Style") or a new `conductor/code_styleguides/output_format_decision.md`.
3. **The "do not include boilerplate" rule** (Fable L396): "Conversational responses (web search results, research summaries, analysis) should NOT use report-style headers and structure; follow tone_and_formatting: natural prose, minimal headers, concise." This is the same insight as Manual Slop's "natural prose for typical conversation" rule (cluster 4 sub-report, L56-58). Fable's framing is more concrete (it explicitly identifies web-search and research-summary as the cases where boilerplate creeps in).
4. **The read-before-edit discipline** (Fable L1216): "View the file immediately before editing; after any successful str_replace, earlier view output of that file in your context is stale — re-view before further edits to the same file." This maps directly to Manual Slop's `conductor/edit_workflow.md:26-31` ("Reading Before Editing (CRITICAL)"). The Fable rule is the model's self-discipline; Manual Slop's is enforced at the agent-system level via `get_file_slice` + `set_file_slice` (the tool re-reads the file before writing). Manual Slop's enforcement is stronger.
5. **The "unconditional" framing for skills** (Fable L432-434): "Before creating any file, writing any code, or running any bash command, first `view` the relevant SKILL.md files. This check is unconditional." This is a useful *style* for directives — don't make the agent decide whether a rule applies; the rule applies. The Manual Slop analog is `conductor/workflow.md` §"Skip-Marker Policy" ("When the underlying issue is fixable in-session, FIX IT INSTEAD of adding a skip marker"). Both reject agent judgment in favor of rule application.
### 4.2 The over-broad elements (reject or de-prioritize in the rebuild)
1. **The 8 named skills (L1558-1576)** are product features for a chat UI serving many users with diverse output needs (Word, PowerPoint, Excel, PDF generation). Manual Slop is a coding tool for one developer; the formats are `.py`, `.toml`, `.md`, and `.json`. The 8-skill registry is over-engineered. The Manual Slop analog is the 45-tool inventory (which is itself over-broad for the typical task but justified by the codebase's breadth — Python + C/C++ + Markdown + RAG + Beads). The cluster 10 sub-report (MCP App Suggestions) addresses a related concern.
2. **The `/mnt/user-data/uploads` vs `/home/claude` vs `/mnt/user-data/outputs` separation** (Fable L342-351) is a *chat-UI* artifact: the user uploads files; the model works on them; the model produces outputs; the user downloads outputs. Manual Slop has no equivalent separation because there is no "upload" — the model reads files from the project tree, edits them, and the project tree is the output. The 3-layer allowlist (guide_tools.md:7-53) is the right abstraction for Manual Slop's domain; Fable's filesystem_configuration is the right abstraction for Fable's domain.
3. **The `present_files` tool** (Fable L362-369): "Share files, not folders. No long post-ambles after linking." This is a chat-UI tool that doesn't apply to Manual Slop. The Manual Slop analog is the Hook API (`docs/guide_tools.md:304-333`) which exposes the GUI state to external automation — a different mechanism for a different purpose.
4. **The `search_mcp_registry` + `suggest_connectors` tools** (Fable L1199-1244): "Call this when connecting to a new MCP might help resolve the user query." This is a *connector-discovery* mechanism for an open ecosystem. Manual Slop's MCP tools are internal and curated (45 tools, all in `mcp_client.py`); there is no registry to search. The `ExternalMCPManager` (per `conductor/tech-stack.md`) provides a similar capability for *external* MCP servers, but it's opt-in, not auto-triggered. Cluster 10 covers this in more detail.
5. **The `package_management` rules** (Fable L416-421): "pip: ALWAYS use `--break-system-packages`." This is Fable-environment-specific (Ubuntu 24 in a container with no externally-managed Python environment). Manual Slop uses `uv` (per `conductor/tech-stack.md`: "uv: An extremely fast Python package and project manager") which manages the Python environment in `pyproject.toml` + `.venv`. The pip rule is irrelevant; the uv workflow is the project's analog.
### 4.3 The nagent alternative (the structural fix)
The `--description` self-describing pattern (nagent §2.4 / decision candidate 5) is the structural alternative to both Fable's `available_skills` registry and Manual Slop's hard-coded `dispatch`. If the rebuild wants to make the tool inventory *extensible* without editing `dispatch()`, the fix is:
1. Each tool (or each sub-MCP module, per `mcp_architecture_refactor_20260606`) emits a `--description` block on `--help`.
2. The `dispatch` function introspects via `mcp_client.get_tool_schemas()` and includes the descriptions in the AI's initial context automatically.
3. Adding a tool = dropping a file with a description; no `dispatch()` edit; no allowlist edit; no capability-declaration edit.
This is a real gap (per `comparison_table.md:31` and `decisions.md:142-155`); the rebuild's `mcp_architecture_refactor_20260606` track is the right scope. The `--description` pattern is *not* Fable's `available_skills` (Fable's pattern is in-prompt self-description; nagent's is executable-level self-description), but the spirit is the same: tools describe themselves; the dispatcher is data-driven.
### 4.4 What the rebuild should adopt
| Fable pattern | Adopt? | Manual Slop equivalent / next step |
|---|---|---|
| File-presence check (L81) | **Yes, already adopted** | `manual-slop_read_file` / `manual-slop_get_file_summary` workflow |
| Read-before-edit (L1216) | **Yes, already adopted** | `conductor/edit_workflow.md` §3 (enforced via `get_file_slice` + `set_file_slice`) |
| Format-based triggers (L323-329) | **Yes, codify** | Add to `conductor/product-guidelines.md` or new `output_format_decision.md` |
| 20-line / 1500-char artifact threshold (L382) | **Yes, codify** | Same location as above |
| "Unconditional" framing for rules (L432-434) | **Yes, adopt** | Already partial via `conductor/workflow.md` Skip-Marker Policy |
| 8 named skills (L1558-1576) | **No** | Over-engineered for one-developer scope |
| 3-location filesystem (L342-351) | **No** | Manual Slop has no upload/output separation |
| `present_files` tool (L362-369) | **No** | Chat-UI specific; Hook API is the project's analog |
| `search_mcp_registry` (L1199-1244) | **No** | Manual Slop has no open ecosystem |
| pip `--break-system-packages` (L419) | **No** | Manual Slop uses `uv` |
| `--description` self-describing pattern (nagent §2.4) | **Yes, deferred to mcp_architecture_refactor** | Subsumed by `mcp_architecture_refactor_20260606` |
| SHA-256 hash validation for edits (nagent §9.4) | **Yes, partial adoption** | Replace mtime validation with hash for stronger guarantees; subsumed by Candidate 9 (defer until need) |
---
## 5. Synthesis notes for the Tier 1 writer
This cluster feeds `report.md` §11 ("Fable's Computer-Use / File Workflow") directly. Cross-references to §13 ("Genuinely Useful Patterns"), §14 ("Anti-User Watchdog Patterns"), §15 ("Persona Performance Patterns").
### 5.1 Key claims to surface in §11
1. **The file-presence check (Fable L81) and the read-before-edit rule (Fable L1216) are the genuinely useful nuggets.** Both are already codified in Manual Slop via `manual-slop_read_file` + `conductor/edit_workflow.md:26-31`. Manual Slop's enforcement is *stronger* than Fable's (the tool re-reads the file before writing; Fable's rule is model-self-discipline).
2. **The format-based triggers (Fable L323-329) and the 20-line / 1500-char artifact threshold (Fable L382) are concrete and codifiable.** They don't appear in Manual Slop's current directives. Add to `conductor/product-guidelines.md` (under "AI-Optimized Compact Style") or create a new `conductor/code_styleguides/output_format_decision.md`. The decision discriminator (L331: "standalone artifact vs conversational answer") is the actionable insight.
3. **The 8 named skills (Fable L1558-1576) are over-engineered for Manual Slop's scope.** Manual Slop is a coding tool for one developer; the formats are Python + TOML + Markdown + JSON. The 45-tool inventory is itself broad but justified by the codebase's breadth (Python + C/C++ + RAG + Beads + network). The 8-skill registry is a chat-UI product feature, not a coding-tool feature.
4. **The 3-location filesystem (Fable L342-351) is irrelevant to Manual Slop.** The project has no upload/output separation; the 3-layer allowlist (`guide_tools.md:7-53`) is the right abstraction. Reject the chat-UI framing.
5. **The `package_management` rules (Fable L416-421) are environment-specific and irrelevant.** Manual Slop uses `uv` (per `conductor/tech-stack.md`); the pip `--break-system-packages` rule is a chat-UI container quirk.
6. **The nagent `--description` self-describing pattern (nagent §2.4) is the structural alternative to both Fable's `available_skills` and Manual Slop's hard-coded `dispatch`.** This is a real gap (per `comparison_table.md:31`); the rebuild's `mcp_architecture_refactor_20260606` track is the right scope.
7. **The nagent SHA-256 hash validation (nagent §9.4) is a stronger guarantee than Manual Slop's mtime validation.** Decision Candidate 9 (per `decisions.md:228-243`) is DEFER UNTIL NEEDED. Document the nagent pattern as a reference; don't adopt until a 200KB+ file scenario surfaces.
8. **The `present_files` tool (Fable L362-369) and the `search_mcp_registry` + `suggest_connectors` tools (Fable L1199-1244) are chat-UI-specific.** Reject in the rebuild. Manual Slop's Hook API (`guide_tools.md:304-333`) and ExternalMCPManager are the project analogs.
### 5.2 Quotes to use in §11
- **Fable L81** (file-presence): "Claude checks for itself" (the full sentence: "A prompt implying a file is present doesn't mean one is, as the person may have forgotten to upload it, so Claude checks for itself"). ≤15 words: "the model should check for the file's presence."
- **Fable L307** (skill-read mandatory): "Reading the relevant SKILL.md is a required first step before writing any code." ≤15 words.
- **Fable L331** (format discriminator): "What matters is standalone artifact vs conversational answer." ≤15 words.
- **Fable L382** (artifact threshold): "A standalone text-heavy document >20 lines or >1500 characters." ≤15 words.
- **Fable L1216** (read-before-edit): "View the file immediately before editing; after any successful str_replace, earlier view output of that file in your context is stale." (paraphrase; full exceeds 15 words)
- **Fable L1595** (read-only enforcement): "Do not attempt to edit, create, or delete files in these directories." ≤15 words.
- **`guide_tools.md:33-37`** (3-layer security): "Blacklist (hard deny): If filename is `history.toml` or ends with `_history.toml`, return `False`. ... Explicit allowlist: If resolved path is in `_allowed_paths`, return `True`. ... Default deny: All other paths are rejected."
- **`conductor/edit_workflow.md:78-79`** (the protocol discipline): "`set_file_slice` IS Valid for Multi-Line Content (Revised 2026-06-09) ... The previous rule ('Do not use set_file_slice for multi-line content') was wrong. `set_file_slice` does literal line replacement by design and is the right tool for 3-10 line surgical edits."
- **`conductor/edit_workflow.md:106-108`** (the contract-change check): "If you change a contract and don't update callers, you have broken the codebase."
- **`nagent_review_v2_3_20260612.md:1925-1927`** (the no-central-registry claim): "There is no central registry: `collect_bin_tool_descriptions()` discovers tools by running every `bin/` executable with `--description` and injecting the results into the startup prompt."
- **`nagent_review_v2_3_20260612.md:3990-3995`** (the safety property): "The patch operation validates the source hasn't changed. If the source has been modified since the split, the patch is rejected (unless `--force`)."
- **`nagent_review_v2_3_20260612.md:4104-4108`** (the Manual Slop recommendation): "Don't add the natural-splitter fallback yet. Manual Slop's tree-sitter covers 95% of real workloads. ... Adopt it only if a 200KB+ file scenario actually surfaces."
- **`decisions.md:144-146`** (Candidate 5, the self-describing pattern): "Manual Slop's 45 MCP tools are dispatched by a flat if/elif in `mcp_client.py:dispatch`. Adding a tool requires edits in 4 places (dispatch, security allowlist, capability declaration, tests). nagent's `--description` self-describing executable pattern is more extensible: drop an executable, it auto-appears."
- **`decisions.md:243`** (Candidate 9, the DEFER): "Recommended priority. DEFER UNTIL NEEDED. No current 1:1 use case requires explicit split/patch. If a future file is genuinely too large for tree-sitter to handle inline, this becomes Candidate #2-priority."
### 5.3 The §13 / §14 / §15 cross-references
- **§13 ("Genuinely Useful Patterns").** Cite the file-presence check (Fable L81), the format-based triggers (Fable L323-329), the 20-line / 1500-char threshold (Fable L382), and the read-before-edit discipline (Fable L1216). Each maps to a Manual Slop analog that is *more rigorous* than Fable's framing. Cite `guide_tools.md:7-53` (3-layer security) and `conductor/edit_workflow.md:1-209` (the 8 numbered rules) as the Manual Slop implementations.
- **§14 ("Anti-User Watchdog Patterns").** Fable's `present_files` tool (L362-369) and the `search_mcp_registry` + `suggest_connectors` tools (L1199-1244) are not strictly anti-user, but they are chat-UI product features that don't fit Manual Slop's domain. Cite these as "not applicable" rather than anti-user. The `recommended_claude_apps` tool (Fable L1180-1197) is mildly anti-user (it nudges the user toward Anthropic products); reject in the rebuild.
- **§15 ("Persona Performance Patterns").** Fable's `present_files` framing ("succinct, no post-ambles" per L362-369) is *style discipline*, not persona; the framing is too narrow to be persona. The genuinely persona-shaped claim is Fable's "high-fidelity, professional output" framing throughout the `computer_use` section — the model is positioned as a *professional assistant*, not a *transformation function over data*. Manual Slop's analog (the data-oriented error handling convention per `conductor/code_styleguides/error_handling.md`) rejects the professional-assistant framing in favor of the transformation-function framing. Cite Fable's framing in §15; reject explicitly.
### 5.4 The non-obvious connection to the data-oriented error handling convention
Cluster 9 has a sibling connection to the data-oriented error handling convention (per `conductor/code_styleguides/error_handling.md`) that cluster 5 (mistakes) flagged. The connection:
- **Fable's `str_replace` description (L1216)** instructs the model to *self-validate* by re-viewing after editing ("stale context" is the failure mode).
- **Manual Slop's `set_file_slice` and `edit_file`** *enforce* the validation at the tool layer (the tool re-reads the file before writing; the result includes the new file content for the model to verify).
- **nagent's `validate_index` (per `nagent_review_v2_3_20260612.md:3996-4006`)** is the strongest: SHA-256 hash validation that *rejects* patches against a stale source.
The three implementations form a progression: prompt-level discipline (Fable, weak) → tool-level discipline (Manual Slop, medium) → data-level discipline (nagent, strong). The data-level discipline is the data-oriented error handling convention applied to the file-write boundary. The synthesis report should surface this parallel in §11.
### 5.5 What the §11 verdict should be
**Verdict: Useful + over-broad.** The file-presence check, the format-based triggers, the 20-line / 1500-char threshold, and the read-before-edit discipline are genuinely useful and worth codifying in Manual Slop's directives. The 8 named skills, the 3-location filesystem, the `present_files` tool, and the `package_management` rules are over-engineered for Manual Slop's per-developer, scripted workflow and should be rejected. The `search_mcp_registry` + `suggest_connectors` tools are chat-UI product features that don't fit the project's domain.
**The recommended Manual Slop action:**
1. Keep the existing 3-layer allowlist (`guide_tools.md:7-53`) and `conductor/edit_workflow.md` protocol as-is. They are *more rigorous* than Fable's framing.
2. Add the format-based triggers (Fable L323-329) and the 20-line / 1500-char artifact threshold (Fable L382) to `conductor/product-guidelines.md` (under "AI-Optimized Compact Style") or create a new `conductor/code_styleguides/output_format_decision.md`.
3. Explicitly reject the 8 named skills, the 3-location filesystem, the `present_files` tool, the `search_mcp_registry` + `suggest_connectors` tools, and the pip `--break-system-packages` rule as chat-UI-specific patterns that don't apply to Manual Slop's domain.
4. Flag the nagent `--description` self-describing pattern (nagent §2.4) as a deferred-rebuild candidate, subsumed by `mcp_architecture_refactor_20260606` (per `decisions.md:142-155`).
5. Flag the nagent SHA-256 hash validation (nagent §9.4) as a deferred candidate, subsumed by Decision Candidate 9 (DEFER UNTIL NEEDED per `decisions.md:228-243`).
---
**Sub-report complete.** This is the evidence base for §11 of `report.md`.
@@ -5,8 +5,8 @@
track_id = "fable_review_20260617"
name = "Fable System Prompt Review (Critical Analysis)"
status = "active"
current_phase = 0
last_updated = "2026-06-17"
current_phase = 7
last_updated = "2026-06-18"
user_hard_rule = "docs/artifacts/Fable System Prompt.txt is NEVER committed. The artifact stays at that local path; the report and the cluster sub-references quote line ranges (≤15 words per quote) but the file does not enter git. Do not modify .gitignore for this; the rule is enforced by the implementer's discipline, not by a tracked file. git add . MUST be inspected before each commit in this track."
[blocked_by]