StatifierBlocks.Core.Assign (StatifierBlocks v0.2.0)

Copy Markdown View Source

core.assign: a leaf step that writes one literal to one datamodel path.

PROVISIONAL - not yet in the vocabulary table

core.assign is a campaign-013 spike proposal (spike/js/proposed-core.js) that ADR-0002 decision 10's vocabulary table, and its 2026-08-28 amendment, do not yet carry - the amendment's section D promotes core.invoke and core.raise only. This type is shipped under the campaign's filing; the decision-10 row it is owed has not been written.

Two config fields: path, the datamodel location to write; value, the literal to write there.

value is SOURCE TEXT

value stores the literal exactly as an author would type it - false, 42350, "manual_review", quotes included for a string - which is why it lands in the compiled expr attribute unchanged. This is not a shortcut around ADR-0002 decision 7's closed field-type set; it is the same string-of-source-text rule this package already applies wherever a literal has to survive verbatim.

Expressions are deliberately not supported in V1. The obvious next value is one computed from datamodel state, and this module does not build it: which expression language, how it would be stored, and whether a block document may carry an expression that must be evaluated to compile are jointly predicator-ex's and statifier-ex's calls, not this package's. Literals only, said out loud here rather than discovered by a reader.

The declaration check is not here, and cannot be

validate_config/1 is handed a config, not a document, so "is path declared in the datamodel?" is a question this callback has no document to answer against. That check, if a host wants one, is a document-level pass over the whole tree - not this type's business.

What an assign to an undeclared location means, and how the write is ordered against a state's other onentry content, are both statifier-ex's and both open.

Summary

Functions

A compound state whose entry writes expr to location and immediately goes final.

core.raise's io/1 exactly, for core.raise's reason: one outcome, so there is no join to refuse and produces is absent rather than :unknown. An assign reads nothing through the type flow either - its input is a literal it carries - so there is no consumes.

Functions

emit(block, context)

A compound state whose entry writes expr to location and immediately goes final.

<state id="s_blk_ASN" initial="s_blk_ASN__done">
  <onentry><assign expr="false" location="review.parked"/></onentry>
  <final id="s_blk_ASN__done"/>
</state>

Emission.element/3 normalizes attribute order alphabetically, so the written attribute order is expr then location regardless of the order they are passed here.

Both attributes are annotated: location from the "path" config field, expr from the "value" field, verbatim - the <assign> element is this block's own, but each attribute value is the author's (ADR-0004 decision 9).

io(config)

core.raise's io/1 exactly, for core.raise's reason: one outcome, so there is no join to refuse and produces is absent rather than :unknown. An assign reads nothing through the type flow either - its input is a literal it carries - so there is no consumes.