managarten/docs/reports/mana-agent-improvements-from-claude-code.md
Till JS e5d230e599 feat(agent-loop): M1 — policy gate + reminder channel + parallel reads
Three Claude-Code-inspired primitives for runPlannerLoop, derived from the
reverse-engineering reports in docs/reports/:

1. **Policy gate** (@mana/tool-registry) — evaluatePolicy() gates every tool
   dispatch: denies admin-scope, denies destructive tools not in the user's
   opt-in list, rate-limits per tool (30/60s default), flags prompt-injection
   markers in freetext without blocking. Wired into mana-mcp with a
   per-user rolling invocation log and POLICY_MODE env (off|log-only|enforce,
   default log-only). mana-ai uses detectInjectionMarker only — tool dispatch
   there is plan-only, so rate-limit/destructive checks don't apply yet.

2. **Reminder channel** (packages/shared-ai/src/planner/loop.ts) — new
   reminderChannel callback in PlannerLoopInput. Called once per round with
   LoopState snapshot (round, toolCallCount, usage, lastCall); returned
   strings wrap in <reminder> tags and inject as transient system messages
   into THIS LLM request only. Never pushed to messages[] — the Claude-Code
   <system-reminder> pattern that keeps the KV-cache prefix stable.

3. **Parallel reads** (loop.ts) — isParallelSafe predicate enables
   Promise.all dispatch when every tool_call in a round is parallel-safe,
   in batches of PARALLEL_TOOL_BATCH_SIZE=10. Any non-safe call downgrades
   the whole round to sequential. messages[] always appends in source
   order, never completion order, so the debug log stays linear.
   Default-off (undefined predicate) preserves pre-M1 behaviour.

Tests: 21 new in tool-registry (policy), 9 new in shared-ai (5 parallel,
4 reminder). All 74 green, type-check clean across 4 packages.

Design/plan: docs/plans/agent-loop-improvements-m1.md
Reports: docs/reports/claude-code-architecture.md,
         docs/reports/mana-agent-improvements-from-claude-code.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:56:40 +02:00

26 KiB
Raw Blame History

Mana-Agent-Infrastruktur — Verbesserungen aus den Claude-Code-Learnings

Stand: 2026-04-23 Voraussetzung: claude-code-architecture.md

Konkrete, priorisierte Verbesserungsvorschläge für unser Agent-Stack (services/mana-ai, services/mana-mcp, packages/mana-tool-registry, packages/shared-ai, Persona-Runner), abgeleitet aus den Patterns, die Claude Code durch Reverse-Engineering exponiert hat.


Inhalt

  1. Zusammenfassung
  2. Ist-Stand: Wo steht unser Stack wirklich?
  3. Gap-Analyse gegen Claude Code
  4. Verbesserung 1 — Permission-Gateway UH1-Style
  5. Verbesserung 2 — Reminder-Injection statt History-Pollution
  6. Verbesserung 3 — Context-Compressor wU2-Style
  7. Verbesserung 4 — Parallel-Execution gW5-Style
  8. Verbesserung 5 — Sub-Agent-Pattern I2A-Style
  9. Verbesserung 6 — Haiku-Tier für Background-Tasks
  10. Verbesserung 7 — Async-Steering-Bus h2A-Style
  11. Verbesserung 8 — Deprecated-Tool-Training
  12. Roadmap und Priorisierung
  13. Explizit nicht übernehmen

1. Zusammenfassung

Claude Code ist im Kern ein minimaler Agent-Loop mit sehr viel Environment- Engineering drumherum. Unser Mana-Stack hat den Loop (runPlannerLoop in packages/shared-ai/src/planner/loop.ts) und die Tool-Registry bereits sauber getrennt — aber fast das gesamte „drumherum" fehlt: Permission-Gating, Reminder-Injection, Context-Compression, parallele Tool-Execution, Sub-Agent-Isolation, Async-Steering.

