Session 150 Infrastructure And Vision Report

Documentation for Architecture

Session 150 — Infrastructure, Research & Vision Report

Date: February 27, 2026 Author: Claude (Session 150, Coding Agent) Scope: Self-hosted sandbox infrastructure decisions, cost analysis, vendor comparison, and Vitto "Jarvis" memory architecture analysis


PART 1: Infrastructure Research & Decisions

1.1 Why We're Self-Hosting

E2B Cloud has hard limits that block our product vision:

E2B Cloud Limitation Our Self-Hosted Reality
1h sessions (free), 24h (pro) Unlimited — VM lives until destroyed or server restarts
$150+/month at 10 users $53/month flat, regardless of users
No custom Chrome extensions in VM Pre-installed in rootfs
E2B holds user browsing data Full data sovereignty — our hardware
Generic VM template Custom image with our tools pre-configured
Per-session only (no persistence) Persistent per-user VMs with snapshots

Break-even: ~8-10 active users. After that, self-hosted saves money every month AND enables capabilities E2B cannot offer at any price.

1.2 What Was Built (Session 150)

32 new files, 1 modified file. All builds pass clean.

Sandbox Orchestrator NestJS App (APIs/sandbox-orchestrator/)

A NestJS API that manages Firecracker microVM lifecycle on bare-metal hardware. This is the "other end" of the SelfHostedProvider HTTP client that was built in Session 144.

Service What It Does
firecracker.service.ts Starts/stops Firecracker VM processes via UNIX API socket. Configures boot-source, drives, machine-config, network-interfaces. Copies rootfs (sparse copy), generates per-session SSH keys.
network.service.ts IP address pool (172.16.0.2-254, 253 addresses). Creates/destroys TAP devices per VM. Attaches to bridge.
vm-executor.service.ts SSH-based xdotool/scrot commands inside VMs. Replicates every E2B SDK method: screenshot, click, type, key, scroll, exec.
sandbox-manager.service.ts Lifecycle orchestration: create → boot → waitForReady → running → destroy. Maintains sandbox state map.
sandbox.controller.ts 11 REST endpoints matching SelfHostedProvider's HTTP contract exactly.
cleanup.service.ts TTL-based VM reaping: 30min idle, 60min max. Detects dead Firecracker processes.
api-key.guard.ts X-API-Key header validation with constant-time comparison (crypto.timingSafeEqual).
vnc-proxy.service.ts WebSocket ↔ TCP proxy for live desktop streaming.
metrics.service.ts Prometheus text format: active VMs, capacity, create/screenshot durations, IP pool, uptime.
health.controller.ts GET /health for SelfHostedProvider connectivity verification.

VM Rootfs Image (deployment/sandbox-orchestrator/)

File What It Does
Dockerfile.rootfs Ubuntu 22.04 + XFCE4 + Chrome + xdotool + scrot + x11vnc + SSH + fonts. Build reproducibly with Docker.
vm-init.sh PID 1 inside VM. Parses kernel boot args (IP, resolution, VNC password, SSH pubkey). Starts Xvfb → desktop → Chrome → VNC → SSH.
vm-network.sh Configures VM networking from kernel boot arguments (static IP, gateway, DNS).
build-rootfs.sh Docker → ext4 conversion: docker build → docker export → mkfs.ext4 → tar extract.
Dockerfile.orchestrator Node.js Alpine + SSH client + iproute2 for the NestJS orchestrator.
sandbox-orchestrator.service systemd unit for auto-restart.
nginx.conf Reverse proxy with SSL, WebSocket upgrade for VNC, rate limiting.

Server Scripts (tools/scripts/sandbox/)

Script What It Does
provision-server.sh Full server setup: Firecracker v1.7.0, KVM, Node.js 20, nginx, SSL, firewall.
setup-network.sh Bridge network (br-sandbox 172.16.0.1/24), NAT masquerade, iptables, persistence.
deploy-orchestrator.sh Build NX app → rsync to server → restart systemd → health check.

Enhanced Existing File

File Change
self-hosted.provider.ts Added API key header (X-API-Key from SANDBOX_API_KEY env), 2-retry with exponential backoff (1s, 3s), 60s health monitoring (critical alert after 3 failures, no auto-downgrade), 45s screenshot timeout.

E2B SDK Method Mapping

