Skip to content

Nightly snapshot 2026-10-31 (nightly-20261031-d16ca71e0)

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 31 Oct 10:05
d16ca71

Development snapshot of develop, not a release. Built 2026-10-31 from d16ca71, 1617 commits after v0.11.0 (compare), by this workflow run. Every binary reports nightly-20261031-d16ca71e0.

The snapshot is published twice: as nightly-20261031-d16ca71e0, which is kept for 14 days, and as the moving alias nightly, which the next night's snapshot replaces. It is never the latest release; Homebrew and the Windows installer follow the stable line only. The sysml-wasm.wasm module, the browser REPL sysml-prod.wasm.gz and the matching wasm_exec.js are available in its assets. The snapshot page explains what it is, how to verify it and what to expect from it; the install guide covers the stable releases.

The Python and Node clients built from the same commit are published as development versions that no default install picks up: pip install opensysml==0.11.1.dev20261031 and npm install @openmbee/opensysml@0.11.1-nightly.20261031.gd16ca71e0 (the nightly dist-tag). Each starts this snapshot's sysml-grpc: the wheel pins the digests of the nightly-20261031-d16ca71e0 assets, and the npm platform packages carry the binaries.
The Jupyter kernel built from it is pip install jupyter-opensysml-kernel==0.11.1.dev20261031, whose platform wheels bundle this snapshot's sysml-jupyter-kernel and whose sdist downloads it by the same pinned digests.

opensysml-sysml.vsix is the VS Code extension built from the same commit: code --install-extension opensysml-sysml.vsix, with a snapshot's sysml-lsp on your PATH or named by opensysml.server.path.

Verify a download against the signed manifest:

sha256sum -c --ignore-missing SHA256SUMS.txt
cosign verify-blob SHA256SUMS.txt --bundle SHA256SUMS.txt.bundle \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity https://github.com/Open-MBEE/OpenSysML/.github/workflows/nightly.yml@refs/heads/develop

Unreleased changes in this snapshot

One line per entry; the full text is under changes/unreleased/ and CHANGELOG.md at this commit.

