Architecture brief · for external review

The PINAVOX Stack

One founder, a small team, and a client base of $10–50M machine manufacturers — served by a fleet of isolated AI brains, one self-hosted agent, and a client product that seeds a platform. This brief consolidates every architecture decision, the economics, and the failure history they were derived from.

Author Stefan Badertscher, PINAVOX Date 5 Sep 2026 Status Decisions locked; build sequenced Ask Section 10 — reviewer questions

0 · Executive summary

The whole system in six lines

Separate state from compute from surface — then never let a credential cross a boundary.

  • State lives in per-tenant brains: git + Cloudflare Worker + D1 + R2, physically isolated per tenant (no shared DB, no namespace filters).
  • Compute is three-tier: an always-on self-hosted agent (browser hands, multi-account email), Anthropic cloud routines (scheduled jobs), and interactive Claude sessions — all billed to existing subscriptions, not per-token API.
  • Surfaces are thin: Slack for capture, claude.ai Projects for conversation, a web Board per client, Obsidian for files. Brain routing is enforced by credential scoping, not by prompt discipline.
  • Client product: each client gets a cloned brain stack (RAG included) + a Board web app at ~$0–2/mo marginal COGS; AI tokens ride on the client's own Claude subscription in phase 1, metered API in phase 2.
  • The predecessor system failed (7 weeks silent, $50–95/day API burn); seven invariants derived from that post-mortem govern every component here.
  • New capital required: ≈ $0. The always-on hardware is an owned laptop; everything else is existing subscriptions plus low single-digit dollars of Cloudflare usage.

1 · System map

Three brain tiers · three compute tiers · hard walls

SURFACES Slack (capture · dispatch) · claude.ai Projects (conversation, MCP-bound) · client Boards (view) · Obsidian (files) · Claude Code (build) STEFAN BRAIN (private) taxes · legal · family · personal ops own Worker + D1 + R2 Access: 1 email, Stefan only raw sensitive files stay X1-local brain holds knowledge + pointers only PINAVOX BRAIN (company) content · leads · sales · playbooks brain.pinavox.app · Worker + D1 truth in git repo · Librarian curates nightly users: Stefan · Fatima · Hilary (MCP OAuth) LIVE since Jul 2026 · 264 docs CLIENT BRAINS (fleet) Sensora → Care4IT → Neuroth → … one stack per client, template-cloned: Worker + D1 + R2 + AI Search (RAG) + Access app + Board web app physical isolation — no shared DB ~$0–2/mo marginal each · build ≈ 3 days once HARD WALL PER-TENANT ISOLATION COMPUTE APEX — self-hosted agent (ThinkPad X1, Ubuntu, Montreal) Slack Socket-Mode listener → claude -p (session-resumable threads) persistent Chrome profiles (research · IGA · Marketplace · LinkedIn) N × Google OAuth tokens (personal + company Gmail/Calendar) Tailscale exit node — team LinkedIn exits via one residential IP runs on existing Claude Team seat — no per-token meter LUKS + TPM auto-unlock · systemd · zero inbound ports · battery = UPS Anthropic cloud routines daily CEO brief · idea capture post-ideas brief · Librarian night-shift agent cron-fired, sandboxed, zero ops subscription-billed Cloudflare edge serves all brains + Boards Workers · D1 · R2 · AI Search client traffic never touches the self-hosted machine no founder-owned server in any client path acts for acts for writes via MCP hosts The X1 has no route to any client brain — it holds no client credentials. Client reliability is Cloudflare's SLA, not a laptop's.
Fig. 1 — The stack. Surfaces are thin and interchangeable; state is per-tenant and physically isolated; compute is split between one owned always-on agent (private + company work), managed cloud routines (scheduled work), and Cloudflare's edge (everything client-facing).

2 · Brain routing — the guarantee

Why a task can't pull from the wrong brain

Three surfaces, three deterministic routers. The critical design choice: routing is enforced by credential scoping, not by model obedience. A mis-phrased prompt cannot cross a wall, because the execution environment for a company task contains no key for the private brain — and vice versa.

