Skip to content

v0.0.7: QOL release

Choose a tag to compare

@HuiJun HuiJun released this 15 Aug 08:06
3b07b1b

Systemica v0.0.7

sysml 0.0.7 · sysml-lsp 0.0.7 · sysml-grpc 0.0.7 · pysysml 0.1.1

This release is about the surfaces. The engine's answers did not change in ways a
model author would notice; what changed is that the answers are now reachable,
discoverable and trustworthy from a script, a prompt, an editor and Python. It
also carries the element-filter, Query-RPC and loading-performance work that
v0.0.6 shipped without a changelog entry of its own.

Highlights

The command line can fail

sysml is usable in CI and in a Makefile for the first time:

  • Exit status means something on every path0 when the requested
    operation succeeded and every requested check held, 1 when a check answered
    false, 2 when nothing was decided (a model that did not analyse, an
    expression that could not be evaluated, an unreadable file, a misused flag). A
    check is gated on analysis, so no verdict is ever reported about a model nobody
    could read.
  • Streams are separated — findings and diagnostics on stderr, requested
    output on stdout, under one sysml: prefix. -h is stdout and exit 0; an
    unknown flag stays stderr and exit 2.
  • Checks run without a prompt-validate, -constraint, -requirement,
    -satisfy, -instantiate, -calc, -action, -state -advance, -json. One
    evaluation stands behind both the flag and the prompt's %constraint /
    %requirement / %satisfy.
  • A project loads as a projectsysml <dir>, sysml 'src/*.sysml' and
    %load <dir> expand, sort and deduplicate their inputs and submit them as one
    submission, so resolution no longer depends on load order; diagnostics keep
    each file's own line numbers.
$ sysml examples/combined-behavioral-demo.sysml -validate ; echo "status=$?"
✓ package VehicleModel
status=0

Breaking: conversion is spelled sysml model.sysml -convert ttl. The model is
a positional argument as in every other mode and -convert names the target
format; -convert <file> and -to <format> are gone (-to reports its
replacement), and the output path no longer picks the format, so -o /dev/null
or a FIFO needs nothing extra.

The REPL stops losing your session

Re-typing a namespace merges into the one already in the buffer instead of
replacing its body. An instance and an active %action / %state session
survive a submission that did not change what they depend on — declaring an
unrelated part def B; no longer discards the instance of A — and anything
genuinely invalidated is dropped with a notice naming the submission that ended
it. The library is discoverable from the prompt: %search, %builtins, Tab
completion over meta commands, symbols and paths, and history kept outside the
temporary directory.

Diagnostics point at the fix

An unresolved name carries the nearest spelling on every surface — command
line, prompt and editor — and candidates are ranked by how a reader would reach
them rather than by edit distance: the budget scales with the typed name's
length, a name in scope beats one reachable only by a path, your own declaration
beats a bundled library one, and a candidate too far out is dropped even when it
is the only one. Whel beside your own Wheel offers Wheel alone.

$ sysml model.sysml -validate
sysml: model.sysml:3:21: unresolved reference: Integer — did you mean ScalarValues::Integer?

