TFD-0030: Hosting model for always-on factory agents
TFD-0030: Hosting model for always-on factory agents
Date: 2026-06-02 Status: Accepted Author: Infrastructure Engineer Scope: infrastructure
Context
The factory increasingly needs always-on, unattended agents rather than just interactive single-user Claude Code sessions. The immediate drivers are two planned chats:
- a customer-intake chat that guides new client requests, and
- an improvement-intake chat that captures CI / enhancement ideas.
Two forces made this a real decision rather than an ad-hoc choice:
- The personal machine is becoming a server. The SER8 (AZW SER8, Ryzen 7 8745HS, 32 GB, Radeon 780M) is the interactive workhorse per the persistent-environment runbook. Running always-on, customer-facing services on it ties up the daily driver and degrades reliability — the CEO described "devolving on my personal computer."
- ToS boundary. The prior runbook verdict ("no VPS needed") was scoped to interactive, single-user use on the Max subscription. Automated / customer-facing agents (the June 15 2026 Claude Code change re:
claude -p/ Agent SDK) fall outside ordinary individual use and require a Claude API key (pay-per-token) — regardless of where they are hosted.
This recurs every time the factory wants to stand up an always-on agent, so it warrants a reusable answer. Related: the factory already shipped the reusable serverless chatbot pattern in REQ-CONS-015 (jct-site-chatbot: widget.js + build-kb.js + Cloudflare Worker, live on jct-transgesco), and the persistent-environment model in departments/engineering/infrastructure-engineer-ivan/runbooks/persistent-claude-code-vps.md.
Decision
Split always-on agents into two layers, hosted differently:
- Customer-facing and unattended chat services → serverless (Cloudflare Workers + Claude API). The customer-intake and improvement-intake chats are built as Cloudflare Workers reusing the existing
jct-site-chatbotpattern. They authenticate with a Claude API key, never the Max subscription. This is the default home for any new always-on, public, or automated agent. - Persistent interactive Claude Code worker → SER8 by default; a small VPS only if isolation from the personal machine is explicitly wanted. A VPS (pick: OVH Beauharnois, QC, ~CA$9/mo, Québec data residency) is reserved for hosting an always-on interactive Claude Code brain + light glue services. It is CPU-only (2–4 GB) and explicitly does not solve local-model/GPU workloads (e.g. Echo transcription speed).
Rule of thumb: if it faces customers or runs unattended, it goes serverless with an API key; it does not live on the personal machine, and a VPS is not the default.
Alternatives Considered
VPS for everything (provision a box, run all agents there via tmux)
A single OVH/Hetzner VPS hosting the chats and any always-on Claude Code. Rejected as the default: a VPS for public chat services means we own uptime, patching, and security for a customer-facing endpoint, where Cloudflare Workers give the same result with no server to maintain and a free tier. The VPS is also CPU-only and small (2–4 GB ≪ the SER8's 32 GB), so it buys neither power nor GPU. Kept as an optional layer for an interactive worker only.
Keep running everything on the SER8 / personal machine
Status quo. Rejected: turns the daily-driver machine into a customer-facing server, the exact "devolving" problem; no isolation, no resilience to the machine being busy/off, and it cannot legitimately run automated customer-facing agents on the Max subscription anyway.
Serverless for the chats (chosen) + optional VPS for the interactive brain
Selected. Matches each workload to the right substrate, reuses an already-shipped pattern, keeps the personal machine clean, and respects the subscription-vs-API-key ToS line.
Consequences
Positive
- Customer-facing chats get a zero-maintenance, scalable home (CF Workers) already proven in the codebase (
jct-site-chatbot). - The SER8 stops accreting always-on services; it stays the interactive workhorse.
- Clear, reusable rule for future always-on agents — no re-litigating per agent.
- Québec data-residency option preserved (OVH Beauharnois) if a VPS is ever stood up.
Negative
- A Claude API key (pay-per-token) is now required for the intake chats — a new, usage-scaling cost line separate from the Max subscription, plus key management/secrets handling.
- Serverless chats send data to the Claude API (and CF) — acceptable for factory intake, but means these are not "local/private," unlike the local-model client product line.
- Two hosting substrates to understand (serverless vs VPS) instead of one.
Neutral
- Does not address Echo / local-model GPU latency — that remains a hardware question (CUDA GPU or hosted Whisper API), tracked separately in JCT-20.
- A VPS remains an open option, not a commitment; this TFD only declares it is not the default home for the chats.