ENTRY claude.ai chat router = the Project Slack thread router = APEX config map Claude Code session router = the mounted repo CREDENTIAL BUNDLE (per task) stefan.env stefan-brain token · personal Gmail OAuth personal calendar · grocery/browser profile contains no company key pinavox.env pinavox-brain token · company Gmail OAuth LinkedIn profile · Notion · Unipile contains no private key BRAIN Stefan Brain Access: 1 email PINAVOX Brain Access: team OAuth DM→private · work→company Ambiguous Slack message → APEX asks once; it never guesses. Cross-brain leakage caught by the nightly Librarian review. Client Projects work identically: the Sensora Project holds only the Sensora connector — it has no route to any other brain.
Fig. 2 — Credential-scoped routing. Each surface resolves deterministically to a credential bundle; the bundle defines the reachable world. This also restores the multi-account email capability the previous system had (personal + company Gmail simultaneously) that single-connector chat products cannot offer.

3 · The agent layer

APEX — a self-hosted Manus-class agent on owned infrastructure

APEX is ~100 lines of glue, deliberately: a Slack Socket-Mode listener that shells into claude -p with per-thread session resumption, on an always-on ThinkPad X1 (Ubuntu) in the founder's home. No agent framework. The intelligence is stock Claude Code; the scheduler is systemd; the state is git.