E2B SDK Call Our Firecracker Implementation Orchestrator Endpoint
E2BSandbox.create({ resolution }) Firecracker VM boot + Xvfb + Chrome POST /sandboxes
sandbox.screenshot('bytes') DISPLAY=:99 scrot via SSH POST /sandboxes/:id/screenshot
sandbox.moveMouse(x, y) xdotool mousemove via SSH POST /sandboxes/:id/click (moveOnly)
sandbox.leftClick/rightClick/middleClick xdotool click 1/3/2 via SSH POST /sandboxes/:id/click
sandbox.doubleClick() xdotool click --repeat 2 via SSH POST /sandboxes/:id/click (doubleClick)
sandbox.write(text) xdotool type via SSH POST /sandboxes/:id/type
sandbox.press(key) xdotool key via SSH POST /sandboxes/:id/key
sandbox.scroll(dir, amt) xdotool click btn 4/5 via SSH POST /sandboxes/:id/scroll
sandbox.commands.run(cmd) SSH exec POST /sandboxes/:id/exec
sandbox.kill() Kill Firecracker process + cleanup DELETE /sandboxes/:id
sandbox.stream.getUrl() x11vnc → WebSocket proxy GET /sandboxes/:id (streamUrl)

1.3 VM Model: Per-User Persistent (Recommended) vs Per-Session vs Dual-Layer

History

Comparison

Factor Per-Session (Current) Per-User Persistent (Recommended v1) Dual-Layer (v2)
Chrome saves logins No — fresh every time Yes — profile persists across tasks Yes
Session time limit No (we own the infra) No No
Parallel tasks Yes (isolated VMs) No (sequential queue) Yes (fork from snapshot)
RAM per user (active) 2GB per task 2GB per user 2GB home + ~500MB per fork
RAM per user (idle) 0 (destroyed) 0 (snapshotted to disk) 0 (snapshotted to disk)
Snapshot storage None ~500MB-1.5GB per user Same + temp fork snapshots
Jarvis score 2/10 8/10 10/10
Dev effort (additional) Done +2-3 days +5-7 days on top

Firecracker Snapshot Performance

Recommendation

Start with Per-User Persistent (Model B) on AX42. Tasks queue sequentially on the Home Machine. Add ephemeral Task VM forking (Model C) when parallel execution demand is proven.


1.4 SSH Performance: ControlMaster

What It Does

Normal SSH: every command opens new TCP → TLS handshake → authenticate → execute → close (~50-100ms). ControlMaster: first command opens normally. Every subsequent command reuses the same TCP connection (~2-5ms).

Impact

Metric Without With Improvement
First command 50-100ms 50-100ms 0%
Subsequent commands 50-100ms each 2-5ms each ~95%
20-step session total SSH overhead ~1.5s ~130ms ~91%

Cost & Effort

Recommendation

Implement immediately. Pure upside, no downside.


1.5 Managed Cloud vs Self-Hosted Bare Metal

Can We Use AWS or Google Cloud Instead?

Firecracker needs bare-metal access to /dev/kvm. Regular cloud VMs don't expose this.

Provider Configuration RAM Monthly Cost KVM/Firecracker
Hetzner AX42 Ryzen 7 PRO 8700GE 64 GB $53 Native bare metal
Hetzner AX102 Ryzen 9 7950X3D 128 GB $112 Native bare metal
AWS i3.metal Xeon, 36 vCPU 488 GB $3,644 Native bare metal
AWS i3.metal (1yr reserved) Same 488 GB ~$2,300 Native bare metal
GCP N2 (nested virt) 8 vCPU 64 GB ~$300-400 Nested KVM (slower)
GCP sole-tenant 8+ vCPU 64+ GB ~$500+ Nested + 10% premium

AWS i3.metal costs 69x more than Hetzner AX42 for capacity we won't use (488GB when we need 64GB). GCP nested virtualization adds latency and costs 6-8x more.

When Cloud Makes Sense

Only if you need sandbox servers in 10+ global regions simultaneously for latency. For US/EU users, Hetzner Ashburn (VA) and Falkenstein (DE) cover everything.


1.6 Hetzner vs Other Bare Metal Providers

