Sessions 176 177 Progress Report

Documentation for Sessions

Sessions 176–177 Progress Report

Date: March 5, 2026 Author: AI Development Team (Claude Code) Status: Complete — All changes deployed and verified Branch: session-177.6 → session-178


Executive Summary

Sessions 176 and 177 delivered two major milestones:

  1. Session 176 — Five new platform capabilities that make Vitto smarter, more aware, and more capable.
  2. Session 177 — First successful boot of our self-hosted Computer Use infrastructure (Firecracker virtual machines on Hetzner bare metal).

Both sessions are fully tested (64 unit tests passing) and deployed to production.


What Changed and Why (Non-Technical Timeline)

Session 176: Making Vitto Smarter

Phase A: Better Permission Names

What: Renamed the top-level permission tier from platform_owner to executive.

Why: The old name platform_owner was confusingly similar to platform_user — the lowest tier. In code, autocomplete would suggest the wrong one. executive is unambiguous and clearly means "top-level CEO/CTO access."

Impact: Affects the Chrome extension, web app chat panel, and all backend role checks. Backward-compatible aliases ensure nothing breaks for existing users.

Phase B: Vitto Knows What Page You're On

What: When you chat with Vitto, it now knows which page of the platform you're currently viewing and what actions are available on that page.

Why: Previously, if you were on the Settings page and asked Vitto "set my autonomy level to Direct," it had no idea you were on Settings. Now it sees your current page, form state, and available buttons — and can directly interact with them.

Impact: Five pages now register their context with Vitto: Settings, Memory Manager, Channel Manager, Workflow Builder, and Skill Marketplace. Each page also exposes actions Vitto can execute (e.g., "create a workflow called X," "update a setting").

Phase C: Fullstack Code Generation

What: A new endpoint that generates both Angular frontend modules AND NestJS backend modules in a single request.

Why: Previously, generating a full feature required two separate steps — one for the Angular component and another for the backend API. Now a single prompt like "Build a task management system" generates the complete stack.

Impact: New POST /module-generation/fullstack endpoint. Streams progress events so the UI can show real-time generation status.

Phase D: Self-Healing Code Generation

What: When generated code has compilation errors, the system now automatically tries to fix them (up to 5 attempts).

Why: AI-generated code sometimes has import errors or type mismatches. Instead of showing the user a broken module, the system now detects errors, asks the AI to fix them, and retries the build — like a developer fixing red CI.

Impact: Two new services: ErrorParserService (understands TypeScript/Angular/NX error formats) and BuildTestFixService (the fix loop). If all 5 attempts fail, the failure pattern is stored in Vitto's memory so future generations avoid the same mistake.

Phase E: Understanding User Emotions

What: Vitto now tracks the emotional tone of your conversation across 5 dimensions: frustration, engagement, confusion, satisfaction, and urgency.

Why: A user who types "THIS IS BROKEN AGAIN!!!" needs a very different response than one who says "I love how this works!" Previously, Vitto used a simple 3-state regex (stressed/playful/frustrated). Now it builds a full emotional arc and adjusts its tone automatically.

Impact: The EmotionalArcService scores every user message and feeds the trend into the system prompt. If frustration is rising, Vitto becomes more direct and solution-focused. If engagement is high, it elaborates more.

Testing

64 unit tests were written across 6 test files covering all five phases. All pass on both backends.


Session 177: First Computer Use Test (and Fixing It)

What Happened

We attempted the first-ever test of our self-hosted Computer Use system — where Vitto controls a virtual desktop to perform tasks like sending emails. It failed with a 500 Internal Server Error.

The Investigation

The error was traced from the frontend through 4 system layers:

User clicks "Send email via Gmail" in Computer Use UI
  → Frontend sends request to backend-ai-api
    → SelfHostedProvider calls POST /sandboxes on Hetzner server
      → Sandbox orchestrator tries to create a Firecracker VM
        → VM creation fails → 500 error returned

Three Root Causes Found

The investigation revealed three cascading bugs, each hidden by the one before it:

Bug 1: Missing /dev/fd symlink (Kernel Panic)

The VM's startup script used a Bash feature called "process substitution" (>(tee ...)) which requires /dev/fd to exist. In a Firecracker VM, this symlink doesn't exist because the normal Linux device manager (udev) never runs. Without it, Bash exits → PID 1 dies → kernel panic.

Fix: Mount /proc filesystem and create the /dev/fd symlink before any other operations.

Bug 2: Network already configured (Kernel Panic)

After fixing Bug 1, the VM hit a second kernel panic. The network configuration script had set -e (exit on any error), but the Linux kernel had already configured the network from boot parameters. When the script tried to add the same IP address, it got "File exists" error → script exited → PID 1 died → kernel panic.

Fix: Removed set -e and added fallback handling for already-configured networks.

Bug 3: No Entropy (SSH Hangs Forever)

After fixing Bugs 1 and 2, the desktop booted (Xvfb, XFCE4, Chrome, VNC all started), but SSH never became available. The root cause: the VM was running a 4.14 kernel (disguised by a misleading filename vmlinux-5.10). In kernel 4.14, the getrandom() system call blocks until the entropy pool is initialized — but a Firecracker VM has NO hardware entropy sources (no disk, no mouse, no keyboard). SSH, D-Bus, and Chrome all need random numbers at startup, so they all hung indefinitely.

