Skip to content

Platform-Agents Architecture — Vercel / per-client posture

Platform-Agents Architecture — Vercel / per-client posture

Section titled “Platform-Agents Architecture — Vercel / per-client posture”

Status: DECIDED. This spec is the ratified platform-agents architecture, authored under ID-71 {71.26} (S458) and promoted to reference/ (S491) — the spec dir keeps a pointer stub. It supersedes the open decision surface in specs/id-71-ai-tooling/research-inputs/vercel-async-worker-architecture.md §4 (the five owner-ratification questions Q1–Q5) and encodes the closure ratified in the S456 batch — decision-register entries DR-042..DR-046 — plus the S456 lifecycle addendum in reference/arch-assessment-compute-posture-s456.md (§A/§B/§C/§D/§E/§I/§J + delta table). The research doc stays unchanged as provenance — it is a research input (RESEARCH genre: “proposes, does not decide”), and this sibling doc is where the decisions live. Exactly one owner question remains open, modelled but not decided here: OQ-71.26-COST (the per-tenant Vercel cost ceiling). British English throughout; DD/MM/YYYY dates.

Citation discipline. Cross-cutting rulings are cited by DR-NNN id and by arch-assessment section (§A..§J, “delta”); the decision register (reference/decision-register.md) and the assessment are canonical and are not restated verbatim here. This spec composes those rulings into one architecture and adds only the cost model (§6).


1. Closure map — research §4 Q1–Q5 → ratified rulings

Section titled “1. Closure map — research §4 Q1–Q5 → ratified rulings”

The research doc posed five owner rulings in its §4. Four are now settled; one is the residue modelled in §6. This table is the load-bearing 1:1 mapping — every downstream section below elaborates one or more rows.

Research §4 questionDispositionRatified by
Q1 — Vendor lock-in posture (thin-and-swappable vs eve-all-in)Settled — thin-and-swappable. AI-tooling posture is a per-client choice behind our own thin interface; lock-in is bounded, the choice swappable. First client is cloud-native; the goose pilot still completes.DR-044 (arch §A/§D)
Q2 — Client-data egress vs the zero-egress discipline + DR-017 (the crux)Settled as a definition, not a fork. “Zero-egress” = no client data at rest in shared multi-tenant third-party infra + no non-essential egress (terms-protected model/transit is the bounded accepted exception); the app/pipeline compute split holds; agent topology is data-plane-per-client / control-plane-central.DR-043 (egress definition, arch §B) + DR-042 (compute posture, arch §A) + DR-045 (agent topology, arch §E)
Q3 — Cost ceiling + per-tenant multiplicationRESIDUE — modelled, not decided. The frame is settled (per-tenant modelling, per-client Vercel projects); no ratified ceiling number exists. Modelled in §6.OQ-71.26-COST (§6 of this spec)
Q4 — Timeline coupling to the id-13* spec chainSettled — the (c)-shaped split, unified. Not option (b) “pivot to eve now”: the goose pilot completes to G6 on the DR-017 per-client topology; the first client is cloud-native; app-side and per-client fleets unify under the one DR-044 per-client interface (not two divergent tracks).arch OQ-2 ruling (delta row 7) + DR-017 + DR-044
Q5 — Where the boundary sits for pipeline orchestrationSettled — orchestrate-only. Pipeline ingress is control-plane only; push-shaped inlets terminate app/bucket-side, connectors are outbound-pull, and the source-binding register derives each binding’s per-binding egress-host allowlist.DR-046 (arch §C/§G/§H, delta rows 3/8)

Reading. The research doc’s sharpest framing — “a Vercel-hosted eve fleet is multi-tenant Vercel infra, the inverse of DR-017” (VR §2, §4 Q2) — dissolves under the ratified model: per-client Vercel projects are the topology (arch §E), so a per-client eve/Workflows fleet in the client’s own Vercel project is per-client-isolated, not multi-tenant. The only surviving fork is “client VPS vs client’s own Vercel project” for a data-plane agent — and both are per-client, both honour the DR-017 boundary. That is Q1’s per-client-choice (DR-044), not an isolation compromise.


