VITTO VS OPENCLAW

Documentation for Sessions

Vitto vs OpenClaw: Honest Assessment & Usage Guide

Session 116 | February 2026 This document is a candid engineering assessment, not marketing material.


TL;DR

Vitto is a multi-service AI agent platform with 13 NestJS modules, 90+ MCP tools, multi-agent handoffs, tiered vector memory, multi-LLM routing, and a layered security system. OpenClaw is a single-binary personal AI assistant with 4 core tools, 565+ community skills, and direct OS access.

They solve different problems. OpenClaw is a power-user's personal assistant. Vitto is an enterprise platform for teams running agents at scale with audit trails, cost control, and security.

What's real vs aspirational is detailed below. Read the "Honesty Check" column carefully.


Feature Comparison

Core Agent Capabilities

Feature OpenClaw Vitto Honesty Check
Autonomous task execution Yes (4 core tools + bash) Yes (10 tools, 4-phase ANALYZE-PLAN-EXECUTE-VERIFY) Both real. Vitto's phased approach is more structured but slower per task.
Multi-model LLM support Claude, GPT-4, Ollama, MiniMax Claude, GPT-4, Gemini, Ollama Both real. Vitto adds SmartRouter with cost-based auto-routing.
Persistent memory Markdown files, basic context Vector-embedded tiered recall (hot cache + Atlas $vectorSearch + platform APIs) Vitto wins clearly. 1536-dim embeddings with semantic recall vs flat files.
Self-extending skills Agent writes its own extensions, hot-reloads Skill CRUD + marketplace + versioning + rollback Different approaches. OpenClaw's is more dynamic (agent self-modifies). Vitto's is more controlled.
Proactive operation Cron jobs, heartbeats, reminders ProactiveMonitorService with @Cron scheduling Both real. Vitto's is integrated into the NestJS lifecycle.
Sub-agents / delegation Single agent only DelegationManagerService + SubAgentService + MCP handoffs Vitto wins. Multi-agent mesh with handoff protocol is production-tested.
Cost visibility None ($300+/day reports) CostTrackerService + CostGuardService (25 iter, 100K token, 5min limits) Vitto wins on guards. BUT: spending persistence is NOT wired (see gaps).

Messaging / Channels

Feature OpenClaw Vitto Honesty Check
WhatsApp Yes (core) Yes (inbound + outbound wired) Both real.
Telegram Yes (core) Yes (Bot API, webhook receiver wired) Both real. Vitto added in Phase 2.
Discord Yes (core) Yes (webhook + PING verification wired) Both real.
Slack Yes (core) Yes (HMAC-SHA256 verified, full reply loop) Both real.
Email No SendGrid HTTP API adapter Vitto only. But untested in production.
iMessage Yes (AppleScript on macOS) No OpenClaw only. Platform-specific.
Signal Yes No OpenClaw only.
Reply routing Implicit (same thread) Explicit routeTaskResponse() with context.replyTo Both work. Vitto's is channel-agnostic.

Security

Feature OpenClaw Vitto Honesty Check
Tool sandboxing None ("YOLO mode") 3-tier: safe/guarded/dangerous with approval flow Vitto wins dramatically. OpenClaw gives unrestricted bash access.
Prompt injection defense None 50+ regex patterns, 8 attack categories, channel-specific limits Exists but NOT WIRED. scanForInjection() is never called in the execution path. Dead code.
Credential management Plaintext in env AES-256-GCM SecretVaultService Vitto wins. But vault is only used for skill requiredSecrets, not system-wide.
Audit logging None MongoDB-persistent, 365-day retention, hot cache, CSV/JSON export Fully wired and real. Every tool call is logged.
Network access control Unrestricted NetworkPolicyService (SSRF protection, endpoint allowlists) Exists, partially wired. Called from validateSkillEndpoint() but NOT from http_request tool handler itself.
Rate limiting None Per-channel rate limits, loop detection, cost runaway detection Exists but NOT WIRED. ChannelRateLimiterService is never called from engine or gateway.
Circuit breakers None CircuitBreakerService (CLOSED/OPEN/HALF_OPEN) Exists but NOT WIRED. Never called from LLM providers or tool execution.
Dead letter queue None MongoDB-backed DLQ with exponential backoff Exists but NOT WIRED. enqueue() is never called from task failure paths.
Container sandbox None Docker-based isolation (--cap-drop ALL, --network none) Exists but NOT WIRED. Only exposed via /security/sandbox/status endpoint. run_command tool does NOT use it.
RBAC None RolesGuard with @Roles('admin') decorator Wired on security controller endpoints. Works for compliance routes.

Enterprise / Compliance

