> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gavai.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How gavAI works

> The three parties involved when someone uses an app built on gavAI, how a single request flows end-to-end, and why we describe the platform by architectural role rather than by vendor.

export const PullQuote = ({children}) => <p className="gv-pull-quote">
    <span className="gv-pull-quote__mark" aria-hidden="true">“</span>
    <span className="gv-pull-quote__body">{children}</span>
  </p>;

export const PageMeta = ({audience, readingTime, prereqs, level}) => {
  const items = [audience && ({
    key: "audience",
    label: "AUDIENCE",
    value: audience
  }), readingTime && ({
    key: "time",
    label: "READ",
    value: readingTime
  }), level && ({
    key: "level",
    label: "LEVEL",
    value: level
  }), prereqs && prereqs.length > 0 && ({
    key: "prereqs",
    label: "PREREQS",
    value: prereqs.join(" · ")
  })].filter(Boolean);
  if (items.length === 0) return null;
  return <div className="gv-page-meta" role="group" aria-label="Page metadata">
      {items.map(item => <div className="gv-page-meta__item" key={item.key}>
          <span className="gv-page-meta__label">{item.label}</span>
          <span className="gv-page-meta__value">{item.value}</span>
        </div>)}
    </div>;
};

export const FeatureTable = ({columns, rows, featuredRow, caption, variant}) => <div className={`gv-feature-table ${variant ? `gv-feature-table--${variant}` : ""}`}>
    <table>
      {caption && <caption className="gv-feature-table__caption">{caption}</caption>}
      <thead>
        <tr>
          {columns.map(col => <th key={col.key} scope="col">
              <span className="gv-feature-table__header">{col.label}</span>
            </th>)}
        </tr>
      </thead>
      <tbody>
        {rows.map((row, i) => {
  const rowClass = [i === featuredRow ? "gv-feature-table__row--featured" : "", row.chosen ? "gv-feature-table__row--chosen" : ""].filter(Boolean).join(" ");
  return <tr key={i} className={rowClass}>
              {columns.map(col => {
    const v = row[col.key];
    if (variant === "tradeoff" && Array.isArray(v)) {
      const pill = col.key === "pros" ? "gv-feature-table__pill--pro" : col.key === "cons" ? "gv-feature-table__pill--con" : "";
      return <td key={col.key}>
                      {v.map((item, j) => <span key={j} className={`gv-feature-table__pill ${pill}`}>{item}</span>)}
                    </td>;
    }
    return <td key={col.key}>{v}</td>;
  })}
            </tr>;
})}
      </tbody>
    </table>
  </div>;

export const ArrowItem = ({children}) => <li className="gv-arrow-item">
    <span className="gv-arrow-item__arrow" aria-hidden="true">{"↳︎"}</span>
    <span className="gv-arrow-item__content">{children}</span>
  </li>;

export const ArrowList = ({children}) => <ul className="gv-arrow-list">{children}</ul>;

export const BrandCard = ({eyebrow, title, href, icon, badge, cta, featured = false, horizontal = false, children}) => {
  const classes = ["gv-card", featured && "gv-card--featured", horizontal && "gv-card--horizontal"].filter(Boolean).join(" ");
  const inner = <>
      {icon && <span className="gv-card__icon" aria-hidden="true">
          <Icon icon={icon} />
        </span>}
      <div className="gv-card__main">
        {(eyebrow || badge) && <div className="gv-card__meta">
            {eyebrow && <Eyebrow label={eyebrow} tone="muted" />}
            {badge && <span className="gv-card__badge">{badge}</span>}
          </div>}
        <h3 className="gv-card__title">{title}</h3>
        {children && <div className="gv-card__body">{children}</div>}
        {cta && <span className="gv-card__cta">
            {cta}
            <svg className="gv-card__cta-arrow" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <line x1="7" y1="17" x2="17" y2="7" />
              <polyline points="7 7 17 7 17 17" />
            </svg>
          </span>}
      </div>
    </>;
  return href ? <a className={classes} href={href}>
      {inner}
    </a> : <div className={classes}>{inner}</div>;
};

