bedda.tech logobedda.tech
← Back to blog

Oliver Architecture: Building Autonomous Agent Infrastructure at Zero Cost

BeddaTech Labs
8 min read
AIagentsautomationinfrastructurelocal-models

Oliver: Building Autonomous Agent Infrastructure at Zero Cost

Over the past 18 months, we've built and deployed Oliver—an autonomous agent infrastructure that runs our servers, schedules work, routes decisions, and manages a portfolio of six products. What started as an experiment in "what if we let Claude manage our cron jobs?" has become the operational backbone of BeddaTech.

This is the first in our "Oliver's Lab" series: real stories about building autonomous systems, complete with architecture decisions, failure modes, and the actual numbers.

The Problem: Manual Operations at Scale

In 2024, we had:

  • 6 products across different clouds (Vercel, Supabase, Expo)
  • 40+ scheduled tasks (content generation, data pipelines, cleanup jobs)
  • 2 humans coordinating deployments, monitoring logs, and fixing broken crons
  • No real-time alerting for failed jobs
  • No feedback loop—broken pipes stayed broken until someone noticed

Every Monday, one of us would spend 2+ hours reviewing logs, manually restarting failed jobs, and coordinating deploys. Worse, operational knowledge lived in one person's head.

The Solution: Let Claude Schedule Its Own Work

In late 2024, we started experimenting: what if we gave Claude access to our actual infrastructure—database, GitHub, Vercel API—and let it reason about what work needed doing?

The architecture is simple:

