S240 Unified Autonomy Engine

Documentation for Sessions

S240: Unified Autonomy Engine — Technical Session Documentation

Session: 240 Date: 2026-03-19 Branch: session-238-239 (concurrent with S239 Memory v2) Status: Complete — 65/65 E2E tests, 0 type errors


Executive Summary

Session 240 built the Unified Autonomy Engine — the system that makes Vitto act like a 24/7 intelligent partner rather than a reactive chatbot. It fuses three previously disconnected concerns into one coherent decision pipeline:

  1. VM Execution — Vitto can now run commands, install packages, and manage files on isolated Firecracker VMs per user
  2. Adaptive Trust — Vitto earns autonomy through proven reliability, not static role assignments
  3. Proactive Intelligence — Vitto learns recurring patterns and acts before being asked

Architecture Overview

The Autonomy Gate (Central Innovation)

Every Vitto action flows through an AutonomyGateService that assembles a read-only snapshot:

User message → AutonomyGate.evaluate(task) → {
  trust:  TrustScoringService.getScore(userId, domain)    // independent
  tier:   TierResolverService.resolve(task, trust)         // reads trust
  action: ActionDecider.decide(trust, tier, task)          // reads both
} → Route to execution tier → Execute → Outcome feeds trust

Design principle: Three independent services, one gate. No god object. Each concern evolves independently. The gate is the only place they meet.

Key Files Created

Service Path Purpose
AutonomyGateService engine/autonomy-gate.service.ts Assembles read-only AutonomyContext per task
TrustScoringService engine/trust-scoring.service.ts Adaptive 0-100 scoring per (userId, domain)
TierResolverService engine/tier-resolver.service.ts Dynamic in-process → VM → browser selection
VmApiClientService engine/vm-api-client.service.ts HTTP client to ai-api sandbox proxy
VmSessionManagerService engine/vm-session-manager.service.ts Per-user VM lifecycle with snapshot restore
SandboxedToolProxyService engine/sandboxed-tool-proxy.service.ts Routes tool calls to VM when tier=vm
VmCredentialInjectorService engine/vm-credential-injector.service.ts First-time deploy key + credential setup
TriggerEngineService engine/trigger-engine.service.ts Frequency-based proactive trigger detection
TaskRecoveryService engine/task-recovery.service.ts Genome-based checkpoint + resume

Schemas Created

Schema Collection Purpose
TrustScore vitto_trust_scores Materialized trust per (userId, domain)
TriggerPattern vitto_triggers Learned proactive patterns with confidence
TaskCheckpoint vitto_checkpoints Genome + tool results, TTL 24h
ChainCheckpoint vitto_chain_checkpoints Multi-step background task state

Phase-by-Phase Breakdown

Phase 0: Configuration (Task 0.1)

Phase 1-2: Infrastructure Layer (Tasks 1.1, 2.1)

Phase 3: VM Execution Layer (Tasks 3.1–3.5)

VmApiClientService — HTTP client with retry + circuit breaker to ai-api's sandbox proxy. Handles:

VmSessionManagerService — Per-user VM lifecycle:

SandboxedToolProxyService — The #1 blocker that was closed:

VmCredentialInjectorService — First-time setup:

Wiring (Task 3.5):

Phase 4: Adaptive Trust (Tasks 4.1–4.5)

TrustScore schema: Materialized in MongoDB, updated event-driven (not computed live):

{ userId, domain, score: 0-100, level: OBSERVE|SUGGEST|DIRECT|AUTONOMOUS,
  recentOutcomes: [...last 50], lastEscalation, trajectory }

Scoring algorithm:

Domain isolation: Trust for code_execution ≠ trust for search_docs ≠ trust for send_message. A user can be AUTONOMOUS for doc search but SUGGEST for code execution.

Wiring:

Phase 5: Proactive Intelligence (Tasks 5.1–5.2)

TriggerPattern schema (stored in vitto_triggers, NOT VittoMemory):

{ pattern, action, confidence: 0-1, userId, spaceId,
  activations, suppressedCount, lastTriggered }