Fix: Downloaded the actual 5.10 kernel from Firecracker's official releases, which supports random.trust_cpu=on (trust the CPU's hardware random number generator). Also added a virtio-rng entropy device to the Firecracker VM configuration, which feeds host entropy into the guest.

Resolution

After all three fixes:


Files Changed

Session 176 (39 files total)

Category Files What Changed
Permission Tiers 8 files platform_owner → executive across types, constants, role maps
Context Completion 7 files Page context wiring, VittoSettings registration, component actions
Page Action Tool 3 files New execute_page_action tool + WebSocket bridge event
Fullstack Gen 4 files FullstackOrchestrationService + /fullstack endpoint
Build-Test-Fix 3 files ErrorParserService + BuildTestFixService
Emotional Arc 4 files EmotionalArcService + genome integration
Unit Tests 6 files 64 tests across both backends
Backend Wiring 4 files Controller/module/client updates

Session 177 (5 files total)

File What Changed
deployment/sandbox-orchestrator/vm-init.sh Complete rewrite: mount-first, /dev/fd symlinks, entropy seeding, deferred SSH
deployment/sandbox-orchestrator/vm-network.sh Removed set -e, added network already-configured fallback
APIs/sandbox-orchestrator/src/app/sandbox/firecracker.service.ts Added random.trust_cpu=on boot arg + virtio-rng entropy device
APIs/sandbox-orchestrator/src/app/sandbox/sandbox-manager.service.ts Pre-flight rootfs/kernel existence checks
APIs/sandbox-orchestrator/src/app/health/health.controller.ts vmPrerequisites diagnostic block in health response

Server Changes (Hetzner 144.76.69.55)


Test Results

Session 176 Unit Tests

Test Suite Tests Status
Permission Tiers (RolesGuard hierarchy) 7 PASS
Page Action Tool (schema, bridge, errors) 7 PASS
Error Parser (tsc/Angular/NX formats) 10 PASS
Build-Test-Fix (sandbox loop, escalation) 6 PASS
Fullstack Orchestration (SSE, delegation) 3 PASS
Emotional Arc (scoring, trends, scenarios) 24 PASS
Total 64 ALL PASS

Session 177 Verification

Check Result
GET /health {"status":"ok","vmPrerequisites":{"ready":true}}
POST /sandboxes {"status":"running"} in ~15s
SSH to VM (172.16.0.2) Connected, /tmp/.sandbox-ready present
Ping to VM 0% packet loss, 0.3ms RTT
VM desktop (Xvfb+XFCE4+Chrome+VNC) All services running

Architecture Decisions

Decision 1: executive over platform_owner

Problem: T0 permission tier name platform_owner shared a prefix with T3 tier platform_user, causing autocomplete confusion and potential assignment bugs.

Alternatives: owner, god, root, executive

Choice: executive — unambiguous, professional, no prefix collision, maps to CEO/CTO role semantics.

Decision 2: Page Context via System Prompt (not tool call)

Problem: Vitto needed awareness of the user's current page and form state.

Alternatives: (a) Send as tool call parameter, (b) Inject into system prompt, (c) Separate context API

Choice: System prompt injection via pageContext field — simplest integration, no frontend changes needed beyond existing VittoPageContextRegistry.

Decision 3: Kernel 5.10 over Entropy Workarounds

Problem: sshd blocked forever on getrandom() in kernel 4.14 Firecracker VMs.

Alternatives: (a) Write custom RNDADDENTROPY ioctl program, (b) Use rng-tools daemon, (c) Upgrade kernel to 5.10

Choice: Kernel upgrade — random.trust_cpu=on provides instant entropy with zero runtime overhead. Combined with virtio-rng for belt-and-suspenders reliability.


Known Issues and Future Work

Immediate

Short-term

Long-term


Lessons Learned

For Developers

  1. Firecracker VMs have zero entropy. Always add random.trust_cpu=on to boot args AND configure the virtio-rng device. Without both, any program that calls getrandom() will hang.

  2. VM init scripts are PID 1. Any uncaught error kills PID 1 → kernel panic. Never use set -e in init scripts — handle errors explicitly.

  3. Process substitution (>(...)) requires /dev/fd. In custom init environments where udev doesn't run, create the symlink manually: ln -sf /proc/self/fd /dev/fd.

  4. Kernel filenames can lie. Always verify the actual kernel version with strings vmlinux | grep "Linux version", not the filename.

  5. Health endpoints should verify prerequisites, not just report uptime. A service can be "healthy" but unable to do its job if required files are missing.

For Operations

  1. provision-server.sh and build-rootfs.sh are separate steps. The provision script explicitly lists rootfs building as a manual next step. Always run both.

  2. After deploying the orchestrator, check /health for vmPrerequisites.ready: true before declaring the service ready.

  3. The Hetzner server has 432GB free disk. Rootfs images are 1.2GB sparse (4GB virtual). We can run ~30 concurrent VMs within the 128GB RAM.


This document covers work completed on March 5, 2026. For technical details, see the MCP decision log (IDs: dev_1772653842350, dev_1772654624402, dev_1772727926853, dev_1772730347392).