2.0.0-rc.24
Pre-release2.0.0-rc.24
Delta since 2.0.0-rc.23.
Two language rules, both with corpus cost
A constructor must supply every field. A partial constructor is now an error.
There is no guessing a default and no letting an old state value creep through: the
model states the full state it is setting, or it does not compile. empty — which
shipped in rc.23 — is how an absent optional is supplied explicitly, and a bare
empty is now checked against the field's cardinality, so it is rejected where the
type demands at least one value.
No set after a morph. Once an entity has morphed, its state is the new
state; a subsequent set either belonged in the morph's own record constructor or
belongs in the new state's handler. Recorded in the Computational Model.
Both land with real corpus cost — riddl-models has 2,309 partial constructors and
115 set-after-morph sites — which is why they ship as an RC first. The corpus could
not migrate ahead of them, because the rules did not exist to migrate against.
riddlc dump --json — a scriptable projection of the model
A flat, machine-readable record per AST node, with source spans and resolved
references. --jsonl streams one record per line; -o writes to a file.
This exists because model-wide campaigns were being driven by regex over .riddl
text — there was no other way to ask a model a structural question. In one session
those scripts produced nine distinct defects, three of them the dangerous shape
where the run succeeds and reports a confident number computed over nothing.
riddlc already knows the answers; now they are reachable.
Diagnostics moved to stderr. Anything a script is meant to parse goes to
stdout; [info]/[error] lines no longer corrupt a pipe.
riddlc find — Unix find, over definitions instead of files
riddlc find model.riddl -type inlet -under-a repository -carries event
Tests cover identity (-type, -name, -path, -regex), containment (-in,
-under-a, -under-name), structure (-maxdepth, -empty, -stub) and RIDDL
facts (-option, -intention, -shape, -arity, -carries, -cardinality,
-unresolved). Output actions are -print, -location, -printpath, -list,
-printf, -print0.
The match count is always printed, including zero, and -expect-min N turns a
short count into a failure — because a selector that silently matched nothing is
indistinguishable from a clean model.
Editing: -exec, -replace, -delete
-exec runs a command per match (;) or once for all of them (+). -replace
makes the script's stdout the node's new source text. -delete removes the span.
Every script receives the node's JSON record on stdin, including a source key
with the exact span text — so the identity transform is jq -r .source.
Nothing is written on a guess. Every script runs first and applies nothing; the
run is refused whole if any script failed or any two spans overlap; then the model
is rewritten, re-parsed and re-validated, and every file is restored if the model
stopped parsing or merely gained errors. -dry-run shows the diff without
writing. Overlapping edits are refused rather than ordered, since which of two
conflicting rewrites survived would otherwise depend on application order.
What feedback is wanted
Whether the two new rules are right, and what they cost you. The constructor rule
in particular is deliberately strict — explicit over convenient — and the corpus
migration against it is the real test of that choice.