export const Eyebrow = ({label, tone = "default"}) => <div className={`gv-eyebrow gv-eyebrow--${tone}`}>
    <span className="gv-eyebrow__bar" aria-hidden="true" />
    <span className="gv-eyebrow__label">{label}</span>
  </div>;

<Eyebrow label="CONCEPTS" />

<PageMeta audience="Developers, technical buyers" readingTime="10 min" level="Concepts" />

By the end of this page you will know who is involved when someone uses an app built on gavAI, what happens between a browser request and a rendered page, and how to read every other section of the docs as **capability-first** — what the platform *does* — rather than vendor-first. Treat this as the orientation page for the rest of the concept docs.

## The three parties

Every interaction on gavAI involves three distinct parties. Confusing them is the most common source of misreadings in the rest of the docs.

<FeatureTable
  columns={[
{ key: "party", label: "Party" },
{ key: "who", label: "Who they are" },
{ key: "see", label: "What they see" },
{ key: "own", label: "What they own" },
]}
  rows={[
{
  party: "End-user",
  who: "Someone using an app a workspace owner has built.",
  see: "A normal website at the workspace's domain, e.g. `shop.acmebakery.com`. No gavAI branding.",
  own: "Their own account on that app, scoped to that workspace only.",
},
{
  party: "Workspace owner",
  who: "A business or builder using gavAI to ship an app.",
  see: "Their builder at `console.gavai.app`, their app's content, traffic, and bills.",
  own: "Their content and their end-users' data. They are the data controller.",
},
{
  party: "gavAI",
  who: "The platform — us.",
  see: "Edge proxy, runtime, storage, AI gateway, billing, audit logs.",
  own: "The platform itself. We are a processor for workspace data, not the controller.",
},
]}
/>

The crucial point: **end-users never see gavAI**. The platform is invisible to them by design. A workspace owner's domain, branding, and identity are what the end-user experiences. gavAI sits behind it.

## One request, start to finish

When an end-user visits a workspace's domain — say, `shop.acmebakery.com` — six things happen. The path is the same for every request.

```mermaid theme={null}
sequenceDiagram
    participant U as End-user browser
    participant E as Edge proxy
    participant R as Workspace runtime
    participant S as Object storage
    participant A as AI gateway (optional)
    U->>E: GET shop.acmebakery.com
    E->>E: Resolve domain → acme workspace
    E->>R: Route request to acme's runtime
    R->>S: Fetch acme's page document
    S-->>R: Page JSON
    Note over R,A: Optional AI step
    R->>A: If the page invokes an AI capability, call the gateway
    A-->>R: Model response
    R-->>U: Rendered HTML over HTTPS
```

The numbered version:

<ArrowList>
  <ArrowItem>**End-user browser visits** `shop.acmebakery.com` over HTTPS.</ArrowItem>
  <ArrowItem>**Edge proxy** receives the request, looks up the domain, and resolves it to the acme workspace.</ArrowItem>
  <ArrowItem>**Workspace runtime** for acme spins up (or wakes) and fetches acme's page document from object storage.</ArrowItem>
  <ArrowItem>**Render** — the runtime reads the page JSON into memory just long enough to build HTML.</ArrowItem>
  <ArrowItem>**Optional AI step** — if the page invokes an AI capability (chat, summarize, classify), the runtime calls the AI gateway, which routes to the configured model provider.</ArrowItem>
  <ArrowItem>**Send back** — the finished HTML is returned to the end-user's browser over HTTPS. The runtime forgets the page body.</ArrowItem>
</ArrowList>

The page body is never logged. Our metrics only carry request counts, timings, and error codes — never the content of what was rendered.

### The publish path runs in parallel

While end-users are reading pages, the workspace owner is editing them. Their path is shorter:

