Skip to content
archived Visibility internal Owner erik@uvilo.com Approver _ Created _ Updated _

Uvilo OS Research

Overview

This document recommends an architecture for the Uvilo Process & Docs System. It was developed iteratively through a series of design conversations and supersedes the original spec.

The system must satisfy two distinct use cases:

  1. Interactive AI co-authoring — A user works with LibreChat to create and refine documents (specs, prompts, outputs, status files). Files are often in an incomplete or inconsistent state mid-session. The editing loop is: LibreChat edits → user reviews → user corrects → back to LibreChat.
  2. Manual editing — A user makes smaller targeted edits to documents via a browser-based WYSIWYG editor, without involving AI.

All users — technical and non-technical — access the system through a browser. No local tooling, Git clients, or filesystem access is required.


Core Architecture

Source of Truth

GitHub (main branch) is the canonical source of truth. It holds the stable, approved version of all documents. Nothing reaches main without an explicit merge.

Working Directories

Each user has a dedicated working directory on a Railway persistent volume — a Git clone of the repository, one per user:

/volumes/erik/UviloWorkspace/     ← erik's clone, on active branch
/volumes/sara/UviloWorkspace/     ← sara's clone, on active branch

These directories are server-side. Users never interact with them directly — they interact through LibreChat and TinaCMS, both of which read and write to these directories.

Two Editing Surfaces

Both surfaces point at the same working directory for a given user. A user can switch freely between them within a session.

SurfaceUse caseHow it works
LibreChatAI-driven editing, long-form generation, iterative refinementMCP filesystem server reads/writes files in the user’s working directory
TinaCMS (local mode)Manual edits, small corrections, WYSIWYG reviewRuns against the same working directory; no GitHub API calls during editing

Editing Workflow

Starting a Session

When a user begins a working session, LibreChat:

  1. Ensures their working directory is up to date (git pull)
  2. Creates a new branch named after the session, e.g. work/erik/onboarding-spec-2026-03-07
  3. Confirms the branch is active in the working directory

The user then edits freely — via LibreChat chat commands, or by switching to TinaCMS in the browser for manual adjustments.

During a Session

  • LibreChat writes files via an MCP filesystem server pointed at the user’s working directory
  • TinaCMS reads and writes the same directory in local mode
  • Files may be incomplete, inconsistent, or in draft state — this is expected and fine
  • No commits happen automatically during the session; the working directory is a free scratchpad

Ending a Session

When the user is satisfied with their work, they tell LibreChat to commit. LibreChat:

  1. Runs git add and git commit with a summary message
  2. Pushes the branch to GitHub
  3. Opens a draft Pull Request against main

The PR is the review gate. The user (or another reviewer) inspects the changes and merges when ready.

Merging to Main

  • PRs are reviewed via the GitHub UI (or via LibreChat if the user prefers)
  • On merge, GitHub Actions triggers a CI build that regenerates the published sites
  • main always reflects stable, approved content

Branching Model

ScenarioBranch namingNotes
Working sessionwork/<user>/<topic>-<date>Created at session start, PR on commit
AI agent taskagent/<task>-<date>Always opens a PR, never commits directly to main
Hotfix / small editfix/<user>/<topic>Can be short-lived; merge quickly

Multiple branches per user are fine. Stale branches (no activity for 30 days) are deleted automatically via a GitHub Actions cleanup job.


Infrastructure Stack

GitHub

  • Hosts the canonical repository
  • Manages PRs, code review, and merge history
  • GitHub Actions handles CI/CD: builds published sites on merge to main
  • Stale branch cleanup runs on a schedule

Railway

  • Hosts LibreChat
  • Hosts TinaCMS (local mode, one instance per user or a shared instance with per-user directory routing)
  • Provides persistent volumes for per-user working directories
  • Estimated storage: 1–5 GB per user (documentation files are small)

MCP Filesystem Server

  • A lightweight server (e.g. @modelcontextprotocol/server-filesystem) running on Railway
  • Scoped to the active user’s working directory
  • Gives LibreChat read/write access to files
  • Also handles Git operations (branch create, commit, push, PR) via shell commands or a Git library

TinaCMS (Local Mode)

  • Runs against the user’s working directory on the Railway volume
  • No GitHub API calls during editing — writes directly to disk
  • Used for WYSIWYG manual editing and review of files generated by LibreChat
  • Configured to point at the correct per-user directory

Astro Starlight (Site Generation)

  • Two sites built from one repository, filtered by frontmatter visibility field:
    • Public sitevisibility: public documents only
    • Internal site — all documents
  • Built automatically on merge to main via GitHub Actions
  • Public site deployed to Vercel or Cloudflare Pages (free tier)
  • Internal site deployed behind Cloudflare Access or basic auth
  • Pagefind — ships with Starlight, zero config, handles full-text search for human users browsing the sites
  • Typesense (optional, later) — server-side semantic search for AI agents doing RAG against documentation

