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.2.0] 2026-08-27
Fixtures become executable. ADR-0006 adds named datasets and free-standing
expressions to a fixture bundle, StatifierUI.TruthTable evaluates the two
against each other into a result matrix, and a bundle can now travel with a
single reusable chart fragment rather than with a whole chart - so a palette
entry carries its own worked examples and a host can run them in its own
suite.
Added
StatifierUI.Fixturesgainsdatasetsandexpressionsfields (ADR-0006): named example datamodels for evaluating expressions against, and named free-standing predicator expressions carrying anexpectmap keyed by dataset name.StatifierUI.Fixtures.Sourcegains optionaldatasets/0andexpressions/0callbacks so a host can supply the two new maps from Elixir alongsidescenarios/0andexample_events/0.StatifierUI.Fixtures.Lintreports an expression matching no compiled guard and anexpectkey naming no dataset, both as warnings.StatifierUI.Fixtures.Expectationsruns everyexpectentry against its named dataset and reports whether the stated value held, for wiring into a host's own test suite.- Depends directly on
predicator(~> 9.0) rather than only transitively throughstatifier. StatifierUI.TruthTableevaluates a bundle's expressions across its datasets and returns the ADR-0006 result matrix, one cell per(expression, dataset)pair. A cell's verdict is:satisfied,:unsatisfied,:undefined,:value,:error, or:missing_dataset- deliberately nottrue/false, so predicator's three-valuedundefinedcannot be collapsed into false by Elixir truthiness.StatifierUI.TruthTable.Markdownrenders that matrix as Markdown, with datasets down the rows and expressions across the columns by default, or transposed withorientation: :expressions_as_rows. Every cell spells its value out as a word and adds emphasis on top, so the three truth values stay distinct in plain text.StatifierUI.Kino.truth_table/2wraps the rendered matrix in aKino.Markdownwidget for a Livebook cell. It needs no session and no Phoenix; without the optional:kinodependency the stub points at the pure renderer instead.StatifierUI.Fixtures.Bundlelets an ADR-0003/ADR-0006 fixture bundle travel with one reusable chart fragment instead of with a whole chart, so a palette entry can carry its own executable examples. A fragment supplies its bundle as aStatifierUI.Fixturesstruct, an atom-keyed Elixir map, a string-keyed sidecar map, or a path to a.fixtures.jsonfile; all four route through the existing validation and converge on one struct.StatifierUI.Fixtures.Bundle.discover/2loads every entry's bundle across a palette of modules, anddiscover_dir/2does the same for a directory of<fragment>.fixtures.jsonfiles. Neither is all-or-nothing: a fragment that ships no examples is reported as an absence, and one malformed bundle is reported against its own name while the rest still load.StatifierUI.Fixtures.Bundle.Markdownrenders a fragment's "test this step" panel - its truth table and its expectation results together - andrender_discovery/2renders a whole palette's worth. The expectations summary reports four counts rather than a pass or a fail, becauseExpectations.check/2andFixtures.Lintdeliberately disagree about whether anexpectkey naming no dataset is a failure or a warning.StatifierUI.Kino.test_panel/2andStatifierUI.Kino.palette_panel/2wrap those renderings asKino.Markdownwidgets. Liketruth_table/2they need no session and no chart; without the optional:kinodependency the stubs point at the pure renderers instead.docs/fixture-bundles.mddocuments the convention and walks an embedder through wiring a palette entry's bundle, discovering a whole palette, and running every fragment's expectations in a host suite.
[0.1.1] 2026-08-24
Documentation-only release: brings the hexdocs to the shared fleet standard. No code changes.
Changed
- Unpublishes the ADRs from hexdocs; they remain in the repository under
docs/adr/. - Fixes the five broken links in the published docs - repo-relative references (research doc, ADRs, inspector notebook, architecture's research link, LICENSE) now resolve as absolute GitHub URLs or badges.
- Adds a badge row (CI, Hex version, downloads, hexdocs, license) and a Documentation index to the README, and corrects the stale claim that the project has no CI.
mix docsnow builds with zero warnings.
[0.1.0] 2026-08-22
First release: authoring, observing, and debugging components for the statifier statechart engine, consuming its effect stream through the language-neutral trace wire format (format version 1). The Livebook inspector is the first assembled frontend; the panes underneath it are pure folds any other frontend can render.
Added
StatifierUI.Diagram.render/2renders a compiled machine and an active configuration as MermaidstateDiagram-v2source forKino.Mermaid, with composite nesting, parallel regions, active-state highlighting, and cross-hierarchy transitions lifted to the composite level with a[lifted: ...]marker.StatifierUI.EventLog.build/1folds a trace message stream into a log grouped by(macrostep, round), ordered by the producer's stamps rather than arrival, andStatifierUI.EventLog.Markdown.render/2renders it as collapsible Markdown forKino.Markdown, with wire-format indexes resolved to state and transition names byStatifierUI.EventLog.Labels.StatifierUI.EventInjection.build/1turns an ADR-0003 fixture bundle (ornil) into the event-injection pane model: a sorted palette of editable event buttons viaStatifierUI.EventInjection.Palette, afree_form_only?flag for the fixture-less degraded mode, andsend/2/send_draft/3to deliver aStatifierUI.EventInjection.DraftthroughStatifier.Session.send_event/2- the ordinary recordable input path, per statifier ADR-0029.StatifierUI.DatamodelExplorer.build_authoring/3andbuild_live/2build a read-only datamodel tree - document<data id>declarations, spec 5.10.1 system variables, predicator provider functions in scope, and either a fixture scenario or a live session's datamodel with entries markedchanged?per macrostep - andStatifierUI.DatamodelExplorer.Markdown.render/2renders it as Markdown forKino.Markdown.StatifierUI.Kino.inspect/3assembles the Livebook inspector: the configuration diagram, datamodel explorer, event injection, and event log panes composed over one shared subscriber, live-updating, detaching cleanly on cell re-evaluation. Compiled only when the optional:kinodependency is present.StatifierUI.Trace.Subscriber.attach/3acceptscatch_up: true: on a session started withrecord: truethe missed prefix is replayed into the buffer atomically with the subscription (statifier ADR-0049); an unrecorded session falls back to live delivery with a:not_recordeddiagnostic the inspector surfaces as "Live-only".StatifierUI.Inspector- the pure pane-assembly fold the Kino shell renders, usable by any other frontend.notebooks/inspector.livemd- the demo notebook, doubling as the milestone's manual acceptance test.- Serializes statifier's
DatamodelChangeeffect as theeffect.datamodel_changewire type, so consumers can observe datamodel values as they are written instead of only the variable namessession.datamodelcarries. New types are additive under the wire format's must-ignore rule. - Every
effect.*wire message carries the engine'sroundstamp in its envelope, alongsidemacrostepandmicrostep; consumers reading older recorded streams must still tolerateeffect.*messages without the key.