Skip to content

Long live OpenSysML - #56

Merged
HuiJun merged 274 commits into
Open-MBEE:mainfrom
JPL-Devin:main
Aug 18, 2026
Merged

Long live OpenSysML#56
HuiJun merged 274 commits into
Open-MBEE:mainfrom
JPL-Devin:main

Conversation

@HuiJun

@HuiJun HuiJun commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

We have renamed the project to OpenSysML, reflecting our commitment to keep this implementation available to the community.

OpenSysML 0.1.0

Everything cut under 0.1.0 in CHANGELOG.md. The release is the project's rename to
OpenSysML plus the first batch of work that makes a model decide, run and render
rather than only parse and resolve.

What this is

A SysML v2 / KerML 1.1 implementation in Go: hand-written lexer and parser, immutable AST with
semantic side tables, lazy memoized name resolution, tiered validation, lowered ActionGraph /
StateGraph execution IR, and four front ends over one core — the sysml CLI/REPL, the
sysml-lsp language server (with a VS Code extension), the sysml-grpc service, and the
opensysml Python client generated against it.

Highlights

  • Objects run the behavior their type exhibits. Materializing an object starts the
    exhibit state machines and performed actions its type declares: one execution, event queue
    and feature-value set per object, entry/do/exit/effect bodies reading and writing that
    object's values, cross-object send reaching the addressed object, and a defined startup and
    quiescence with typed budget errors instead of a hang. %invoke <object> <op> performs an
    operation of the object's type; %state <object> attaches the debugger to the object's own
    machine.
  • An SMT solver decides what a model's conditions permit (experimental, solver optional):
    %check for satisfiability with an assignment, %explain for a minimal unsat core with
    file:line:col per conflicting condition, %solve for a witness that keeps fixed what already
    is, %configure for the variant selections an assertion permits, and %optimize for the
    objectives an analysis def states — lexicographic, with every optimum verified rather than
    reported on trust. What a backend can do is modelled as probed capabilities, so a missing
    feature is a typed refusal naming backend, feature and operation; z3 and cvc5 are both gated in
    CI, with and without a solver present.
  • A view renders. %render <name> [form] and sysml -render turn a view's exposed set into a
    tree, interconnection diagram, state machine, action flow or table, as text, Mermaid or Markdown.
    State and action renderings read the same lowered graphs the runtime executes, so a diagram
    cannot drift from what runs. Rendering is a read: no object is materialized and a debugging
    session keeps stepping across it.
  • A model is edited through the source it was parsed from. ApplyEdits (and model.edit() in
    Python) rewrites the bytes of the parsed source, leaving every untouched byte identical, then
    re-parses and re-analyzes before handing the result back — all edits of a request or none.
  • Behavior converts to RDF (experimental): action and state bodies now have metaclasses and
    round-trip byte-identically through Turtle; 102 of 120 example models convert, up from 71, and
    the remaining 18 are refused with the construct named rather than partly written.
  • Semantics and notation fixes worth calling out: a nested value body governs over an
    inherited value (KerML §7.3.4.5); require/assume bodies resolve and type-check to any depth
    in their own scope; binding connectors propagate in both directions with typed conflict and
    cycle errors; bind accepts qualified and chained ends; named control nodes register their
    names; feature-chain resolution is linear in chain length; and an element reached through two
    scope trees is exposed and rendered once, since a symbol's identity is now the declaration it
    was built from.
  • The exp/ln/log/atan2 inconsistency is gone. They are declared by the non-normative
    OpenSysMLMathFunctions extension, so a bare call is now a typed error naming the import that
    makes it legal, instead of being reported unresolved and evaluated anyway.

Breaking changes

The rename is a clean break — every name has exactly one spelling from this release on:

Was Is
github.com/Open-MBEE/Systemica github.com/Open-MBEE/OpenSysML (old path resolves only for v0.0.x)
pysysml (PyPI, import) opensysml 0.3.0; entry point opensysml-generate, state dir ~/.opensysml, tag opensysml-v*
SYSTEMICA_* env vars OPENSYSML_*
urn:systemica:sysml: urn:opensysml:sysml: (still the sysx: prefix)
SystemicaMathFunctions OpenSysMLMathFunctions
VS Code systemica.* settings opensysml.*, extension opensysml-sysml
archives systemica-<os>-<arch> opensysml-<os>-<arch>, formula Open-MBEE/tap/opensysml

