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>
26 KiB
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
- Zusammenfassung
- Ist-Stand: Wo steht unser Stack wirklich?
- Gap-Analyse gegen Claude Code
- Verbesserung 1 — Permission-Gateway
UH1-Style - Verbesserung 2 — Reminder-Injection statt History-Pollution
- Verbesserung 3 — Context-Compressor
wU2-Style - Verbesserung 4 — Parallel-Execution
gW5-Style - Verbesserung 5 — Sub-Agent-Pattern
I2A-Style - Verbesserung 6 — Haiku-Tier für Background-Tasks
- Verbesserung 7 — Async-Steering-Bus
h2A-Style - Verbesserung 8 — Deprecated-Tool-Training
- Roadmap und Priorisierung
- 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 —
onToolCallwird 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)ToolContextmituserId/spaceId/jwt/invoker/getMasterKey(types.ts:58-74)registerTool+getRegistrySingleton (registry.ts)encryptedFieldsals deklaratives Feld — nicht handler-intern. Genial für zukünftige CI-Drift-Checks gegen die web-appcrypto/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.createmitcontentkö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'→ Defaultdeny, 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
- in den System-Prompt eingebacken und bleibt dort ewig (veraltet), oder
- 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' }inMission.iterations[]geschrieben und die summierten Originale werden archiviert in einer neuen Tabellemana_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:
- Parallelisieren wenn alle
toolCallseiner RoundpolicyHint: 'read'haben. - Serialisieren sobald eine davon
write/destructiveist. - 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) →faststattprimary. Spart 80 % Kosten beim Kompressor.- Mission-Trigger-Klassifikation statt Regex (heute
tick.ts:73-82): stattDEEP_RESEARCH_TRIGGERals 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
fastformuliert 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.tsloggt 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.deletewenn wir nurnotes.archivehaben).
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_syncLWW-Semantik adressiert ist. BatchTooleinführen — das Claude-Code-Pattern ist,BatchToolzu deprecaten, weil das Modell nativ paralleletool_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.
Related
claude-code-architecture.md— Technische Grundlage dieses Berichtsdocs/plans/mana-mcp-and-personas.md— Ongoing-Plan für mana-mcp + persona-runnerdocs/architecture/COMPANION_BRAIN_ARCHITECTURE.md§20-22 — Agent-Design der Webappdocs/reports/ai-agent-architecture-comparison.md— Weiterer externer Vergleich