Skip to content

Serializes datamodel_change as a wire type - #27

Merged
johnnyt merged 1 commit into
mainfrom
sui-h92-datamodel-change-wire
Aug 22, 2026
Merged

Serializes datamodel_change as a wire type#27
johnnyt merged 1 commit into
mainfrom
sui-h92-datamodel-change-wire

Conversation

@johnnyt

@johnnyt johnnyt commented Aug 22, 2026

Copy link
Copy Markdown
Member

Why

Since sui-bpb landed session.datamodel, a wire consumer can see the
datamodel's variable names but never a value: the snapshot is taken before
the binding fold, so every <data> element arrives as {"$undefined": true},
and the DatamodelChange effects that carry the actual writes were dropped
with an {:unknown_effect, :datamodel_change} warning per assignment. This
serializes them, closing the gap and unblocking the datamodel explorer pane
(sui-t36.7).

What

  • New wire type effect.datamodel_change (the tenth effect.* type), one
    message per successful datamodel write, consuming statifier's
    Statifier.Effect.DatamodelChange (st-oef3) as-is - no upstream change.
  • location_path serializes as a heterogeneous JSON array: string segments
    are object keys, integer segments are 0-based array indexes. JSON's own
    typing carries the distinction, so no tagging is needed; location_source
    keeps the raw author string alongside.
  • new_value/prior_value follow the _event.data three-way absence rule
    (:undefined omits the key, nil is JSON null), because ADR-0037's
    unbound sentinel makes nil a genuinely stored null here. The normalizer's
    put_event_data/2 generalizes to put_defined/3 for all three fields.
  • The owner vocabulary gains the widened "invoke" kind for
    <invoke idlocation> writes (Owners table grows to six variants).
  • docs/wire-format.md: full payload schema, the location_path and
    mutual-exclusivity (d_index/c_index) rules, type index row 24, and the
    versioning decision recorded explicitly - the format version stays 1,
    since adding a type is additive under the must-ignore rule.
  • Tests: @coverage grows to 19 pairs; a new describe covers the assign,
    <data>-binding, and <invoke idlocation> shapes plus the value codec;
    the type-index drift test now checks 24 types.

Notes

  • Full mix quality green (243 tests, 95.4% coverage, dialyzer clean; the
    two permanent skips, Gettext and Sobelow, are declared not-applicable).
    mix gate.verify also run directly and green.
  • The @coverage maximal literal populates d_index and c_index together,
    a shape the engine never emits - deliberate, so the produced key set covers
    the full documented schema; the real mutually-exclusive shapes have their
    own tests. Called out in a comment at the table.

Closes sui-h92

Adds effect.datamodel_change, the tenth effect.* type: one message per
successful datamodel write, carrying the resolved location_path (a
heterogeneous JSON array - string segments are object keys, integer
segments are array indexes), the raw location_source, and the written
values. new_value and prior_value follow the _event.data three-way
absence rule, since the engine distinguishes unbound (:undefined) from
a stored null here; put_event_data/2 generalizes to put_defined/3 for
all three fields. The owner vocabulary gains the widened "invoke" kind
for <invoke idlocation> writes.

Until now a wire consumer could observe datamodel variable names
(session.datamodel snapshots before the binding fold) but never a
value; folding these messages over that snapshot reconstructs the
datamodel at any point in the run.

The format version stays 1, recorded in the new schema section: adding
a type is additive under the must-ignore rule. Type index grows to 24;
the @coverage table to 19 pairs.

Refs: sui-h92
@johnnyt
johnnyt merged commit 2991987 into main Aug 22, 2026
1 check passed
@johnnyt
johnnyt deleted the sui-h92-datamodel-change-wire branch August 22, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant