for platform teams

Runs on your laptop. Ships to your cluster.

Same .vinos/routines.yaml runs on the engineer's MacBook and on your Kubernetes cluster via ghcr.io/vinpatel/vinos-cloud (v2.1). Systemd timers on the box, CronJobs in the cluster. One spec, two runtimes.

Three outcomes when the same spec targets both runtimes.

Portability, symmetry, cost. Laptop-first for iteration, cluster for the always-on runtime — with no two-tool split-brain.

Portable spec — yaml → CronJob.

vinos-routine export --k8s will emit a K8s CronJob per routine — schedules translated, secrets referenced, state bound to a PVC. The .vinos/routines.yaml spec ships today (v2.0.5); the exporter + Helm chart land in v2.1.

vinos-routine export --k8s · coming v2.1

Same runtime, laptop or cloud.

Python + bash + SQLite + optional Ollama HTTP client. The Docker image is the same binary as the laptop package — minus Hyprland and friends.

ghcr.io/vinpatel/vinos-cloud:2.1 · ~200 MB

$5/mo Hetzner runs your agents 24/7.

When the laptop sleeps, cluster or VPS picks up the schedule. State converges through the shared ledger.

helm install vinos vinos/agents · v2.1

The proof — one spec, two manifests.

Left: what your engineer commits. Right: what the exporter emits for your cluster.

.vinos/routines.yaml yaml
apiVersion: vinos.computer/v1
kind: RoutineSet
metadata:
  project: startup-inc

defaults:
  agent:
    route: auto
    model: llama3.1:8b
    escalate_to: claude-sonnet-4-6
  budget:
    max_dollars_per_day: 0.50
    on_exceed: skip

routines:
  - name: pr-review
    schedule:
      oncalendar: "*-*-* 09,13,17:00:00"
      timezone: America/New_York
k8s/pr-review-cronjob.yaml · generated yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: pr-review
  namespace: vinos-agents
spec:
  schedule: "0 9,13,17 * * *"   # from oncalendar
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: routine
              image: ghcr.io/vinpatel/vinos-cloud:2.1
              args: ["run", "pr-review"]
              envFrom:
                - secretRef: { name: vinos-api-keys }
              volumeMounts:
                - { name: state, mountPath: /var/lib/vinos }
          volumes:
            - name: state
              persistentVolumeClaim: { claimName: vinos-ledger }

Cloud runtime and Helm chart target v2.1 — see the roadmap. Today the exporter emits CronJob YAML; the Helm chart, PVC scheme, and Secret conventions are specced in that doc.

Questions platform teams ask.

Helm chart?
Targeted for v2.1 — helm install vinos-agents vinos/agents. Design intent: one CronJob per routine, one PVC for the shared ledger, one Secret for API keys, one optional Deployment for a cluster-local Ollama sidecar. Chart values will mirror RoutineSet defaults. Not yet published — see the v2.1 roadmap for shipping trigger.
Where does state live in the cluster?
A single PVC mounted at /var/lib/vinos across all CronJob pods (RWX StorageClass required for cluster-wide shared ledger; RWO with a per-routine subdirectory works for isolated runs). Ledger is SQLite; concurrent writes serialized by WAL mode plus a routine-name advisory lock.
Secrets management?
API keys live in a K8s Secret (vinos-api-keys by default), mounted via envFrom. External Secrets Operator, sealed-secrets, SOPS — all work; the container only needs the env vars at run time. Key names match the laptop config (ANTHROPIC_API_KEY, OPENAI_API_KEY).
Multi-tenant?
v2.2. One shared Ollama, per-repo RoutineSets, per-tenant API keys, per-tenant budget caps, tenant-scoped ledger view. Aimed at internal-platform teams running agents for multiple product teams on one pool. Today: one namespace per tenant works as a stopgap.
Observability?
SQLite ledger today — vinos-ledger tail streams events, and vinos-ledger export --prometheus is planned to emit a scrape-friendly text format. OpenTelemetry traces per routine run are on the v2.2 wishlist; happy to prioritize if a sponsor asks for it.
GPU nodes for local Ollama?
Optional. If you deploy the Ollama sidecar with the NVIDIA device plugin, the routine runtime uses the cluster's GPU for the local route. If not, all routines fall back to escalate_to — cost caps still enforced.

Try it on your laptop first.

Same spec ships to the cluster in v2.1. Start local, migrate when the runtime lands.

Uninstall: pacman -Rns vinos-*. No lock-in. MIT-licensed.