Provider Model CPU RAM Storage Price/mo Bandwidth KVM Locations
Hetzner EX44 i5-13500 14c/20t 64 GB 2×512GB NVMe €39 20 TB Yes DE, FI, US, SG
Hetzner AX42 Ryzen 7 PRO 8700GE 8c/16t 64 GB 2×512GB NVMe €49 20 TB Yes DE, FI
Hetzner AX52 Ryzen 7 7700 8c/16t 64 GB 2×1TB NVMe €64 20 TB Yes DE, FI
Hetzner AX102 Ryzen 9 7950X3D 16c/32t 128 GB 2×1.92TB NVMe €104 20 TB Yes DE, FI
OVH Advance-2 EPYC 4584PX 16c/32t 64 GB 2×960GB NVMe $123 Unlimited Yes US, EU, APAC
Contabo Ryzen 12 Ryzen 9 7900 12c/24t 64 GB 1TB NVMe €86 Unlimited Yes DE, US, UK, AU, JP, SG

Provider Assessment

Hetzner — Price leader. €39-49 for 64GB NVMe bare metal. Zero setup fees. Excellent docs and rescue system. Limited to 5 locations. 2026 price increases of 3-10% effective April 1.

OVH — 30+ locations worldwide. Unlimited bandwidth. Strong DDoS protection. 2-2.5x more expensive than Hetzner. Mixed support reputation since 2021 Strasbourg fire.

Contabo — 6 regions including Asia-Pacific. Unlimited bandwidth. Network quality noticeably worse than Hetzner/OVH. Slow support. VDS products may not expose KVM.

Hetzner Model Decision Tree

Need Pick Why
Absolute cheapest EX44 (€39) Intel i5-13500, near-AX102 single-thread, no ECC
Best balance AX42 (€49) Ryzen 7 PRO, ECC RAM, modern, €10 more than EX44
Most storage headroom AX52 (€64) 2×1TB NVMe, highest PassMark at 64GB
Scale-up AX102 (€104) 128GB RAM, enterprise NVMe, doubles capacity

Note: AX42/AX52/AX102 had a motherboard defect in Q1-Q3 2024 production units. Hetzner is replacing affected boards. Orders placed Feb 2026+ get post-fix hardware. The EX44 (Intel) was unaffected.

Migration (AX42 → AX102)

Trivial. Run provision-server.sh on new server, rsync rootfs + snapshots, update DNS, cancel old server. ~30 minutes total, ~5 minutes downtime. Zero code changes needed.


1.7 Mac as Sandbox Server

Why Mac Doesn't Work for This

Firecracker does not run on macOS. It requires Linux KVM. Mac uses Apple's Hypervisor.framework (UTM/QEMU) — different API, different snapshot model, different networking. Using a Mac would require rewriting the entire orchestrator.

Mac Hosting Costs (For Reference)

Provider Model RAM Price/mo
My Remote Mac M4 16GB $75
Macly.io M4 16GB $100
Scaleway M4 Pro 64GB €335
MacStadium M4 Pro 64GB $399

At $360-399/month for 64GB, a hosted Mac is 7-8x more expensive than Hetzner AX42 ($53) with no advantage for our use case.

When Mac Makes Sense (Future)

If Vitto needs to control macOS-specific apps (Xcode, Keynote, Final Cut) or automate iOS development workflows. That's a genuine future opportunity but not v1.


1.8 Final Infrastructure Decision

Decision Choice Cost
Hardware Hetzner AX42 (€49/mo) → AX102 (€104/mo) when scaling €49/month
VM Model Per-User Persistent with Firecracker snapshots +2-3 days dev
SSH Optimization ControlMaster (implement now) 30 minutes dev
Year 1 total cost ~€588 ($636)

PART 2: Can Vitto Be "Jarvis"? — Honest Analysis

2.1 The Vision (Restated for Clarity)

Vitto is a 24/7 AI assistant that:

  1. Knows the user — preferences, history, work style, credentials
  2. Knows the space — projects, code, data, team members, goals
  3. Remembers everything — conversations from 6 months ago, that one time you changed the API key, the fact you prefer dark mode
  4. Acts in the real world — browses the web, logs into Gmail, files an LLC, deploys code
  5. Gets smarter over time — learns from outcomes, adapts to the user, shares wisdom across the platform
  6. Works 24/7 — not per-session, not per-conversation. Vitto is always "on"

Is This Possible?

Yes, with caveats. Let me be precise about what works, what's hard, and what's unsolved.


2.2 What We Already Have (Honestly Assessed)

After exploring the entire codebase, Vitto already has a surprisingly robust memory architecture:

The Three-Tier Memory System

TIER 1: HOT (In-Memory)
├── 50 most recent memories per user
├── Keyword matching, instant retrieval
└── 30-min TTL, evicted on overflow