Die gute Nachricht: unsere Architektur ist vorbereitet. Die Registry- Trennung (@mana/tool-registry, @mana/shared-ai), die saubere ToolContext- Abstraktion, die LWW-Projektionen — all das sind solide Fundamente, auf denen man die Claude-Code-Patterns inkrementell nachziehen kann, ohne den Stack umzubauen.

Größter Impact-Hebel: Reminder-Injection + Context-Compression. Größtes Sicherheitsdefizit: fehlendes Permission-Gate auf MCP-Ebene. Größter Performance-Hebel: Parallel-Tool-Execution bei Read-Tools.


2. Ist-Stand: Wo steht unser Stack wirklich?

Die Haupt-Loop: runPlannerLoop

Unser Äquivalent zu Claude Codes nO-Master-Loop lebt in packages/shared-ai/src/planner/loop.ts:117-210. Das Muster ist isomorph zu Claude Code:

while (rounds < maxRounds) {                   // entspricht Claude's while-loop
  const response = await llm.complete(...);    // entspricht stop_reason-Check
  if (response.toolCalls.length === 0) break;  // terminiert bei Text
  for (const call of response.toolCalls) {
    await onToolCall(call);                    // entspricht MH1-Dispatch
  }
}

Abweichungen:

  • DEFAULT_MAX_ROUNDS = 5 (loop.ts:115) — Claude Code hat kein hartes Round-Limit, sondern ein Token-Limit.
  • Tool-Calls werden sequenziell abgearbeitet (loop.ts:172-188) — explizit so dokumentiert: „Parallel execution is a perfectly valid optimisation for pure-read tools but we keep order here".
  • Kein Permission-Gate — onToolCall wird einfach aufgerufen.
  • Kein Reminder-Injection-Mechanismus — System + Prior + User, fertig.

Mission-Runner: mana-ai

services/mana-ai/src/cron/tick.ts (670 Zeilen) orchestriert den Loop im Background. Besonderheiten:

  • 60-Sekunden-Tick statt event-driven (tick.ts:102-286) — das Polling-Modell fängt DB-Changes nur mit Lag auf.
  • Overlap-Guard via Module-Level-Boolean running (tick.ts:100) — einfach aber funktioniert.
  • Cross-Tick-State-Machine für Deep Research (tick.ts, handleDeepResearch) — das einzige Feature, das „länger als ein Tick" überbrückt.
  • Per-Agent-Concurrency (tick.ts:194-208) — mit Budget-Gate auf Token-Ebene. Gut.
  • Key-Grants (tick.ts, crypto/) — RSA-OAEP-gewrappte MDKs pro Mission, TTL-clamped. Sehr solide.

MCP-Gateway: mana-mcp

services/mana-mcp/src/ ist bereits implementiert, nicht nur geplant. 379 LOC total, stateless, JWT-gated. Tool-Registrierung in mcp-adapter.ts:81-124:

for (const spec of getRegistry()) {
  if (!isExposable(spec)) continue;   // filter admin-scoped
  server.tool(spec.name, spec.description, shape, invoke);
}

Das ist elegant — aber isExposable ist die einzige Policy-Schicht (mcp-adapter.ts:35-37). Es gibt keine Rate-Limits, keine pro-Request-Policy, keine User-Whitelist pro Tool, keine Command-Injection-Prüfung für freie Text-Felder.

Tool-Registry: @mana/tool-registry

packages/mana-tool-registry/src/ (rund 400 LOC). Sehr sauber:

  • ToolSpec<I, O> mit Zod-Schemas (types.ts:91-122)
  • ToolContext mit userId/spaceId/jwt/invoker/getMasterKey (types.ts:58-74)
  • registerTool + getRegistry Singleton (registry.ts)
  • encryptedFields als deklaratives Feld — nicht handler-intern. Genial für zukünftige CI-Drift-Checks gegen die web-app crypto/registry.ts.

Aktuell abgedeckte Module: habits, spaces, todo, notes, journal, calendar, contacts, articles, missions, tags (types.ts:18-29). Laut mana-ai/CLAUDE.md: 31 propose-Tools über 16 Module sind server-seitig sichtbar; 28 weitere auto-Tools leben ausschließlich in der Webapp.