Feature OpenClaw Vitto Honesty Check
Tamper-evident audit None SHA-256 hash chain on audit entries Exists but NOT WIRED. computeHash() is never called from SecurityAuditService.record(). Hash fields exist in schema but are always null.
Data retention None RetentionPolicyService (365/180/90/30-day tiers) Wired via controller endpoint. Needs @Cron job to run automatically.
GDPR export None exportUserData() + deleteUserData() with tombstoning Wired via controller. Functional.
Team learning None shareLevel on memories, recallTeam() method Wired via controller. But no teams exist in the user model yet.
Skill versioning None Immutable snapshots + rollback Wired. updateSkill() auto-creates snapshots. Rollback endpoint works.
Multi-tenant No (single-user) Yes (userId scoping throughout) Vitto wins. Built for teams.

Deployment

Feature OpenClaw Vitto Honesty Check
Setup time "Minutes" (single binary) Railway per-service deployment with Dockerfiles OpenClaw wins on simplicity. Vitto requires 3+ services + MongoDB + env config.
Self-hosted Yes (runs locally) Yes (Docker/Railway) Both.
Cloud deployment Community-hosted Railway with per-service branches, health checks, auto-restart Vitto has proper production infra.
Background operation Runs in terminal or as service Requires running NestJS backend(s) OpenClaw is simpler. Vitto needs infrastructure.

What's ACTUALLY Working End-to-End

These features you can use RIGHT NOW with confidence:

  1. Submit a task via POST /engine/tasks and watch it execute through ANALYZE-PLAN-EXECUTE-VERIFY phases
  2. Send a Slack/WhatsApp/Telegram/Discord message and get a response routed back through the same channel
  3. Tool execution with security audit - every tool call is logged to MongoDB with sandbox level, duration, success/failure
  4. Semantic memory recall - ask Vitto about past interactions and get vector-similarity ranked results
  5. Multi-LLM routing - SmartRouter selects provider by complexity, with failover and history tracking
  6. Skill CRUD with versioning - create, update (auto-snapshot), rollback, publish with security vetting
  7. Cost guard limits - 25 iterations, 100K tokens, 5-minute max per task enforced
  8. SSE event streaming - real-time task progress via GET /engine/events
  9. Multi-agent handoffs - delegate tasks to other agents via MCP handoff protocol
  10. GDPR export/delete - export or tombstone all user data via security controller

What EXISTS But Is NOT Connected (Dead Code)

These services were built but never wired into the execution flow:

Service What It Does What's Missing
scanForInjection() Scans text for 50+ injection patterns Never called before tool execution or LLM input. No caller.
sanitizeOutput() Strips leaked system prompts, env vars Never called on LLM/tool output. No caller.
ChannelRateLimiterService Per-channel rate limits + loop detection Never called from ChannelGateway or VittoEngine. No caller.
CircuitBreakerService Provider failure circuit breaking Never wraps LLM calls or tool execution. No caller.
DeadLetterQueueService Failed task retry with backoff Never called from task failure handlers. No caller.
HashChainVerifierService.computeHash() Tamper-evident audit hashing Never called from SecurityAuditService.record(). Chain is empty.
ProcessSandboxService OS-level process isolation Never called from run_command tool. Tool uses raw execAsync.
ContainerSandboxService Docker container isolation Only exposed via status endpoint. Never used for execution.
NetworkPolicyService SSRF protection + endpoint allowlists Only called from SkillManagerService.validateSkillEndpoint(), never from http_request tool.
CostTrackerService.recordSpending() Persist spending to MongoDB Never called from PhaseExecutor or AgentLoop after LLM calls.

Impact: These represent approximately 40% of the Phases 1-5 code. The services are correctly built, registered in modules, and injectable. They just need callers.


How to Use Vitto Today

Prerequisites

Submit a Task

curl -X POST http://localhost:3003/vitto-api/engine/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "request": "Analyze the authentication flow in our codebase and suggest improvements",
    "userId": "user-123",
    "context": {
      "layer": "developer",
      "spaceId": "my-space"
    }
  }'

Stream Task Progress (SSE)

curl -N http://localhost:3003/vitto-api/engine/events

Recall Memories

curl "http://localhost:3003/vitto-api/engine/memories/search?query=authentication+flow&userId=user-123&limit=5"

Manage Skills

# Create a skill
curl -X POST http://localhost:3003/vitto-api/engine/skills \
  -H "Content-Type: application/json" \
  -d '{
    "name": "code-reviewer",
    "description": "Reviews code for security and quality issues",
    "category": "developer",
    "triggers": ["review code", "check code quality"],
    "steps": [{ "action": "analyze", "params": { "focus": "security" } }]
  }'

# Publish (runs security vetting)
curl -X POST http://localhost:3003/vitto-api/engine/skills/{id}/publish

# View version history
curl http://localhost:3003/vitto-api/engine/skills/{id}/versions

