Files
alkgen/docs/architecture/decisions/002-handlebars-substrate-strict-mode.md
glm-5.3-flash a91ea2ec89 docs(architecture): phase 1 base: text-generation core specs, ADRs 001-010, OQ tracker
- overview.md, core.md, emit.md, targets.md: modular spec set for the
  generalized engine (contexts + templates + partials -> text), with
  the three targets (ssr-html, bast-rust-codecs, call-handlers,
  wgsl-jit) as template sets plus emit postures
- ADRs 001-010: one core/template-set split, handlebars 6.4 strict
  substrate, sync/wasm/deterministic posture, typed contexts with
  builders, per-registry escaper, SSR library posture, typed direct
  codecs output contract, template-set ownership, feature gating,
  library-only v1
- open-questions.md: OQ-01..OQ-08 centralized tracker carrying phase-0
  residue (GN-01/02/07/09) with three deferred(scope) entries plus a
  resolved disposition for phase-0 OQ-GN-04
- tasks/architecture/: external-trigger tracker tasks paired with the
  deferred OQs (taskgraph validate passes)
- phase-0.md checklist dispositioned for OQ-GN-04; AGENTS.md lifecycle
  updated to phase 1

Verification: taskgraph validate (4 tasks OK), cargo fmt --check,
cargo test, em-dash grep clean; architecture-reviewer pass returned
zero critical issues
2026-11-06 08:18:43 +00:00

3.1 KiB

ADR-002: handlebars-rust 6.4 substrate: strict mode, typed errors, embedded templates

Status

Accepted

Context

The render substrate was settled in Phase 0 (validated stack, wasm playground shipped by handlebars itself), but the substrate posture was distributed across conventions, phase-0 prose, and two precedent codebases (typebox-rs and the reader POC). It needs one decision record, because posture is what typebox-rs got wrong (unwrap-based registration, no strict mode, silent empty output) and what the POC validated as right.

Decision

  1. Substrate: handlebars-rust pinned to 6.4 from crates.io. The vendored checkout (/workspace/handlebars-rust, one commit past v6.4.4) is reading material and an emergency patch source only, not the dependency.
  2. Strict mode always: every registry the library constructs or exposes sets strict mode on. A missing context variable is a render error, never silently-empty text (AGENTS.md convention 6; alkminer-v1 ShaderBuilder precedent; the POC caught a stale context key through strict mode at build time).
  3. Registration is fallible and typed: template and partial registration surfaces propagate parse errors as typed errors (no unwrap). Malformed templates and malformed inputs are data, not crashes (AGENTS.md convention 2).
  4. Assets are embedded code: templates come from const &str or include_str!; dir_source (filesystem) and script_helper (rhai) features are off-limits in lib code; templates are pinned by golden render tests (AGENTS.md convention 7).
  5. Partials are first-class: registration supports partials alongside templates from day one (branch-3 (template-JIT) requirement priced in while free; also the SSR fragment unit).
  6. One registry per template set: strict mode, escape policy (ADR-005), and partial namespaces are registry-scoped properties, so a single per-set registry is what makes them enforceable rather than advisory. Cross-set asset reuse is a source-level include, never registry surgery. Consumer sets use the same construction path (machinery equality, ADR-008).

Consequences

  • Positive: strict mode turns silent-output bugs into build-time errors at the generator, close to the cause, instead of compile or runtime bugs in consumers; typed registration keeps the no-panic posture intact for hostile inputs.
  • Positive: the embedded-asset rule keeps lib code wasm-clean and reproducible.
  • Negative: strict mode can reject templates for missing-but-defaulted keys; the remedy is context shape and template guards ({{#if}}), the pattern F-3 validated, not a strict-mode escape hatch.
  • Negative: pinning to a crates.io version means substrate bug fixes ride the handlebars release train; the vendored checkout bounds the emergency case.

References

  • core.md (registry construction, template assets)
  • ADR-003 (platform posture incl. the off-limits features)
  • Phase 0, sections "What is already settled" and typebox-rs prior art (docs/research/phase-0.md); reader POC findings F-3, F-4 (docs/research/reader-poc-summary.md)