v0.0.8: Shakeout release
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
Modelgainedinstantiate,execute_actionandexecute_state, so every
call taking a model hash is reachable on the model it is about.- A cached
~/.pysysml/bin/sysml-grpcrecords 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 ownpysysml.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, raisingStaleServiceErrornaming the remedy
instead of aMissingCapabilityErroron the first newer call. It is stopped only
when this client started it and no other client holds it. sysml-grpc -versionreports the metadata the linker sets, where a released
binary saidversion 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 underexamples/
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%slotsshows the instantiated value. - A
calcbody written withoutreturnis not expression-type-checked, so no
static dimensional warning is reported inside it. - Submitting any declaration to the REPL ends an active
%actionor%state
debugging session. semanticTokens/full/deltais 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.0The full list of changes is in CHANGELOG.md.