Content Structure

All documents live under UVILO_FOLDER (the repo root). The folder structure mirrors the existing Google Drive Canonical/ layout. Documents use markdown with YAML frontmatter:

---
title: "Onboarding Quiz Spec"
visibility: internal          # internal | public
tags: [product, onboarding]
owner: "erik@uvilo.com"
status: archived
last_reviewed: 2026-03-07
---

The status field distinguishes in-progress work from approved content, without requiring a separate folder structure.


What Was Ruled Out and Why

ApproachRuled out because
Google Drive as source of truthNo native Git branching; conflict resolution is crude (duplicate files); MCP integration requires Drive API service account complexity
Local filesystem sync (Mutagen, rclone to laptop)Requires per-user daemon setup on each machine; not viable for non-technical users
GitHub MCP server for live AI editingIntroduces a round-trip through the GitHub API on every file write; breaks the tight LibreChat → review → edit loop; adds latency and rate limit exposure
Trunk-based merging (no branches)Files are routinely in incomplete/inconsistent state mid-session; committing directly to main would corrupt the canonical base
TinaCMS in standard mode (GitHub API)Couples every save to a GitHub API call; doesn’t support in-progress branched work cleanly
One shared working directory for all usersSimultaneous edits from different users on different branches would overwrite each other

Implementation Roadmap

Phase 1 — Foundation

  • Create GitHub repository; migrate Canonical/ content as initial commit
  • Set up frontmatter schema across all documents
  • Initialize Astro Starlight; deploy public site
  • Basic GitHub Actions CI on merge to main

Phase 2 — Editing Infrastructure

  • Provision Railway persistent volumes, one per active user
  • Clone repository into each volume
  • Deploy MCP filesystem server scoped to per-user directories
  • Connect LibreChat to MCP server; validate read/write/git operations

Phase 3 — TinaCMS Local Mode

  • Deploy TinaCMS in local mode on Railway, pointed at per-user working directories
  • Validate that LibreChat and TinaCMS edits are visible to each other in real time
  • Test full session workflow: branch → edit → commit → PR → merge

Phase 4 — Site Publishing

  • Configure two-site Starlight build (public/internal filtering)
  • Deploy internal site behind Cloudflare Access
  • Add Pagefind search

Phase 5 — Scale and Polish

  • Stale branch cleanup automation
  • Typesense semantic search for AI RAG
  • PR review workflow improvements
  • Per-user TinaCMS configuration (branch switching, session management)

Cost Estimate

ComponentCost
GitHub (repo + Actions)Free
Railway (LibreChat + TinaCMS + volumes)~$20–40/mo depending on users
Astro StarlightFree (open source)
PagefindFree (static, client-side)
Public site hosting (Vercel/Cloudflare Pages)Free tier
Internal site (Cloudflare Access)Free up to 50 users
Typesense (optional, self-hosted on Railway)~$5–10/mo
Total~$20–50/month

Project Execution Model

The current job-based system (timestamped folders in Dropbox, designed for single-session tasks) is replaced by a project-based system where each Architecture project is implemented across multiple sessions.

Each project maintains its State document plus two additional files for cross-session continuity:

  • Project_Name_State.md — Living progress document with todo list using checkbox conventions: - [ ] (not started), - [ ] [STARTED] (in progress), - [x] (done), - [ ] [BLOCKED] (waiting)
  • Project_Name_History.md — Compressed summaries of each completed session (model used, tokens consumed, what was done, state changes)
  • Project_Name_WIP.md — Running detailed log during a session (file paths edited, commands run, errors encountered, decisions made); primarily for crash recovery

An agent starting a new session reads the State document for current progress and Project_Name_History.md for context on prior work. The Project_Name_WIP.md is a scratchpad that gets long and messy — it exists so that if a session crashes, the next agent can see exactly where things were left.

What Was Ruled Out and Why (Agentic Execution)

ApproachRuled out because
Frequent git commits as crash recoveryUnstaged/uncommitted files on disk already reflect actual progress; commits should happen at meaningful checkpoints, not as a recovery mechanism
Markdown checkbox [-] for “in progress” stateNot supported by GitHub Flavored Markdown or most viewers; renders as a regular list item; [STARTED] prefix after the checkbox is unambiguous and human-readable
YAML (project.yaml) for task stateAdds friction for humans adding todos; markdown checkboxes with prefix conventions are easier to edit and still machine-parseable
Claude Desktop for long agentic workThe response rollback bug (#10065) has been open for 6+ months with no fix; tool-heavy sessions silently lose all work
Single long chat sessionsContext window limits, compaction threshold bugs, and the rollback issue make these unreliable for work exceeding ~15 minutes
Human typing “Continue” every 10 minutesDefeats the purpose of autonomous execution; the system should self-continue across sessions