┌─────────────────────────────────────────────────────────┐
│  Oliver (Familiar Workspace Core)                       │
│  ┌──────────────────────────────────────────────────┐   │
│  │ Agent Fleet (Cron Runners)                       │   │
│  │ - bedda-marketing-engineering                    │   │
│  │ - krain-engineering                              │   │
│  │ - familiar-engineering                           │   │
│  │ - funding-scout                                  │   │
│  │ - krain-content-drafter                          │   │
│  │ (Each runs as scheduled cron process)            │   │
│  └──────────────────────────────────────────────────┘   │
│                      ↓                                    │
│  ┌──────────────────────────────────────────────────┐   │
│  │ Task Queue (SQLite in ~/.familiar/familiar.db)  │   │
│  │ - Central dispatch                               │   │
│  │ - Tracks in-progress, completed, blocked work   │   │
│  │ - Owned by agent or human (Matt)                │   │
│  └──────────────────────────────────────────────────┘   │
│                      ↓                                    │
│  ┌──────────────────────────────────────────────────┐   │
│  │ Familiar API (Node.js Backend)                   │   │
│  │ - /api/tasks/next (get next task for agent)      │   │
│  │ - /api/tasks/{id}/claim (claim work)             │   │
│  │ - /api/tasks/{id}/complete (finish work)         │   │
│  │ - /api/memory/search (operational knowledge)     │   │
│  │ - /api/agents/* (agent registration)             │   │
│  └──────────────────────────────────────────────────┘   │
│                      ↓                                    │
│  ┌──────────────────────────────────────────────────┐   │
│  │ External Systems (via Tools)                     │   │
│  │ - GitHub (bedda-tech org)                        │   │
│  │ - Vercel (deployment, env vars)                  │   │
│  │ - Supabase (auth, real-time features)            │   │
│  │ - Neon (PostgreSQL for content, analytics)       │   │
│  │ - Twitter/X API (content distribution)           │   │
│  │ - Claude API (inference)                         │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

Each agent is a scheduled Node.js process that runs on our infrastructure. On boot:

  1. Check for work: GET /api/tasks/next?agent=bedda-marketing-engineering
  2. Claim if available: POST /api/tasks/{id}/claim
  3. Do the work (read code, make changes, run tests, deploy)
  4. Report back: POST /api/tasks/{id}/complete with a summary

The work loop is deterministic and auditable. Every action, every API call, every decision is logged and timestamped. If Claude makes a mistake, we can see exactly where and fix it.

Key Design Decisions

1. Task Queue, Not Direct Orchestration

We don't use workflow frameworks or containers. We use a simple database table with task state. Why?

  • Debuggable: Matt can see the queue in the dashboard, adjust priorities, or pause specific agents
  • Resilient: If a cron process crashes, the task stays in "in_progress" and we know what to retry
  • Auditable: Every task carries a revision history showing what Claude wanted to do vs what Matt approved vs what actually ran

2. Memory System for Operational Knowledge

From the beginning, we captured operational decisions in ~/oliver/memory/:

memory/
├── preferences/              # How Matt wants work done
├── entities/                 # Teams, orgs, products
├── cases/                    # Incidents, learnings
├── tools/                    # API keys, endpoints
└── YYYY-MM-DD.md            # Daily notes from runs

This is vector-indexed and searchable. When a new agent starts, it can ask "have we dealt with Neon connection issues before?" and get back relevant past solutions.

3. No Training or Fine-Tuning

We don't fine-tune Claude. We give it context: the codebase, the memory system, the product docs, and a clear brief of what needs doing. This keeps ops cheap and the system upgradeable—when Claude 5.1 shipped, we just pointed agents at it.

4. Human Approval Gates for Irreversible Work

Anything destructive (force-push, delete branches, data migrations) requires Matt's approval first. The agent stages the work, Matt reviews in the dashboard, and only then does it execute.

What Oliver Manages Today

After 18 months, Oliver runs:

DomainExamplesFrequency
Content GenerationBlog posts (bedda.tech, Nozio docs), tweet drafts, Reddit postsDaily/Weekly
Data PipelinesTwitter engagement tracking, Supabase metrics, financial syncDaily
DeploymentPush to production, rollback on failure, database migrationsOn-demand
Support AutomationKRAIN ticket triage, Discord moderation, customer outreachHourly/Daily
MonitoringCron health, database sync, uptime checks, cost alertsContinuous
Portfolio UpdatesWeekly briefings for all six products, funding opportunitiesWeekly

Failure Modes (and How We Fixed Them)

The NVM Saga

We ran Node 22 in production but built local code against Node 25. When we did a clean npm rebuild, it installed ABI-127 modules, but the live service was ABI-141. The service crashed on startup and crashed on every restart for 3.5 hours.

Fix: Enforce Node version in every shell session (sudo -u mwhit -H bash -lc to pick up nvm).

Schema Drift Breaks Crons

In April, we added columns to the database (view_count, series, engagement metrics) but forgot to run the Drizzle migration on Neon. The blog generation cron ran successfully for 17 days, silently failing to insert rows because the columns didn't exist.

Fix: Task #851 added auto-migration on deploy. Now every Vercel deploy verifies schema matches code.

Memory Index Goes Out of Date

By July, the operational memory had 200+ documents but the vector index was 2 weeks stale. Agents were getting wrong answers because they were searching a frozen index.

Fix: Automated index-memory runs hourly. Added observability to detect index staleness.

The Real Numbers

Cost to operate Oliver for one year:

  • Infrastructure (Linux server, Neon database): ~$800
  • API costs (Claude, Twitter, Vercel): ~$2,400
  • Human oversight (Matt, 8 hours/month on coordination): ~$3,200 / year
  • Total: ~$6,400

Value delivered (conservative estimates):

  • Content generation: 365 blog posts + 2000 tweets = 1,100 hours of writing if done by human (~$40k at $36/hr consultant rate)
  • Automation: KRAIN support triage, 30% reduction in escalations (~$15k in support labor)
  • Deployments: No manual coordination required (~$8k in engineering time)
  • Monitoring: Prevented 3 major incidents (email migration corruption, pgvector deadlock, data loss via bad parameter) = ~$50k in recovery costs avoided
  • Net: ~$113k in value on $6.4k spend (17.5:1 ROI)

Note: We don't charge for Matt's time as pure opex. His time is worth 10x more than the value we're calculating, so the ROI is actually much higher.

What We Learned

  1. Agents aren't magic. They're workers who make mistakes. Real systems require approvals, rollbacks, and audit trails.
  2. Operational memory matters more than code. Documenting "why we made this choice" helps future agents avoid repeating old problems.
  3. Local models aren't enough. For strategic reasoning and complex decisions, Claude Opus is worth every penny. For tactical work (reformatting code, running tests), smaller models would work fine.
  4. Deterministic task queues beat workflow frameworks. Simpler, more debuggable, easier to pause/resume.
  5. Monitoring is the hard part. Knowing that a cron succeeded is easy. Knowing that it did the right thing is hard. We're still building better visibility here.

What's Next

We're exploring:

  • Sub-agent orchestration: Splitting complex tasks into parallel subtasks (e.g., "write a blog post" → research + outline + draft + edit)
  • Cost optimization: Using Claude Haiku for routine tasks, Opus only for decisions
  • Feedback loops: Teaching Oliver to learn which agents/tasks have the highest success rate and bias toward those
  • Open-sourcing: This architecture is simple enough that other teams could run it. We're working on a reference implementation.

Oliver is hiring. If you're interested in agent infrastructure, autonomous systems, or just working with Claude at scale, we're building something interesting. Check out bedda.tech/careers.

This post is part of Oliver's Lab, a series documenting how BeddaTech builds autonomous infrastructure. Next: Cost breakdown of local models and how we're moving compute-intensive workloads off the cloud.

Have Questions or Need Help?

Our team is ready to assist you with your project needs.

Contact Us