<ArrowList>
  <ArrowItem>Workspace owner signs into `console.gavai.app`, edits their pages.</ArrowItem>
  <ArrowItem>Hits **Publish**. The new page JSON lands in their isolated storage namespace.</ArrowItem>
  <ArrowItem>The edge cache for that workspace is invalidated.</ArrowItem>
  <ArrowItem>The next end-user request (step 1 above) picks up the new content.</ArrowItem>
</ArrowList>

Two paths, one storage record per page. The architecture is symmetric on read and write.

## Same content, three views

A useful mental check for how the isolation works: take a single piece of content — Acme's homepage headline, "Fresh bread, daily." — and look at how each party experiences it.

<FeatureTable
  columns={[
{ key: "party", label: "Party" },
{ key: "what", label: "What they see" },
{ key: "form", label: "Form" },
]}
  rows={[
{
  party: "End-user (browser)",
  what: "A rendered page on `shop.acmebakery.com`. Headline, image, **Order now** button. No gavAI branding anywhere.",
  form: "Finished HTML.",
},
{
  party: "Workspace owner (builder)",
  what: "Editable fields in the builder — a `headline` input, a `subhead` input, a `Publish` button.",
  form: "Structured JSON with named props.",
},
{
  party: "gavAI (storage)",
  what: "A storage record with `id`, `size`, `updated`, `hash`. The `body` is workspace-isolated.",
  form: "An object key in the workspace's namespace, with metadata visible to operators only for support and billing.",
},
]}
/>

The same piece of content. Three shapes. Operators see metadata — size, timestamp, hash — not bodies for ad-hoc reads. See [Multi-tenant isolation](/concepts/multi-tenant) for the architectural guarantees that back this.

## We describe roles, not vendors

The platform exposes a fixed set of **architectural roles**: edge runtime, object storage, primary database, end-user identity, transactional email, payments, secret store, AI gateway, and so on. Each role is a stable contract. The **vendor** that fills a role today is an implementation choice.

This matters for two reasons:

<ArrowList>
  <ArrowItem>**Your integration doesn't break when we swap a vendor.** You depend on "the platform sends email" — not "the platform uses any specific email provider."</ArrowItem>
  <ArrowItem>**You can audit what the platform does without re-auditing every time a vendor changes.** Roles are stable; vendors are swappable.</ArrowItem>
</ArrowList>

If we swap a vendor, you get a **30-day notice and a right to object** before the change goes live. The current list of vendors is published at [Subprocessors](/security/subprocessors).

## What gavAI never does

A short, exhaustive list — these are commitments, not aspirations:

<ArrowList>
  <ArrowItem>We never read workspace content we weren't instructed to (by an explicit operator action or your written authorization).</ArrowItem>
  <ArrowItem>We never sell workspace data.</ArrowItem>
  <ArrowItem>We never use workspace content to train models. Your data is yours.</ArrowItem>
  <ArrowItem>We never mix workspaces. Every workspace runs on its own isolated runtime, its own database boundary, and its own storage namespace.</ArrowItem>
</ArrowList>

<PullQuote>The architecture is built to make these commitments enforceable, not just promised.</PullQuote>

See [Multi-tenant isolation](/concepts/multi-tenant) for the technical details and [Scopes](/security/scopes) for the access boundaries.

## Where to go next

<Columns cols={2}>
  <BrandCard eyebrow="ARCHITECTURE" title="Platform architecture" href="/concepts/architecture" icon="cpu">
    The four surfaces — Builder, runtime, Component Registry, MCP layer — and how they connect.
  </BrandCard>

  <BrandCard eyebrow="ISOLATION" title="Multi-tenant isolation" href="/concepts/multi-tenant" icon="building">
    The boundaries that keep one workspace's data away from every other workspace.
  </BrandCard>

  <BrandCard eyebrow="DATA MODEL" title="PageBlocks" href="/concepts/pageblocks" icon="layout-grid">
    The composable building blocks the Builder uses to assemble pages.
  </BrandCard>

  <BrandCard eyebrow="SECURITY" title="Subprocessors" href="/security/subprocessors" icon="shield">
    The vendors that fill each architectural role today, with the 30-day right-to-object policy.
  </BrandCard>
</Columns>
