Skip to content

v0.9.2 - Interchange Fidelity Release

Choose a tag to compare

@HuiJun HuiJun released this 05 Oct 14:21
· 6405 commits to develop since this release
4226ad9

OpenSysML 0.9.2

0.9.2 is a patch release on 0.9.1, cut from main: the interchange fixes asked for on the 0.9.1
line — a converted model names the library elements it references, Convert takes the id form,
successions, transitions, variants and requirement constraints are exported in the shape the
grammar gives them, the service reports the parser's diagnostics as the command line does — and
the Python client's release work: a typed reader for API and toolkit JSON, and a wheel that pins
the service release it was built against. It carries none of the features that follow 0.9.1 on
develop. Eighteen develop pull requests, the export fixes of a nineteenth and the two
Windows-installer hotfixes are in; full detail per change is in
CHANGELOG.md § 0.9.2.

The wire is additive (ConvertRequest.id_form, one new optional field; buf breaking
against the 0.9.1 api/proto reports nothing). The notation accepted by 0.9.1 is accepted by
0.9.2 with one exception, under Upgrading.

Upgrading

  • Interchange output changed shape. Turtle, API JSON and Convert now write every referenced
    standard-library element as an element of the graph (isLibraryElement), a succession's two
    ConnectorEnds, a transition's source member and parameter members, variant x; as a
    VariantReference, a bare require c; as a ReferenceSubsetting, and nonunique as
    sysml:isUnique false; the metamodel table moved to the OMG 20250201 metamodel and declares
    FlowUsage, PayloadFeature, FlowEnd and TerminateActionUsage. Graphs written by 0.9.1
    still read; goldens pinned to 0.9.1's output need refreshing.
  • Diagnostics that moved. A usage that implicitly subsets a unique library feature
    (action def A { action b[*] nonunique; }) is now an error at the declaration, as a written
    :> was (#726). The gRPC service now
    reports the parser's errors and warnings — a reserved keyword written as a name, a
    nonstandard-notation warning under strict conformance — so a service client sees the
    diagnostics the CLI always reported.
  • The writer refuses what it cannot export faithfully. A succession end with no target, a
    transition whose source member disagrees with its sysml:source, or a variant x; whose x
    does not reach the referenced feature is refused with a diagnostic rather than written
    approximately.
  • Python. A download refused for want of sigstore raises SigstoreUnavailableError (an
    UnpinnedReleaseError) naming the install. opensysml.metamodel is new.
  • REPL. Ctrl-C at an empty sysml> prompt exits (status as %quit); at a ...> continuation
    it discards the buffered text instead of submitting it.
  • Migration output changed. The SysML v1 migrator drops nonunique where v2 forbids it and
    writes an orthogonal region's entry; then s; in the region that owns the target; both are
    marked approximated in the report.

Interchange: API JSON, Turtle and Convert

  • Library references resolve. A reference to a standard-library element is its normative id,
    a hash no reader can turn back into a name. Each referenced library element is now stated under
    that id with its metaclass, qualifiedName and declaredName, so every @id an API JSON output
    references is an element of it (#731).
  • Convert takes the id form. ConvertRequest.id_form is qualified (the default) or
    uuid, as sysml -id spells it, for ttl and api-json output from content, a file or a
    parsed model (#732).
  • Normative shapes. first a then b; owns its two connector ends under
    EndFeatureMembership (#760); a
    transition owns the FeatureChainMember naming its first source and its parameter members,
    and first b.c/then b.c read back as written
    (#803); variant x;, variant P::x; and
    variant a.b; are VariantReferences; a bare or chained assume/require/assert is a
    ReferenceSubsetting; MultiplicityRange::bound and Flow::flowEnd are written as arrays.
  • Toolkit full-JSON imports preserve flows, transitions and library references; a library
    stub with a stale id resolves by its qualified name with a warning; reference-usage return
    parameters keep their metaclass on a round trip; bulk decoding no longer rescans the graph per
    owner.

Service and query

  • A query can select, where and OSLC-filter an element's elementId — the id Convert
    writes for it — so a query result joins a converted graph
    (#733); of two elements named alike in
    two scopes each now reports its own.
  • ParseFile, ParseSources and edits report the parser's diagnostics once, as the workspace
    does, for every client language.

Python client

  • opensysml.metamodel: generated SysML v2 metaclasses and read_json, a lazy typed reader
    over API and toolkit JSON that needs no engine — PartDefinition → owned AttributeUsage →
    its library MassValue type as attributes, with range checking (check_ranges=False to opt
    out), custom metaclasses through supertypes=, DataVersion envelopes unwrapped, malformed
    values reported when read. See
    Python metamodel classes.
  • The wheel installs its own release. The release pipeline builds the sysml-grpc binaries
    first and stamps their digests into the wheel and sdist, failing the release unless all five
    service assets are pinned and match the signed SHA256SUMS.txt; pip install opensysml==0.9.2
    then opensysml.connect() downloads and verifies 0.9.2's service with no environment variable
    and no sigstore at run time. Java does the same; a crate published from the tag carries the
    digests too.
  • The PyPI page reads a short README; the long one moved to client/python/DEVELOPING.md.

SysML v1 migration

  • isUnique="false" on a property that becomes a composite part/item/action — or anything
    else implicitly subsetting a unique library feature — is written without nonunique, read from
    the bundled library through the checker's own rules, so the output validates clean. Attributes,
    references and parameters keep it.
  • An initial pseudostate whose transition enters a sibling orthogonal region becomes that
    region's entry instead of leaving the machine to stop at initialization with
    region … has no initial state; coinciding entries are written once, conflicting ones refused
    with both targets named.

Engine, REPL and examples

  • MeasurementReferences::one is the identity of the unit product: 0.7 [one] * 800 [W] is
    560.0 [W], power * duration * efficiency folds to 67200.0 [SI::J] and is admitted to an
    EnergyValue; rad, sr and a percent stay in the product.
  • Ctrl-C at an empty prompt exits the REPL; at a continuation prompt it discards the line.
  • The messages-and-events demo validates clean
    (#758).

Performance

Parity with 0.9.1, measured as for 0.9.1 against 0.9.0 (every benchmark on both revisions,
benchstat over six runs, doubtful rows re-run interleaved): no row regresses by a margin the
re-run confirms; package geomeans move within the machine's spread (−2.3% to +1.1%).
The one systematic difference is the model loader, which allocates +0.4–0.7% bytes per element
(+0.08% allocations) for the semantic fixes' bookkeeping — not measurable in time. sysml -validate on 3 000-, 6 000- and 12 000-declaration models and on the Apollo 11 model is the same
wall time and resident set to the 10 ms / 1 MiB resolution; the binary is 128 KiB larger; an
empty session starts in the same 0.02 s. Record:
performance-release-0.9.2-vs-0.9.1.md.
The Python client's paths were not measured; no benchmark covers them.

Packaging

  • Linux amd64/arm64, macOS amd64/arm64 and Windows amd64 archives, sysml-grpc binaries with
    .sha256 sidecars, SHA256SUMS.txt with its cosign bundle and SLSA provenance, the Python
    wheel and sdist, and the npm, Maven Central and crates.io packages are built by the release
    workflow from tag v0.9.2. New: the wheel, sdist and crate pin the service digests of this
    release (above).
  • The Windows MSI jobs no longer check out the repository on Windows — they consume the packaging
    inputs the Linux job uploads — and release-windows.yml can be re-run against an existing tag
    (gh workflow run release-windows.yml --ref main -f tag=v0.9.2).
  • macOS binaries are not Developer ID signed or notarized;
    macos-distribution.md
    gives the workarounds.

Verification

The pre-tag gate of docs/project/releasing.md on the release commit (Go 1.25, Linux amd64):
gofmt -l . empty, go build ./..., go vet ./..., golangci-lint and gosec clean,
go test -count=1 ./... all packages ok with the OMG training corpus, the three pilot corpora,
the pilot library XMI and the PSSM suite required and the RDF round-trip ratchet unmoved, the
race suite in CI, the Python client's 1317 tests, the metamodel and ontology table drift checks,
buf breaking against the 0.9.1 schema with no breaking change, and the documentation id, link
and figure checks, mkdocs --strict and python3 scripts/changelog.py check clean. The merged
main passes the SonarCloud quality gate (new-code coverage 85.9%, no open bug or vulnerability).

Each fix was then exercised on the built 0.9.2 sysml and sysml-grpc beside the 0.9.1 build
on the same input — library elements and dangling @ids in API JSON, id_form over gRPC,
succession ends, parser diagnostics over gRPC, implicit-subsetting uniqueness, elementId in
OSLC, the [one] identity, migrated nonunique and orthogonal entries, Ctrl-C, the toolkit JSON
fixtures, the Python reader — and the example models checked validate clean on both. The Python
packaging steps (digest stamp, wheel and sdist verification, a no-sigstore install downloading
its pinned service, tampered and unpinned downloads refused) were rehearsed with the exact
pipeline commands before tagging. Every change in the range merged through the pull-request CI
on develop and, for the release branch, through the full pull-request CI against main.