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
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).
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.