11. Capstone: schema a real config

Put it all together — vocabulary, constraints, document root, and instances for a deployment config.

After this lesson you can

- Design a closed vocabulary with symbol_set - Declare block kinds with labels, defaults, and list fields - Validate instances against the schema and evaluate the result

Before you start: Tooling day-to-day

The capstone is the workflow you'll actually use: pick a config your project needs (deployments, pipelines, fixtures), declare its vocabulary as types, point a @document at them, and author real instances. A symbol_set closes an enum-like field — wcl check rejects any symbol not in the set — which is usually the first constraint worth adding.

Work schema-first: get one instance validating, then tighten (defaults for the common case, @min/@max where numbers have bounds, optionals where absence is legal). When the schema stops surprising you, the config is done.

§ 1Exercise: A deployment config from scratch

Model apps deployed to environments: a closed Env vocabulary, an app block with defaults, and two instances.

wcl
// A tiny deployment config — schema and data in one file.
symbol_set Env { dev  staging  prod }

@block("app")
type App {
  @inline(0)   name: identifier
  env:         Env
  @default(1)  replicas: u32
  @default([]) domains: list<utf8>
}

@document
type Deploy {
  @children("app") apps: list<App>
}

app web {
  env      = :prod
  replicas = 3u32
  domains  = ["example.com", "www.example.com"]
}

app worker { env = :staging }

Expected result

wcl check prints OK, and wcl eval deploy.wcl apps.web.replicas prints 3u32; worker picked up replicas = 1 and domains = [] from the defaults.

Hint

Set env = :production on an app — the check fails because production isn't in the Env symbol_set. Closed vocabularies catch typos schemas otherwise miss.

§ 2Exercise: Make it yours

Extend the schema with one thing your real config needs — a nested block (@child), a numeric bound (@min), or an optional field — and keep the document validating.

Expected result

wcl check still prints OK after the extension, and at least one instance exercises the new declaration.

Hint

Add the constraint first and watch check fail, then fix the data — the error message names the file, field, and rule, which is the debugging loop you'll live in.