TIER 2: WARM (MongoDB + Vector Search)
├── vitto-memories: vector-embedded (1536-dim, OpenAI text-embedding-3-small)
├── execution-traces: full task history (90-day TTL)
├── strategy-memories: what approach works best per task type
├── $vectorSearch with cosine similarity, threshold 0.7
└── Text search fallback when vectors unavailable

TIER 3: COLD (Platform Intelligence)
├── golden_decisions: cross-platform decision history
├── core_rules: 10+ distilled, always-apply rules
├── learned_patterns: task-specific patterns with success rates
└── Retrieved via API from backend-ai-api

What Gets Stored Today

Event What's Saved Where
User says "remember I prefer TypeScript" Explicit memory (confidence 1.0) vitto-memories
User completes a chat message LLM-extracted facts, preferences, skills vitto-memories
Vitto completes a task Execution trace + outcome + lessons learned execution-traces + vitto-memories
Task succeeds/fails Strategy memory updated (success rate recalculated) strategy-memories
Pattern observed 3+ times with 80% success Promoted to core rule core_rules

What Gets Injected into Every LLM Call

  1. User identity (name, email, roles, subscription) — ~100 tokens
  2. User memories (preferences, skills, facts) — ~500 tokens
  3. Core rules (always-apply patterns) — ~500 tokens
  4. Relevant patterns (task-specific) — ~300 tokens
  5. Similar past decisions — ~300 tokens
  6. Knowledge distribution — variable

Total context overhead: ~2,000-3,000 tokens per call.

Honest Grade: B+

The foundation is solid. Vector search for semantic recall, tiered storage, automatic memory extraction, pattern promotion. But there are real gaps.


2.3 The Hard Problems (Where Jarvis Breaks)

Problem 1: Context Window Is Finite

The fundamental constraint. Claude Opus has a 200K token context window. That sounds large, but:

185K tokens is a lot — roughly 300 pages of text. But a user who's worked with Vitto daily for 6 months has generated:

You cannot fit all of this into one prompt. This is the core challenge everyone in the industry faces.

What Competitors Do (And Their Limits)

Approach Who Uses It Limit
RAG (retrieve relevant chunks) Everyone (OpenAI, Claude, Gemini) Only finds what you query for. Misses tangential relevance.
MemGPT/Letta (OS-style memory management) Letta Agent manages its own memory via tools. Adds latency. Self-editing can corrupt memories.
Knowledge graphs (entities + relationships) Cognee, Google Structured, queryable. But building/maintaining the graph is expensive.
Conversation summarization ChatGPT, Claude Lossy — nuance is lost. "You mentioned preferring TypeScript" but not "you mentioned it in the context of migrating from Java."
Full context window stuffing Claude 200K, Gemini 1M Works for single sessions. Doesn't scale across months of history.

None of these fully solve the problem. They all trade off between recall accuracy and token efficiency.

Problem 2: Semantic Search Misses Tangential Relevance

Vector search is great for "find memories about TypeScript preferences." It's bad for "I'm building an e-commerce checkout — what did I say 3 months ago about payment processing?"

The second query requires understanding that "checkout" relates to "payment processing" which relates to a conversation about Stripe where you mentioned preferring their newer API. The semantic connection is 3 hops deep. Current vector search catches maybe 1 hop.

Problem 3: Memory Staleness

Vitto remembers you prefer React. Three months later, you switch to Svelte. The old "prefers React" memory is still in the database with high importance. Unless Vitto explicitly detects the contradiction and updates the memory, it will keep injecting stale context.

Our current system has no contradiction detection. Importance never decays. Old memories don't get challenged.

Problem 4: Cross-Space Context Leaking

If a user works on Space A (medical app) and Space B (gaming app), Vitto's memories are partially space-scoped (spaceId field) but many memories are user-scoped. Medical terminology could leak into gaming recommendations.

Problem 5: The "Always On" Illusion