2. Compute posture and the egress boundary

Section titled “2. Compute posture and the egress boundary”

Ruling: DR-042 (compute posture) + DR-043 (egress definition).

  • The pipeline stays on-prem (data-adjacent, compute-heavy, single-tenant — IONOS/Coolify VPS, writing the client’s own single-tenant Supabase project); the Next.js app stays on Vercel as a per-client Vercel project (stateless, public-by-design, no client data at rest — the tenant boundary is the Supabase project, not the app server). App-on-VPS and self-hosted-Supabase are per-client contractual options, not defaults (arch §A). “On-prem” is a property of where data lives and is processed; fronting ingress with Cloudflare does not change it (DR-046, arch §C).
  • The egress bright line is at-rest-in-multi-tenant (DR-043). Client document content already leaves the box today under the on-prem design — extraction/embedding calls Anthropic (no-train/ZDR terms), and client data sits at rest in single-tenant Supabase. Those are the two accepted, contracted data processors; the honest test for any new dependency (Vercel included) is “does it add a new third party, and at rest or only in transit?” (arch §B).
  • Consequence for the agent layer: a per-client Vercel project is a new transit path, not a new at-rest-in-multi-tenant store, provided the orchestrate-only discipline (DR-046, §Q5 of the closure map) holds — Vercel Workflows/Queues persist step inputs/outputs, so any step that handles client records would breach the bright line; steps must trade in pointers/IDs, never records.

Note (not a decision here): Vercel Secure Compute is AWS-shaped and Enterprise-only, so it does not apply to IONOS boxes as a private-networking control; the Vercel Static-IP allowlist ($100/mo/project, Pro self-serve) is the ratified origin-terminated escape hatch for private ingress (DR-046, arch §F). This matters to the cost model (§6): the cloud track can stay on Pro and avoid Enterprise entirely.


3. Per-client agent topology and the posture choice

Section titled “3. Per-client agent topology and the posture choice”

Ruling: DR-045 (topology) + DR-044 (posture choice).

3.1 Data plane per-client, control plane central (DR-045)

Section titled “3.1 Data plane per-client, control plane central (DR-045)”

Every agent type runs inside the client’s own isolation boundary — the client VPS or the client’s own Vercel project — with a per-client service-actor, generalising DR-017 from goose to all data-plane agents. The Platform control/observability plane is central and trades in telemetry only (run status, tokens, timings, health — never client corpus content). Every client gets all agent types; each client’s instances run in that client’s boundary. The central plane gives one cross-client view without any client content crossing into Platform, because it carries metadata, not data (arch §E). The observability plane that realises this is §5.

3.2 Posture is a per-client choice behind a thin interface (DR-044)

Section titled “3.2 Posture is a per-client choice behind a thin interface (DR-044)”

Each client chooses one of two postures, kept behind our own thin swappable interface so the choice is reversible and lock-in bounded (this is Q1’s answer):

PostureWhere the agent runsTooling substrateIngress to the VPS pipeline
Cloud track (first client — cloud-native)The client’s own Vercel projectVercel Workflows / AI Gateway / Queues / (Sandbox if ever needed), behind our interfaceCloudflare Tunnel default; Static-IP allowlist (Pro) if origin-terminated required (DR-046)
Strict on-premThe client VPSLocal-equivalent stack: pgmq (Queues) · LiteLLM (AI Gateway) · Nango (Connect) · goose (agent runtime); durable-workflow execution is the one real local gap (Temporal/Inngest — real ops on a 4 GB box)Loopback / no public reach for scheduled work; DR-046 posture

The local stack is feasible for four of six Vercel primitives (Queues → have it via pgmq; Gateway → LiteLLM; Connect → Nango; runtime → goose), Sandbox is far but unneeded near-term, and durable-workflow execution is the single genuine gap (arch §D). The thin interface is what makes one proven agent artefact promotable to either target (§4).


4. Platform-agents lifecycle — prove → pin → promote

Section titled “4. Platform-agents lifecycle — prove → pin → promote”

Ruling: DR-045 (lifecycle clause) + arch-assessment §J (owner-confirmed with three refinements).