Persona-Runner

Nicht implementiert. Plan in docs/plans/mana-mcp-and-personas.md. Wichtig: wir haben dort die Chance, die Sub-Agent-Patterns aus §8 direkt richtig zu bauen, statt nachträglich nachzurüsten.


3. Gap-Analyse gegen Claude Code

Pattern (Claude Code) Mana-Äquivalent Status Priorität
nO Master-Loop runPlannerLoop vorhanden, solide
MH1 Tool-Dispatcher onToolCall + Registry-Handler vorhanden
UH1 Permission-Gateway nur isExposable Admin-Filter ⚠️ stark lückenhaft hoch
gW5 Parallel-Scheduler (max 10) sequenziell fehlt mittel
wU2 92%-Compressor keinerlei Context-Kompression fehlt hoch
<system-reminder> Reminder-Injection User-Prompt-Concat, kein transientes Channel fehlt hoch
h2A Async-Message-Queue 60s-Tick, kein mid-task interrupt fehlt niedrig
I2A Sub-Agent (Fresh-Context) Persona-Runner (extern, geplant) 🟡 im Plan, nicht isomorph mittel
File-Freshness-Tracking n/a — wir editieren keine Files — n/a
Haiku für Background-Tasks alle Calls gehen an mana-llm primary model fehlt mittel
BatchTool deprecated wir haben weder Batch noch parallel — n/a
CLAUDE.md-Disclaimer-Pattern Agent-Context / Memory ohne Disclaimer 🟡 improvement-worth niedrig

4. Verbesserung 1 — Permission-Gateway UH1-Style

Problem

services/mana-mcp/src/mcp-adapter.ts:34-37 — der einzige Gate ist Scope-Filter:

function isExposable(spec: AnyToolSpec): boolean {
  return spec.scope === 'user-space';
}

Das reicht nicht:

  • Kein pro-User-Opt-In für gefährliche Tools (z. B. habits.delete).
  • Kein Rate-Limit pro User pro Tool (MCP ist JWT-gated, aber ein entwendeter JWT kann in 10 Sekunden 1000 Calls machen).
  • Kein Path-/Content-Filter für Freitext-Argumente (Tool notes.create mit content könnte Prompt-Injection ins Frontend tragen).
  • destructive-Policy-Hint ist dokumentiert (types.ts:48) aber nicht durchgesetzt — die Registry weiß, welches Tool destructive ist, aber niemand liest das an der Grenze.

Vorschlag

Ein zentrales evaluatePolicy() in @mana/tool-registry:

// packages/mana-tool-registry/src/policy.ts (neu)
export interface PolicyDecision {
  allow: boolean;
  reason?: string;
  /** Optional: inject as <system-reminder> on next turn. */
  reminder?: string;
}

export function evaluatePolicy(
  spec: AnyToolSpec,
  ctx: ToolContext,
  rawInput: unknown,
  opts: {
    userSettings?: { allowDestructive: boolean; perToolRateLimit?: number };
    recentInvocations?: readonly { toolName: string; at: Date }[];
  },
): PolicyDecision;

Aufgerufen wird sie in mcp-adapter.ts vor spec.handler() und — wichtig — auch in mana-ais onToolCall-Callback. Damit ist die Policy an einer Stelle und für beide Consumer gültig.