LLMs are stateless. Every API call starts from zero. The "always on" feeling is an illusion built from:

  1. Injecting memories into the system prompt (makes it seem like Vitto "remembers")
  2. Resuming conversation history (makes it feel continuous)
  3. Proactive actions (Vitto checks your inbox even when you're not asking)

The illusion breaks when the context window can't fit everything that matters.


2.4 What Would Actually Make Vitto Groundbreaking

Here's where I'll be inventive. Most competitors do RAG + conversation history. Here's what could genuinely differentiate Vitto:

Idea 1: The "Mind Map" — Structured Memory Graph (Not Just Vectors)

Instead of flat vector embeddings, build a knowledge graph per user where:

User → owns → Space "MyApp"
       │        ├── uses → Tech: Angular, NestJS, PostgreSQL
       │        ├── deployed_on → Railway
       │        └── has_feature → Auth (uses → JWT, preferred → Passport.js)
       │
       ├── prefers → TypeScript over JavaScript
       ├── dislikes → CSS-in-JS
       ├── works_at → peak hours 9am-1pm
       │
       └── did_task → "Set up Stripe checkout" (3 months ago)
                ├── used → Stripe API v2023-10-16
                ├── chose → embedded checkout over hosted
                └── lesson → "Webhooks need idempotency keys"

Why this is better than vectors alone: When Vitto is asked to "add payment processing to Space X," it can traverse the graph:

  1. Look up Space X → find tech stack (Angular + NestJS)
  2. Find related past task → "Set up Stripe checkout"
  3. Pull the lesson → "Webhooks need idempotency keys"
  4. Know the user's preference → embedded checkout over hosted

This is 3-hop reasoning that vector search cannot do. It requires structured relationships, not just semantic similarity.

Implementation: Use MongoDB's $graphLookup (already available in our stack) or a dedicated graph layer. Nodes are memories, edges are typed relationships. Build the graph incrementally as memories are created.

Estimated effort: 2-3 weeks for a basic graph with entity extraction + relationship building. Can use Claude itself to extract entities and relationships from conversations.

Idea 2: "Cognitive Load Budgeting" — Smart Context Assembly

Instead of stuffing everything into the context window, Vitto should plan what to remember for each request:

User asks: "Help me add Stripe to my checkout"

Step 1: CLASSIFY the request → payment integration, web development
Step 2: BUDGET the context → 3,000 tokens for memories, 2,000 for patterns
Step 3: RETRIEVE strategically:
   - User's payment preferences (200 tokens)
   - Space tech stack (100 tokens)
   - Past Stripe task summary (300 tokens)
   - Stripe patterns from platform knowledge (500 tokens)
   - Recent conversation context (1,000 tokens)
   - Core rules (500 tokens)
   - SKIP: user's CSS preferences (irrelevant)
   - SKIP: memories about their gaming project (wrong space)
Step 4: ASSEMBLE context with priority ordering (most relevant first)

Why this matters: The key insight from LLM research is that models show a U-shaped performance curve — they attend better to information at the beginning and end of the context, with a "lost in the middle" effect. Smart assembly means putting the most critical memories first.

We partially do this today (tiered recall, importance scoring). The gap is there's no request-aware budgeting — we inject the same user context regardless of whether the user is asking about TypeScript or asking about their weekend.

Idea 3: "Memory Metabolism" — Active Forgetting and Consolidation

Human brains don't store every detail — they consolidate, generalize, and forget. Vitto should do the same:

DAY 1: "User said they prefer tabs over spaces"     → Store as memory (importance 0.7)
DAY 7: Memory consolidation runs. This memory accessed 0 times. → Decay importance to 0.5
DAY 30: Still not accessed. → Decay to 0.3
DAY 90: → Archive (remove from warm tier, keep in cold)

vs.

DAY 1: "User's API key for Stripe is sk_live_xxx"   → Store (importance 0.9)
DAY 7: Accessed 3 times during Stripe integration    → Boost to 0.95
DAY 30: Accessed 1 more time                         → Stays 0.95
DAY 90: Not accessed in 60 days                      → Decay to 0.8 (still high — credentials don't expire)

We have consolidation (7-day conversation merging in MindService.runMemoryConsolidation()). But we don't have importance decay. Every memory stays at its initial importance forever. This means after 6 months, the hot cache is dominated by old high-importance memories that haven't been relevant in months.

Fix: Add an accessedAt timestamp, decay formula: effectiveImportance = baseImportance * (0.95 ^ daysSinceLastAccess). Simple exponential decay. Keeps frequently-accessed memories alive, lets unused ones fade.

Idea 4: "Contextual Persona" — Pre-Computed User Summaries

Instead of assembling context from raw memories on every call, maintain a living document per user that summarizes who they are:

USER BRIEF (auto-generated, refreshed daily)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Name: Paco
Active spaces: MyApp (Angular/NestJS), GameProject (Unity)
Working style: Morning person, peak 9am-1pm. Prefers detailed explanations.
Tech preferences: TypeScript, Angular, NestJS, PostgreSQL. Dislikes CSS-in-JS.
Recent focus: Stripe payment integration (past 2 weeks)
Open tasks: 3 pending code reviews, 1 deployment blocked on env vars
Credentials on file: Gmail, GitHub, Stripe (all stored in VM profile)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This is ~200 tokens and gives Vitto 80% of the "I know you" feeling. It's regenerated daily (or on significant events) by summarizing the full memory store. The LLM sees this brief + the most relevant specific memories, not a dump of 500 memories.

No one is doing this well. ChatGPT has "Memory" but it's just a flat list of facts. Letta/MemGPT self-edits a "core memory" block but it's limited and can corrupt. A properly maintained User Brief that's regenerated from the full memory graph is more reliable and more comprehensive.

Idea 5: The VM as Memory Extension

This is the truly unique angle that no competitor has:

Vitto's persistent VM IS a form of memory. Chrome cookies are memory. Bookmarks are memory. Browsing history is memory. Saved passwords are memory.

When Vitto logs into Gmail on the user's VM, that login session persists. Next time Vitto needs to check email, there's no "remember the password" step — the browser remembers. This is physical-world memory that exists outside the LLM's context window entirely.

Traditional AI assistant:
  "Check my Gmail" → Look up credentials → Log in → Navigate → Read → Log out

Vitto with persistent VM:
  "Check my Gmail" → Open Chrome tab → Already logged in → Read

  Time: 30 seconds vs 5 seconds
  User friction: Zero vs "enter your 2FA code"

This is what makes the Hetzner + Firecracker + per-user persistent VM decision so important. It's not just about cost savings over E2B. It's about making the VM an extension of Vitto's memory — a physical, browser-based memory layer that doesn't consume context window tokens.


2.5 What's Actually Fine (Don't Over-Engineer)

Being honest about what doesn't need fixing:

  1. Vector search for recall is good enough for 90% of queries. Don't build a full knowledge graph before validating that users actually have multi-hop recall needs.

  2. 2,000-3,000 tokens of context overhead is acceptable. Claude's 200K window has plenty of room. Don't obsess over token optimization until you're genuinely hitting limits.

  3. The Intelligence Pyramid (core rules → patterns → decisions) is a solid architecture. Pattern promotion based on success rate is a genuinely good idea that most competitors don't have.

  4. Memory extraction from conversations works. The regex + LLM extraction pipeline catches explicit memories reliably. It misses some implicit ones, but that's acceptable.

  5. The tiered recall (hot → warm → cold) with fallback is well-designed. The architecture handles the "I don't remember but let me check" case gracefully.


2.6 Honest Risk Assessment

Risk Severity Likelihood Mitigation
Context window overflow (too many memories) High Medium (at scale) Cognitive load budgeting + user brief
Stale memories polluting context Medium High (guaranteed over time) Importance decay + contradiction detection
Vector search misses tangential relevance Medium Medium Knowledge graph for multi-hop reasoning
Cross-space context leaking Low Medium Strict spaceId filtering (already exists)
Memory corruption (LLM self-edits incorrectly) High Low (we don't self-edit) Keep human-authored memories immutable
Chrome profile security (persistent logins) High Low (Firecracker isolation) At-rest encryption, jailer, ephemeral SSH keys
Users expect Vitto to remember EVERYTHING Medium High Set expectations: "I remember what matters" not "I remember everything"

2.7 Recommended Roadmap

Phase 1: Foundation (Now → 2 weeks)

Phase 2: Intelligence (2-4 weeks)

Phase 3: Differentiation (1-2 months)

Phase 4: Scale (3+ months)


2.8 The Bottom Line

Can Vitto be Jarvis? Yes — with the right memory architecture.

The LLM is not the bottleneck. Claude is smart enough. The bottleneck is what context you give it. The difference between a mediocre AI assistant and Jarvis is not the model — it's the memory system that decides what the model knows about you when it starts thinking.

What we have today is a B+. The gaps are:

  1. No importance decay (memories get stale)
  2. No request-aware context budgeting (same context injected regardless of task)
  3. No multi-hop reasoning (vector search is 1-hop only)
  4. No User Brief (no pre-computed "who is this person" summary)
  5. No VM-as-memory integration (Chrome state isn't queryable)

Fix those five things, and you have something no competitor offers: an AI that genuinely knows you, remembers your work, has a physical machine ready to act, and gets smarter every day.

The persistent VM on Hetzner is the missing physical layer. MCP + MongoDB + vector search is the digital layer. The knowledge graph would be the reasoning layer. Together, they give Vitto three forms of memory that reinforce each other — and that's architecturally unique in the market.


Sources