The Runtime Flow

Status: implemented Core model.

This page describes the shared flow used before any capability-specific work. Read the exact directive reference for syntax and edge cases.

Read the Core in detail

Use this page as the map, not as the only Core reference. Read Host and Scope, Data and Evaluation, Rendering Model, Actions and Results, and Updates and Redraw before capability work.

One execution path

authored host HTML
  -> initialize host data and capture the source template
  -> create the current evaluation scope
  -> decide structure, then render bindings and side effects
  -> perform an explicit action when its trigger occurs
  -> place an allowed result through *response
  -> update from the stored template when a Sercrod entry point requests it

The source template is captured from the initial host children. A structural update renders from that stored template and current scope, not from the already-rendered DOM as though that DOM were the source of truth.

Scope and expression evaluation

Host data is the primary expression scope. Expressions can use normal data names and $data; nested contexts can also expose $root, $parent, and local values created by directives such as *let, *for, and *each.

Those local values describe the current rendered context. They do not mutate host data unless a directive or expression explicitly writes to it. Reusable or complex work belongs in declared methods rather than increasingly large attribute expressions.

Expressions are trusted template execution. Do not treat expression evaluation, expression-based data, methods, or HTML-output directives as a security boundary for untrusted input.

Rendering before side effects

For one rendered node, Sercrod first handles text and scope preparation, then structural directives, then child-host boundaries, then side-effect and IO directives, and finally ordinary bindings, output, event binding, and child rendering. This order matters: a directive that decides DOM shape is not an incidental effect of a later action on the same node.

Structural rendering follows a regeneration model. Known non-structural changes may update registered text, attribute, class, style, or form-value commands, but that is not virtual-DOM diffing and does not change the structural contract for conditions, repetition, templates, insertion, removal, or reorder.

Actions, redraw, and notification

Sercrod redraw is requested through its own entry points: Custom Elements lifecycle handling, whole data assignment, directives, event handlers, *update, or explicit update() calls. Directly mutating a nested JavaScript object is not itself a general redraw trigger.

sercrod-change can report an observed data change to users or external code. It is deliberately separate from render scheduling. Do not describe this model as Proxy- or MutationObserver-based change detection.

For user input, *input writes a control value to a writable data path. *lazy changes refresh timing but does not discard the value; *eager is the explicit live-refresh form. The combined *lazy and *eager case is not a portable assumption.

Result placement is explicit

An HTTP response, loaded value, adapter action result, or WebSocket message is placed only when the producing directive supports the existing *response contract. *response is a destination declaration, not an action by itself. The legacy *into form remains a compatibility alias for a simple destination; use the detailed reference before relying on its precedence or mapping rules.

Text output uses *print or *textContent. HTML output uses *innerHTML or *compose and has a separate trust requirement. A result being available does not make it safe to render as HTML.

Evidence

Status: implemented.

Evidence: docs/spec/runtime.md, dist/sercrod.js host lifecycle, evaluation, update, and response-placement paths; canonical manual dist/man.json; and focused evidence in sandbox/app/communication/test/directive.test.js, sandbox/app/iterate/test/directive.test.js, and sandbox/app/todo/test/save-load-fallback.test.js.