Composition and reconcile
Why cross-section behaviour lives at the template as a reconcile rule, never inside a section, and why that rule runs at publish rather than at fill.
What it is
Section titled “What it is”A template’s composition is the site it builds: the section instances it is made from, and the pages those instances are laid out across — which sections appear, on which page, in what order, and, for a section composed more than once, which instance holds which content. An instance listed on two pages is one instance rendered on each, which is how a header is shared. A reconcile rule is layered on top of that composition: a cross-section adjustment that looks at two or more composed instances together and adjusts what one of them shows because of what another one resolved to. Composition decides what the site is made of; reconcile decides how those instances relate to one another.
Why it works this way
Section titled “Why it works this way”A section is written once and used inside any template that composes it — the same section instance renders unmodified on one template’s page and on another’s. That reuse depends on a section never assuming anything about which other sections happen to sit beside it on a given page: a section is independent by construction, and that independence is exactly what makes it something you can drop into a different composition and review on its own, without reading every other section first. Sections and declarations covers the shape that independence takes; here, the point is what it forecloses.
Once that independence holds, anything that genuinely needs to see two sections at once has nowhere left to live. Not inside either section — writing it there would mean that section secretly assumes a specific sibling is present, which is exactly the assumption independence rules out, and the next template to compose it without that sibling would silently lose the behaviour. So a cross-section adjustment has to live one level up, in the one place that already sees the whole composed list: the template. That is the whole argument for why reconcile is a template-level concern rather than something a section reaches for on its own.
A reconcile rule runs at publish — after fill has produced a draft and after a user has finished editing it, right before the pipeline’s final render turns that content into markup. Like a fill decision, and like the renderer itself, a reconcile rule has to be a synchronous, pure function of what it is given: the site’s already-composed content and the property’s facts, nothing read from a clock, a network call, or anything outside the deliverable it is reconciling. That constraint is what makes publishing safe to repeat — because a rule’s output depends only on the deliverable’s own stored content, reconciling (and therefore rendering) the same content always produces the same page. A rule that could reach outside the deliverable would break exactly that guarantee, and because reconcile rules run in order, each seeing what the ones before it already changed, one nondeterministic rule would carry its unpredictability into every rule that runs after it.
How it works
Section titled “How it works”In prose, not code — the declaration itself is template.ts:
A template’s template.ts declares its section instances — each naming a section, and
an instance id when the section is composed more than once — and then declares the
pages, each with a label, a path, and the instances it renders in order. Together that
is the composition. A reconcile rule is declared alongside it: it names which of the
composed instances’ slots it reads, and a function that inspects the site’s composed
content and the property’s facts and returns the edits it wants — replace a slot’s value
on one instance, or drop an instance from every page that lists it. The rule reads one
flat namespace spanning every page, because what it is deciding is a relationship
between instances, not a fact about where they sit. The platform is what carries those
edits out; a rule cannot reach into the site and rewrite it directly, the same
separation of declaration from execution that
runs through fill. See template.ts for
the full declaration and template-invalid for what
composing or reconciling incorrectly gets rejected for.
What it is not
Section titled “What it is not”Not a layout engine. Composition decides which section instances a site has, which page each one renders on, and in what order; it says nothing about how any of them look. Layout is the JSX and CSS a section authors itself, exactly as if it were the only section on the page.
Not a way to share code between sections. Two sections that want to share logic do it the ordinary way, an import both of them use, not through composition or a reconcile rule. Reconcile exists only for the narrower case an import cannot cover: a decision that depends on what a specific sibling instance actually resolved to, on this deliverable, after fill and editing have both already run.
Not user-editable. A reader who has been thinking of the editor as where every content decision gets made should not extend that to composition: a person using the published editor can revise a slot’s own content, and switch off a section or a page the template declared optional, but cannot add, remove, or reorder section instances or pages, and cannot write or disable a reconcile rule. That structure belongs to the template, fixed at authoring time, not to the deliverable a user is editing.
Where next
Section titled “Where next”template.ts— the composition and reconcile declaration itself, with signatures.- Add another template — the workspace layout a second template needs.
- Add a second page — declaring pages, sharing an instance between them, and linking across them.
template-invalid— the full contract composition and reconcile are validated against.