The lifecycle is not a new mechanism — it generalises the already-ratified runbooks/platform-to-client-promote.md pattern (prove-on-Platform → release-pin → per-client config-delta promote) from the pipeline image to the agent layer.

  1. Prove on Platform — client-zero, on Platform data only. Agents are built and tested against the Platform’s own Supabase project and corpus, never a client’s. The Platform Vercel project is a true tenant in the per-client topology, not a shared cross-tenant runtime that peeks across tenants (arch §J refinement 1).
  2. Release-pin. A proven agent version is cut to an immutable release pin, exactly as the pipeline vX.Y.Z pins work today.
  3. Per-client config-delta promote — release-pinned per client, never fleet-push. The proven pin is offered to each client on that client’s own schedule; there is an append-only per-client release-pin history. Per-client deltas are minted fresh — service-actor credentials, DB refs, AI Gateway keys — the same shape as the runbook’s env re-key (arch §J refinement 2).
  4. Propagation target differs by posture (DR-044). For a cloud-track client the target is that client’s own Vercel project (the first client is cloud-native); for a strict-on-prem client the target is the local stack on their VPS. The thin swappable interface (§3.2) is precisely what makes one proven artefact promotable to either (arch §J refinement 3).

The goose pilot is this model already in motion (see §7): pilot on Server B, staging-pointed, gates G0–G6, then per-client rollout on the DR-017 topology.


5. Observability plane — the central, telemetry-only view

Section titled “5. Observability plane — the central, telemetry-only view”

Ruling: DR-045 + arch-assessment §I (rec-4 concrete recommendation). No single tool is the plane. It is a two-leg hybrid, both legs telemetry-only, with Raindrop explicitly excluded (local dev / CI eval-authoring only — never a hosted runtime plane; arch §I.3, DA §8).

5.1 Leg 1 — Vercel AI Gateway, team scope (the model-telemetry leg, cloud track)

Section titled “5.1 Leg 1 — Vercel AI Gateway, team scope (the model-telemetry leg, cloud track)”

The Gateway’s observability is team-scoped with per-project + per-API-key drill-down (request count, tokens, P75 duration/TTFT, cost) with exportable request logs. Because every per-client Vercel project lives in the single Platform Vercel team, the team-level dashboard is the per-client rollup — per-client projects give per-client rows for free, per-API-key summaries give per-agent breakdown within a client, and none of it carries corpus content. Adopting the Gateway for cloud-track clients is what creates this leg (advances research OQ-4 / main-paper OQ-4 toward “adopt”, matching the owner lean). Caveats (all load-bearing):

  • Covers only requests routed through the Gateway — strict-on-prem clients never touch it.
  • Team-wide ZDR is $0.10/1K requests (per-request only filter is free).
  • BYOK keys are skipped by default under ZDR unless individually marked ZDR-compliant — material because the platform BYO-keys Anthropic today (arch §B).
  • The rollup depends on client projects staying in the Platform Vercel team (see §5.3).

5.2 Leg 2 — Platform-DB agent_runs-shaped telemetry rollup (the system of record)

Section titled “5.2 Leg 2 — Platform-DB agent_runs-shaped telemetry rollup (the system of record)”

The system of record generalises the proven pipeline_runs pattern — the pipeline POSTs /api/internal/pipeline-runs/recordpipeline_runs rows → the datapath-watch monitor (platform-to-client-promote.md §2.2–2.3 uses it as the promote gate). Generalise it to an agent_runs-shaped feed: every data-plane runtime — on-prem goose, local-stack (LiteLLM spend logs), pipeline walks, and cloud agents alike — posts run status, tokens, timings, error class to the Platform DB, NEVER client corpus content. This is the only leg that covers strict-on-prem clients and the only one the platform owns end-to-end; the Gateway dashboard is the richer live view for the cloud track, the DB rollup is the durable system of record.