The pre-release "slot" vocabulary is removed rather than aliased, since it never shipped:
%slots%features; Instance.slots and SlotValue are gone from the wire with field
number 3 and the name slots reserved, so neither is reused; the Python client keeps only
features / raw_features / get_feature / FeatureValueError / feature_value*, and requires
the service's feature_values capability before handing back an object, so a pre-0.1.0 service is
named instead of answering with an object that appears to hold nothing. Diagnostic text changed
with the vocabulary (feature value …, do action steps); exit statuses did not.

Not in scope / known limitations

Stated in full under Known limitations in the 0.1.0 changelog entry. The ones that shape
expectations: constraint solving and RDF conversion are experimental (RDF omits expressions
and has no demonstrated triplestore round trip); %optimize needs z3 specifically; an edit sets a
value or renames a declaration and refuses create/delete/rename-of-referenced; only an action
member is executable via %invoke; a package-owned binding does not propagate; and a rendering is
tool-defined output, since SysML v2 §10.2 leaves rendering to the tool.

Verification

gofmt -l . empty, go build ./..., go vet ./..., go test -race ./... and make lint
(staticcheck + gosec) green; the Python suite green against a service built from this source; the
stdlib conformance gate clean; the OMG training corpus at its pinned 98/100 baseline; SMT suites
run under both z3 and cvc5 as well as with no solver present; scripts/check-doc-links.py reports
no broken link. Compliance is tracked rule by rule, with honest status flags, in
docs/project/spec-compliance.md.

HuiJun and others added 30 commits August 17, 2026 10:53
…l-metaclasses

* feat(export): map behavioral nodes to RDF metaclasses

An action or state body converts instead of being refused: the initial and
final node, perform, send, accept, terminate, assign, the fork/join/merge/
decision control nodes, while/loop/for, if/else, and the state machine's
states, substates, regions, entry/do/exit, defer, pseudostates and
transitions, each with a notation to RDF to notation round trip. Shapes that
are not mapped, including a succession that does not name both of its ends,
are still reported with the node named.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* docs(export): record the behavioral RDF mapping and the new conversion rate

102 of the 120 models under examples/ now convert, up from 71. RDF stays
experimental: no triplestore round trip has been run.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(export): carry metadata annotations and implicit kinds through RDF

A metadata annotation was converted as an empty string and lost, and a feature that wrote no kind keyword came back with the kind's canonical keyword written out. Both are now carried, and the annotation shapes that cannot be written back are reported. Corrects the experimental notice, which still said behavioral bodies are refused.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(export): publish the else marker as a sysx term

The flag helper only routes an allow-listed name to the extension namespace, so the else marker of a branch was emitted as sysml:isElse, a term the OMG vocabulary does not define, while the decoder and the docs both name sysx:isElse. It is now written directly, as every other behavioral flag in the file is, and pinned by a test that reads the branch back from the marker alone.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
A path led by a package (`P::alpha.inPort`) reached no occurrence, so the own-port fallback claimed it as a port of the sender and stamped the sender's identity on it, delivering to nobody. addressOwner now resolves the leading prefix that names the owning occurrence, and the fallback only claims a path that starts inside the sending behavior; a path naming several occurrences is unroutable.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
%view instantiated an object of every exposed element for every framed concern on every run, leaving a copy in the runtime each time and computing verdicts against fresh defaults. It now reuses the object the session holds, keeping a created one as %satisfy does.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…ts name

