Commit graph

2 commits

Author SHA1 Message Date
Till JS
2769241de3 docs(plans): agent-loop plan reflects M1 shipped + M2 core shipped
Update the plan doc to match reality:

  - Title + intro: "M1 + M2 (core)" instead of just M1.
  - Exit criteria: mark the two achievable ones DONE with commit
    refs; flag POLICY_MODE=enforce soak as ops-blocked; correct the
    parallel-read-speedup criterion that was misformulated (mana-ai
    SERVER_TOOLS are all propose-policy, so parallelisation
    actually kicks in on the webapp side, covered by 54a12ffd5).
  - New M2 section: 5-row status table (M2.1-M2.4 + bonus shipped;
    M2.5 Haiku-tier pending).
  - M2 config table (MANA_AI_COMPACT_MAX_CTX).
  - M2 metrics listed (compactions_triggered_total, compacted_turns).
  - Open polish items: allowDestructive still hardcoded to [].

No code changes. Future sessions reading the plan now see the
actual shipped surface instead of a stale M1-only snapshot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 18:12:58 +02:00
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