Konkrete Regeln für M1:

  • policyHint: 'destructive' → Default deny, User muss explizit in Settings opt-in (pro Tool oder pro Scope).
  • Rolling 60-Sekunden-Window: Cap bei 30 Calls/Tool/User/Minute auf MCP.
  • Für Tools mit Freitext-Argumenten (content, description, note): ein Zod .refine() das klassische Injection-Marker ({{, <system, ignore previous) erkennt und loggt — nicht blockiert, aber markiert.

Aufwand

~1 Tag. Die Registry ist dafür gebaut.


5. Verbesserung 2 — Reminder-Injection statt History-Pollution

Problem

In runPlannerLoop wird die messages-History pro Round durch Assistant- und Tool-Turns erweitert — korrekt und nötig. Was nicht passiert: transienter Kontext (Token-Budget, Agent-Memory-Updates, User-Interjections, Mission-Deadline-Änderungen) wird entweder

  1. in den System-Prompt eingebacken und bleibt dort ewig (veraltet), oder
  2. in den User-Prompt per String-Concatenation injiziert (mutiert die History, invalidiert KV-Cache, landet in Logs).

Die <agent_context>-Blöcke aus mana-ai v0.5 sind schon ein Schritt in die richtige Richtung, aber sie sind im System-Prompt und nicht transient.

Vorschlag

ReminderChannel als neuer Input-Slot für runPlannerLoop:

// packages/shared-ai/src/planner/loop.ts
export interface PlannerLoopInput {
  // … bestehende Felder …
  /** Per-round transient hints. Called after every assistant turn;
   *  injected as a fresh system message at the end of `messages` before
   *  the next LLM call. NOT persisted in the returned message log. */
  readonly reminderChannel?: (roundIndex: number, state: LoopState) => string | null;
}

Die Reminder-Strings werden als transiente { role: 'system', content: '<reminder>…</reminder>' } vor jedem LLM-Call eingefügt und nach dem Call wieder entfernt — sie leben nie in messages, landen nicht in der Iteration-History. Genau das Pattern von Claude Codes <system-reminder>-Tags.

Use-Cases heute schon sinnvoll:

  • Token-Budget: „Du hast 80 % deines Mission-Budgets verbraucht. Plane Tool-Calls sparsam."
  • Mission-Timer: „Mission ist in 2 Minuten überfällig — priorisiere."
  • Zero-Knowledge-Mode: „User ist ZK — verbotene Tabellen werden nicht decrypted. Frag nicht nach."
  • Nach TodoWrite: aktuellen Todo-State echoen (wie in Claude Code, §7).
  • Stale-Data-Warning: „Letzter Sync vor 45 min — Daten könnten veraltet sein."

Aufwand

~4h für die Loop-Änderung, ~2 Tage für die ersten drei Reminder-Producer.

Warum wichtig

Das ist der größte qualitative Hebel — er wirkt sich auf jede einzelne Mission-Iteration aus, nicht nur auf Edge-Cases. Genau das, was Claude Code so feedback-sensitiv macht.


6. Verbesserung 3 — Context-Compressor wU2-Style

Problem

Bei langlaufenden Missions (Deep Research, Multi-Round-Plans) wird die Iteration-History in Mission.iterations[] immer länger. Heute wird sie komplett in den buildSystemPrompt()-Call geschoben — irgendwann overflowed das den Context.

services/mana-ai/src/cron/tick.ts:211-221 ruft planOneMission, das via runPlannerLoop alle Iterations durchreicht. Kein Abbruch, kein Pruning, keine Summary.

Vorschlag

Einen dedizierten compactHistory() pro Mission-Lifecycle:

// packages/shared-ai/src/planner/compact.ts (neu)
export async function compactIterations(
  iterations: readonly MissionIteration[],
  llm: LlmClient,
  opts: { budgetTokens: number; maxInputTokens: number },
): Promise<{ preserved: MissionIteration[]; summary: CompactSummary }>;

Trigger-Heuristik (analog zum 92 %-Trigger):

  • Wenn die kumulierte Token-Schätzung der iterations[] > 0.6 × maxInputTokens → komprimieren.
  • Alle Iterations älter als die letzten 3 werden in eine einzelne Compact-Iteration gefasst mit dem Schema { goal, decisions, filesChanged, currentProgress } (genau das, was Claude Code persistiert).
  • Die Compact-Iteration wird als synthetische Iteration mit actor: { kind:'system', source:'compactor' } in Mission.iterations[] geschrieben und die summierten Originale werden archiviert in einer neuen Tabelle mana_ai.iteration_archive (nicht gelöscht, nur nicht mehr Teil des Prompt-Contexts).

Kompressionsrate aus Claude Code: ~6.8× gemeldet. Bei uns realistisch ~3-5×, weil Iterations schon strukturiert sind.

Aufwand

~3-5 Tage inkl. Archiv-Tabelle und Migration.

Wann sinnvoll

Jetzt für Deep-Research-Missions (die schon heute Token-Explosion riskieren), später für normale Multi-Round-Plans.


7. Verbesserung 4 — Parallel-Execution gW5-Style

Problem

packages/shared-ai/src/planner/loop.ts:172-188 — Kommentar im Code:

„Parallel execution is a perfectly valid optimisation for pure-read tools but we keep order here so the message log tells a linear story when the user debugs a failure."

Das Argument ist legitim für Debug-Ergonomie, kostet aber bei multi-Read- Plans linear Zeit. Mission mit 5 read_*-Tools: 5× LLM-Latency statt 1×.

Vorschlag

Claude Codes gW5-Regel direkt übernehmen:

  1. Parallelisieren wenn alle toolCalls einer Round policyHint: 'read' haben.
  2. Serialisieren sobald eine davon write/destructive ist.
  3. Harte Grenze 10 parallel — bei mehr: in Batches à 10.
// packages/shared-ai/src/planner/loop.ts (patch)
const allRead = calls.every(c => getPolicyHint(c.name) === 'read');
if (allRead && calls.length > 1) {
  const results = await Promise.all(
    calls.slice(0, 10).map(call => onToolCall(call))
  );
  // … append to messages in source order, not completion order
} else {
  for (const call of calls) { /* sequential */ }
}

Wichtig: Reihenfolge in messages bleibt Source-Order, nicht Completion-Order. Das erhält die Debug-Lesbarkeit, die der bisherige Kommentar schützen wollte — wir verlieren also nichts, gewinnen aber Wanduhr-Zeit.

Aufwand

~2h. Die Information (policyHint) existiert bereits in der Registry.

Voraussetzung

Verbesserung 1 (Policy-Gate) sollte vorher laufen, damit policyHint an der Loop-Grenze autoritativ ist.


8. Verbesserung 5 — Sub-Agent-Pattern I2A-Style

Problem

Der Plan sieht den Persona-Runner als eigenes Service auf :3070 vor (docs/plans/mana-mcp-and-personas.md). Das ist für Deployment-Isolation sinnvoll, aber es ist nicht das Claude-Code-Pattern.

Claude Codes I2A ist in-process:

  • Fresh messages[] (kein Parent-History-Leak)
  • eigenes Token-Budget
  • eigene Tool-Permissions (restriktiver)
  • Parent kriegt nur die finale Summary zurück, nicht die Zwischenschritte
  • Rekursions-Grenze: 1 Level

Vorschlag

Zwei-Schichten-Modell:

(a) In-Process Sub-Loop in @mana/shared-ai:

// packages/shared-ai/src/planner/sub-agent.ts (neu)
export async function runSubAgent(opts: {
  readonly parentLoop: { messages: readonly ChatMessage[]; spec: ToolSpec };
  readonly task: string;
  readonly allowedTools: readonly string[];  // Whitelist, restriktiver als Parent
  readonly maxRounds?: number;                // Default 3
  readonly llm: LlmClient;
  readonly onToolCall: (call: ToolCallRequest) => Promise<ToolResult>;
}): Promise<{ summary: string; usage: TokenUsage }>;

Wird vom Task-ähnlichen Tool in der Registry aufgerufen. Rekursion wird über einen Depth-Counter im ToolContext verhindert (ctx.subAgentDepth >= 1 → error).

(b) Persona-Runner als Out-of-Process Orchestrator für Langläufer — der bleibt, wie im Plan, ein eigener Service. Aber: er ruft intern denselben runSubAgent-Code, nur mit höherem Round-Budget und Persona-spezifischen System-Prompt.

Warum zweistufig

In-Process-Sub-Agents sind für Context-Laundering da (dirty Recherche- Kontext vom Parent fernhalten). Der Persona-Runner ist für Langzeit- Lifecycles (eine Persona lebt über mehrere Wochen). Beides braucht dasselbe primitive runSubAgent, aber andere Deployment-Modelle.

Aufwand

~1 Woche.


9. Verbesserung 6 — Haiku-Tier für Background-Tasks

Problem

Claude Code nutzt Haiku für hochfrequente Nebencalls:

  • Quota-Check
  • Topic-Detection
  • Session-Summarization
  • Command-Injection-Detection
  • Auto-Compact-Fallback

Bei uns geht jeder Call an mana-llm mit dem Default-Modell — das ist für Routing-Entscheidungen ("ist dieser User-Input eine Frage oder eine Mission?") overkill und teuer.

Vorschlag

@mana/shared-ai bekommt einen TieredLlmClient:

// packages/shared-ai/src/planner/tiered-client.ts (neu)
export function createTieredLlmClient(baseUrl: string): {
  primary: LlmClient;    // für runPlannerLoop
  fast: LlmClient;       // für Classification, Summarization, Guard
};

Konkrete Einsätze:

  • compactIterations (§6) → fast statt primary. Spart 80 % Kosten beim Kompressor.
  • Mission-Trigger-Klassifikation statt Regex (heute tick.ts:73-82): statt DEEP_RESEARCH_TRIGGER als Regex ein Haiku-Call „Ist dieses Mission- Objective Deep Research?" — robuster und überrascht nicht bei neuen Formulierungen.
  • Reminder-Producer (§5): Der Token-Budget-Reminder wird via fast formuliert statt hartkodiert — variiert die Phrase pro Runde (weniger Prompt-Staleness).
  • Command-Injection-Check für Freitext-Tool-Args (in §4 erwähnt) → fast.

Modell-Mapping in mana-llm

Wir müssen mana-llm einen tier: 'primary' | 'fast' Request-Parameter geben, der dann intern auf ein billigeres Modell routet (z. B. Ollama llama3.1:8b lokal für fast, Claude/Gemini-primary über Cloud für primary).

Aufwand

~3 Tage, fast alles in mana-llm.


10. Verbesserung 7 — Async-Steering-Bus h2A-Style

Problem

Unser Mission-Runner tickt alle 60 Sekunden (tick.ts:102). Wenn der User mid-Mission etwas ändert (neues Objective, Mission pausieren, neuen Kontext hinzufügen), wird das erst im nächsten Tick sichtbar.

Claude Codes h2A ermöglicht User-Interjections während ein Tool läuft. Das ist für uns nur teilweise relevant — Missions sind explizit als Background-Jobs konzipiert — aber es gibt einen konkreten Use-Case:

Konkreter Use-Case: Companion-Chat im Frontend

Die Webapp hat einen Companion-Chat (unified mana app). Der läuft interaktiv. Heute nutzt er vermutlich (packages/shared-ai/src/planner/loop.ts) direkt — also dieselbe sequenzielle Loop.

Vorschlag: runPlannerLoop bekommt einen optionalen AbortSignal und einen InterruptChannel:

export async function runPlannerLoop(opts: {
  // … bestehend …
  readonly signal?: AbortSignal;
  readonly interruptChannel?: {
    readonly take: () => ChatMessage | null;  // non-blocking pull
  };
}): Promise<PlannerLoopResult>;

Vor jedem nächsten LLM-Call: const msg = interruptChannel?.take() — falls vorhanden, als user-Message einfügen statt die Loop stumpf weiterlaufen zu lassen.

Aufwand

~1 Tag.

Ausdrücklich nicht tun

h2A nicht für mana-ai-Background-Missions einbauen. Der Tick- Ansatz ist für Server-side-Missions korrekt — User-Interjections kommen dort über den normalen Sync-Flow (Mission-Update → nächster Tick sieht es).


11. Verbesserung 8 — Deprecated-Tool-Training

Problem

Wir haben aktuell 59+ Tools in der Registry/Shared-AI. Nicht alle sind gleich sinnvoll für LLMs zum Planen — manche sind redundant (notes.create vs. notes.append_to_note vs. notes.update_note), manche werden praktisch nie genutzt.

Claude Codes BatchTool-Deprecation ist instruktiv: Anthropic hat das Tool rausgenommen, weil das Modell selbst gelernt hat, mehrere tool_use- Blocks pro Turn zu senden — das Feature war wegtrainiert.

Vorschlag

Einen monatlichen Tool-Usage-Audit:

  • Metrik mana_ai_tool_invocations_total{tool} aus bereits existierenden Metrics
  • Report aller Tools unter Top-50-Percentile-Calls → Kandidat für Deprecation
  • Alternative: mcp-adapter.ts loggt den vom Modell geforderten aber erfolglosen Tool-Call — daraus wird sichtbar, welche Tools das Modell erfindet, weil der Name „intuitiv" wäre (z. B. notes.delete wenn wir nur notes.archive haben).

Das ist weniger eine Code-Änderung und mehr ein Prozess: alle 6 Wochen einen 1-Stunden-Review, Tools konsolidieren.

Aufwand

0 für die Infra (Metrics sind da). 1h pro Audit-Zyklus.


12. Roadmap und Priorisierung

M1 (2 Wochen)

# Verbesserung Aufwand Abhängigkeit
1 Permission-Gateway (§4) 1 Tag
2 Reminder-Injection Loop-API (§5) 4 h
3 Parallel-Execution für Reads (§7) 2 h §4 (policyHint)
4 Async-Steering im Companion (§10) 1 Tag

M1-Outcome: Sicherer MCP-Gateway, qualitativ bessere Mission-Planung durch Reminders, schnellere Multi-Read-Plans, Companion-Chat abbruchbar.

M2 (3-4 Wochen)

# Verbesserung Aufwand Abhängigkeit
5 Context-Compressor wU2 (§6) 3-5 Tage §9
6 Haiku-Tier in mana-llm (§9) 3 Tage
7 Reminder-Producer Library (§5) 2 Tage M1 #2

M2-Outcome: Deep-Research-Missions skalieren, Background-Calls 80 % billiger, Reminder-Channel in Produktion.

M3 (Persona-Runner)

# Verbesserung Aufwand Abhängigkeit
8 In-Process runSubAgent (§8) 1 Woche M1 #1, M2 #5
9 Persona-Runner nutzt runSubAgent 2 Wochen M3 #8

M3-Outcome: Sub-Agent-Pattern einheitlich, Persona-Runner kann komplexe Multi-Step-Personas orchestrieren, ohne Parent-Context zu verseuchen.

Ongoing

# Verbesserung Aufwand
10 Tool-Usage-Audit (§11) 1h alle 6 Wochen

13. Explizit nicht übernehmen

Nicht jedes Claude-Code-Pattern macht für uns Sinn:

  • File-Freshness-Tracking — wir editieren keine Dateien im Agent-Kontext. Das Äquivalent wäre „Sync-Freshness-Tracking", das aber schon durch mana_sync LWW-Semantik adressiert ist.
  • BatchTool einführen — das Claude-Code-Pattern ist, BatchTool zu deprecaten, weil das Modell nativ parallele tool_use-Blocks sendet. Wir sollten das direkt als Endzustand adoptieren (§7), nicht über ein Batch-Zwischenstadium gehen.
  • yoga.wasm / Ink — die Mana-Webapp ist SvelteKit, kein Terminal-UI. Das UI-Layer-Muster ist für uns irrelevant.
  • --bypassPermissions-Mode — für ein Multi-User-Produkt mit Zero-Knowledge-Option darf es kein Opt-Out aus der Policy geben.
  • Der Haiku-Quota-Ping — unser Billing läuft über mana-credits, wir sehen Quota deterministisch vor dem Call, nicht probabilistisch.