Detection: After each task completion, checks: "has this user asked for similar things 3+ times in 14 days?" If yes, creates pattern with confidence 0.5.

Lifecycle:

Why not VittoMemory: S239's admission control scores on factualConfidence and semanticNovelty. Trigger patterns are predictions (low factual) that repeat (low novelty) — they'd be quarantined.

Phase 6: Resilience (Tasks 6.1–6.3)

TaskRecoveryService — Genome-based checkpoints:

Agent Nesting — Depth-2:


S239 Memory v2 Compatibility

Analyzed concurrently running S239 spec. Key integration points:

S240 Component S239 Impact Resolution
Trust scoring None — reads outcomes, not memory Safe
Trigger patterns Would conflict with admission control Separate collection
Sub-Vitto context Must use new WindowManager + Genome Wired through new APIs
Checkpoint recovery Benefits from genome service Uses genome instead of raw replay
VM lifecycle Fully independent infrastructure layer No conflict

S239 features that benefit S240 for free:


Test Coverage

Suite Tests Coverage
VM Execution E2E 7 Session create/restore/snapshot, tool proxy routing, degradation fallback, credential injection
Trust Scoring E2E 9 Score computation, domain isolation, escalation cap, critical drop, floor enforcement, trajectory
Trigger Engine E2E 12 Pattern detection, confidence growth/decay, auto-delete, dispatch integration, suppression
Task Recovery E2E 8 Checkpoint create/restore, genome resume injection, TTL cleanup, VM snapshot restore
Agent Nesting E2E 5 Depth-2 spawn, in-process constraint, budget inheritance, tool cap, depth-3 rejection
Background Tasks E2E 15 Chain checkpoint CRUD, pause/resume/cancel, step sequencing
Mind Service 9 Virtual context, genome aggregation, stale topic eviction
Total 65 All passing

Decisions Logged (MCP)

ID Type Question Confidence
dev_..4051slx architecture Unified vs incremental vs top-down 0.93
dev_..8b11um0 architecture Always-on vs snapshot vs ephemeral VMs 0.95
dev_..z4mge7c architecture Static vs dynamic trust scoring 0.92
dev_..3qxz9w5 architecture Trigger storage: memory vs dedicated collection 0.91
dev_..3xo53t5 architecture Checkpoint: event sourcing vs genome-based 0.94
dev_..veqh6fq architecture Agent nesting depth and resource constraints 0.93

All 6 outcomes reported as successful. 4 conventions added. 7 lessons reflected.


Conventions Established

  1. Trust domain scoping: Scores are per (userId, actionDomain) — never assume cross-domain trust
  2. Trigger storage isolation: Proactive triggers go in vitto_triggers, never VittoMemory
  3. VM sticky claims: Per-tool-call claiming with sticky sessions — release on task completion
  4. Nesting resource guards: Depth-2 is in-process only, 50% budget, 3-tool cap

Known Limitations & Future Work

Limitation Severity Future Fix
Frequency-based triggers miss one-shot critical patterns Medium Phase 2: semantic similarity detection
4-hop VM latency (vitto → ai-api → orchestrator → VM) Medium Evaluate direct connection once stability proven
LLM resume after checkpoint may diverge on complex tasks Medium Limit recovery to tasks <20 iterations
Trust gaming via trivial task spam Low Complexity weighting already mitigates; monitor
Warm pool costs money when idle Low TTL eviction (15min default), max 2-3 VMs

Files Modified (Existing)

File Change
sub-vitto-orchestrator.service.ts MAX_DEPTH=2, reads tier from AutonomyContext, reports sub-Vitto outcomes
autonomy.service.ts Extended with ActionDecider role, reads trust from TrustScoringService
background-task.service.ts Fixed Mongoose FlattenMaps type casts on ChainCheckpoint queries
user-genome.service.ts Fixed Mongoose lean() type cast on getUserGenome
.env.local Added VM_WARM_POOL_SIZE, VM_SESSION_TTL_MINUTES, TRUST_ESCALATION_CAP_DAYS