Skip to content

v0.0.8: Shakeout release

Choose a tag to compare

@HuiJun HuiJun released this 16 Aug 03:38
· 746 commits to main since this release
e2d49be

Systemica v0.0.8

sysml 0.0.8 · sysml-lsp 0.0.8 · sysml-grpc 0.0.8 · pysysml 0.2.0

This release is about trust in the answers. v0.0.7 made the answers reachable from
a script, a prompt, an editor and Python; this one fixes nine ways a reachable
answer could still be the wrong one — a violating model reported ✓ passed with
exit 0, a released sysml-grpc reporting version dev, a Python client serving a
cached binary from a different release, an RDF export refusing every model with a
constraint. The editor surfaces the LSP advertised but stubbed are implemented, a
dimensional mistake is caught at validation time, and the documentation is a
handbook instead of a page per feature.

Highlights

A check answers about the object, not the declaration

A constraint or requirement declared on a definition is now evaluated against the
object that carries it, so %constraint, %requirement and -constraint on an
instantiated model read the object's values rather than the declaration's
defaults. A model violating its own mass budget used to be answered ✓ passed
with exit 0 — the failure mode that matters most, since it is silent:

$ sysml rover.sysml -instantiate Rover::rover -constraint Rover::RoverDef::MassBudget ; echo "status=$?"
✓ Created instance of Rover::rover
  ID: 1
✗ Constraint Rover::RoverDef::MassBudget failed (on Rover::rover ID: 1)
  Assertion evaluated to false: chassis.mass <= maxMass
status=1

%eval reads the same subject, so a check and an %eval of a feature in one
session can no longer answer about different objects (a nested redefined feature
is still the exception, below); where several objects carry the feature it refuses
to choose rather than picking one. And a condition whose evaluation could
not be carried out is worded as undecided (? … could not be evaluated) and names
why, where it used to print a failure while exiting 2.

Dimensional mistakes are caught before evaluation

A comparison or sum of quantities whose dimensions are both statically determined
and incommensurable is reported at validation time, as a type-tier warning,
from the stdlib QuantityDimension power factors:

$ sysml model.sysml -validate
model.sysml:6:9: warning: operator '<' combines incommensurable quantities: MassValue (dimension M) and m (dimension L)
        mass < 1000.0 [m]
        ^~~~~~~~~~~~~~~~~

Evaluation keeps its hard error, and a warning changes no exit status — so this
catches the mistake early without failing a build that used to pass. A dimension a
declaration does not determine stays unknown and is not reported: there are no new
warnings on examples/, the bundled library or the OMG corpus.

Editors get highlighting and quick fixes

textDocument/semanticTokens/full and /range are implemented over a new
internal/core/highlight package, so highlighting comes from the parse rather
than from a TextMate approximation. textDocument/codeAction answers quick fixes
carried as structured edits from the layer that reported the diagnostic — a
located missing semicolon, a near-miss spelling, an importable namespace. Token
deltas are not implemented and are not advertised.

RDF export stops refusing constraints

The members that state a condition — a constraint body's conditions, a
requirement's assumptions and required conditions, a subject, a result — have a
mapping, so converting a model with a constraint no longer aborts. Conditions are
carried as sysx:condition notation, as every expression-valued position in this
mapping is. Turtle written back as SysML also spells the notation now: an
unrestricted name gets its quotes, so a model with a quoted name re-parses — every
example model that converts and validates on its own — 44 of the 71 — now
round-trips through Turtle and back and validates again.

Python — pysysml 0.2.0

  • Model gained instantiate, execute_action and execute_state, so every
    call taking a model hash is reachable on the model it is about.
  • A cached ~/.pysysml/bin/sysml-grpc records the release and the repository
    it was downloaded from beside it, and a cache from another release is replaced
    rather than served — the failure that silently disabled newer RPCs. A failed
    integrity check is its own pysysml.ChecksumMismatchError — exported from the
    package, like every other exception a documented failure raises — and is never
    answered from the cache; a download that fails on the network keeps the working
    binary.
  • A service already listening is asked what it is and compared against the release
    and capabilities asked for, raising StaleServiceError naming the remedy
    instead of a MissingCapabilityError on the first newer call. It is stopped only
    when this client started it and no other client holds it.
  • sysml-grpc -version reports the metadata the linker sets, where a released
    binary said version dev / commit unknown.

The command line reads standard input

A lone - names standard input wherever a model path is taken, -convert
included, and is reported as <stdin>; it is read even when stdin is /dev/null,
and stays distinct from a file named -. sysml-lsp parses its command line with
the flag package, so -version works and an unreadable flag is a usage error
rather than protocol mode.

Documentation is a handbook

The pages are organized by what a reader is doing rather than by the feature that
landed: a numbered guide (install → first model → command line → REPL → checking →
behavior → saving and RDF → editors → Python → troubleshooting) under
docs/guide/, looked-up material under docs/reference/, design under
docs/internals/, status under docs/project/. QUICKSTART.md and
RDF_INTEROP.md are split into the chapters they already were, the guide content
stranded in examples/*.md and python/README.md is folded in, and the paths the
v0.0.7 README linked leave pointers behind. scripts/check-doc-links.py gates
every relative link and heading anchor in CI.

Release publishing keeps the notes

Release assets are published with ghr -replace. -delete is an alias of
-recreate: it deleted the release and its tag ref and created an empty one, so
re-running the workflow for a tag wiped hand-written release notes, the title and
the prerelease/latest flags. The Homebrew tap now updates itself from a scheduled
workflow in Open-MBEE/homebrew-tap, reading the release's SHA256SUMS.txt, with
scripts/render-homebrew-formula.sh as the manual fallback.

Verification

Gate Result
gofmt -l . clean
go build ./... / go vet ./... clean
make lint (staticcheck, gosec) pass
go test -race -count=1 ./... 3,687 tests and subtests — 3,682 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/ 369 pass, 26 skip (integration, no service listening)
scripts/check-doc-links.py 0 broken links

Known limitations

  • Converting a model whose behavior is stated as action or state nodes to RDF
    still reports the node and aborts (initial nodes, perform, send,
    terminate, loop nodes, state regions): 71 of the 120 models under examples/
    convert.
  • A nested feature redefined on an instantiated object is not yet the subject of a
    check or an %eval, so those answer about the declaration — and print no
    (on …) — while %slots shows the instantiated value.
  • A calc body written without return is not expression-type-checked, so no
    static dimensional warning is reported inside it.
  • Submitting any declaration to the REPL ends an active %action or %state
    debugging session.
  • semanticTokens/full/delta is not implemented and is not advertised.

Install

# Homebrew
brew install Open-MBEE/tap/systemica

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

# Python client
pip install pysysml==0.2.0

The full list of changes is in CHANGELOG.md.