@@ -4,10 +4,45 @@ Notable changes per release. Format follows [Keep a Changelog](https://keepachan
44versions follow [ Semantic Versioning] ( https://semver.org/spec/v2.0.0.html ) . Cutting a release
55is described in [ docs/project/releasing.md] ( docs/project/releasing.md ) .
66
7- ## Unreleased
7+ ## 0.4.0 — 2026-08-28
8+
9+ Release 0.4.0 is about what a model * writes* . An ` assign ` used to put any value into any feature —
10+ a ` String ` into a ` Real ` attribute, a length into a duration — statically and at run time; a write
11+ now answers to the target feature's declared type, multiplicity and, where the target is a quantity,
12+ its dimension, on every path that stores a value. ** A model that relied on an unchecked write no
13+ longer validates** , which is why this is a minor rather than a patch.
14+
15+ The runtime also learned the structure it was flattening away: a typed state usage materializes the
16+ content of the definition typing it, a nested action node runs the flow it owns, an assignment target
17+ may be a feature chain, and a performed action's features live on the performance occurrence that
18+ holds them rather than on whatever like-named feature the performer happened to have. A behavior body
19+ now resolves a name where the name is written rather than reaching into the performer for it.
20+
21+ Beyond execution, a view specializing ` SequenceView ` renders as a sequence diagram, a ` Real ` prints
22+ as the shortest decimal that reads back as the same value, and the pinned OMG pilot implementation
23+ moves to release ` 2026-07 ` (` jupyter-sysml-kernel ` 0.61.0) with every oracle baseline re-recorded
24+ against it.
825
926### Changed
1027
28+ - ** A write answers to its target feature's declared type and multiplicity.** An ` assign ` wrote any
29+ value into any feature: a ` Real ` attribute accepted a ` String ` , statically and at run time. KerML's
30+ FeatureWritePerformance "assigns the values of a feature on an occurrence to the given
31+ replacementValues", so those values are values of that feature — the rule already applied to an
32+ initial value. The type pass now walks every body an ` assign ` may stand in and checks the written
33+ value with the initial-value rule resolved against the target's declaration, and the runtime checks
34+ the same before storing, on every write path. A rejected write leaves the feature as it was.
35+ - ** An output a declaration binds is checked too** , so a body-less ` out a : Integer = n ` no longer
36+ answers with whatever an untyped input carried: the rule holds however an output is given its
37+ value.
38+ - ** A written decimal conforms to ` Rational ` ** , as the type tier already read one. The two tiers
39+ disagreed, so a decimal written to a ` Rational ` feature validated clean and then failed at run
40+ time.
41+
42+ - ** A bound or written quantity is judged by the dimension its target declares.** A feature declared
43+ with a quantity value type refuses a quantity measured in another dimension — statically where the
44+ value's dimension is determined, and at run time on every write path.
45+
1146- ** The pinned OMG pilot implementation is now release ` 2026-07 ` (` jupyter-sysml-kernel ` 0.61.0)** ,
1247 with the reference validators, the vendored standard library, the pinned corpora, grammars and
1348 Xpect suites, and every oracle baseline re-recorded at that pin. Two notations the new grammar
@@ -30,6 +65,19 @@ is described in [docs/project/releasing.md](docs/project/releasing.md).
3065
3166### Added
3267
68+ - ** A typed state usage inherits the content of the definition typing it.** The definition's
69+ substates, initial transition, entry/do/exit behaviors, transitions, deferred events and
70+ attributes are materialized per usage rather than shared, including inside a parallel body.
71+ Recursive typing, and content lowering cannot represent, are typed errors rather than silence.
72+
73+ - ** A nested action node runs the flow it owns.** A nested node's own members are its
74+ subperformances: lowering carries them as a subgraph and the executor performs that flow before
75+ the node completes. An action usage stating no body of its own resolves to the action definition
76+ typing it, so ` %action ` on a ` perform ` usage runs.
77+
78+ - ** An assignment target may be a feature chain.** Lowering carries the whole walk and the runtime
79+ writes the feature on the object the chain reaches, resolved in the statement's own scope.
80+
3381- ** A view specializing ` StandardViewDefinitions::SequenceView ` (or ` sv ` ) renders as a sequence
3482 diagram** , at the prompt (` %render ` ), from the command line (` sysml -render ` ) and over the LSP, in
3583 the text form and as a Mermaid ` sequenceDiagram ` . The occurrences an interaction declares in its
@@ -45,9 +93,57 @@ is described in [docs/project/releasing.md](docs/project/releasing.md).
4593
4694### Fixed
4795
96+ - ** A behavior body resolves a name where the name is written** , rather than reaching into the
97+ object performing it for any like-named feature — which name resolution does not admit. A
98+ performer feature is read and written only where the name resolves to it, and ` this ` inside an
99+ owned performance denotes the owning object.
100+
101+ - ** A performed action's features are written to its performance occurrence.** A performed action's
102+ declared attributes and out parameters are features of the action performance the ` perform ` usage
103+ holds, so they are initialized from that occurrence's slots and written through it.
104+
105+ - ** A state's attributes reach the occurrence exhibiting it** , so an exhibited state and the
106+ occurrence behind it no longer hold divergent data.
107+
108+ - ** A send nested in a flow is routed by every flow around it.** A send saw only the action's own
109+ connectors and those of the flow it sat in, so a connector declared by an intermediate flow could
110+ not route it; each activation now carries the connectors of every enclosing flow.
111+
112+ - ** An inherited transition retargets to a redeclared substate** , rather than to the substate the
113+ supertype declared.
114+
115+ - ** A machine's own supertype is no longer read as recursive typing** , which rejected a state
116+ machine that specialized another.
117+
118+ - ** A chained assignment binds no output of a calculation** : the chain's last segment was counted as
119+ the calculation computing an output of that name.
120+
48121- ** Clicking a sequence participant now reveals its declaration, and the cursor highlights it**
49122 using Mermaid's participant data attributes.
50123
124+ - ** The site's OpenMBEE links point at the host that serves HTTPS.**
125+
126+ ### Project
127+
128+ - ** The end-to-end example is one model, driven three ways.** A bomb-disposal robot whose structure,
129+ calculations, fork/join and nested flows, hierarchical state machine, solver cases and views are
130+ the same model throughout, with a walkthrough of the commands that drive it from the CLI, the REPL
131+ and the Python client. A nested action node no longer reports the token-flow limitation when a
132+ view renders it.
133+
134+ - ** The dimensional defect in the pilot's ` Dynamics.sysml ` is a declared erratum** , so the corrected
135+ copy is what the oracles re-run over and the published corpus is still never edited.
136+
137+ - The documentation site states the Open-MBEE and NumFOCUS affiliation in its footer, and the
138+ header's wiki link is labelled Community Wiki.
139+
140+ - ** The Python client is unchanged in this release** , so no ` opensysml ` version is published with
141+ it: the client published as 0.3.2 installs a v0.4.0 ` sysml-grpc ` by taking the asset's digest from
142+ the release's signed ` SHA256SUMS.txt ` , which is what an unpinned release's verification is for.
143+ Pinning v0.4.0's digests in ` python/opensysml/binary.py ` and publishing 0.3.3 remains optional,
144+ and is worth doing only for callers still on ` opensysml ` 0.3.0, which predates that path and
145+ installs a release it pins no digest for only under ` $OPENSYSML_ALLOW_UNPINNED_DOWNLOAD ` .
146+
51147## 0.3.1 — 2026-08-27
52148
53149A performance patch. Loading a model costs less of everything and answers the same: on a
0 commit comments