CapabilityManus-class SaaS agentAPEX (self-hosted)
Multi-step live web researchYesYes — real Chrome, headed, watchable via remote desktop
Logged-in sessions (groceries, Marketplace, airline)Ephemeral, per-run loginsPersistent dedicated Chrome profiles — log in once, stays live across reboots
IP reputationDatacenter IPs → bot wallsResidential IP (the founder's home line)
Multiple Gmail / calendar accountsOne account per connectorN × OAuth token files, selected per credential bundle
Multiple brains with hard wallsNo conceptCredential-scoped routing (Fig. 2)
Marginal cost per taskPer-credit pricing$0 — existing Claude Team seat
Purchase completionAttempts full checkoutDeliberate stop-line: fills carts / prepares bookings; human clicks buy. Server-side carts make the handoff seamless (cart appears in the owner's own app)

Reliability posture (the boring parts that matter)

4 · Why these rules exist — the predecessor's post-mortem

"Vox" — OpenClaw daemon on a rented VPS, Jan–Aug 2026

Failure (observed, logged)Invariant derived
Claimed actions it hadn't completedR1 — No claim without an artifact. Every action returns a link/path/row-ID or reports failure.
24 sync-failure alerts over 7 weeks into a channel the founder had stopped reading; nobody noticedR2 — The output is the heartbeat. No ops channel; the absence of expected work product is the alarm.
Status file claimed jobs ran on the VPS that actually ran elsewhereR3 — Status is derived from artifact timestamps, never declared.
Scheduled daily briefs lost the founder's trust ("not up to date, not at a good level of trust") and were all disabledR4 — Reactive first. Proactive jobs added one at a time, each with a stated success condition.
$50–95/day per-token API burn; one $22 scrape produced zero usable rowsR5 — Spend reported daily, ceiling enforced in code. Personal/company compute rides subscriptions; API is reserved for revenue-attached product COGS, capped per tenant.
Bespoke agent framework only the founder could repairR6 — Thin glue over stock tooling. Losing the glue loses a script, not a system.
A "vacation-week" review routine ran 40 days past its scope, committing daily requests to be cancelledR7 — Everything scheduled carries an expiry and a three-strikes auto-disable.

5 · The client product

A brain + a Board per client — the deliberate seed of the PVOS platform

Every PINAVOX client (industrial machine manufacturers running the Production Visibility OS™ content system) gets a cloned stack: Worker + D1 + R2 + managed RAG (Cloudflare AI Search, multilingual embeddings) + an Access-gated Board. The client's team connects their own Claude to their brain via MCP and works conversationally; the Board is the shared operational view.

Division of labor — deliberately LLM-free Board

ActivitySurfaceAI cost bearer
Drafting, discussing, "what's missing on piece S-012?"Client's own Claude (Project + MCP connector) — full-window chat, artifacts, long textsClient's subscription phase 1 / metered API phase 2
Weekly content meeting: add ideas live, move stagesBoard grid — type, Enter, next numbered row (IDs brain-assigned; human-typed IDs corrupted the pilot client's sheet)None — no LLM in the Board
Reading a full article, reviewing filesBoard full-page view / file manager (R2)None

Data model — hard-capped against feature creep

Two levels, forever: Piece (idea, TAYA category, priority, sales-use) → Assets (channel × language, stage, date, link). No tasks, no dependencies, no automation builder. The grid stays dumb; anything intelligent — summaries, charts, "what changed since last week" — is asked in chat and answered by the brain. UI is English-only; per-language columns (DE/EN) are content-tracking data, not localization.

Unit economics

ItemPhase 1 (now)Phase 2 (product)
Infra per client brain~$0–2 / mo~$0–2 / mo
AI tokens$0 — client's own Claude via MCPmetered API, hard-capped per tenant in code
Build effort≈ 3 days (first), then template-clone in hours
Pricingbundled in PVOS engagementmonthly tool fee ≥ 10× capped COGS (cap guarantees margin floor)
Trigger to move3+ client brains live · MCP-side token telemetry from phase 1 sets the phase-2 price — measure, then price; never guess
Position

Phase 1 is not a compromise — it is instrumentation. Client-side Claude usage through the Worker produces exact per-tenant token telemetry. The embedded-API chat ships only when that data exists, with a per-tenant spend ceiling enforced in the Worker (the same class of runaway that produced $95 days structurally cannot recur, because the cap is code, not policy).

6 · Security model

Summarized — each item enforced, not aspirational

7 · Cost picture

Before vs after

LinePredecessor eraThis architecture
Agent model usage (founder ops)$50–95 / day (API, peaks)$0 marginal — existing Team seats
Hosting$25 / mo VPS$0 — owned X1 (+ ~$2/mo power)
LinkedIn proxy plan$20–25 / mo (planned)$0 — Tailscale free tier, residential exit
Cloudflare (all brains + Boards)$5 / mo Workers Paid + ~$0–2 / mo per tenant
Client-facing AIn/a$0 (phase 1) → capped COGS priced into fee (phase 2)
New hardware$0 — repurposed owned laptop

The structural fix is not frugality — it is moving founder-side compute onto flat-rate subscriptions and reserving metered API strictly for revenue-attached, ceiling-capped product COGS. The binding constraint becomes Claude seat capacity (shared with the founder's own usage), managed by model-routing routine jobs to cheaper tiers.

8 · Current status

Honest inventory, 5 Sep 2026

ComponentState
PINAVOX Brain (Worker + D1 + MCP OAuth, team access, nightly Librarian)LIVE since Jul 2026
Cloud routines (CEO brief, post-ideas, night-shift)LIVE — runaway review routine killed 5 Sep (R7 now enforced)
Brain Librarian (nightly curation: capture wide → curate → cite sources)LIVE — verified from run logs 5 Sep: fired every night, ~3 min/run, zero misses; curated learnings land as cited Brain entries + Slack digest + push
LinkedIn post-performance ingest → brain (closes the content flywheel)NEXT — prerequisite before the brain generates weekly posts; entry count is not the gate, the feedback loop is
Command Center (outreach: D1 + web UI + guarded send)LIVE — pattern-proof for the Board
Sensora brain (first client clone: frameworks, planner, RAG, Board)BUILDING — phase A/B/C sequenced; framework approval + Access app pending
APEX on X1 (wipe → Ubuntu → listener → browser hands)BUILDING — hardware in hand, spec locked
Stefan Brain split (private stack + credential bundles + routing)NEXT — after APEX phase 1
PINAVOX-internal Board (retires Notion content DBs)NEXT — clone of Sensora Board once proven
Phase-2 embedded client chat (metered API)GATED — on 3+ live brains + telemetry

9 · Positions taken

Where the advisor disagreed, and what stands

10 · Questions for the reviewer

Where outside pattern-matching beats inside conviction

Round 1 outcome — 5 Sep

Reviewer confirmed: physical tenant isolation, vendor-risk posture, and the bus-factor bar ("Fatima restarts APEX without calling Stefan" — now a binary phase gate alongside the adversarial isolation test and handoff one-pager). Product-wedge question answered: stay inside delivery until 10 clients run the system — the platform emerges from real usage pain. Still open below: fleet ops at 50+, phase-2 pricing model, vendor de-risk timing.