Docs
GitHub
Understand QueryLayer

QueryLayer Architecture

Understand the site-local runtime, trust boundaries, data model, and delivery path.

Edit this page on GitHub ↗

Status: Authoritative. This document describes the product QueryLayer is. Where older documents conflict with this one, this document wins.

#The product

QueryLayer is an open-source, WordPress-like CMS for search-driven Astro websites. It is installed per website, on infrastructure that website's owner controls, and operates entirely from that installation:

<managed-site.example>
├── Public Astro website
├── /admin            — site-local QueryLayer administration
├── Site-local authentication (local auth service; local administrator accounts)
├── Site-owned database (Postgres, installation-local)
├── Revision and publishing services (immutable revisions, pointers, preflight)
├── Background workers/scheduler (pg_cron → local edge functions)
├── Agent API/MCP endpoint (/api/functions/v1/querylayer-mcp)
└── Site-owned secrets and integrations (Vault + local edge-function env)

There is no QueryLayer Cloud account, no querylayer.dev login, and no company-operated service in any runtime path. An optional hosted service (managed hosting, updates, backups, multi-site overview, remote monitoring) may exist later as an add-on — never as a runtime, authentication, licensing, or availability dependency.

#Runtime composition

An installation is a single Docker Compose stack (reference distribution under install/):

Layer Component Notes
Gateway QueryLayer web gateway (install/gateway) Serves the admin build at /admin, injects runtime configuration, proxies /api/* to the platform, serves the managed site's static build
Platform Self-hosted Supabase stack (Apache-2.0), pinned to self-hosted/v0.8.0 images Postgres + GoTrue auth + PostgREST + Storage + Realtime + Edge Runtime behind Envoy, bound to the internal network
Data The QueryLayer SQL schema (supabase/migrations) ~160 migrations; identical logic to the original hosted project, now applied locally
Functions 11 Deno edge functions (supabase/functions) MCP, publish dispatcher, forms, connectors; run in the local Edge Runtime
Scheduler pg_cron jobs (created by migrations) Invoke local edge functions through the installation's own public URL via Vault-stored config
Admin Static Astro admin build (src/) Served by the gateway at /admin; runtime config comes from /admin/config.js, never baked into assets
Site Operator's Astro site (e.g. Backup Generator Guide) Built by the operator; content fetched from the installation's own /api at build time

#Identity, authentication, and authorization

  • Human authentication is installation-local (GoTrue inside the stack). The first owner account is created by the installer directly via the local admin API — no invite email, no external identity provider.
  • All row-level-security logic derives identity from the local auth.* schema (auth.uid(), auth.sessions). Nothing about the code assumes a QueryLayer-operated project; it assumes an installation-local auth service.
  • Agents authenticate with governed bearer grants (ql_agent_…), resolved server-side by authenticate_agent_connection into installation/site-scoped permissions. Agents never hold database-owner credentials.
  • The governance contract is unchanged and non-negotiable: autonomous planning orchestrates; typed governed proposals authorize mutations; server-side execution performs approved mutations.

#Delivery (publishing)

request_content_publishpublish_jobs → scheduler → delivery provider. The delivery provider is pluggable:

  • Today's implemented provider is a Vercel Deploy Hook (used by the pilot).
  • An installation with no provider configured still completes publication inside QueryLayer (immutable pointer advance, audit, preflight) and records the delivery outcome independently.

#Boundary classification (Phase 1 audit result)

Class Components
Installation-local (now) Local auth service; local Postgres + RLS; local edge functions; local pg_cron scheduler; local Vault-backed secrets; /admin gateway + admin build; local MCP endpoint
Reusable unchanged Immutable revision model; draft/published pointers; revision-scoped SEO metadata; scheduling/unpublish/rollback; audit ledger; claims/evidence; agent identities, proposals, approvals, runs, durable tasks; harness-neutral MCP contract; @querylayer/client + @querylayer/astro; integrations (GSC, GA4, Bing, IndexNow, Resend, Turnstile)
Optional hosted service (later) Managed hosting; remote monitoring; multi-site overview; update service
Must be removed (done in this correction) Mandatory querylayer.dev administration; central Supabase project identity as a runtime dependency; central OAuth-callback defaults as the only path; org/membership bootstrap requiring a central account; "self-hosted as metadata" setup UI; private-release licensing posture

Pilot-specific data (hardcoded site UUIDs, domains, Vercel project IDs) is excluded from fresh installations: pilot migrations are never applied (scripts/install-site.mjs maintains the exclusion list, mirrored in .gitattributes for public archives), and generic migrations that once embedded pilot rows are guarded to no-op when the pilot site is absent.

#Non-goals for the installable core

  • No requirement for a company-operated account at any lifecycle stage (install, upgrade, operate, or restore).
  • No shared control plane in the runtime path.
  • No agent mutation authority beyond typed governed proposals and explicit installation-owner policy (including "no autonomous publishing" by default).

#Acceptance contract

The corrected architecture is proven by scripts/acceptance-single-site.mjs: admin at /admin, local sign-in, RLS-scoped workspace, immutable draft, exact-revision preview, site-local publishing, governed agent connection to the local MCP endpoint, and zero requests to company-operated services. A clean-room installation must pass this test before any release.