Skip to content

Architecture

Vita follows a layered architecture where data flows from sources through processing into views that power the user experience. This is the master map: read it first, then dive into individual feature pages.

Note: Architecture counts in this doc are generated from code via ./run architecture-metrics (snapshot: 78 routers, 77 scheduler task loops, 124 top-level data directories, 60 skills). A health.py docs-count-drift check fails CI if this page or overview drift from the live numbers β€” so don't hand-edit these without re-running the metric.

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           USER INTERFACES                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Claude Codeβ”‚  Web UI   β”‚ Telegram Bot β”‚ E-ink Displayβ”‚  Todo Console        β”‚
β”‚ (CLI)      β”‚ +Workshop β”‚  (Mobile)    β”‚ (Raspi Zero) β”‚  (ESP32 x4 OLED)    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€              β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  iOS App  β”‚  Stream Dock  β”‚  EPD47    β”‚              β”‚                      β”‚
β”‚  (Voice)  β”‚  (Ajazz 153E) β”‚  Canvas   β”‚              β”‚                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Public surfaces (read-only): canvases/board shares, reports, podcast, EU    β”‚
β”‚  guide, RSS  β†’  served by the public-api role behind ngrok tunnels           β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                 β”‚
         β–Ό                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     FASTAPI BACKEND (78 routers)                    β”‚
β”‚  health* goals board feed voice education workshop capabilities ...β”‚
β”‚  growth/canvases (incl. *_public read-only)                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     AUTONOMOUS SYSTEMS                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Scheduler   β”‚  Sentinel    β”‚  Executive    β”‚  Consolidation        β”‚
β”‚  (77 tasks)  β”‚  (26 detect) β”‚  (OODA loop)  β”‚  (micro-processing)   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   Sleep Guardian  β”‚  Coaching  β”‚  Forge Workshop  β”‚  Board Meetings  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         CORE SYSTEMS                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Memory Layer   β”‚    Identity     β”‚      Search                     β”‚
β”‚  (Views+Trends) β”‚ (Obs/Interviews)β”‚  (BM25+Vector, 430k+ chunks)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     DATA STORAGE (124 directories)                  β”‚
β”‚  data/           goals/         profile/        memory/             β”‚
β”‚  (checkins,      (active,       (basics,        (views,             β”‚
β”‚   garmin, photos,achieved,      prefs,          sources,            β”‚
β”‚   activities,    retired)       communication)  prompts)            β”‚
β”‚   sentinel,                                                         β”‚
β”‚   executive, ...)                                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