The base library is not implicitly visible, so a bare Integer is an error with
its qualified spelling offered; every shipped examples/*.sysml and
examples/*.kerml imports what it uses and analyses cleanly.

Element filters are evaluated

filter <expr>; in a package, definition or usage body, import P::*[@T], and a
filter at a document's root all gate the names beside them. A condition is a
boolean predicate over one candidate with the candidate as the implicit self
(KerML 8.2.4), judged against a symbol and the metadata annotating it, with
conformance through supertypes — so @Safety matches a metadata type
specializing Safety. A condition outside the evaluated subset is reported as
such rather than silently selecting nothing, and completion applies the filters
in force where the name is being completed.

Runtime

  • An action flow ends at a node with no succession, so an action whose last
    node is a plain nested action reaches Completed instead of failing.
  • A performance holds its values in one feature space its tokens share, so a
    fork's concurrent branches no longer overwrite each other's assignments —
    which write decides a feature both branches assign is step order, stated in
    docs/SPEC_COMPLIANCE.md.
  • A fifth runaway bound, SYSML_MAX_ELEMENTS (default 1 000 000), bounds the
    collection elements one evaluation holds, so 1..10000000 is refused before it
    conjures ~1 GB. %budget prints the five bounds and the variable that raises
    each.
  • An evaluation outside a body (a guard, a change condition, a default, an
    argument, a constraint check) runs in a scope of its own, so a revisited
    decision re-reads its calc usage over current values instead of returning the
    first evaluation's result.

Editors

A first-party VS Code extension lives in editors/vscode: TextMate highlighting
for .sysml and .kerml, comment/bracket configuration, and an LSP client that
finds sysml-lsp from systemica.server.path, a workspace's bin/sysml-lsp, or
PATH. It is built and side-loaded from this repository (make vscode-package)
and is published to no marketplace. Completion is typed and context-aware, and
sysml-lsp now serves a session over one reader — it used to race two decoders
over its own stdio and die with corrupted framing within seconds of typing.

Python — pysysml 0.1.1

  • Model.eval() evaluates in the model's context; pysysml.eval() still works
    without one.
  • Instance expansion is complete and typed: nested parts, connector ends and
    slots carry their kind, so a value is a bool/int/float/str rather than
    a string, and a DataFrame column has a usable dtype.
  • Verification raises on a wrong-kind subject (WrongKindError) instead of
    answering an undecided verdict, and connect("host:port") is accepted.
  • Conversion APIs, a Query RPC accepting the SysML v2 API & Services query
    model's JSON payloads verbatim, and typed model generation are available.

Performance

Loading a large model is linear where it was quadratic (three lookups scanned a
namespace's members once per member), and ParseFile hits its cache on the
source it read, so re-loading unchanged content costs ~0.5 ms instead of ~35 ms.
docs/PERFORMANCE.md records the measurements.

Removed

internal/core/deps — the sysml.toml manifest, lockfile, git fetcher and
resolver — is deleted. Nothing imported it: no manifest was ever looked for by
the command line, the prompt or the server, and the README claim it backed is
gone.

Verification

Gate Result
gofmt -l . clean
go build ./... / go vet ./... clean
make lint (staticcheck, gosec) pass
go test -race -count=1 ./... 3,585 tests and subtests — 3,580 pass, 5 self-skip, 0 fail
TestStdlibConformance 95/95 bundled library files clean
OMG training corpus 98/100 files clean (2 files / 4 errors, pinned OMG source bugs)
pytest python/tests/ pass

Known limitations

  • A surviving REPL debugger session keeps the executor it was started with rather
    than being re-lowered.
  • @Safety; as a standalone semicolon-terminated annotation member does not
    parse; @Safety (no semicolon), @Safety part x; and metadata Safety; do.
  • The LSP advertises no code actions, and SemanticTokensFull is still a stub —
    highlighting comes from the TextMate grammar.
  • Model has no instantiate / execute_action / execute_state convenience
    method; the Connection methods behind them do exist.
  • sysml -validate - treats - as a filename (no stdin), and a piped
    expression is parsed as a model rather than evaluated.

Install

# Homebrew
brew install Open-MBEE/tap/systemica

# or a release archive
curl -fLO https://github.com/Open-MBEE/Systemica/releases/download/v0.0.7/systemica-linux-amd64.tar.gz
curl -fLO https://github.com/Open-MBEE/Systemica/releases/download/v0.0.7/SHA256SUMS.txt
sha256sum -c --ignore-missing SHA256SUMS.txt && tar xzf systemica-linux-amd64.tar.gz

# Python client
pip install pysysml==0.1.1

The full list of changes is in CHANGELOG.md.