%view filed the object under the quoted notation spelling while every other command files it under the raw qualified name, so an element whose name needs quotes got a second copy the rest of the session could not see.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
addressOwner and slotObject discarded the error from building an object or reading a slot, so an exhausted step budget or an unreadable derived slot surfaced as UnroutableSendError. Both now return the underlying error and resolveAddress propagates it.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…it enabled

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
… tail

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
A conformance report evaluates the object the session already holds for an exposed element, and otherwise materializes one in a runtime of its own, so %view leaves the session's instance map — and every later check reading it — as it found it.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
The first segment of a target was taken from the sending object's slots before name resolution, so a body-local receiver sharing a feature's name was shadowed and the message reached the wrong object. A cross-namespace receiver now also carries the identity of the occurrence owning it, and an address outside every object no longer reaches one.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…with

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
An address now resolves to one of three complete destinations - a port, a
receiving node or an object - built only by constructors that refuse an
incomplete one, and every consumer is held to all of it by Message.reaches
instead of by emptiness tests, so a sibling accept can no longer take a
message addressed to a named part.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
%print writes the whole session model back as SysML v2 notation, and %print <name> one element and its body, through the writer %save writes .sysml with: export.SysMLElement formats one element's source via the same format.Source path, so comments and text as typed survive and a print can be submitted again. Printing is a read: no runtime object, no change to instances, the buffer, or an active %action/%state debugging session.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
A performed action was executed with no object attached, so an accept inside it
presented object 0 and could not take a message addressed to the part performing
it. invokeAction now carries the performer into the nested execution.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
A declaration's span ends where the next token begins, so it runs over the blank lines and comments between the two. export.SysMLElement now cuts the source at the element's last real token, so the note belonging to what follows is printed with that element only.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…jected message to its destination

A qualified target resolved through no occurrence was matched against the sender's own same-named element, so a send to a twin object's port or receiver was confined to the sender; a message injected with a destination but no delivery kind was open to any consumer.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
* fix(runtime): deliver addressed sends by object identity

An addressed `send S() to target` identified its addressee by simple name, so any object owning a same-named port or receiving node could consume the message: traffic crossed topology boundaries no connection crosses.

Lowering now keeps the whole target path for an addressed send, and the runtime resolves it through the instance graph to the object that owns it plus the port path within that object. A delivered message records that object and is confined to it, so a same-named port of another object never sees it; a dotted target reaching no port of an addressable object is an UnroutableSendError instead of a silent delivery.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): keep addressed sends reaching behaviors and qualified names

An addressed send confined to the sending object stopped reaching a behavior
no object performs, and a qualified receiver name (`P::R`) was lowered as a
feature chain, so it resolved to no port and was reported unroutable.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): resolve a qualified addressed target before own features

A qualified receiver was truncated to its last segment and matched against the sender's own features first, so `Other::reader` could be delivered to the sender's own `reader`. Resolve the written name first and fall back to the sender's features only where the bare name names that same element; a port the sender cannot reach is an UnroutableSendError. Adds the addressed unroutable failure mode to the robustness suite.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(lower): render a via target as connector ends are rendered

A qualified via target was rendered with :: while connector ends keep dots, so routing matched no end and the send was reported unroutable. Renders a via target with FeaturePath again; only an addressed target keeps its namespace form.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): address a namespace-qualified path through its object

A path led by a package (`P::alpha.inPort`) reached no occurrence, so the own-port fallback claimed it as a port of the sender and stamped the sender's identity on it, delivering to nobody. addressOwner now resolves the leading prefix that names the owning occurrence, and the fallback only claims a path that starts inside the sending behavior; a path naming several occurrences is unroutable.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): report why an addressee could not be located

addressOwner and slotObject discarded the error from building an object or reading a slot, so an exhausted step budget or an unreadable derived slot surfaced as UnroutableSendError. Both now return the underlying error and resolveAddress propagates it.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): address a receiver by the scope that resolves its name

The first segment of a target was taken from the sending object's slots before name resolution, so a body-local receiver sharing a feature's name was shadowed and the message reached the wrong object. A cross-namespace receiver now also carries the identity of the occurrence owning it, and an address outside every object no longer reaches one.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): build a message's destination whole or refuse the send

An address now resolves to one of three complete destinations - a port, a
receiving node or an object - built only by constructors that refuse an
incomplete one, and every consumer is held to all of it by Message.reaches
instead of by emptiness tests, so a sibling accept can no longer take a
message addressed to a named part.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): run a performed behaviour as the object performing it

A performed action was executed with no object attached, so an accept inside it
presented object 0 and could not take a message addressed to the part performing
it. invokeAction now carries the performer into the nested execution.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): take a qualified address from its qualifier, hold an injected message to its destination

A qualified target resolved through no occurrence was matched against the sender's own same-named element, so a send to a twin object's port or receiver was confined to the sender; a message injected with a destination but no delivery kind was open to any consumer.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
* feat(repl): print the session model as notation at the prompt