Input β†’ Processing β†’ Output

  1. Data Ingestion (Perception)
  2. Garmin Connect syncs sleep, HRV, steps, activities (6h poll loop)
  3. RideWithGPS syncs cycling routes and tracks
  4. Libre CGM syncs continuous glucose data (8h loop)
  5. Location tracking logs GPS history
  6. Voice transcription via Groq Whisper
  7. Email sync via Google API (work + personal, 15min loop)
  8. X/Twitter feed ingestion via Camofox browser (6h loop)
  9. Slack, Signal, Telegram DM sync (hourly 5am-10pm)
  10. Podcast sync from Pocket Casts (4h loop)
  11. HN + RSS media feeds (15min/30min loops)
  12. Google Photos sync and Takeout import
  13. Calendar events via Google Calendar API
  14. Manual check-ins capture daily state

  15. Processing Layer (Memory)

  16. Raw data stored in data/{source}/YYYY-MM-DD.json across 124 directories
  17. Hybrid search engine: BM25 + vector embeddings across 430,000+ indexed chunks
  18. Memory views with staleness tracking (build_view.py)
  19. Unified activities system aggregating from multiple sources
  20. Stream markup capture (inline XML tags processed in real-time)
  21. Typed capability contracts project canonical owner functions into agent, CLI, HTTP, and browser transports
  22. Consolidation loop (continuous micro-processing during waking hours)
  23. Identity observations extracted from conversations
  24. Education ledgers join curriculum maps, mastery evidence, packets, artifacts, and retest queues
  25. Face detection and clustering via InsightFace ML pipeline
  26. Speculative computation (budget-aware LLM inference)

  27. Autonomous Systems

  28. Sentinel loop (26 detectors configured, 19 active β€” monitoring conditions)
  29. Executive loop (OODA work cycles with question routing)
  30. Sleep Guardian (predictive sleep risk scoring and training gate)
  31. Coaching system (contextual coaching messages via Telegram)
  32. Forge workshop (problem-first idea development pipeline)
  33. Board meetings (multi-persona deliberation with Robert's Rules)
  34. Self-improvement loop (nightly proposal revision via /sleep)

  35. Output Channels (Effectors)

  36. Daily Brief email (VDB) synthesizes morning context
  37. Web dashboard (20+ route groups) visualizes data
  38. Workshop pages compose capabilities into prompt-speed personal interfaces
  39. E-ink display (800x480, 6-color) on Raspberry Pi Zero
  40. EPD47 canvas (4.7" e-paper creative display)
  41. Todo console (ESP32 with 4 OLED displays)
  42. Stream dock (Ajazz AKP153E programmable buttons)
  43. Public read-only surfaces (reports, canvas/board shares, podcast feed, EU guide, RSS) via ngrok tunnels
  44. CLI provides interactive coaching
  45. Telegram delivers proactive messages and coaching
  46. Participant-aware Telegram topics let long-running agents receive and ledger mid-run steering
  47. X/Twitter posting via Camofox browser
  48. Image generation via gpt-image-2
  49. HTML reports and slide presentations via Claude frontier models + gpt-image-2
  50. Cloud sessions for background Claude execution

Key Subsystems

Data Layer (data/)

Directory Purpose
data/checkins/ Daily health check-in logs
data/garmin/ Synced Garmin Connect data
data/rwgps/ RideWithGPS cycling data and analyses
data/activities/ Unified activity tracking (aggregates, sync status)
data/identity/ Observations, interviews, quotes
data/proactive/ Telegram message queue and conversation state
data/scheduling/ Frequency goal occurrences and patterns
data/board/ Board meetings and resolutions
data/feed/ Feed / Media Signal Refinery (items, scores, producer state)
data/media/ Legacy media items and health
data/objectives/ Daily and weekly objectives with conversation state
data/tokens/ Token usage aggregates, sessions, and summaries
data/location/ GPS history logs
data/voice/ Voice memo transcripts and sessions
data/x/ X/Twitter drafts, posts, feed, bookmarks
data/experiments/ Structured experiment protocols and results
data/coaching/ Coaching cooldowns, effectiveness, goal-identity maps
data/email/ Email sync state and conversations
data/photos/ Photo metadata, face clusters, thumbnails, crops
data/sentinel/ Sentinel state, log, and detector configs
data/executive/ Executive loop DB, work context
data/sleep/ Sleep risk log, outcomes, guardian weights
data/forge/ Forge workshop ideas (spark/smelt/shape/forge)
data/research/ Research queue, findings, syntheses
data/reports/ Research reports and HTML presentations
data/cgm/ Continuous glucose monitor daily data
data/podcast/ Podcast episodes, curation, transcripts
data/calendar/ Calendar events and trigger state
data/consolidation/ Consolidation loop state
data/stream-captures/ Stream markup capture state
data/code-production/ Code metrics by year
data/speculative/ Speculative computation results and budget
data/heartbeat/ Topics for periodic discussion
data/projects/ Project registry
data/capabilities/ Capability idempotency and provenance records (usage is in data/capabilities/usage.db)
data/workshop/ Cross-device view-chrome preferences for Workshop pages
data/education/ Curriculum ledgers, packet metadata, artifacts, mastery evidence, and retest state
data/skill-shares/ Frozen, portable snapshots for public agent-skill shares
data/vault/ Encrypted sensitive data (AES-256-CBC)
data/overnight/ Overnight analysis summaries
data/devices/ Device / peripheral registry
data/generated_images/ Image generation output
data/screen/ Screen-journal frames, metadata, and journal.db
data/agenda-meetings/ Agenda-meeting records, transcripts, and item outputs
data/capacity/ Capacity-kill events ledger, exhaustion blocks, account state
data/mastermind/ Agent-Mastermind event ledger and constitution snapshots
data/links/ Start-page links (links.db) and visit signal
data/doc-audit/ Documentation-coverage audit results

Note: This is a representative slice. The full count is 124 top-level directories under data/; new subsystems add their own as they land. To enumerate the live set, list data/*/.

Memory Layer (memory/)

The memory system provides precomputed views for fast access:

  • memory/views/ - Aggregated snapshots (health, goals, identity, training, week summary, CEO scorecard)
  • memory/sources/ - Raw source documents for trend analysis
  • memory/prompts/ - Instructions for building each view
  • memory/_meta/ - Staleness tracking and build logs

Views are rebuilt by scripts/memory/build_view.py, which tracks staleness and rebuilds when source data changes. Hybrid search (BM25 + vector, 430,000+ chunks across 23 source types) provides retrieval across all indexed data sources. The 23 source types are: board_summary, checkin, codebase_doc, email_catalog, entity_file, event, experiment, garmin, interview, interview_meta, journal, meeting, observation, podcast_digest, quote, rwgps_memory, scratch, signal, slack, story, telegram, transcript, and voice. See Search for retrieval internals.

Profile (profile/)

Static user configuration:

  • profile/basics.json - Name, DOB, measurements
  • profile/preferences.json - UI and system preferences
  • profile/communication.json - How to interact with this user

Goals (goals/)

Active and achieved goals with metadata:

  • goals/active/ - Current goals being tracked
  • goals/achieved/ - Completed goals (archived)
  • goals/visions/ - Long-term life visions

Each goal includes check-in prompts, metrics, and frequency targets.

API Structure

The FastAPI backend (api/src/main.py) is a single app that mounts 78 routers (one router file per concern, in api/src/routers/). The same app code serves two roles:

  • Internal role (port 33800, ./run api) β€” full surface, owns the scheduler and all background loops.
  • Public role (port 33802, ./run public-api) β€” read-only process with VITA_API_ROLE=public set, so the lifespan handler skips start_scheduler() and the board-meeting recovery. It fronts the public ngrok tunnels. DomainGuardMiddleware restricts which routes each public hostname can reach.

A representative slice of the router catalog:

Endpoint prefix Purpose
/api/v1/health System health + the split health domain (see below)
/api/v1/goals Goal CRUD operations
/api/v1/objectives Daily and weekly objectives management
/api/docs Documentation serving
/api/v1/board Board meeting system (meetings, resolutions, members)
/api/v1/feed Feed / Media Signal Refinery (items, scores, feedback)
/api/v1/media Legacy media items
/api/v1/vdb Daily brief operations
/api/v1/data Raw data browser
/api/v1/tokens Token usage tracking and sessions
/api/v1/interviews Interview management
/api/v1/activities Unified activity tracking (heatmap, zones, quick-log)
/api/v1/location Location history and tracking
/api/v1/voice Voice transcription and sessions
/api/v1/cloud Cloud Claude session management
/api/v1/email Email sync and management
/api/v1/email/catalog Important-email catalog curation/scoring
/api/v1/todo-console ESP32 display management
/api/v1/x X/Twitter draft management
/api/v1/sync Data sync operations
/api/v1/sync-meetings Meeting-recording sync
/api/v1/meeting-review Meeting / offsite report review
/api/v1/scheduler Scheduler control
/api/v1/photos Photo management, timeline, thumbnails
/api/v1/faces Face detection, clustering, labeling
/api/v1/executive Executive loop cycles, config, comments
/api/v1/ceo CEO transformation dashboard
/api/v1/sentinel Sentinel detector CRUD and fire
/api/v1/forge Forge workshop idea management
/api/v1/proposals Self-improvement proposal kanban
/api/v1/code-production Code metrics and tracking
/api/v1/podcast-curation Podcast episode curation
/api/v1/podcast Podcast episode serving
/api/v1/growth Internal work-specific surface (out of scope for these docs)
/api/v1/canvases canvas workspace (plat docs) with computed measures
/api/v1/drafts Draft content store
/api/v1/benchmarks Model/system benchmark results
/api/v1/devices Device registry
/api/v1/peripherals Hardware peripheral control
/api/v1/system-kernel System kernel / runtime control
/api/collections Report collections
/api/messaging Messaging (Slack/Signal/Telegram) sync surface
/api/reports Research reports and presentations
/api/v1/scratch-pads Daily/weekly scratch pad management
/api/v1/garmin Garmin data access
/api/v1/inference LLM model routing and usage
/api/v1/streamdock Stream dock button management
/api/v1/sessions Session registry and discovery
/api/v1/clux CLI session streaming for iOS
/api/v1/browser Browser automation sessions
/api/v1/agents Agent configuration management
/api/v1/webhooks External webhook receivers
/api/v1/capabilities Typed capability discovery, generated spec, and shared execution transport
/api/v1/workshop Live index of agent-authored Workshop pages
/data/education/packets Internal, path-confined serving of generated education PDFs
/sk/{token} Public, token-scoped frozen skill shares

Note: Several routers have no common /api/v1 prefix and serve public-tunnel surfaces directly β€” canvases_public, shared_reports, skillshare_public, and eu_guide. These are the read-only output surfaces reached through the public-api role. Domain-specific allowlists still decide which paths each public hostname may expose.

Capability layer and Workshop

The Capability Layer is the contract boundary between interfaces and domain owners. A capability declares typed input/output, side-effect class, source, examples, and transport policy, then delegates to an existing owner module. The same execute() path produces a non-throwing v1 envelope for Python, CLI, HTTP, and the Workshop browser SDK. This prevents a new interface from inventing a parallel data or mutation path.

The Workshop is the first browser-native consumer of that boundary. Static pages under workshop/pages/ use workshop/lib/vita.v1.js, declare a narrow capability allowlist, expose freshness and rejection states, and store only view chrome locally through vita.workshop.prefs_*. Domain state stays with its capability owner.

The split health domain

What used to be a single /api/v1/health router is now spread across nine router files that all mount under the /api/v1/health prefix, so the domain can grow without one giant file:

Router file Concern
health.py Core system health check + shared health surface
health_center.py Health center landing/aggregation
health_checkins.py Daily check-in records
health_sleep.py Sleep data and guardian surface
health_bodycomp.py Body-composition tracking
health_doctor.py Doctor visits / clinical surface
health_visits.py Visit scheduling and records
health_regimen.py Supplement / regimen tracking
health_genetics.py Genetics data surface

Scheduler

The VitaScheduler runs 70 async task loops β€” no cron, no systemd timers, all internal asyncio loops registered through the loop-engine registry (api/src/loop_engine/registry.py, the canonical task-count source). The scheduler only runs in the internal API role; the public-api role disables it.

Daily Scheduled Tasks (PT)

  • 00:05 - Daily rollup (scratch notes into weekly)
  • 00:30 - /sleep deep reflection cycle
  • 03:00 - Transcript cleanup
  • 04:45 - VDB draft pass 1 (before garmin)
  • 05:00-06:30 - Garmin poll (5min intervals, triggers VDB pass 2)
  • 07:00 - VDB send deadline
  • 10:00 - Proactive coaching + heartbeat nudges
  • Daily - Morning kickoff, evening check-in, winddown triggers

Weekly Tasks

  • Sunday 6:00 AM - Board meeting (multi-persona)
  • Sunday 10:00 AM - X content generation

Recurring Loops

Frequency Tasks
30 sec Stream dock refresh
5 min Voice session TTL cleanup
15 min Token aggregation, session sync, email sync, HN fetch, heartbeat
30 min RSS feeds, e-ink display, EPD47 canvas, doc scan
1 hour Messaging sync (Slack, Signal, Telegram DMs) β€” 5am-10pm only
4 hours Podcast sync
6 hours Garmin full sync (skips 5-6:30am), X feed sync (8am-10pm)
8 hours CGM sync (LibreLink)

Autonomous Loops

Loop Description
Executive OODA work cycles (configurable interval, default 60min)
Sentinel Event detection polling (configurable per-detector)
Consolidation Micro-processing: triage, CLI scan, scratch synthesis
Research Autonomous topic research from queue
Speculative Budget-aware precomputation
Deep analysis Long-running analytical tasks
Synthesis Cross-source data synthesis
Auto-curator Content curation scoring
Podcast curation Episode scoring and queue management
Calendar sentinel Calendar-triggered event detection
Equilibrium sync Executive loop equilibrium maintenance
Feedback aggregation Consolidate feedback signals
Commitment followup Track and nudge on commitments
Code production Git metrics collection
Photo ingest Photo pipeline processing
Vault commit Encrypted data commit cycle
Ecosystem scan External ecosystem monitoring
Deploy reminder Deployment reminder tracking

File Conventions

JSON Files

Single records per file: data/checkins/2026-01-03.json

JSONL Files

Append-only logs: data/identity/observations.jsonl

Naming

  • Dates use ISO format: YYYY-MM-DD
  • Slugs use kebab-case: weekly-training-structure
  • IDs use short hashes or UUIDs

Tip: All data writes go through the safe primitives in scripts/utils.py β€” atomic_write / atomic_write_text (tmp+rename), atomic_append / atomic_append_text, safe_read_json, and generate_uuid. A health.py unsafe-writes check fails CI if raw open(..., 'w') touches a data file outside the allowlist. This is surfaced as the data-integrity skill.

Security Model

  • All data stays local (no cloud sync)
  • Credentials in ~/.config/vita/ (outside repo)
  • API keys never committed to git
  • No remote pushes allowed (enforced in hooks)
  • Public surfaces are read-only and route-restricted: the public-api role plus DomainGuardMiddleware gate which paths each public hostname can reach

Local Infrastructure

Service management (./run)

Every vita service starts, stops, and reports status through a single bash entry point: ./run <service> [start|stop|restart|status|log]. It holds a service registry, writes PID files under .logs/, reclaims ports, and offers a dev full-stack launcher (./run dev with --with-daemons / --with-tunnels flags).

Warning: vita's own services run exclusively through ./run β€” there are no vita systemd units. Alerts about a dead service must recommend ./run <svc> restart, never systemctl. (Caddy below is host infrastructure, not a vita service, which is why it is the one exception.)

Common commands:

./run api               # internal API + scheduler (port 33800)
./run public-api        # read-only public API (port 33802, no scheduler)
./run web               # Vite dev server (port 33801)
./run stepwise status   # stepwise workflow server (port 8341)
./run podcast-tunnel    # ngrok tunnel β€” podcast.ham.xyz
./run status            # status of all services
./run stop              # stop everything

Public tunnels (ngrok)

Four ngrok tunnels expose read-only public surfaces, all fronted by the public-api role (so tunnel serving never stalls on the scheduler event loop):

Tunnel command Public hostname Surface
./run podcast-tunnel podcast.ham.xyz Podcast RSS / episode feed
./run reports-tunnel vita-reports.ham.xyz PIN-gated reports, canvas/board shares
./run rss-tunnel vita-rss.ham.xyz RSS feed (unguarded dedicated domain)
./run eu-tunnel eu.ham.xyz Trip guide (root redirects to /eu)

Reverse Proxy (Caddy)

Caddy provides friendly URLs for local services:

URL Backend Config
http://vita.localhost / http://vita.desk localhost:33801 (Web UI) /etc/caddy/conf.d/vita.caddyfile

Caddy runs as a host-level systemd service (caddy.service, enabled at boot). This is the deliberate exception to the ./run-only policy: Caddy is shared host infrastructure, not a vita service. Everything vita runs through ./run.

Ports

Port Service Notes
33800 FastAPI backend (internal) ./run api; owns the scheduler
33801 Vite dev server (Web UI) ./run web
33802 Public read-only API ./run public-api; serves tunnels, no scheduler
8341 Stepwise workflow server ./run stepwise

Note: Some other docs (and CLAUDE.md) describe the living-briefing API at http://localhost:33801/.... That is the same backend, reached through the Vite dev server's proxy in development; the FastAPI app itself listens on 33800. Both are correct β€” 33801 is the proxied path, 33800 is the direct backend.

Verification & Hygiene Gates

Tiered checks wired into ./run guard edits and CI:

Command What it runs
./run verify-fast Codebase health summary
./run verify-standard Health + additional checks
./run verify-full test-all (api + root + web + optional iOS)
./run health / ./run health --full scripts/codebase/health.py β€” ~25 policy checks (large files, router/module size, route security policy, scheduler-loop policy, unsafe writes, bare excepts, docs-count drift, …)
./run typecheck mypy gate (scripts/typecheck/mypy_gate.py) + tsc
./run architecture-metrics [--summary] Regenerate the router/task/data-dir/skill counts
./run gen-types Generate TypeScript types from the OpenAPI schema

health.py is the policy-enforcement layer β€” it is what turns "don't write data with raw open" and "don't drift the architecture counts in the docs" into hard CI failures.

Runtime verification

The gates above check the code. A second family checks whether what's running and what's rendered can be trusted β€” see Verification & Anti-Lying Machinery:

Check Where it runs
uv run python -m freshness --status on demand; exit 1 if any registered source can't back a number (contract)
code_fresh.* rows nightly rollup β€” a running process holding stale bytecode means a committed fix is not live
self_restart_guard inside ./run <svc> restart β€” refuses to tear down the service hosting the caller's own turn
fold_assertion after /sleep's reflect step β€” a silent no-op fold fails loudly
freshness.* + _run_services_liveness() rows nightly data_source_health rollup

Extension Points

Add new capabilities by:

  1. New data source β€” Add a sync script to scripts/, register a loop in the scheduler registry (api/src/loop_engine/registry.py)
  2. New command β€” Add a skill to .claude/skills/
  3. New view β€” Add a prompt to memory/prompts/, run /update-trends
  4. New API endpoint β€” Add a router file to api/src/routers/ and include_router it in api/src/main.py

File Locations

Path What lives there
run Service manager (start/stop/status/log for every vita service)
api/src/main.py FastAPI app β€” mounts all routers, lifespan, scheduler bootstrap
api/src/routers/ One router file per concern (77 mounted)
api/src/scheduler.py VitaScheduler β€” async task loops
api/src/loop_engine/registry.py Canonical scheduler-task registry
api/src/middleware/domain_guard.py Public-surface route restriction
scripts/codebase/health.py Codebase policy checks (CI gate)
scripts/codebase/architecture_metrics.py Generates the architecture counts
scripts/utils.py Safe data primitives (atomic writes, safe reads, UUIDs)
data/search/vita.db Hybrid search index (chunks + vectors)
web/src/ React 19 SPA (TanStack router/query, Vite)

Where to go next