# Rollback
curl -X POST http://localhost:3003/vitto-api/engine/skills/{id}/rollback \
  -d '{ "targetVersion": "1.0.0" }'

Check Security Dashboard

# Audit logs
curl "http://localhost:3003/vitto-api/security/audit?limit=20"

# Audit stats
curl http://localhost:3003/vitto-api/security/audit/stats

# Export for compliance
curl http://localhost:3003/vitto-api/security/audit/export/csv > audit.csv

# GDPR export
curl http://localhost:3003/vitto-api/security/compliance/gdpr/export/user-123

Configure Messaging Channels

# Slack: Configure webhook at POST /engine/integrations/slack/events
# Telegram: Set webhook to POST /engine/integrations/telegram/webhook
# Discord: Set webhook to POST /engine/integrations/discord/webhook
# WhatsApp: Configure Twilio webhook at POST /engine/integrations/whatsapp/webhook

Schedule Tasks

curl -X POST http://localhost:3003/vitto-api/engine/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "daily-health-check",
    "cronExpression": "0 9 * * *",
    "taskType": "prompt",
    "taskConfig": {
      "prompt": "Run health checks on all services and report status",
      "layer": "developer"
    }
  }'

Architectural Strengths (What's Genuinely Good)

  1. Module isolation is excellent. 13 NestJS modules with clean dependency graph. No circular imports. SecurityModule exports everything downstream needs. Zero DI failures detected.

  2. Audit logging is solid. Every tool call hits recordAudit() with sandbox level, input/output, timing, and success/failure. 365-day retention with TTL indexes. Hot cache for fast dashboard reads. This is real SOC 2 foundation.

  3. Memory system is sophisticated. Vector embeddings with Atlas $vectorSearch, tiered hot/warm/cold recall, importance scoring that evolves with access frequency. This is genuinely better than OpenClaw's flat Markdown files.

  4. Multi-agent handoffs work. MCP-based handoff protocol with WebSocket push, REST fallback, offline queuing, and sentinel reconnection. Tested across Cursor, Claude Code, VSCode, and Chrome extension.

  5. Skill versioning is well-designed. Immutable snapshots before every update, semver bumping, full rollback with pre-rollback safety snapshots. The data model is sound.

  6. SmartRouter is smart. Cost-based routing with provider failover, routing history, and decision persistence. The in-memory-first + MongoDB-secondary pattern is the right tradeoff for latency.


Critical Gaps to Fix (Prioritized)

P0 — Wire the Dead Code

These are the highest-leverage fixes. The code exists and is tested, it just needs callers:

# Fix Effort Impact
1 Call scanForInjection() in ToolRegistryService.executeTool() before passing input to handler 5 lines Activates prompt injection defense
2 Call rateLimiter.check() in ChannelGatewayService.normalizeInbound() 5 lines Activates rate limiting + loop detection
3 Wrap LLM calls in SmartRouterService.route() with circuitBreaker.execute() 10 lines Activates circuit breaking on provider failures
4 Call dlq.enqueue() in VittoEngineService when a task fails after max retries 5 lines Activates dead letter queue
5 Call hashChain.computeHash() in SecurityAuditService.record() and store on the document 5 lines Activates tamper-evident audit chain
6 Call costTracker.recordSpending() in PhaseExecutorService after each LLM call 5 lines Activates spending persistence

Total effort: ~35 lines of glue code. This would activate 6 major security features.

P1 — Missing Integration Points

# Gap Why It Matters
7 run_command tool does not use ProcessSandboxService Commands run with full process.env access (secrets are stripped, but no resource limits)
8 http_request tool does not call NetworkPolicyService.validate() Any URL can be fetched, including private IPs (SSRF)
9 No @Cron job for RetentionPolicyService.enforceRetention() Retention policy exists but never runs automatically
10 Team learning has no team model shareLevel and teamId exist on memories but no team entity exists in the system

P2 — Architecture Gaps vs OpenClaw

# Gap Why It Matters
11 No self-modification capability OpenClaw's killer feature: agent writes/reloads its own skills at runtime
12 No desktop daemon for background operation Vitto requires running backend services; OpenClaw runs as a single process
13 No frontend onboarding wizard Setup requires manual env config + service startup
14 BullMQ/Redis task queue not implemented Plan called for BullMQ but current task scheduler is in-memory + MongoDB

Verdict

Vitto's foundation is strong. The module architecture, memory system, multi-agent handoffs, and audit logging are production-grade. The security services are well-designed and correctly registered.

The main problem is integration, not implementation. ~40% of the security code (Phases 1-5) exists as standalone services that aren't called from the execution flow. Fixing this requires ~35 lines of glue code, not new features.

vs OpenClaw:

Bottom line: Wire the dead code (P0 items 1-6), and Vitto goes from "impressive architecture with gaps" to "enterprise-ready AI agent platform."