Prevu — Design Philosophy
This file captures the beliefs that drive every decision in Prevu — the why behind the rules in AGENTS.md and the positioning in docs/product-positioning.md. When in doubt about a feature, an architecture call, or a UI choice, this is the lens.
It is short on purpose. Anything that isn't in this file isn't load-bearing enough to override case-by-case judgment.
What Prevu is
Prevu is the staging and review layer for coding agents.
Not a developer cloud. Not a hosting platform. Not deploy-inference magic. One narrow, sharp slice of the agent loop:
agent changes code → project runs in staging → human reviews → agent iterates
A reusable VM-backed environment is the substrate. The product is the flow.
Foundational beliefs
These are the bets we're making about the world. If they turn out to be wrong, the product needs to change shape. If they're right, every other decision falls out of them.
1. Coding agents need a real place to run
A diff is not a product. A unit-test pass is not a product. The thing a human can review is the project actually running. Until that running result is in front of the human, the agent's loop is blocked. We exist to unblock it.
2. The agent owns deployment, we own the environment
Real projects are messy: framework quirks, private dependencies, undocumented build steps, half-broken migrations. We will never out-guess the agent on how this specific project should run. So we don't try. We give the agent a real Linux VM with Docker and the agent runs whatever it needs to run. We provide the substrate, the access, the bindings, the review surface — never the heuristic that pretends to know the project.
3. The environment is a purchased workspace, not an ephemeral session
A VM with PVC-backed storage that the user paid for is theirs until they explicitly destroy it. Idle handling is pause (stop compute, keep disk). Auto-destroy on TTL or quota is a reflex from CI/preview-deploy land that does not apply here. Workspace state — git checkouts, Docker volumes, scratch files, debug history — is part of what the user is buying.
4. Stable, copy-pasteable surfaces beat clever UX
Both humans and agents read the dashboard. An agent that screenshots the page and reasons over the DOM has to see the same authoritative text as the human. A green dot is not a status. status: ready is. Every command, slug, URL, and SSH line in the UI should be selectable and copyable in one motion. UI text and API JSON say the same words.
Product principles
In tension with each other on purpose. Use judgment when they conflict.
-
Review over hosting. Optimize for getting work in front of a human. Don't optimize for running something forever. If a feature makes long-running cheaper but reviewing slower, it's the wrong feature.
-
Environment over inference. Provide a real place. Don't promise to figure out the project. If a "framework detector" creeps in, it has to fail loudly and hand off to the agent — never silently guess.
-
Agent outside, Prevu around. Prevu does not host the agent. Not in the control plane, not in user VMs. The agent operates Prevu through stable, equivalent surfaces: MCP, CLI, REST API, dashboard. All four show the same data.
-
Private by default, shareable when ready. A binding doesn't exist until the agent or user creates it. URLs aren't public until someone says so. The default is "no leak."
-
Reusable by default, resettable when needed. One VM hosts many tasks, branches, and sessions over time. Resetting workspace state, cleaning bindings, pausing compute, and destroying the VM are all explicit, named, idempotent operations.
-
Small, sharp, understandable. Every additional feature is a tax on the product's definition. We win by making one workflow feel obvious and reliable, not by covering more surface than the next platform.
Hard invariants
These are not principles. They are rules. A change that violates one of these is wrong, full stop, even if the local tradeoff looks good.
- VMs never auto-destroy. Idle = pause. The only thing that destroys a VM is an explicit user action.
- No agent runs inside Prevu. Not in the control plane. Not in the user VM. We are the surface, not the operator.
- Two-domain split.
app.prevu.cloudis the dashboard.*.prevu.pageis per-environment URL space. They have separate TLS, separate cookies, separate purposes. Don't put dashboard pages onprevu.page. Don't put environment URLs onprevu.cloud. - All SSH goes through the sshpiper gateway. Per-env SSH services are
ClusterIPonly. The user never gets a per-env public IP. - Slug is the single identity.
<slug>is the user-typed name, the DB key, the K8s resource-name suffix, and the public URL prefix — all the same string. No hashes, no internal IDs leaking into URLs. Globally unique by construction. - Multi-tenant from day one. Every API/SQL query filters by
owner_id. Cross-tenant bleed is a bug class we never accept, even in dev.
When one of these has to bend (very rarely), it changes here first, with a written reason. Never silently in code.
How we build
Engineering ethos that flows directly from the above.
Agents are first-class readers
Every UI principle in AGENTS.md exists because an agent must be able to operate the product as well as a human. Semantic HTML always. Icons paired with text. URLs reflect state (every page state is a GET). Server-render the truth so a curl returns meaningful HTML, not a JS-loading skeleton. API key names match UI labels — paused in JSON, paused on screen, never 💤 Sleeping.
Information density over decoration
This is a tool, not a marketing page. Whitespace serves grouping, not aesthetics. The reference points are Linear, Datadog, Cloudflare. Not Stripe homepage. No animation on critical paths — page transitions, action feedback, and status changes must be instantaneous. A spinner is fine. A 400ms slide-in that hides content is not.
Build for the case that exists, not the one that might
No premature abstractions. No backward-compat shims for code that hasn't shipped to anyone. No feature flags for features no one has asked for. Three similar lines is better than a wrong abstraction. Pre-launch we can break anything we want; post-launch we change the philosophy file first.
Comments default to none
Code is the truth. Add a one-line comment only when the why is non-obvious — a hidden constraint, a workaround for a specific bug, a surprising invariant. Never narrate what the code already says.
One source of truth per concept
Slug is the identity. lib/env-service.ts is where environment lifecycle lives — both REST routes and Server Actions go through it. i18n/en.json owns visible text. packages/shared/src/slug.ts owns slug rules. When you find a concept defined in two places, that's a defect to fix, not a tradeoff to balance.
Shared substrate, equivalent surfaces
MCP, CLI, REST API, and dashboard are four views of the same operations. Adding an operation means adding it to all four (or having a clear reason it belongs in only one). The agent should never need to use a different surface to access a different capability.
What we are not
Saying no is half the work. These are positions we hold against pressure to expand.
- Not a developer cloud. "Cloud for agents," "developer cloud," "agent OS," "infrastructure primitive" — none of these are us.
- Not production hosting. No SLA on long-running user services. No managed databases. No backups (yet). Staging is the product.
- Not auto-deploy. We don't read your
package.jsonand decide. The agent decides. - Not a marketplace. No third-party services running in the user's VM that we maintain.
- Not a CI/CD replacement. CI validates and ships. We let humans see and react.
- Not a generic VM rental. The VM is the implementation; the workflow is the product. Users should think "my agent's work is now somewhere I can review," not "I rented a computer."
How to use this file
When you're about to make a non-trivial decision — schema change, new endpoint, UI restructure, pricing model, integration — read the relevant section here first. If your change is consistent with the philosophy, ship it. If it conflicts, you have two options: change the change, or change the philosophy (in a PR, with a written reason, before any code).
Philosophy drift is the most expensive bug a product can ship. This file is the cheapest place to catch it.