The proven pattern this generalises is code-true and indexed (gitnexus, canonical, 10/07/2026): the row shape PipelineRunRow (lib/query/fetchers.ts:184-217) and PipelineRunResult (lib/intelligence/types.ts:73-83); the run-start startPipelineRun (lib/pipeline/start-run.ts:95-174); the read/monitor surfaces PipelineRunsPanel (components/intelligence/pipeline-runs-panel.tsx:30-179) and HealthPanel / sanitisePipelineMessage (components/intelligence/health-panel.tsx). This spec mandates no modification of these symbols — the agent_runs generalisation is a deferred build whose schema ownership (ID-138 register-adjacent vs id-71 agent-layer) is an open orchestrator call (arch addendum OQ-3), recorded in §8. The symbols are cited only to anchor the pattern as real.

5.3 Standing assumption (record explicitly)

Section titled “5.3 Standing assumption (record explicitly)”

The Gateway leg (5.1) assumes client projects remain in the Platform Vercel team. A future client who demands their own Vercel account drops to leg 2 only (the DB rollup) — acceptable, but an explicit standing assumption of this architecture, not an accident (arch addendum OQ-1).


6. OQ-71.26-COST: awaiting owner sign-off — per-tenant cost-ceiling model

Section titled “6. OQ-71.26-COST: awaiting owner sign-off — per-tenant cost-ceiling model”

This is the one residue. The frame is settled (per-tenant modelling; each client a Vercel project; ZDR and Secure Compute multiply per tenant). No ratified ceiling number exists. This section models the per-tenant cost across posture options and recommends a ceiling per posture — it does not decide. Owner sign-off closes it.

6.1 Sourced unit prices (research provenance, checked 07/07/2026; arch re-check 09/07/2026)

Section titled “6.1 Sourced unit prices (research provenance, checked 07/07/2026; arch re-check 09/07/2026)”

All prices below are from the research doc §1.2–1.6 / §2 and the arch-assessment §B/§F. They are sourced; the volumes applied to them in §6.3 are not (see §6.2).

Cost componentUnit priceNotes
Vercel Pro (per project)$20/mo, includes $20 usage creditThe per-tenant floor; usage (Functions/Workflows/Queues/Sandbox) draws down the credit first
Workflows — Events$0.02/1K events50K/mo free on Hobby only, not Pro
Workflows — Data Written$0.50/GBSmall under orchestrate-only discipline (pointers, not records — §2)
Workflows — Data Retained$0.50/GB-monthPro retention 7d post-completion; small if payloads are pointer-shaped
Workflows — step computeVercel Functions / Fluid ratesAbsorbed into the $20 credit at pilot scale
Queues~$0.60/1M ops (4 KiB chunks)pgmq is the strict-on-prem baseline (bundled in the client’s own Supabase — $0 incremental)
Sandbox$0.128/vCPU-hr active + $0.0212/GB-hr memoryOnly for code-execution agents — no current need; model as $0 near-term
AI Gateway — model spendZero markup (provider list price) + $5/mo team creditNot a Vercel-added cost — equals the Anthropic token cost the platform already pays; the $5 credit is team-scoped, not per-project
AI Gateway — ZDRTeam-wide $0.10/1K requests (Pro and Enterprise); per-request only filter freeBYOK skipped by default under ZDR (§5.1)
Static-IP allowlist$100/mo per project (Pro self-serve)Origin-terminated ingress escape hatch (DR-046); only when a client contractually requires no third party seeing ingress cleartext
Secure ComputeEnterprise-only; not publicly pricedAWS-shaped private networking — does not apply to IONOS; the Static-IP allowlist replaces its role for the cloud track, so Enterprise is avoidable

6.2 Assumptions — stated explicitly (these are NOT sourced)

