All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Entries for unreleased work are not written here directly. Each issue drops a
fragment in changelog.d/; the fragments are assembled
into a version section at release. See that README for the format and for when a
change warrants an entry at all.
[0.1.0] 2026-09-14
The first release. Riddler is a dynamic content runtime: a host authors content as JSON documents - screens now; emails, images and feature flags forthcoming - and Riddler resolves each against a visitor's context, while the host renders, sends or serves what comes back. A document is admitted and validated on its own, resolved against a host's context and a visitor's responses into the nodes that visitor is shown, its templates compiled and rendered against the subset, and the responses it collects validated against the screen they were shown. The conformance corpus is authored here and emitted into riddler_spec so a second implementation runs the same cases.
Added
Riddler.Template.compile/1accepts a template only when every tag and filter in it is inside the template subset, reporting oneRiddler.Findingper refused construct rather than the first.Riddler.Template.render/3renders a compiled template as text in lenient or strict mode, returning the paths that were missing in lenient and an error carrying them in strict.- A screen document is admitted from decoded JSON and validated on its own, with every reason it is refused reported at once: unknown node types, duplicate or misshapen keys, missing fields, heading levels out of range, conditions that do not parse, templates outside the subset, malformed writes, unknown formats, and variants that are empty or bury a default.
- A visitor's responses are validated against the screen they were shown:
required, theemail,phone,pattern,integerandnumberformats, andminandmaxon the numeric ones, with a question a condition hid unable to fail and a button declaringvalidatesfalse able to submit without any check at all. A question may now carrypattern,minandmaxbeside itsformat. - A screen document resolves against a host's context and a visitor's responses into the nodes that visitor is shown, with hidden nodes absent, every container collapsed to its winner, every template rendered, and what could not be decided reported rather than refused.
mix riddler.corpusemits the conformance corpus and the JSON schemas into a riddler_spec checkout, byte-stable and with agenerated_byheader naming the version and the source file, refusing to emit a corpus this implementation does not satisfy;--checkreports drift instead of writing.- A document's envelope carries
kind, the content kind it belongs to. It is an optional string and it defaults toscreens, so a document that names none is a screen document; the decided kind is carried through to the resolved document, and a kind this package has no runtime for is adocument.unknown_kindfinding naming the value.
Changed
- The screens kind is named after the kind rather than after the nodes inside
a screen:
Riddler.Elementsand everything under it is nowRiddler.Screens, and the corpus capabilitieselements.admit,elements.resolveandelements.validate_responsesare nowscreens.admit,screens.resolveandscreens.validate_responses, emitted fromcorpus/screens/. NoRiddler.Elementsname and noelements.*capability survives this release.templates.renderis unchanged.