%print writes the whole session model back as SysML v2 notation, and %print <name> one element and its body, through the writer %save writes .sysml with: export.SysMLElement formats one element's source via the same format.Source path, so comments and text as typed survive and a print can be submitted again. Printing is a read: no runtime object, no change to instances, the buffer, or an active %action/%state debugging session.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(repl): print an element without the note written for the next one

A declaration's span ends where the next token begins, so it runs over the blank lines and comments between the two. export.SysMLElement now cuts the source at the element's last real token, so the note belonging to what follows is printed with that element only.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Keeps the conformance %view row and main's new %print row in spec-compliance.md.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
devin-ai-integration Bot and others added 29 commits August 18, 2026 13:26
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
* Record how to test %optimize in the sysml REPL

Co-authored-by: jason.han <jason.han@jpl.nasa.gov>

* docs(skills): record the article a kind's first letter chooses

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Emit the narrowest standard SMT-LIB 2.6 logic a query needs instead of ALL,
falling back to the non-standard ALL only for datatypes and strings, which the
logic list covers with nothing, and saying so in the script and the docs.

Model what the layer requires of a backend as capabilities, probed once per
executable (or declared by the caller) and cached, so an unsupported feature is a
typed UnsupportedCapabilityError naming the backend, the feature and the
operation rather than a silent degrade or a fabricated verdict. A probe the
backend leaves undecided settles nothing, keeping 'lacks the feature', 'cannot be
run' and 'did not decide' three distinct reports.

Add a portability harness reporting pass/refuse/fail per feature against whatever
OPENSYSML_SMT names, wired into both CI configs against z3 and cvc5.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
… no optimization

cvc5 implements no (minimize …)/(maximize …), so these tests reported the refusal rather than an optimum under it; they now skip with what the backend said, and still run under z3.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…y model

%optimize preflights CapOptimization and CapOptimizationPriority through the shared capability model, so a backend refusing them is a typed NoOptimizationError naming the missing extension rather than a process failure from a script it will not parse.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…ption

A backend declining (set-option :print-success false) would answer it, and that answer would be read as its verdict; the reads already look past the acknowledgements SMT-LIB's default prints, so the opening option is dropped. The fake cvc5 in the %optimize test now rejects the optimization commands as cvc5 does, which is what the capability model settles it by.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…al its own

Nonlinear and mixed arithmetic are now checked in every logic they are emitted
under (QF_NIA/QF_NRA, AUFLIRA/AUFNIRA, div by a variable), so a backend taking
one form and refusing another is reported as lacking the capability rather than
as our malformed script. Optimizing only relabels a refusal as no optimization
when the refused capability is an optimization extension, and cacheKey copies
before appending.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…portability

* feat(solve): make third-party SMT-LIB solvers a supported story

Emit the narrowest standard SMT-LIB 2.6 logic a query needs instead of ALL,
falling back to the non-standard ALL only for datatypes and strings, which the
logic list covers with nothing, and saying so in the script and the docs.

Model what the layer requires of a backend as capabilities, probed once per
executable (or declared by the caller) and cached, so an unsupported feature is a
typed UnsupportedCapabilityError naming the backend, the feature and the
operation rather than a silent degrade or a fabricated verdict. A probe the
backend leaves undecided settles nothing, keeping 'lacks the feature', 'cannot be
run' and 'did not decide' three distinct reports.

Add a portability harness reporting pass/refuse/fail per feature against whatever
OPENSYSML_SMT names, wired into both CI configs against z3 and cvc5.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* test(repl): skip the %optimize solver tests on a backend implementing no optimization

cvc5 implements no (minimize …)/(maximize …), so these tests reported the refusal rather than an optimum under it; they now skip with what the backend said, and still run under z3.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* feat(solve): settle the optimization extensions through the capability model

%optimize preflights CapOptimization and CapOptimizationPriority through the shared capability model, so a backend refusing them is a typed NoOptimizationError naming the missing extension rather than a process failure from a script it will not parse.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(solve): read past acknowledgements instead of sending an unread option

A backend declining (set-option :print-success false) would answer it, and that answer would be read as its verdict; the reads already look past the acknowledgements SMT-LIB's default prints, so the opening option is dropped. The fake cvc5 in the %optimize test now rejects the optimization commands as cvc5 does, which is what the capability model settles it by.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(solve): probe every emitted form of a feature and keep each refusal its own