Section titled “6.2 Assumptions — stated explicitly (these are NOT sourced)”
  • Frame: per-tenant, each client one Vercel project. The first client is cloud-native (arch delta row 7). The model is per-tenant; the platform-wide bill is × N clients.
  • Volumes are illustrative bands, not measured — the goose pilot has zero AI spend yet (VR §2), so there is no production request/event history to source from. Where a number below is unknown it is labelled and given a bounded range; do not treat any band as a measured figure.
    • Model requests / tenant / month: pilot ~1K–10K · early ~10K–100K · scaled ~100K–1M. (Drives ZDR and any Gateway-metered cost.)
    • Workflow events / tenant / month: ≈ agent-runs × steps/run. Pilot ~10K–50K · early ~50K–500K. (Unknown; bounded.)
    • Workflow Data Written/Retained / tenant / month: small by design — orchestrate-only keeps payloads pointer-shaped (§2); assume ≤ 1–2 GB/mo. If a step ever handled records this would breach DR-046, not merely cost more.
    • Queue ops / tenant / month: pilot ~≤ 1M (≈ $0.60). Negligible at modelled scale.
  • Postures modelled: (a) cloud track on Pro, Cloudflare-Tunnel ingress; (b) cloud track on Pro + Static-IP origin-terminated ingress; (c) strict on-prem. Enterprise is modelled only to show it is avoidable (§6.1 Secure Compute row).

6.3 Per-tenant monthly estimate by posture

Section titled “6.3 Per-tenant monthly estimate by posture”

Bands reflect the §6.2 volume ranges; the floor is the $20 Pro base, which the usage credit largely absorbs at pilot scale.

Component (per tenant / month)(a) Cloud, Pro, CF-Tunnel(b) Cloud, Pro + Static-IP(c) Strict on-prem
Vercel Pro base$20 (incl. $20 credit)$20— (no Vercel project)
Workflows events + data (orchestrate-only)~$1–5 (mostly absorbed by credit)~$1–5— (local durable-exec gap — Temporal/Inngest, ops, not Vercel $)
Queues< $1 (or $0 via pgmq)< $1$0 (pgmq in client Supabase)
Sandbox$0 (no current need)$0$0
AI Gateway ZDR ($0.10/1K req)~$1 (pilot) → $10 (early) → **$100 (scaled, 1M req)**same bandn/a (LiteLLM local; no Gateway)
AI Gateway model spend (pass-through)= existing Anthropic cost (not Vercel-added)same= existing Anthropic cost (Anthropic direct)
Static-IP allowlist$0 (CF-Tunnel)+$100$0
Vercel-attributable per-tenant total~$22–35 (pilot→early) rising with ZDR at scale~$122–135 (pilot→early)~$0 incremental

Strict-on-prem (c) is ~$0 incremental Vercel spend — its real cost is VPS headroom (the 4 GB Server B is the constraint to watch) and one-time ops to stand up LiteLLM + Nango + pgmq (+ optionally Temporal/Inngest for the durable-execution gap). Model spend still flows to Anthropic directly (pass-through, same as the cloud track).

Section titled “6.4 Recommended per-tenant ceilings (rationale, not a ruling)”
  • (a) Cloud track, Cloudflare-Tunnel ingress: recommend a ceiling of $20 fixed + a metered variable band, provisionally ~$50/mo/tenant at pilot→early scale (covers Pro + generous usage headroom + ZDR). The AI Gateway ZDR line is the one that scales ($0.10/1K → ~$100/mo at 1M requests), so the ceiling should be reviewed when a tenant crosses ~100K model requests/month, not set flat.
  • (b) Cloud track + origin-terminated ingress: +$100/mo Static-IP → provisionally ~$150/mo/tenant. Only for a client with the contractual “no third party sees cleartext” requirement (DR-046) — most cloud-track clients stay on (a).
  • (c) Strict on-prem: ~$0/mo incremental Vercel; the ceiling is VPS sizing + a one-time durable-execution-engine ops cost, not a recurring Vercel bill.

Key finding for sign-off: the cloud track can stay on Pro and avoid Enterprise entirely — ZDR is Pro-available and the Static-IP allowlist replaces Secure Compute’s private-networking role for IONOS (§6.1). That removes the largest unbounded cost risk the research doc flagged (Enterprise pricing is not public). Uncertainty that remains and blocks a hard number: the per-tenant request/event volumes (§6.2) are unmeasured until the goose pilot produces AI spend; the ceilings above are bounded estimates on sourced unit prices, not measured figures.


7. The goose pilot’s place in this architecture

Section titled “7. The goose pilot’s place in this architecture”

