<program>
The root container of a scrml application. Owns route inference, middleware, documentary metadata, channels, and the per-app auth boundary.
Syntax
<program [attributes]>
<page path=... />
<channel name=... />
<auth role=... />
...
</program>
The opening <program> carries app-wide attributes (documentary metadata, middleware config, auth defaults). Its body holds the structural children that compose the app: pages, channels, auth gates, top-level reactive state, and inline server functions.
Worked example
A small app with documentary attributes, two pages, a real-time channel for chat, and a logged-in-only admin page.
<program title="Acme Cards"
description="A kanban for the gas patch."
version="v0.4.1"
author="Bryan MacLee"
license="MIT">
<page path="/" />
<page path="/board" />
<auth role="Admin">
<page path="/admin" />
</auth>
<channel name="presence" topic="board">
<online> = []
</channel>
</program>
The documentary attributes feed the HTML
<head>
(per SPEC §40.7). The
<auth role="Admin">
wrapper omits
/admin
from anonymous JS bundles (code-split only, per the
Approach A closure-analysis + per-route per-role artifact splitter)
— it is NOT a content-secrecy gate; the served HTML still
carries the markup (see the
<auth>
page).
The channel body uses V5-strict declarations; its cells
auto-sync across connected clients.
Semantics
-
One <program> per entry file.
The entry-file <program> declares the app's
structural shape: which pages exist, which channels
are active, which auth defaults apply. Non-entry files
that contain a
<page>are part of the filesystem-routed page tree, not additional program roots. -
Documentary attributes feed <head>.
title=,description=,version=,author=,license=land in the emitted HTML head metadata. Nested <program> blocks with these attributes fire W-PROGRAM-TITLE-NESTED. Per SPEC §40.7. - Channels are children, not file-level siblings. <channel> declarations live inside the entry-file <program> (sibling of <page>). Pure-channel module files (no <program> in the file) MAY declare channels at file top — the sharing pattern. E-CHANNEL-OUTSIDE-PROGRAM fires on misplaced channels in a file that has <program>. Per Insight 30 (S87).
-
Auth wraps page subtrees.
<auth role="X">around a <page> (or group of pages) makes those routes per-role. Closed-form predicates ship per-role bundles via the Approach A artifact splitter; runtime-fallback predicates ship eagerly with a runtime gate and emit W-AUTH-RUNTIME-FALLBACK. Per SPEC §40.1 + §40.9. -
Top-level reactive cells are program scope.
A
<x> = valuedeclaration inside <program> but outside any <page> is visible to every page. Use for cross-page reactive state (current user, theme, feature flags).
Errors this feature can fire
- W-PROGRAM-TITLE-NESTED
- W-PROGRAM-001 — non-entry-page suppression
- E-CHANNEL-OUTSIDE-PROGRAM
- E-CHANNEL-SHARED-MODIFIER
- W-AUTH-RUNTIME-FALLBACK
- W-AUTH-LOGIN-MISSING
- W-AUTH-PAGE-INFERRED
Attributes
| Attribute | Category | Meaning |
|---|---|---|
| title= | Documentary | App title; lands in <head> per §40.7 |
| description= | Documentary | App description; meta tag |
| version= / author= / license= | Documentary | Project metadata; head + chunks.json compiler field source |
| db= | Middleware | DB driver resolution; consumed by ?{} blocks (SPEC §44) |
| auth= | Middleware | App-wide auth default (required / public) |
| csrf= / ratelimit= | Middleware | App-wide middleware defaults |
| cors-max-age=N | Middleware | CORS preflight cache; default 86400 (S81 §39.2.1) |
| channel-reconnect=N | Middleware | Project-level channel reconnect default (S81 §38.3.1) |
| idempotency-store= | Middleware | Per-app idempotency-key backend (S72 ratification) |
| headers= / log= | Middleware | Custom response headers / log sink. Full list: SPEC §40.2 |
Edge cases
-
Nested <program> blocks.
SPEC §43 supports nested program execution
contexts (shared-nothing, lifecycle-bounded, RPC-only
between). Nested programs may NOT redeclare
documentary attributes that belong on the root
(
title=fires W-PROGRAM-TITLE-NESTED). - SPA-shape files have an implicit <program>. A file with no top-level <program> but with <page> declarations is treated as a non-entry page within an SPA-style structure. W-PROGRAM-001 surfaces this pattern. Multi-file route trees are the canonical Day-30 shape.
- Channels and pages are siblings. A <channel> declared INSIDE a <page> fires E-CHANNEL-INSIDE-PAGE (channel scope is program-wide; nesting it in a page breaks the multi-client sync semantic).
Related features
-
<page path=...>
— route declaration. Filesystem-routed by
default;
path=overrides. Reference page queued. - <channel name=...> — real-time multi-client surface. V5-strict body; auto-sync. Reference page queued.
- <auth role=...> — per-role visibility. Drives the per-route per-role artifact splitter. Reference page queued.
- <schema> — declarative database schema. Cross-checked with ?{} at compile time. Reference page queued.
Specification
This page summarizes SPEC §40 (Middleware and Request Pipeline), §40.7 (documentary attributes), §43 (Nested <program>), §38.1 (channel placement), and §40.1 (<auth> first-class element). The normative text lives at compiler/SPEC.md in the scrmlTS repository. When this page disagrees with SPEC.md, SPEC.md is authoritative — surface the contradiction and we'll fix the docs.
Quick-lookup anchors: SPEC-INDEX.md entries — documentary attributes, nested program / workers, channel file-level placement, middleware / handle(), auth-graph.