Added

  • The Apache Airflow provider is documented alongside the other surfaces: a README feature entry and status row, a reference page (docs/reference/airflow-provider.md) mapping its assets, operators, sensors, requirement gates and SysMLActionDag to the service calls behind them, and entries in the downloads page and the client-choice list.
  • Add an optional, checksum-verified APE reference model migration regression covering generated syntax, nested requirement references, report identities, and attached images.
  • API JSON export can provide a separate standard-library name table without adding library elements as roots, with an opt-in legacy ownerless-stub mode for existing consumers.
  • Document prose can be written as AsciiDoc: a KerML textual representation rep language "asciidoc" /* … */ inside a Document or Section expands in place into content blocks, and one inside a part : Paragraph yields that paragraph, alongside the Markdown form.
  • -doc-form asciidoc renders a document as AsciiDoc from the compiled document tree — =/== headings by level, block anchors and <<anchor,text>> cross references, link: macros, _emphasis_, *strong*, `code` and stem:[…] runs under a :stem: latexmath header, |=== tables with [cols] percentages from columnWidths and spanning group rows, */. lists, term:: definitions, [stem] formula blocks, image:: macros and diagram sources in [source,<form>] listings, every model string escaped so it cannot open AsciiDoc structure — and -render-documents -doc-form asciidoc writes a set of .adoc files whose cross-document references are xref: macros.
  • Java client: ConversionOptions.withIncludeLibraryStubs restores the pre-0.11.0 library stubs in api-json (gated on the convert_library_stubs capability) and a Conversion carries its libraryReferences; Model.renderView takes compartments and Model.importData takes importAs (Model.IMPORT_AS_VALUES), the request options the other clients already expose.
  • Julia client: convert_* take id_form (ID_FORM_QUALIFIED or ID_FORM_UUID) and include_library_stubs (gated on the convert_library_stubs capability) and a Conversion carries its library_references; render_view takes compartments, each RenderNode naming its compartment; import_data takes import_as; and an UNAUTHENTICATED status arrives as AuthenticationError.
  • MATLAB client: convert takes idForm ('qualified' or 'uuid') and includeLibraryStubs (gated on the convert_library_stubs capability) and a Conversion carries its libraryReferences; renderView takes compartments, each node naming its compartment; importData takes importAs; and an UNAUTHENTICATED status raises opensysml:connect:unauthenticated.
  • Node client: convert takes idForm ("qualified" or "uuid", the spelling of derived ids in a graph), an OSLC query is preflighted on the service's oslc_query capability (exported as CAPABILITY_OSLC_QUERY), and an UNAUTHENTICATED status arrives as the new AuthenticationError.
  • Documentation: a client feature-parity page (docs/reference/client-parity.md) comparing the Python, Node, Java, Rust, Julia and MATLAB clients option by option, each cell linked to its proving test, with the open gaps and their estimates.
  • Python client: convert takes id_form (ID_FORM_QUALIFIED or ID_FORM_UUID) and include_library_stubs, and query takes oslc — OSLC Query 3.0 text evaluated in place of the standard's Query — on both Connection and Model, each gated on the service's convert_library_stubs and oslc_query capabilities; a Conversion carries the library_references (LibraryReference) an api-json conversion names beside its elements.
  • Rust client: ConvertOptions.include_library_stubs restores the pre-0.11.0 library stubs in API JSON (gated on the convert_library_stubs capability), a Conversion carries its library_references (LibraryReference), and DataImportOptions.import_as names what each imported row is made into.
  • Execution-conformance instance fixtures can pin, beside each validation verdict, the verification cases run about the requirement it asserts — the verifications list of a validation.verdicts entry names each case, the object it ran on, its verdict kind and the objective verdicts of the same run — so one fixture holds a satisfaction verdict and the verification verdict -validate prints with it.
  • CI audits every dependency tree for known vulnerabilities and fails on a finding.
  • DocumentQueries::Differ(left, right, key, column): a keyed value comparison of two projected tables — one row (key, left, right) per key value on both sides whose column cells differ.
  • Markdown and AsciiDoc document bodies read model values into the prose: [label](sysml:value:<target>) and sysml:value[<target>, label] plan a value run that resolves the feature as a sysml: reference does and renders it as the same feature renders in a SpanColumn cell — quantities with their unit, strings, booleans, enumeration literals, multi-valued features joined — reading the session's object when it holds the chain's root.
  • Whole-document markup bodies: a Markdown or AsciiDoc rep in a Document or Section may now carry headings (#…######, ==…), which open Sections nested by level in place among the sibling parts, so one body can write a whole document outline.
  • The drawio rendering form routes every edge the model leaves unrouted before it writes the file, with the libavoid orthogonal router the VS Code diagram panel draws with, run in-process from its WebAssembly build and checked point for point against the panel: each edge's ends are written as its anchors on the two cells and its bends as waypoints, around the boxes and to the ports of the view, inside the container the edge belongs to, and a stated Route is kept as written.
  • A drawio rendering form writes a view as an uncompressed diagrams.net (draw.io) file that draw.io desktop, diagrams.net and the VS Code draw.io extension open and edit: tree, interconnection, state, action, case, mixed, requirement, definition and package renderings, with the §8.2.3 notation's node and edge glyphs, nested parts and regions as container children, ports on the border, stated positions, routes, colours and fonts, notes and pictures, and every cell tagged with the element's qualified name and declaration for later tooling.
  • sysml -import-diagram, the LSP opensysml/importDiagram request, the MCP import_diagram tool and the VS Code Import Diagram command read three more kinds of edit back from a draw.io file: an element renamed by retyping its cell's text (applied as a rename, so its declaration and every reference move, through the path a Layout of the cell takes), a note whose text was edited, and a picture whose image source was changed to a file the model can name.
  • A draw.io file the drawio rendering form wrote and a user edited in draw.io is imported back as DiagramLayout metadata (Layout, Route, Style, Canvas, Note, Picture) through the model editor, by sysml -import-diagram <file> [-view <name>] [-dry-run], the LSP request opensysml/importDiagram, the MCP tool import_diagram and the VS Code command Import layout from draw.io…; only cells that differ from a fresh export are written, and cells the model cannot carry are reported.
  • The editors guide (docs/guide/08-editors.md) gains a Helix, Neovim and Zed section pointing at the tree-sitter-sysml grammars and query files, with the Helix languages.toml declaration that pairs them with sysml-lsp.
  • The in-browser engine (sysml-engine) honours advance on ExecuteState and ExecuteAction as sysml-grpc does, running a state machine or an action for a simulated duration, through one runtime implementation both share; the homepage hero gains a "Mission phases on the clock" scene that runs MissionSequence::MissionPhases on the engine for 400,000 s (or 800,000 s) and animates the trace it records, clock instants included.
  • ExecuteAction takes trace and events: the run's trace comes back as DocumentEvent records of each token step, wait, accept, send, decision, assignment and the completion (capability action_trace, in the wasm module too), and the events are posted to the performer in turn as the run waits, as the REPL's %send does; every client passes both options.
  • Go client client/opensysml: WithIDForm (IDFormQualified, IDFormUUID) and WithLibraryStubs conversion options, with the LibraryReferences an API JSON conversion names; WithBaseModel on ParseDocuments, filling the model's Affected document names (gated on parse_sources_affected); and ImportAs (ImportAsValues) on ImportData — the request options the other clients already expose.
  • sysml-grpc flags -host, -token-file, -token, -allow-unauthenticated, -allow-insecure-token-transport and the OPENSYSML_GRPC_TOKEN variable, with the same meanings the first four have on sysml-mcp; the bearer-token and loopback rules the two commands share live in one package, internal/frontend/guard.
  • The Python (token=, AuthenticationError), Node and browser (token), Java (ConnectionOptions.token), Rust (Connection::external_with_token), Go (opensysml.WithToken), Julia (external(…; token)) and MATLAB (external(…, 'token', …)) clients send a bearer token on every call, defaulting to $OPENSYSML_GRPC_TOKEN; each is tested against a token-protected service.
  • Renderings mark a usage inherited by the owner it is drawn or listed under — through typing, subclassification or subsetting — with the graphical notation's ^ before its name (SysML v2.1 §8.2.3.6): node heads, compartment rows, pinned ports and folded membership-edge labels in the text, Mermaid, DOT, PlantUML and D2 forms and on the VS Code canvas; a redefinition the owner declares reads bare.
  • Java client: ConversionOptions takes withCompact, withOmitDerived, withKeepDerived and withIncludeCheckDiagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in Conversion.diagnostics() with their severities; ParseOptions.withBaseModelHash relates parseSources to a previous model and Model.affected() names the documents whose results may differ (gated on parse_sources_affected).
  • sysml -run-query … -json reports the query's table as data under table: the projected columns in order and one rows entry per row with its element and cells (per column, the values the cell holds as the prompt prints them — empty for an empty cell, several for a collection; an element without a name is spelled by its elementId), beside the row and column counts in values.
  • Julia client: every convert_* takes compact, omit_derived, keep_derived and include_check_diagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in the Conversion's diagnostics with their severities; parse_sources takes base_model_hash and affected(model) names the documents whose results may differ (gated on parse_sources_affected).
  • A library package two documents of the workspace declare — two copies of the standard library under the editor's folder or the OPENSYSML_LIBRARY_PATH tree, a copy of a standard library file beside the bundled one, a user library vendored twice — is reported once per workspace as the library-declared-twice warning, on the copy references do not resolve to, naming the one they do: on the command line, at the prompt, in the editor's problems list, over gRPC/Connect and through the MCP server.
  • A loop an action body reaches is a LoopAction performance of the run, held under the performing action's loops (Actions.sysml loops : LoopAction[0..*] :> subactions), and every iteration performs the loop's body as an occurrence held under the loop's body (LoopAction::body, ControlPerformances.kerml LoopPerformance::body), typed by the body action the loop declares (loop action body { … }) with its nested actions as the body's subperformances; both begin and end with the loop and the iteration, so subperformances, suboccurrences, enclosedPerformances, timeEnclosedOccurrences and this read them, loops#(1).body is [] before the first iteration and never refused, and a loop nested in a body is held under that iteration's body.
  • Document prose can be written as Markdown: a `rep language "markdown" /* ...
  • :>> text = "..." is the spelling the manual and examples now use for a paragraph's text; attribute redefines text = "..." stays equivalent.
  • MATLAB/Octave client: opensysml.convert, Model.convert and Model.save take compact, omitDerived, keepDerived and includeCheckDiagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in the Conversion's diagnostics with their severities; parseSources takes baseModelHash and Model.affected names the documents whose results may differ (gated on parse_sources_affected).
  • Magic MDK: Export as SysML v2… on the Magic MDK context menu writes the project as SysML v2 text.
  • elementId of an owning membership: a query's owningRelationship, owningMembership, ownedRelationship and ownedMembership cells spell each membership by the id the conversion writes for it — the member's id with the _om suffix, or the entry/exit/do member that owns the action it performs — in the REPL, CLI (-json tables), gRPC and rendered documents; the identity reader mints them as the writer does, including which members get none (imports, entry/exit/do members, filters, a one-ended first, a dependency's prefix metadata).
  • The pilot-rejection corpus and the type-tier tests pin that a message typed by an item definition (message m : Note from a.emit to b.receive;) is rejected with A flow usage must be typed by flow definitions., in every spelling of the declaration, exactly as the flow form is: a message declaration is an abstract flow usage (SysML v2.1 Beta 2 §8.4.12.2), and message m of Note names the payload type rather than a typing.
  • sysml -metamodel-table writes the pinned pilot metamodel's table as JSON — every metaclass with its parents and abstractness, every property with its defining class, kind, range, bounds, order, derivation, redefinitions, subsettings and opposite, every enumeration, and the pilot tag, commit and metamodel date — so generators outside this module (the QVTS reflection queries in Open-MBEE/qvts) follow the same table the API-JSON and RDF writers do.
  • A mixed rendering draws the membership of every member nested in its owner's node as an edge from the owner to the member, with the glyph the graphical notation gives that membership: the feature membership's diamond for a usage — filled for a composite usage, hollow for a referential one, with the usage's multiplicity at its end — the owned membership's circle-plus for a nested package, definition or other member that is no feature, and the keyword glyph of a membership drawn as a relationship of its own (require, assume, assert, frame, event, a portion), so no kind is drawn twice and none is left without its glyph.
  • The nightly snapshot builds the Cameo plugin (Magic_MDK_<core>-<tag>.zip, around the night's own sysml-grpc binaries, checked against the night's manifest) and the SysON MDK backend jar and frontend tarball at the night's commit, and keeps them as the run's cameo-plugin and syson-plugin workflow artifacts for the snapshot's 14 days; BinaryStager --from <dir> (-Dopensysml.binaries) stages already-verified binaries in place of a release download.
  • Node client: connection.convert takes compact, omitDerived, keepDerived and includeCheckDiagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in Conversion.diagnostics with their severities; connection.parseSources takes baseModelHash and the Model names the documents whose results may differ in affected (gated on parse_sources_affected).
  • The relationship glyphs of the SysML v2 graphical notation (§8.2.3) whose ends a rendering draws are now edges of their own kind in the DOT, PlantUML, Mermaid, D2 and text forms and the VS Code diagram panel: a succession flow (dashed, filled head, «succession flow») is told from a flow in action and interconnection renderings; a required, assumed or asserted constraint, a framed concern and an event occurrence are «require», «assume», «assert», «frame» and «event» edges with an open head; a timeslice or snapshot carries the three-quarter circle at its occurrence; a ::> reference subsetting its hollow triangle and dots, labelled references; a package's alias of a drawn package the hollow circle of an unowned membership; and a view usage's expose statements dashed «expose» edges to the drawn elements, suffixed */** as imports are.
  • The MCP server's npm runner is also published as @openmbee/opensysml-mcp, the name the other OpenSysML npm packages share: npx -y @openmbee/opensysml-mcp starts the same server as npx -y @openmbee/sysml-mcp, from the same @openmbee/sysml-mcp-<os>-<cpu> platform packages at the same version, through an opensysml-mcp command beside sysml-mcp.
  • docs/project/performance-release-0.12.0-vs-0.11.0.md records the release-gate measurement of 0.12.0 against 0.11.0 in three columns — 0.11.0 as released (go1.25.11), 0.11.0 rebuilt with go1.27.3, and the candidate, first before and then after its performance fixes, with every merge up to the release head accounted for — so that the toolchain change and the source changes are told apart: every benchmark on each, benchstat over six rounds, whole-binary timings on generated and real models, the stress constellation, the export element-ID rows #1699 fixed, and the merge each regression traces to, with the fix pull request each motivated listed as it lands.
  • A plain lib/ directory beside a project's .project.json is now a well-known library directory, read like .sysand/lib: OpenSysML reads what any package manager that follows KerML 10.3 project interchange installs (sysand today) under lib/ or .sysand/lib beside .project.json; it does not fetch.
  • Python client: Connection.convert takes compact, omit_derived, keep_derived and include_check_diagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in the result's diagnostics with their severities; Connection.parse_sources takes base_model_hash and the Model names the documents whose results may differ in affected (gated on parse_sources_affected).
  • Python client: Model.convert, Model.to_api_json, Model.save and the module-level opensysml.convert take the compact, omit_derived, keep_derived and include_check_diagnostics options Connection.convert takes, gated the same way on the service's convert_compact and convert_check_diagnostics capabilities, so a loaded model writes its compact API JSON without dropping to its connection.
  • Project and WhereFeature read any property the SysML metamodel gives an element's metaclass (isComposite, isPortion, direction, ownedRelationship, …), through the reflective evaluator, beside the model's own features; elementId is the id a conversion of the model writes, in the REPL and CLI as in the gRPC query service.
  • A failed document query carries the QVTS outcome record behind its message: queryexec.Error.Outcome, a pathError (Failure{step, expected, frontier} per failing element) or a modelError (Finding{step, element, constraint, observed}), field for field with lean/QVTS/Outcome.lean.
  • Reflective reads (Project, WhereFeature, [@…] filters, metaobjects) now answer Element::aliasIds (none: no notation sets it) and Element::isImpliedIncluded (false) on every element, RequirementDefinition/Usage::reqId (its declared short name), Invariant::isNegated (assert not), Type::isSufficient on a connector end, and, on a declared connector as a Relationship, isImplied (false), ownedRelatedElement and owningRelatedElement (none).
  • The query surfaces (REPL, sysml -run-query, gRPC, documents) spell the relationships an element owns by elementId as the RDF conversion writes them, where they had none: the relationship element of each head clause (: T → _ft0, a definition's :> D → _sc0, a usage's → _sp0, subsets → _ss0, redefines → _rd0, references and an end-form subsets → _rs), a bound connector end's reference subsetting (_prs), an import, and the Annotation of a dependency's prefix metadata (_an).
  • scripts/release-downloads.py prints the download counts of every GitHub release at once — per release with its date and asset count, per asset under each release (--assets), or totalled per asset name across all releases (--by-asset) — with --stable to leave out the nightlies, --json for another tool, and --traffic for the clones and views of the last fourteen days that GitHub's traffic API reports to a token with push access.
  • The release SBOMs now cover every asset class: the WebAssembly modules (sysml-wasm.wasm, sysml-prod.wasm.gz), written by scripts/release-sbom.py from the module information Go embeds in them, which go version -m and syft cannot read from this format; the npm tarballs openmbee-opensysml-<x.y.z>.tgz, openmbee-sysml-mcp-<x.y.z>.tgz and openmbee-opensysml-mcp-<x.y.z>.tgz, now packed by a build-npm-package job before the manifest so that tarballs and SBOMs are lines of SHA256SUMS.txt and publish-npm publishes bytes the signed manifest lists, each SBOM describing the packed manifest with its dependencies resolved through the lockfile; and the Windows installer, whose opensysml-<x.y.z>-windows-amd64.msi.spdx.json is derived from its inputs — the Go executables and the bundled Z3 release declared from packaging/msi/z3.pin with its version and digests — and listed in SHA256SUMS-windows-msi.txt (and, signed, in SHA256SUMS-windows-signed.txt).
  • Every release now publishes an SPDX 2.3 JSON software bill of materials per asset, <asset>.spdx.json, for each archive, wheel, sdist, sysml-grpc and sysml-jupyter-kernel binary.
  • Stable v* releases are announced in the maintainers' Slack channel after the GitHub release is published.
  • The REPL chapter explains what a = … result line shows — add(2, 2) answers [4] where 2 + 2 answers 4 — as the values the result feature holds in its effective multiplicity, with the square brackets as display notation for a sequence rather than KerML syntax and the return : Integer[1] spelling that prints one value bare; the Jupyter and command-line chapters point to it.
  • The temporal members of occurrences answer from what a run produced.
  • Rust client: ConvertOptions takes compact, omit_derived, keep_derived and include_check_diagnostics (gated on the convert_compact and convert_check_diagnostics capabilities), the check's diagnostics arriving in Conversion::diagnostics with their severities; SourcesOptions::base_model_hash relates parse_sources to a previous model and Model::affected names the documents whose results may differ (gated on parse_sources_affected).
  • Rust client: Model::convert_with and Model::save_with take a &ConvertOptions, so a held model is written with id_form, include_library_stubs (gated on the convert_library_stubs capability) and documents as Connection::convert writes it; Model::convert and Model::save keep their signatures and defaults.
  • The security policy is published where users look.
  • A security policy, SECURITY.md, says how to report a vulnerability privately, who responds, the acknowledgement, triage and fix deadlines (critical within 14 days, high and medium within 60), the coordinated-disclosure terms, how automated and AI-assisted reports are handled, which versions receive fixes, and how to verify a release's signed checksum manifest and provenance.
  • The self-model gained a second document written in AsciiDoc, OpenSysMLAsciiDoc::MarkupNote (examples/self-model/asciidoc/markup.sysml): three rep language "asciidoc" bodies with sysml:value[…] runs read from the model, <<xref>> cross-references, a heading-opened section and the markup-parser table as a query.
  • The smt engine encodes a feature valued by an expression over other features (attribute y : Integer = x + 1) as the interpreter computes it, at every read over the current values: each state defines the feature by its expression and every read within a move substitutes it, through features so valued in turn, so guards, loop conditions, properties, assumptions and results all see the derived value.
  • The solver asserts a derived declared value — an expression over other features of the same element, attribute volume : VolumeValue = height * width * length; — as the defining equation of its variable, where it used to fix the value the evaluator derived or, when a feature it reads held nothing, leave the value free of its operands (so %solve Box::Crate::fits synthesised a volume with no relation to height, width and length).
  • Conformance fixture state_action_default_performances pins that a state's entryAction, doAction and exitAction each hold one performance whether or not the state declares an entry, do or exit action — States::StateAction redefines StatePerformance's entry[1], do[1] and exit[1] steps (KerML 1.0 §9.2.11.1), so an undeclared one is a default performance, not an empty value — beside the library's genuinely optional [0..1] features (incomingTransitionTrigger, accepted, a view's viewRendering), which hold nothing; docs/project/spec-compliance.md gains the row.
  • scripts/check-upstream-drift.sh, run weekly by the Upstream drift workflow, reports when the pilot implementation or the SysML-v2-Release repository publishes a release newer than scripts/pilot-pin.sh pins, when the pinned tag stops resolving to the pinned commit, whether the newest release changed the specification PDFs the compliance map's clause numbers read, and when an OMG specification page lists a SysML or KerML version it has not recorded.
  • WhereType takes exact = true to keep only the elements whose own metaclass is named — neither its subclasses nor the model's own types — as a reflective walk over the metamodel needs (DocumentQueries from the Extensions Library pin that declares it).
  • The REPL session resolves an import or qualified reference whose first segment nothing declares against a workspace root: the .sysml/.kerml file under it declaring that root namespace loads as %load would, in the same submission, and %eval/%calc do the same for the names they are given.

Changed

  • The semantics package calls symbols.AnnotatesOthers directly instead of through a private alias of it; no behaviour changes.
  • ast.Inspect reads a struct type's node-bearing fields once per type instead of describing every field of every struct it visits, and no longer descends into fields that can hold no node (keywords, flags, spans).
  • Calculation definitions and usages are drawn with the action (behaviour) rendering, as action definitions and usages are: %viz A::add and a view exposing a calc default to it, #action: accepts a calc, and its directed parameters are the node's pins, an unnamed return parameter the pin named result — where the TREE kind drew in x and return : Integer as attributes and the action kind drew nothing.
  • The Mermaid, D2 and PlantUML action and mixed renderings list an action's or calculation's parameter pins that no edge reaches in a parameters compartment of the node (in x, in y, out result, typed when typings are shown), as the tree form lists them, instead of leaving them out and naming them in a pin(s) not drawn notice; the Jupyter kernel's %viz A::add Mermaid diagram therefore shows a calculation's parameters.
  • The runtime resolves the declarations a feature chain's segments name once per model and base feature instead of on every evaluation, and noting them for a chain no longer allocates a restore closure.
  • The race-enabled test suite runs as ten CircleCI shards instead of six.
  • The CircleCI build-test workflow on develop and main finishes sooner and no longer queues behind the pipelines it supersedes.
  • The compliance map's validation rows and the constraint manifest are keyed to the constraint names of the pinned KerML 1.1 Beta 2 and SysML v2.1 Beta 2 texts: the manifest's specifications block pins the Beta 2 PDFs the release ships, each row cites the Beta 2 name first and the pilot validator's name second where they differ, a check the Beta 2 text does not state is marked a pilot-only check, and rows for validateAttributeDefinitionFeatures, validateAttributeUsageFeatures and validateControlNodeIsComposite record them as satisfied by construction from the notation.
  • conditionText in internal/exec/runtime carries its own doc comment again, instead of leaving it stranded above qualifiedNameText.
  • sysml model.sysml -convert sysml (and -convert kerml, and the notation -migrate sysml writes) lays the statements of the notation out: a new line after the { of a body and after each ; in it, the } on a line of its own, nesting indented — so a model generated on one line comes back one statement per line.
  • Dependabot no longer proposes @testing-library/react updates for the SysON frontend: 12.1.5 narrowed its peer range to React 17 while the frontend pins React 18, so the grouped npm update failed npm ci; the React-18 major is taken by hand.
  • Dependabot no longer offers @types/vscode bumps for the VS Code extension: vsce package refuses a typing newer than the extension's engines.vscode floor (^1.86.0), so the devDependency stays at the floor and moves with it.
  • Dependabot opens at most one grouped minor/patch pull request per ecosystem a week and no longer offers major versions; a maintainer takes each major by hand.
  • scripts/download-doc-pdf-toolchain.sh retries each download (pandoc, Graphviz, PlantUML, D2) three times before giving up, as the other download scripts do, so a transient upstream error such as the 502 GitLab returned for the Graphviz packages no longer fails the PDF toolchain job outright.
  • The document planner's markup-section outline compares section paths with slices.Equal and names the open-heading record it keeps while scanning bodies once, with no change in behaviour.
  • The downloads page lists sysml-mcp: its per-platform release archive in the individual-tools table, the @openmbee/sysml-mcp npm package and the MCP Registry entry under package managers, the --tools option of the install script, and that the Homebrew formula, the Windows MSI and the nightly carry it too.
  • Pull requests are opened ready for review, so the full CI tier runs from the first push; the quick tier is an opt-in for work-in-progress, taken by opening the pull request as a draft, which has to be marked ready before it is considered.
  • The REPL's witnessLine and sameName forwarders to analysis.WitnessLine and simresults.SameName, and the metamodel evaluator's containsSymbol, which no production code called, are removed; their tests call analysis.WitnessLine, simresults.SameName and slices.Contains directly.
  • The RDF writer's bookkeeping of the relationship ids it writes for a declaration (writtenRelationships in internal/translate/export) is split into one helper per source of relationships — an end feature's references, a dependency's prefix metadata, the head's clauses and a bound end's reference subsetting — with no change to the ids written or to the writer's speed.
  • The vendored extension libraries are re-pinned to the upstream commit that makes Open-MBEE/OpenSysML-Extensions-Library a KerML 10.3 project interchange; scripts/sync-extension-libraries.sh now vendors its .project.json, .meta.json and LICENSE into internal/workspace/libs/extensions-project/, and a gate holds every vendored unit to the recorded SHA-256 checksum and indexed root namespace, so the bundled copy is provably the published project.
  • The conformance record now states why a bare concrete flow def X; is reported as relating fewer than two elements while a flow definition whose two ends are inherited (flow def F :> Flows::Message;) is clean, and why the end-must-be-a-usage rules for flow and connection definitions examine inherited ends: KerML derives an association's related types from every end feature it owns or inherits, and SysML types each of those ends as a usage.
  • Bumped connectrpc.com/connect to 1.21.1 and connectrpc.com/grpcreflect to 1.3.1 in the root and tools/ modules (the Go bumps of Dependabot PR #1639, which conflicts with develop); no API changes for the gRPC/Connect front end.
  • The language server now speaks through go.lsp.dev 1.0 (jsonrpc2, protocol and uri 1.0.1).
  • sysml-grpc binds loopback by default: -port 50051 alone now serves localhost:50051, reachable only from the same machine, and the health server binds the same host.
  • Every sysml-grpc call is logged on one line at INFO with the peer address, method, protocol, status code, duration and whether it was authenticated, on both transports; a refused call is logged at WARN with the peer.
  • The source.StringValue and source.StringText helpers are now called directly where string literals are read or written: the private one-line aliases unquote (in the solver, the semantics engine and the symbol-facts frontend) and stringLiteral (in the SysML v1 migrator) are gone, and semantics.SimpleSymbolName holds the body its unexported twin simpleSymbolName forwarded to.
  • The homepage hero lists the Saturn V mass roll-up as a table instead of drawing every stage and engine as nested boxes: one row per part, indented as the composition nests, with the model's mass and propellantMass beside a totalMass column that stays empty until Run has the engine evaluate the roll-up and fill it from the engines up; the instrument-unit variants show the undetermined roll-up, and the engine's reason, in the cells themselves.
  • The landing page's mass table lights its roll-up levels from one timeline — each level scheduled at its offset from the start, the last held for a step — instead of waiting between levels, and its source editor loads the published model in one asynchronous step; what the page shows is unchanged.
  • One helper takes the last segment of a qualified name.
  • The Cameo plugin is Magic MDK and the SysON plugin is SysON MDK.
  • Magic MDK declares and enforces its compatibility floor.
  • The pull-request workflow runs on merge-queue commits.
  • mermaidArrow takes only the edge kind, which is all it reads, and lists each arrow once; Mermaid output is unchanged for every edge kind.
  • Node client: save(model, path, options) takes the idForm and includeLibraryStubs options convert takes, as its SaveOptions, and hands them to Model.convert unchanged, with the same refusals and capability gates.
  • The @openmbee/opensysml npm client requires Node 22.22.2 or later (engines.node >=22.22.2); Node 20 is no longer supported.
  • A part usage typed only by an item definition (item def I; part p : I;) is no longer reported as part-usage-part-definition, and that diagnostic code is withdrawn.
  • Each run of an action in a Monte Carlo, sweep or exploration no longer re-lowers the action and rebuilds its feature index.
  • The pinned OMG pilot implementation is now release 2026-09 (jupyter-sysml-kernel 0.63.0)
  • An alias member without a name parses.
  • The tag's pin-release-digests job now opens a second pull request, hotfix/pin-vX.Y.Z against main, beside chore/pin-vX.Y.Z against develop: main's head is the tagged commit and cannot carry its own pin, so without it every build-test run on main — and its SonarCloud scan — failed the hygiene suite until the next release.
  • The release's opensysml and jupyter-opensysml-kernel packages are uploaded to PyPI by a GitHub Actions workflow, release-pypi.yml, with trusted publishing, so every file carries a PEP 740 attestation like the nightly snapshots' do.
  • Python client: the module-level opensysml.convert takes the id_form (ID_FORM_QUALIFIED or ID_FORM_UUID) and include_library_stubs options Connection.convert and Model.convert take, gated the same way on the service's convert_library_stubs capability.
  • Diagnostics spell a written qualified name through one method.
  • Project and WhereFeature reading a feature an element row lacks now fail with a missing-feature error naming the element and the features it does have (Target, Property, Candidates), instead of leaving the cell empty, and carry the QVTS outcome record (Feature(<name>) step, the element and its features as frontier); a property no row carries stays unknown-property.
  • A document query's Named now tells a name no element carries from one several elements carry, instead of refusing both as names no single element.
  • record.ShortName now holds the last-segment logic itself instead of forwarding to an unexported shortName; an orphaned doc comment in the same file was removed.
  • The REPL calls nsmerge.MemberName directly instead of through a private forwarding alias; no behaviour change.
  • The compliance map states the representative-object policy for a feature that states and inherits no multiplicity: the specification bounds the number of values a feature may hold (KerML 1.1 §7.4.12, §7.4.5.2; SysML v2 §7.6.3) and leaves open what a representative instance materializes for a valueless feature, so OpenSysML materializes one representative object for such a feature, none for a declared [0..*], and judges no count against the defaulted feature; recorded as a tool decision.
  • A SysML v1 Requirement Diagram is now migrated as a view rendered Views::asTreeDiagram, drawing the requirements, their nested requirements and the satisfy, derive, refine and verify relationships shown, where it fell to Views::asTextualNotation.
  • The REPL's dependency search collects the root namespaces a submission imports or references only when the submission left a reference unresolved, instead of walking every submission's text twice.
  • Every occurrence that began has its start shot, so reads that answered the static shape alone now answer the run: start/startShot on an instantiated object is a snapshot object rather than <undetermined>, snapshots, timeSlices, portions, timeEnclosedOccurrences, spaceTimeEnclosedOccurrences and spaceEnclosedOccurrences list the shots that happened (a time slice takes all of the occurrence's space, so a shot is space-enclosed too) and are open until the occurrence ends, successors is undetermined until it ends, and predecessors lists what ended before it began; Clocks::TimeOf/DurationOf return bare numbers where they returned quantities of seconds.
  • A shot carries the values its occurrence held at that instant: an ended occurrence's end shot reads its values, and a start shot reads the values nothing assigned since the start; one assigned since is undetermined on the start shot, saying the value then was not recorded.
  • A message a state machine takes only to drop it (no transition accepts it) leaves its Transfers::Transfer unended; a send … to from a performed action lists the transfer under that performance's outgoingTransfers as a via send does.
  • The runtime answers the subsetting walks a feature read repeats once per model — the relationships a feature declares of one kind, the features of a type they name, and whether a feature subsets another through any chain — and reading the subsetters an object holds no longer copies the list when the object holds every one.
  • The self-model's architecture document (examples/self-model/document.sysml) writes its prose as Markdown bodies whose figures — tier and pass counts, budget defaults, command counts, the MCP server's groups, path and token variable, the AsciiDoc converter variable — are sysml:value: runs read from the model instead of retyped text; its budget-exhaustion caption now counts the eight budgets the runtime declares.
  • The hand-written membership and index helpers (contains, containsElement, containsSymbol, containsFit, containsInstance, containsFeatureValue, indexOfSymbol, joins, containsColumn, indexOfAPIJSONProperty, containsInt, containsString, Query.declares, containsWord, appendUnique, lastName) in the migrator, the runtime, the solver, the analysis framework, the document planner, the API JSON writer, the semantics package and the tools module are gone; their call sites use slices.Contains, slices.ContainsFunc, slices.Index and symbols.LastSegment directly.
  • The solver's single-value assumption bookkeeping (assumeOne and mergeAssumed in internal/exec/solve) tests membership with slices.ContainsFunc instead of hand-written loops; no behaviour changes.
  • docs/project/spec-compliance.md cites clause numbers from the specification editions the pilot pin ships (SysML v2.1 Beta 2, KerML 1.1 Beta 2) and says so up front; stale implementation paths, test names and line-number references were re-pointed at the current tree, table rows with an unescaped | inside a code span render as one row again, and the duplicated view-rendering bullet is gone.
  • The same document now states what the implementation does where its rows had drifted: calculation purity, the implicit [1..1] of SysML v2 §7.6.3 against the KerML 0..* default, nested subrequirements, x + null, excludingAt past the end, the API Query operators and orderBy are recorded as approximate with the clause each falls short of; the bare-import visibility row is faithful; duplicated connector and view-rendering rows, an empty "Decisions to Reassess" table, quotations the Beta 2 text does not contain and internal work-item references are gone.
  • The sorted-unique helpers of the REPL comparison, the Xpect referee, the LLM fidelity bench and the grammar census are gone.
  • The grammar census exports StripModelSource directly instead of forwarding to an unexported twin.
  • suggest.EditDistance takes its three-way minimum from the builtin min
  • The sysml-mcp toolkit counts UTF-16 units with the standard library.
  • A typing spelled typed by in a .sysml file is reported as kerml-notation.
  • The symbol builder maps a usage kind to its SymbolKind through the single exported UsageSymbolKind; the unexported duplicate usageSymbolKind is gone.
  • A usage the model itself declares with an open multiplicity now reads closed over the model, by the rule the library collections already follow (KerML 1.0 §7.3.2.2, §7.4.11, §7.4.12): a lower bound of 0 that nothing declared meets is met by no value, so part wheels : Wheel[0..*];, item cargo : Box[0..4];, ref part spares : Wheel[*];, part spare : Wheel[0..1];, attribute tags : String[0..*]; and part nested : Wheel[0..*] { part hub; } read as the empty sequence on a package-level usage (car.wheels), bare or qualified (Probe::wheels), and in a constraint or calc (size(wheels) == 0 is true), exactly as on new Car(), instead of <undetermined>.

Fixed

  • Writing api-json builds one index of the graph's subjects, metaclasses, incoming memberships and owner positions per write, shared by the metamodel evaluator, the mapping-name pass and the writer's name index.
  • Writing api-json no longer rereads the names of every earlier member of a namespace for each member's qualifiedName: each namespace's member names are read once, so a namespace's qualified names cost time linear in its member count rather than quadratic.
  • pilot-apijson-diff now scores a property the pinned pilot exports differently from one JVM to the next in its own pilot-nondeterministic scorecard column, declared with evidence in tools/referee/apijson/nondeterminism.go and written into the baseline, instead of letting -check fail on a value that moves with the JVM; FeatureChainExpression.featuringType is the first declared row (three expressions in the pilot's ServerSequenceModelOutside example gain or lose a reference to an element the pilot never exports).
  • Use Asciidoctor.js 4.1.1 for rep language "asciidoc" bodies, clearing GHSA-g3hv-75wg-m249 from the converter's dependency tree; 4.x has no runtime dependencies.
  • An attribute a state or action definition declares over its own occurrence features — size(entryAction), size(en), size(subperformances), a nested part fresh — reads the performance's features: the exhibited machine's or performed action's own, not the exhibiting part's same-named feature nor an object of the bare declaration.
  • The runtime's binding walks allocate only where a binding can be found: a feature read that climbs to its owners spells out the feature path only while an owner declares a binding, the witness draw builds its pool index on the first candidate, the sibling subsetters' set is made on the first value, and a body is scanned for declared features without listing its members first.
  • The RDF and API JSON exports state an expression body parameter's isVariable/mayTimeVary as the metamodel derives them (its owning type is the Expression, an Occurrence); the parameter's symbol is looked up by name on the body it declares, so the pair was never stated.
  • A feature valued by an expression (attribute y : Integer = x + 1), computed as it is read, now carries the order-dependence marks of what its expression reads at that moment, through features so valued in turn, and a write computed from it (assign z := y + 10) stands on those choice points as a write from x would.
  • The SMT engine (-engine smt) refuses an action declaring a feature valued by an expression over other features instead of encoding it as the value it held at the start, which proved results the run does not reach.
  • A redefining feature that declares no value (attribute :>> y; over attribute y : Integer = x + 1) is bound as the feature it redefines is: its value follows x as it is read, where it was evaluated once as the performance started, and it carries the marks of what the inherited expression reads.
  • sysml -bundle archives what the project's .meta.json records: the two manifests plus exactly the files its checksum keys and index targets name, with a recorded file missing from the tree an error naming it; a directory without a .meta.json is archived as KerML 10.3 describes — the project file and the model files — so a repository's README, scripts, __pycache__, editor backups and version-control metadata no longer travel in the archive.
  • A tree rendering (-render '#tree:…', %viz, the Jupyter kernel's default) drew the directed parameters of a calculation, action or constraint definition or usage — in x, out y, return — as attribute members with membership edges, and an anonymous return as a bare attribute.
  • A cast at the head of a feature chain is judged for conformance.
  • The query surfaces spell each feature-chain clause of a head (subsets a.b, a.b, redefines a.b, a.b) by the elementId of its own subsetting or redefinition, as the RDF conversion materializes one relationship per chain Feature it owns; the identity reader had keyed chains by their text and reported the first clause's id for every repetition.
  • A pull request that changes only the committed baselines or figure pages under docs/project/ now runs the Go test shards.
  • The CircleCI Go static checks job on develop is no longer killed at the Check Go dependencies for known vulnerabilities step.
  • The compact API JSON form (api-json-compact/1) lists a key in referenceKeys only when every value under it is a reference or a collection of references.
  • The not represented notice of a most (COMPMOST) or ports (COMPTREE) compartment folding no longer counts the members a folded row has from its type as "left undrawn": they belong to the type, which is drawn or reachable from the row.
  • A constraint that declares no condition — a bare constraint def Empty;, a usage typed by it, or a negated constraint stating only assumptions — is now reported as no value (ErrNoValue), the error an unbound calc result reads as, instead of the distinct no condition to evaluate verdict.
  • elementId is now read for the end features a head binds (connect a to b, bind, flow, succession), which the conversion writes as end features of their own; queries and document tables over such ends no longer find the cell empty.
  • make coverage-shard SHARD=tools no longer fills the disk.
  • A «Refine», «Satisfy», «Verify», «DeriveReqt», «Allocate» or plain dependency, or a connector, drawn on a SysML v1 activity, state machine, block definition or internal block diagram now keeps its line: the migrator routes it on the ActionFlowView, StateTransitionView, tree or interconnection view the diagram is written as whenever the view shows both of its ends (SysML v2 graphical notation 8.2.3.3 draws a dependency between any two shown element nodes), where it was reported not drawn; the action, state and tree renderings draw such exposed relationships as dashed open-arrow edges with their keyword, following their Route, and draw an exposed end that is no node of the graph as a plain box.
  • A loaded file's qualified names are followed to the files beside and below it as its imports are: a file that names a root namespace only by qualified name (view v : SYSMODViews::ProjectView, with no import of SYSMODViews) now loads the file declaring that namespace too, so two library packages that import each other resolve when a model naming only one of them is loaded (sysml -validate Consumer.sysml with private import SYSMOD::*; reported SYSMODViews::ProjectView and three more unresolved; naming the project directory, which loads every file, did not).
  • A #derivation connection whose original or derived requirement itself carries the @original or @derive metadata (RequirementDerivation::OriginalRequirementMetadata, legal on a requirement usage) now states its derivation: a body end's reference to a requirement tagged that way is its participant, and only the library's own DerivationConnections::originalRequirements/derivedRequirements an end subsets are read as role statements.
  • Deriving a feature's value marks what it stands on over the memoized footprint of its expression without copying the footprint's reads to hold them via the object's feature.
  • Name resolution now memoizes a derived short name whose naming feature cannot be resolved (a :>> redefinition no general offers a target for), as it already did for one it can: every unqualified lookup through the scope asked each such member again, re-running the failed redefinition lookup once per member per lookup.
  • The example walkthroughs under examples/ again show what the pinned binaries print: a calculation or analysis result held in its effective multiplicity (fuelUsed = [120.0], = [6432.955324716369 [SI::'m/s']]), the (N independent) choice-point counts and the order-dependent marker on a value a schedule decides, the current Mermaid frontmatter and one-line container titles, the %features listing of a completed state machine, the instance IDs a session allocates, and the figures of the check engine, -render-all and the stdlib conformance gate.
  • Documentation: the verdicts demo's held-rover transcripts show the verification case marginCheck failing with the satisfaction it verifies after the drive (four Findings rows, verification = "fail", the report's violated row), as the build has answered since a verification case a part definition owns runs over the held object.
  • Documentation: the views demo's Mermaid action rendering shows the renderer's current output — dashed successions, the parameters compartment in the action titles and the title margin it reserves.
  • Documentation: the external-tool demo's dry run prints the real-valued arguments the model binds (250.0, 290.0).
  • The project records again point at the code they describe: paths that moved in the internal/core → internal/{syntax,semantic,check,workspace} layering (pilot-differential.md, pilot-rejection.md, pilot-xpect.md, pilot-corpora.md, adjudications.md, omg-issues.md, spec-pilot-gap-register.md, diagram-layout-annotations.md, spec-compliance.md), the tools/cmd/pilot-exec-diff referee, the Apollo 11 corpus the release performance reports measured (airbus/apollo-11-sysml-v2 at 6e9c93f, not a download script that does not exist), and the feature counts of the Calculations (16) and Actions (21) lists in spec-compliance.md.
  • Documentation: the CLI reference lists -layout <file> under -migrate and -library-references <file> and -include-library-stubs under -convert api-json, the REPL reference lists %occurrence <name>, and the service-transports capability table names convert_library_references, convert_library_stubs, render_document_asciidoc and order_dependence, as GetServerInfo answers.
  • Documentation: the architecture page's Tier 6 (analysis and verification drivers) is marked landed, with the REPL, CLI and gRPC entry points that exist, in place of the planned %run/%verify.
  • Documentation: the spec-compliance table names the bundle determinism test by its current name, TestBundleIsDeterministicAndUnbundleReproducesTheRecordedFiles.
  • Documentation: the view-rendering-forms page's switch example subsets Views::asInterconnectionDiagram from a rendering usage, the shape the checker accepts and the renderer reads, in place of a rendering definition specializing a usage.
  • The handbook and reference pages again show what the pinned binaries print: the runtime-showcase analysis in README.md holds its results in their effective multiplicity (margin = [70.65198768706614 [SI::'m/s']]), REPL diagnostics carry their code (error[unresolved]:, error[syntax]:, error[binding-connector-type-conformance]:), a %render tree, Mermaid, DOT, PlantUML and D2 rendering names elements unqualified without their declared types, a state-machine session prints its Use %events … and Use %step … hints, its choice-point count and the order-dependent marker on a value a schedule decides, and the Java dependency snippet names the current 0.11.0 artifact on Maven Central.
  • The drawio rendering form lays unplaced nodes, and the members inside a container, out with a corridor between neighbours that the edge router can use: twice its clearance, the two half port squares, and one nudging lane (50 px instead of 40), so two parts with ports on their facing sides route instead of being left for draw.io to route under a notice.
  • The drawio rendering form no longer falls back silently when the router finds no path for an edge: the file carries a notice naming the edge and its cells, and an end at a port still leaves through the port's face.
  • The duplicate-library check of #1462 keeps only the first declaration of each library package name until a second is met, instead of a list per name.
  • A query reading elementId no longer converts the loaded model to RDF for the ids: they are minted from the writer's identity tables, the ids the graph would carry, so a model with large query files beside it answers in milliseconds rather than seconds and gigabytes; the REPL and CLI open one such reader per set of loaded documents and reuse it across the queries run over them.
  • An evaluation context is 152 bytes instead of 184: the chain being evaluated is noted by its last segment, its length and a pointer to the memoized declarations where #1514 carried two slice headers, and the open-inputs flag of #1461 shares a word with the behavior-body flag.
  • SequenceFunctions::excludingAt follows its library body.
  • name-conflict no longer warns when the only memberships colliding under one name are those a view's exposes bring (view v { expose a::**; expose b::**; } with a p in both a and b): a view exposes each expose's own memberships, so both p are exposed and rendered.
  • A connection, interface or allocation usage a package declares (connection outer : Link connect sys.x to sys.y;) now counts in all Link and reads as one Link with its ends attached (outer.a == sys.x), as the same usage nested in a part already did; a usage stating [0..*] denotes none, one stating [2] two connectors each attached, and two such usages a bind joins share one connector with its ends whichever is read first.
  • A package-level action or state usage now denotes one representative performance, as a package-level part or connection does: a bare read of P::a is that object rather than <undetermined>, all Act counts it beside the nested performances, a stated [0..*] denotes none and a fixed [2] two.
  • Tree and definition renderings draw a feature membership as the graphical notation does: from the owner to the usage's node, with a filled diamond at the owner for a composite usage and a hollow one for a non-composite usage — a ref, an attribute, a port nested in a part, an end, a directed or an enumeration usage — as the model derives isComposite, and the usage's typing as a definition edge of its own from the usage to its definition.
  • A feature value whose type is unrelated to the feature's own type is now reported as the bound-feature-types warning at the feature, as the pilot reports it: attribute def R :> Real; attribute a : R = 5; warns, since Integer and R specialize neither the other, where the value was judged against Real and passed.
  • An object's feature values are keyed by the feature, not by its name: for part def Both :> A2, A1 { attribute b :>> A1::a = 3.0; } the name a on an object of Both is the surviving A2::a and reads its own value (2.0), in either order of the generals and whether a definition or a usage owns the redefinition, while b, and a read as an A1 ((bd as A1).a, a ref : A1), read 3.0.
  • The formatter no longer indents a line that begins with :>>, :> or another operator one level deeper than its body when the statement above it ended; :>> mass = v.mass; written on its own line now sits at the body's level like the statements around it.
  • -convert sysml now lays a succession chain out one statement per line: action a; then action b; then action c; written on one line becomes three, then leading each successor.
  • The frontier a failed Named query records (-run-query, -json's checks[].outcome, %run-query, the gRPC QueryOutcome detail) lists the namespace's owned members only: an alias declared there was listed as a member of metaclass Membership, which no element has; its name is still offered as a spelling for a typo.
  • gRPC VerifyConstraint, VerifyRequirement and RunAnalysis naming no subject_symbol_id now evaluate over the objects Instantiate holds for the model, as VerifySatisfaction already did and as the REPL's checks are about the objects a session holds: a verification case a definition owns runs once per held object of the definition and its verification_verdicts name each object, a constraint or requirement a definition owns is checked on the held object carrying it (ambiguous over several), and a case a definition owns runs as a feature of the held object of that definition.
  • A RunAnalysis run of a verification case over the held population that would pass the held-objects bound is RESOURCE_EXHAUSTED too, and a RunAnalysis tool dry run over the population undoes the preview's writes and puts the runtime's tool runner back, as the REPL's preview does.
  • The hygiene test that holds client/release-digests.json to every release the changelog records no longer fails a checkout of the tagged release commit itself — main after a release — whose pin can only land on develop afterwards; a commit past the tag without the pin still fails as before.
  • Every performance the run creates carries the implicit specializations of its kind (KerML §7.3.4).
  • A ref use case written in a body is a reference usage.
  • A state's entryAction/doAction/exitAction stays resolvable beside the entry/do/exit action that redefines it.
  • A state's entry and exit actions are subperformances of the state, not its subactions.
  • A send … via a port over a connector inherited from a general part def now reaches the part a specialization redefines for the connector's end (part def Sys :> Top { part redefines b : B2; }), instead of a freshly materialized part of the general type that nothing else holds.
  • A usage linked to an installed project by elimination — its IRI spells a repository path whose last segment is not the project's name — is now a warning on the consumer's .project.json naming the project taken and the publisher/name the resource should end with, judged by -warnings-as-errors like the ambiguity warning; before, the fallback was silent.
  • A project interchange archive holding the project's folder rather than its contents, as the OMG library releases are laid out, is read as the project in that folder, and an index entry naming no member no longer refuses the archive: both are warnings on the archive's path, and the units are found by what they declare.
  • A project installed as a sub-package of a repository (pkg:git/<host>/<path>#packages/gears) is read through its own installation alone: the usage's fragment names the sub-package (gears under the repository's owner) rather than the repository's project, and a directory below an installed project — or a member directory of an installed archive — that holds a .project.json of its own is a project of its own, not among the parent's files — whether the project or a file in it is named, in the language server's workspace, and in -bundle, which leaves the nested tree out of the parent's archive.
  • A feature that declares no multiplicity and inherits none now has the usual default 0..* (KerML 1.1 §7.4.12, §7.4.5.2; SysML v2 §7.6.3) instead of an assumed 1..1, so a KerML feature such as class C { feature x : Real = (1.0, 2.0); }, or a SysML attribute owned by a package, holds a default value of any count.
  • The library index cache (~/.cache/sysml-ls/libs) no longer serves one build's records to another build of the same commit.
  • A library loaded from OPENSYSML_LIBRARY_PATH that holds two copies of a file now reports the same diagnostics on a warm start as on a cold one.
  • A declaration instantiated twice (%instantiate test::b twice, gRPC Instantiate twice) leaves two live objects of its definition, and subjectless verification and checks now see both instead of the newest alone.
  • sysml -validate no longer fails over a model whose rep language "asciidoc" bodies need a converter the host lacks: a missing markup converter is now the warning document-plan-markup-tool-missing at the document's first such body, naming the converter looked for, whether OPENSYSML_ASCIIDOCTOR named it or it was the default looked up on PATH, and the remedy, and the rest of the document is still validated with those bodies unchecked (-warnings-as-errors makes it a failure).
  • The release workflow's publish-maven job no longer goes red while Maven Central is still publishing an uploaded deployment.
  • Usage::mayTimeVary (and so a usage's isVariable) is derived over the usage's effective isComposite: a performed action or exhibited state, referential by the notation (perform, exhibit), may vary in time as the specification derives (SysML v2.1 §8.3.6.4 deriveUsageMayTimeVary); the reflective read answered false for them.
  • The MCP server reference and the release procedure no longer say that the GitHub MCP Registry and VS Code's Browse MCP Servers list sysml-mcp by virtue of its official MCP Registry entry: the GitHub registry is a curated selection of the official one that onboards a server on request, so the pages say so and configure VS Code by hand until org.opensysml/sysml-mcp is onboarded there.
  • A project interchange archive (.kpar) whose .meta.json records a checksum of algorithm NONE, or with an empty value, as sysand writes for a member it did not digest (MBSE4U's sysmod-sysmlv2 releases), now reads: such a checksum records no digest and is neither verified nor refused.
  • Patch GHSA-g3hv-75wg-m249 by resolving the production minimatch dependency to 11.0.1 in the VS Code extension under vscode-languageclient and in the Node client under @tufjs/models.
  • The RDF and API JSON exports state isVariable/mayTimeVary for the usages a declaration implies — a connector's end features, a transition's link and trigger parameters, a trigger's payload and receiver parameters, a satisfy's subject, a flow end's feature — as deriveUsageMayTimeVary reads them from their owning type (a connection or action yes, a succession or binding no), and Usage::mayTimeVary derives for a requirement's subject parameter.
  • The missing-feature error's "did you mean" offers the features nearest to the missing segment by edit distance; it listed the first three alphabetically, so an element with four or more features could be told to try a name unlike the one the query spelt.
  • A document query's Named, and the type names WhereType and WhereMetadata take, now read a qualified name as the notation and the element's own qualifiedName spell it, a segment no basic name spells quoted: Named(qualifiedName = "Vehicle::'Spare Parts'::Pad") names the element rather than failing as Vehicle has no member 'Spare Parts' — did you mean Spare Parts?.
  • A feature read at namespace level (sysml -e P::xs, a bare expression or %eval in the REPL, gRPC Evaluate) now holds its value in the feature's effective multiplicity, as the same feature read on an object already did: a [0..*] attribute valued = 4 reads [4] on both, where the model-level read printed the bare 4.
  • A connection, interface or allocation usage nested in a part with a stated multiplicity (connection pair : Link[2] connect x to y;) now holds that many connectors, each with its ends attached to the features the connect clause names (sys.pair#(1).a === sys.x, size(sys.pair) == 2), [0..*] none, and all Link counts them, as the same usage declared at package level already did.
  • The relationship edges of the DOT, PlantUML, Mermaid, D2 and VS Code canvas writers now follow the glyphs of the SysML v2 graphical notation (§8.2.3) rather than UML habits: a typing is a solid hollow triangle with two dots at its base (--:|>), a redefinition a hollow triangle with a bar (--||>), a subsetting a plain hollow triangle with no subsets text, an owned membership a circle-plus at the namespace, a flow a solid arrow with a filled head, an action succession a dashed arrow with an open head (the Pilot draws it solid), a state transition solid with an open head, a binding labelled =, and satisfy, verify, allocate, include, perform and exhibit solid open arrows labelled «satisfy», «verify», «allocate», «include», «perform» and «exhibit»; an import reads «import», «import»* or «import»**.
  • Binary + and - written with an empty second operand (1 + null, 3 - (), x - y for a y holding no value) now evaluate as the invocation KerML 1.1 §8.4.4.9.6 makes them, '+'(1, null) and '-'(3, ()): the library declares y as [0..1], so the operator is the unary sign (1, -3), as the function form already answered.
  • A value reached through a part (sensor.raw written by racing branches, sensor.scaled = raw * 10, a value read from either after the join) is now reported order-dependent where -schedule explore proves more than one outcome: the result surface read what a part's object holds under a fresh run, losing the run's marks, and an object's feature valued by an expression recorded nothing of what it read; the place is the part's, so two parts of one definition hold two values of its feature and left.raw racing leaves right.raw bare.
  • A binding connector whose multiplicities link fewer values than its ends hold — binding [1] bind [0..1] tf.edges = [0..1] tfe in ShapeItems::Box, binding [1] bind [0..*] base.edges = [0..*] be in ShapeItems::Cylinder, or a user model's binding [1] bind [0..1] left = [0..1] right between two collections — identifies some value of one end with some value of the other (KerML 1.0 §7.4.6, §8.3.4.5.2) and determines neither, so reading a bound feature no longer fails with "binding end cannot be resolved": the feature holds what its own declaration states, and the collections it subsets read through it (Box.tfe, Box.tflv, Box.vertices, Cylinder.be, Cylinder.edges).
  • Reading subparts, subitems or suboccurrences of a timeslice or snapshot part nested in a part no longer fails with occurrence lifetime does not admit the change: … as a portion of itself.
  • Clients:
  • The pull-request workflow's protobuf breaking-change check compares the schema against the pull request's merge base with its base branch (a merge group's base_sha), not the base branch's tip, so a field another pull request adds to api/proto/sysml.proto after a branch was cut no longer fails that branch as a deleted field until it merges the base branch.
  • A CompositeConstraint with a single member is refused as malformed, as the standard's constraint : Constraint [2..*] requires, by the service and by every client translator.
  • Project/WhereFeature on a feature several element rows lack report every such element in the QVTS record (one path failure each) and name the others in the message, instead of stopping at the first.
  • The ambiguousName finding of Named names the namespace that owns the duplicated members, as the QVTS reference semantics do, not the duplicated name.
  • Query.orderBy sorts the matched elements by the listed properties in order of precedence, ascending and stable with declaration order as the final tie-break, on the RPC, the MCP query tool and every client; an unknown property is refused as select and where refuse one.
  • The API & Services Query RPC now accepts all seven PrimitiveConstraint operators of §7.1.4: <=, >=, in (membership of the property's value in a list) and instanceOf (the element's metaclass conforms to a named metaclass, so a PartUsage is an instance of Usage, Feature and Element) join =, < and > in sysml.proto, the executor and every client translator, which refuse a malformed operand shape before sending.
  • Writing api-json parses each ordered-collection annotation with a fixed couple of allocations per member: a reference, string, number or boolean member spelled the way the annotation writer spells it is read without a JSON decoder, and any other spelling still goes through the decoder.
  • RDF import: a conjugated port with an explicit subsets, redefines or references clause (port p : ~Pd subsets Parts::Part::ownedPorts;) now reads back from Turtle and the API element form.
  • The RDF export states a usage's isVariable and mayTimeVary as the metamodel derives them (Usage::mayTimeVary redefines Feature::isVariable; deriveUsageMayTimeVary), the value the reflective read already answered; it wrote neither, so an RDF consumer read false for every usage.
  • A feature chain evaluated at runtime (-e, a feature value, a condition) resolves each member in the namespace of the feature before it, as the static read does: a feature a redefinition removed from that namespace (KerML §7.3.4.5, §8.3.3.1.10) is unresolved reference: u has no member subj: U::s redefines it instead of reading the value under the redefined name.
  • The static read of a member chain no longer resolves, through the usage's type, a name the usage's own redefinition removed: a.x for part a : A { attribute y :>> x; } is unresolved member: x, as a::x and b.x for a definition owning the redefinition already were; attribute :>> x = 1; keeps the name it takes.
  • The runtime's memo of the features a feature's relationships name, per owner type (#1626), no longer records the features that declare no relationship of the kind asked for, which were most of its entries and grew with every type an instantiation touched.
  • scripts/release-announce.py --snippet now accepts only files under the directory the script is run from: the path is canonicalized first (.. and symlinks resolved) and one that lands outside the working directory fails with an error naming it, instead of being read from anywhere on the machine.
  • A submission's parse trees are let go once its files are accepted, instead of being held through the analysis for the root namespaces an unresolved reference would be looked up by (#1441); a reference left unresolved parses the text again.
  • The release browser REPL module is the RE build again.
  • The first rendering of a document a workspace holds as its interface record (a warm record cache, as sysml-mcp's render_view and the LSP opensysml/render request read one) was empty — the view exposes everything under …, and there is nothing there — until a views call parsed the document.
  • A requirement check is allTrue(assumptions()) implies allTrue(constraints()) (Requirements::RequirementConstraintCheck::result), as the value read of result, the subrequirement check and the solver already judged it: a subject failing an assume constraint satisfies the requirement whatever its require constraints read, instead of being reported as violating them.
  • The files beside a loaded file are searched for the root namespaces the analysis actually left unresolved, not for every root the file names: a qualified name an import already answers (import Lib::*; then Inner::Thing, with Lib::Inner) no longer loads an unrelated sibling declaring a root Inner, and the files loaded for a reference are read for their own unresolved references in turn (a qualified name leading to a file whose import leads to a third).
  • editors/vscode/tools/route-goldens.mjs, which re-records the libavoid parity goldens, now writes only inside the repository checkout: the default output directory and the libavoid module are found from the tool's own location rather than the working directory, and an output-directory argument is canonicalized (.. and symlinks, dangling ones included, resolved through its deepest existing ancestor) and refused with an error naming where it resolves when that is outside the checkout, before any directory is created; each golden file is checked the same way before it is written, so a symlinked golden cannot redirect the write outside the checkout.
  • The by operand of a satisfy usage is a feature reference or feature chain (SysML.xtext SatisfactionReferenceExpression), and one written as a wider expression (satisfy requirement sr : R1 by sub#(1);, by (a, b), by parts->first(), by self.items#(2), by new Sub()) is now reported once, where the chain ends, with the usage closing at its ; so the members after it parse undisturbed, instead of a cascade of three diagnostics about the declaration, a metadata prefix and a body member; a by subject the next line's member follows is still reported as the missing ; it is, while an operator opening the next line (by a / + b;) extends the operand and is reported once as the expression it makes.
  • A satisfy usage declared without by inside a part or part definition (part craft : Lander { satisfy requirement touchdown : Touchdown; }) takes the owning object as the requirement's subject (SysML v2 §7.21.4): reading its result (craft.touchdown.result, Requirements.sysml RequirementCheck::result) now evaluates the requirement's conditions on that object and agrees with -satisfy, and reading the subject itself (craft.touchdown.lander.verticalSpeed) answers about that object, where both read <undetermined>; an owner the subject's type or multiplicity refuses leaves the subject unbound, and the result read reports the refusal as the check does.
  • %satisfy, -satisfy and the gRPC VerifySatisfaction sweep over a definition's satisfy r; now label each object they decide by the indexed path %validate and -validate= print for it — satisfy costReq holds (on test::fleet.cheap[1] ID: 2) rather than (on test::fleet.cheap ID: 2) — the runtime spelling a carrier's path once, as the validation walk spells the object it reaches; the gRPC satisfy verdict carries it as instance_path.
  • The constraint solver now reads a feature's multiplicity as the model computes it: a stated, redefinition-inherited or implicit [1..1] (SysML v2 §7.6.3) multiplicity that admits several values refuses the read as before, and a feature that declares and inherits none, which the usual default 0..* governs (KerML 1.1 §7.4.12, §7.4.5.2), is read as one value under an assumption the query records (Query.AssumedOne) and %check, %solve, %explain, %configure and %optimize print, instead of being taken for exactly one value silently.
  • %configure, %check, %solve, %explain, %optimize and the smt engine no longer refuse a definition or part with … = a undetermined (declared by the model): value cannot be fixed for solving: a undetermined has no literal in the term language when an attribute's declared value is an expression over features nothing gives a value to (attribute volume : VolumeValue = height * width * length; with height, width and length unset).
  • scripts/release-announce.py validates --snippet by raising from the path helper and reporting the usage error from main, so the containment check is recognised as a sanitizer by static analysis (pythonsecurity:S8707); a snippet under the working directory (also through a symlink) is still read and one resolving outside it is still refused.
  • The Implementation column of docs/project/spec-compliance.md and the other compliance tables under docs/project/ cites the live Go declaration again: every identifier that had been deleted, renamed, re-cased or moved to another file now names its current file:function, and tests/hygiene checks the column against the parsed Go tree so it cannot drift silently.
  • Every surface names an object a subsetting usage materializes by that usage.
  • A requirement usage nested in a requirement definition or usage is a subrequirement (SysML v2 §7.21.2): one of the container's required constraints, its value its own assumptions implies constraints, bound to the container's subject when it declares no subject of its own and keeping one it declares, through any depth of nesting.
  • A subsetting feature that states no value of its own (item tfe [2] :> edges;) now holds values of the feature it subsets when that feature holds values by its own declaration, as many as its lower bound asks, instead of objects made up for the bound that the subsetted feature never held (KerML 1.0 §7.3.4.4); a binding constraint on the subsetter picks the values its other end holds (§7.4.6), and a subsetted feature holding fewer values than the bound asks is the multiplicity violation the read already reports.
  • A succession written in a nested action, or in a loop/while/for or if body, is reported when an end names a feature the action does not feature — the enclosing definition's subject or part, or a node of the enclosing action (Must be an accessible feature (use dot notation for nesting), KerML 1.1 §8.3.4.5.3 checkConnectorTypeFeaturing), as the OMG pilot reports it; such ends were silently accepted inside loop bodies and as the first end of first x then y.
  • this written in a behavior body now denotes the context occurrence the member read .this answers: the object owning the performance for an action, state, calc or constraint a part owns (Objects.kerml ownedPerformances::this default that, Parts.sysml "the this reference of an ownedAction is always its owning Part"), the owner's this for a subaction (Performances.kerml subperformances::this default (that as Performance).this), and the performance itself only when no object owns it.
  • this.<feature> written in a behavior definition resolves <feature> against the declared type of this (Occurrences.kerml Occurrence::this : Occurrence[1] default self), as the pilot does: a definition reading its own feature, or its enclosing part's, through this. is refused at analysis as an unresolved member — read the definition's own feature by name.
  • A behavior run reads by name what another performance wrote to a feature of its occurrence, and a feature a definition's body assigns after this materialized the occurrence keeps the assigned value when read by name (the read re-derived the declared default).
  • A definition that redefines this with a type (ref part :>> this : H;, the pilot-clean way to read a performer's features in a definition) is valued from the same context occurrence the member read answers, so this.level reads the performer's level; an object performing it that is no H is refused as "an object of Q" written to a feature typed by H.
  • The nonstandard-notation pass no longer walks every expression of a document looking for a typed by on a body-expression parameter (#1478) when the document spells none: the parser counts the spellings and the pass sweeps only while one is unreported.
  • A calculation whose result parameter is never bound — a body with no result expression or return, or one that runs to its end without returning — is now reported as no value (ErrNoValue), the same error an out parameter the body never assigns reads as, instead of the distinct no result expression / calculation returned no value errors.
  • A usage whose resource is the ECMA-427 package URL a package manager writes for a repository — pkg:generic/<name>?vcs_url=<vcs>+<transport>://<host>/<path>[@<version>][#<subpath>], the qualifier percent-encoded (pkg:generic/sysmod-sysmlv2?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2FMBSE4U%2Fsysmod-sysmlv2%405.1.6) — now links the project installed under lib/ exactly as the pkg:git/<host>/<path>[@<version>][#<subpath>] spelling does: the host and path, the @<version> and the #<subpath> are read from the decoded vcs_url, the bare <vcs>+<transport>:// URL is read the same way, and a .git suffix on the repository path is not part of the name.
  • A usage that names no installed project by publisher and name is linked by elimination only when its resource spells where the project is kept rather than the project — a version-control package URL (pkg:git/, pkg:svn/, pkg:hg/) or a plain URL; every other pkg:<type>/<publisher>/<name> form is matched by name alone and stays unresolved when that project is not installed, where before it could fall back to the one unrelated installed project.
  • The nested features of a calc, constraint or state usage a part definition owns read through a feature chain as any usage's members do (KerML 1.0 §7.3.4.6, §7.4.9.3; SysML v2 §7.19.2, §7.20.2, §7.18.2): rig.area.w and rig.area.scale are the input the evaluation bound and the body local it left, rig.fits.limit and rig.fits.margin the input and local of the check, in a body (attribute aw = area.w;), over a declared object (-e Probe::rig.area.w) and over a constructed one (new Rig().area.w) alike; rig.area, rig.area() and rig.fits.result keep reading as the computation and the verdict.
  • usage-typing now fires on a usage typed by a feature chain that resolves to a feature (part p : rig.wheel;), as it does on a usage typed by a feature by name: a usage's types are classifiers, nominally definitions (SysML v2 §8.3.6.4 Usage::definition), so the chain's last feature is checked against the usage's kind rule and reported in the pilot's words (A usage must be typed by definitions., An occurrence, item or part must be typed by occurrence definitions. and the per-kind siblings).
  • A usage's versionConstraint is read as an npm-style semver range — exact, =/v prefix, < <= > >=, ^, ~, x/* wildcards, hyphen ranges, space/comma as AND, || as OR, pre-releases ordered as semver 2.0.0 and admitted only where the range names their release — and the highest installed version in the range is taken, on the publisher/name match and by elimination alike; before, only an exact version was understood, so a range never linked by elimination and on the name match the latest installed version was taken regardless.
  • A migrated use case diagram showing a requirement nested in another requirement exposes and lays it out by its qualified name ('Test Requirements'::'MAPS Quality of turbulence'::'MAPS Spectrum Mean'), as an expose and a metadata … about must name a member; the feature chain written before ('Test Requirements'.'MAPS Quality of turbulence'.'MAPS Spectrum Mean') is a syntax error there, so a Cameo project with such a diagram failed to migrate with the migrated notation could not be written: … expected ';' after expose statement.
  • The object materialized to stand in for the unspecified value of a value-typed feature (an unvalued out result : Boolean[1] of a state definition a part exhibits, read when the machine starts) is dropped once the feature holds a value — by an assignment or an outside write, a binding resolving, a collection assigned whole, or under a redefining name — instead of staying registered as an object nothing holds (it stays while another feature or a live run's data still names it); a write landing on an occurrence feature now also reaches the data of every run over it (the state machine, a performed action or an action run directly, a snapshot restored included), and a journal rolling the write back restores that data with the stand-in, so a held image of the part round-trips the graph the run leaves, and InstanceCount/InstanceIDs no longer count the stand-in.
  • A variant usage no longer derives Usage::mayTimeVary (and so isVariable) true: its VariantMembership is an OwningMembership, not a FeatureMembership, so it has no owning type (SysML v2.1 §8.3.6.4 deriveUsageMayTimeVary); the RDF and API-JSON exports state the pair false for it, as the pilot does.
  • A verification verdict now carries the notes its answer rests on — the features a solver question reads as one value or object while only the default 0..* multiplicity governs them, and the object-holding features whose own assertions it does not state — on every surface: the gRPC Verdict.notes (verdict_notes capability), the MCP verify tools, and the Go, Python, Node, Rust, Java, Julia and MATLAB clients, worded as the REPL's solver commands print them.
  • A verification case a definition owns now runs once on every object of the definition a report is about, so the objects a multiplicity repeats (part cheap : Definition [2], the members of a [0..*] collection, a part nested inside a repeated part) each get their own run and verdict on %requirement/-requirement, %satisfy/-satisfy, -validate -json, the gRPC verification reports and the document verdicts query; a definition's satisfy without by is likewise decided once per repeated object.
  • The VS Code diagram panel's canvas now covers everything it draws: an edge label or arrowhead routed above, left or right of the outermost boxes — «derive» and «satisfy» over the top row of a requirement view, say — is no longer cut off at the canvas's edge.
  • The VS Code diagram panel routes an edge between an owner and a member drawn inside it — the membership edges of a mixed rendering, a tree's structural usages — inside the owner's box: from the owner's header line, straight above the member where the row allows, to the member's border, through the lanes between the other members and never outside the owner; an edge between two siblings stays inside their container, and an edge that leaves a container crosses its border below the header, not through the header.
  • A command whose process has no record cache root — no $HOME or $XDG_CACHE_HOME, or one outside what a WASI host preopened, as a wasip1 build run with only its model directory — now holds every file loaded quietly instead of warning record cache unavailable … Bad file number on every run, and a custom standard library loads without its stdlib symbol cache unavailable warning too.
  • The VS Code diagram panel now draws a collapsed element as the CLI renders it: the ports on its boundary stay, with every edge that ends at them, and only what the element nests is folded away.
  • A DiagramLayout::Layout with collapsed = true about a state or an action now folds its body in the state and action renderings of every form, as it already did in the tree and interconnection renderings: the nested states, actions and the transitions or flows between them are not drawn, and the element keeps its collapsed tag.
  • The VS Code diagram panel keeps a Layout with a stated width and height as a fixed box: the port usages under it are drawn as pins on its border, each connector anchored at its pin, and an unplaced member the box has no room for is left undrawn with a notice, as a stated size leaves compartment rows unwritten in the rendered forms.
  • A behavior writing a feature it declares judges the count by the feature's effective multiplicity, as a write to an object's feature does: attribute x : Real :> many; on an action or state definition now holds (3.0, 4.0) written by its own body (it inherits [0..*], KerML 1.1 §7.4.12) instead of refusing a second value against the representative one, while an attribute with the implicit [1..1] (SysML v2 §7.6.3) and a stated bound still refuse a count outside it on every path.

Security

  • Every dependency govulncheck ./..., npm audit --omit=dev and cargo audit reported as vulnerable and reachable is replaced.
  • Every Maven dependency osv-scanner reports as vulnerable in the Java client, the SysON plugin and the MDK plugin is replaced.
  • Every third-party GitHub Action the workflows use is pinned to a commit SHA.
  • The Java client verifies release signatures with sigstore-java 2.4.0 instead of 1.3.0, and the Apache HttpComponents it brings are held past their advisories.

Supported versions. Until 1.0.0, each release line is supported only until the next release. From 1.0.0 the previous minor release line is also supported for 90 days after its successor ships, so that a fix can be taken without a feature update. How to report a vulnerability, and what to expect, is in SECURITY.md.

Verify your download. Check SHA256SUMS.txt and its cosign signature before running anything: https://runtime.opensysml.org/guide/security/#verifying-a-release.