The goose pilot (id-71 G0–G6) is this model already in motion, not a thing to be replaced by the ratified architecture:

  • It runs on Server B, staging-pointed, through gates G0–G6, then per-client rollout on the DR-017 topology (per-client container on the client’s own VPS, per-client recipe + service-actor).
  • It is the strict-on-prem posture’s agent runtime already (§3.2) and the prove → pin → promote lifecycle already exercised (§4).
  • Q4’s timeline ruling (closure map) is therefore not “pivot the pilot to eve now”: the pilot completes on the current topology, the first client is cloud-native, and the two do not diverge because the DR-044 thin interface unifies them — app-side and per-client fleets are one interface with two propagation targets, not two competing tracks. eve is re-evaluated at its GA as one possible backing for the cloud-track side of that interface — a swap behind the interface, never a re-litigation of topology.

Supersedes: specs/id-71-ai-tooling/research-inputs/vercel-async-worker-architecture.md §4 (Q1–Q5 open surface). The research doc remains unchanged as a research input / provenance (its §1 capability survey, §2 platform-fit, §3 alternatives table, and §1.2–1.6/§2 pricing data — checked 07/07/2026 — are this spec’s sources).

Ratified rulings (decision register — cited, not restated):

  • DR-042 — compute posture: pipeline on-prem, app on Vercel; on-prem = residence + processing.
  • DR-043 — “zero-egress” = no client data at rest in shared multi-tenant infra + no non-essential egress; terms-protected model/transit is the bounded accepted exception.
  • DR-044 — AI-tooling posture is a per-client choice behind a thin swappable interface (cloud in the client’s own Vercel project / local-equivalent stack on the client VPS); first client cloud-native; goose pilot completes.
  • DR-045 — agent topology: data-plane per-client, control-plane central telemetry-only; the two-leg observability hybrid; prove-on-Platform → release-pin → per-client config-delta promote.
  • DR-046 — pipeline private ingress (Cloudflare Tunnel default, Static-IP escape hatch) and the ingress-is-control-plane-only invariant (push inlets terminate app/bucket-side; connectors are outbound-pull; per-binding egress-host allowlist).
  • DR-017 — goose per-client topology (generalised to all data-plane agents by DR-045).

Assessment anchor: reference/arch-assessment-compute-posture-s456.md — §A (compute posture), §B (egress per option / what ZDR + Secure Compute cover), §C (Cloudflare-still-on-prem), §D (local-equivalent feasibility), §E (per-client vs central topology), §F (the {127.20} ingress ruling), §I (observability plane — two-leg hybrid), §J (platform-agents lifecycle), and the “What changed vs the main paper (delta)” table (rows 3/5/6/7/8 in particular).

Runbook anchor: runbooks/platform-to-client-promote.md (§2.2–2.3, §4) — the prove → pin → config-delta promote pattern this architecture generalises from the pipeline image to the agent layer; the per-client release-pin history (per-client-release-pins.md).

Code anchor (pattern only — no modification mandated; gitnexus canonical, 10/07/2026): PipelineRunRow (lib/query/fetchers.ts:184-217), PipelineRunResult (lib/intelligence/types.ts:73-83), startPipelineRun (lib/pipeline/start-run.ts:95-174), PipelineRunsPanel (components/intelligence/pipeline-runs-panel.tsx:30-179), HealthPanel / sanitisePipelineMessage (components/intelligence/health-panel.tsx).

Open questions carried out of this spec (owner / orchestrator):

  1. OQ-71.26-COST (§6) — the per-tenant Vercel cost ceiling. Modelled here on sourced unit prices + bounded, unmeasured volume bands; awaiting owner sign-off. Blocked on real pilot AI-spend volumes.
  2. Vercel team residency as a standing assumption (§5.3, arch addendum OQ-1) — the Gateway telemetry leg assumes client projects stay in the Platform Vercel team; a client demanding their own Vercel account drops to leg 2 only. Recorded, not blocking.
  3. agent_runs telemetry schema ownership (§5.2, arch addendum OQ-3) — whether the generalised rollup is specced in ID-138 (register-adjacent) or id-71 (agent-layer) is a small orchestrator call, not an architecture decision; named here so it is not dropped.