Surface Overview

A surface is a deployment context for a specific type of service work. Surfaces define what kind of evidence is required, what the execution stages are, and how jobs behave within that service domain.

What a surface is

Think of a surface as a template for a service type. The same execution pipeline runs for every surface, but each surface can customize:

  • What evidence must be captured (e.g. arrival photo, before/after photos)
  • The minimum evidence requirements before a job can be completed
  • Display names and service tiers

Examples of surfaces:

  • auto-detailing — mobile vehicle detailing service
  • qtm-astrology — advisory/consultation service
  • qtm-landscaping — landscaping service
  • event-coordination — event coordination service

How surfaces relate to execution

Every job is tied to a surface. When an intake is submitted, it specifies which surface the service is for. This carries forward through the entire execution chain:

Intake (surface: auto-detailing)
  → Job (surface: auto-detailing)
    → ServiceEvent (surface: auto-detailing)
      → Record (surface: auto-detailing)

The surface determines what the operator needs to do to complete the job. An auto-detailing job requires arrival, before, and after photos. An advisory service may not require photo evidence at all.

Surface policy enforcement

When an operator tries to complete a ServiceEvent, the system checks the surface’s evidence requirements. If the required evidence categories haven’t been captured, the system blocks completion.

The surface is not just a label — it actively governs the execution path.

Surface runtimes

Each surface is backed by a surface runtime — a module in the system that defines its behavior. Surface runtimes register themselves with the system and are resolved by surface slug (e.g. "auto-detailing").

Surfaces are defined in:

  • src/lib/surfaces/ — individual runtime modules
  • src/lib/surface-runtime.ts — the registry and resolution logic

Guardrails

  • Preserve the distinction between planned, partial, and live.
  • Avoid marketing language.
  • Keep IDs, namespaces, and lifecycle terms precise.
  • Surface requirements are enforced at the runtime level, not the UI level.