Nonlinear and mixed arithmetic are now checked in every logic they are emitted
under (QF_NIA/QF_NRA, AUFLIRA/AUFNIRA, div by a variable), so a backend taking
one form and refusing another is reported as lacking the capability rather than
as our malformed script. Optimizing only relabels a refusal as no optimization
when the refused capability is an optimization extension, and cacheKey copies
before appending.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* docs(solve): shorten the multi-check comment

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
A probe reply SMT-LIB does not define, such as `maybe`, says nothing about the
feature: the executable is not answering as a solver. Report it as a
SolverProcessError naming the capability check, keeping capability refusal for an
explicit `(error ...)` or `unsupported` reply.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…utors

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…rocess-error

A probe reply SMT-LIB does not define, such as `maybe`, says nothing about the
feature: the executable is not answering as a solver. Report it as a
SolverProcessError naming the capability check, keeping capability refusal for an
explicit `(error ...)` or `unsupported` reply.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
* feat(runtime): execute binding connectors

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): refine binding endpoint resolution

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): avoid stale binding outcomes

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): distinguish binding cycles from unset ends

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): resolve nested binding paths

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* test(runtime): tidy nested binding container assertion

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): handle named binding declarations

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): correct binding endpoint values

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): keep exact set equality bucketed

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): refresh binding-derived values

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): format binding collections and reject ambiguous contributors

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(runtime): preserve set order in binding diagnostics

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
* Add SMT capability/optimize recipes to the sysml REPL testing skill

Co-authored-by: jason.han <jason.han@jpl.nasa.gov>

* docs(skills): make the solver-tee recipe runnable as written

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
…and edit features it was missing

The release notes carried two sections for one unreleased version, and the
0.1.0 one described intermediate states the merged release supersedes: the
pre-rename Python name, the pre-behavior RDF model counts, SYSTEMICA_* and a
known limitation the mapping's behavior coverage closes.

The SMT solving path (%check, %explain, %solve, %configure, %optimize, the
capability model and the portability and differential gates) and the
source-preserving edit path (ApplyEdits, model.edit()) had landed with no
changelog entry at all, and no row in the README capability table.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…d through

A document's own scope tree and the global index build a symbol each for one
declaration, so pointer identity made a wildcard or filtered expose show an
element as many times as it was reached. symbols.KeyOf keys an element by the
declaration it was built from; resolve, semantics, edit and the LSP share it.

Also adds the solver and views demo models with walkthroughs, and names a
rendering kind with the article it reads with ("an action rendering").

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
* docs: fold the pending changes into the 0.1.0 entry, with the solver and edit features it was missing

The release notes carried two sections for one unreleased version, and the
0.1.0 one described intermediate states the merged release supersedes: the
pre-rename Python name, the pre-behavior RDF model counts, SYSTEMICA_* and a
known limitation the mapping's behavior coverage closes.

The SMT solving path (%check, %explain, %solve, %configure, %optimize, the
capability model and the portability and differential gates) and the
source-preserving edit path (ApplyEdits, model.edit()) had landed with no
changelog entry at all, and no row in the README capability table.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(view): expose an element once, whichever scope tree it was reached through

A document's own scope tree and the global index build a symbol each for one
declaration, so pointer identity made a wildcard or filtered expose show an
element as many times as it was reached. symbols.KeyOf keys an element by the
declaration it was built from; resolve, semantics, edit and the LSP share it.

Also adds the solver and views demo models with walkthroughs, and names a
rendering kind with the article it reads with ("an action rendering").

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
%slots, Instance.slots/SlotValue on the wire, and the slots/raw_slots/get_slot/SlotError spellings in the Python client never shipped in a release, so 0.1.0 takes the clean break. Proto field 3 and the name slots stay reserved.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…k an object

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>
…ated-slot-api

* feat(api)!: remove the deprecated slot spellings before 0.1.0

%slots, Instance.slots/SlotValue on the wire, and the slots/raw_slots/get_slot/SlotError spellings in the Python client never shipped in a release, so 0.1.0 takes the clean break. Proto field 3 and the name slots stay reserved.

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

* fix(python): require the feature_values capability before handing back an object

Co-Authored-By: jason.han <jason.han@jpl.nasa.gov>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jason.han <jason.han@jpl.nasa.gov>
@HuiJun
HuiJun merged commit ff3616c into Open-MBEE:main Aug 18, 2026
3 checks passed
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