Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
39 changes: 24 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# only if a variant's delta ever grows past caring about. The test job
# clippy-checks the slim variant so it cannot rot between releases.
#
# The wasm job gates the browser face: clippy for
# The wasm job gates the browser face: clippy for the wasi CLI and for
# wasm32-unknown-unknown, then the real pipeline — wasm-pack build, the
# stdlib bundle + sealed-snapshot generation, and a node smoke test that
# loads the built module and asserts snapshot replay is engaged. On tags
Expand Down Expand Up @@ -67,7 +67,8 @@ env:
jobs:
test:
name: test (full corpus gates)
timeout-minutes: 45
# The full corpus plus lint/docs outgrew 45 minutes on a cold runner.
timeout-minutes: 90
# Release PRs (release/* -> main, opened and admin-merged by
# tools/release.sh in one step) run these gates like any other PR.
# Skipping them costs less than it looks: the tag is pushed by the
Expand Down Expand Up @@ -98,6 +99,10 @@ jobs:
rustup show active-toolchain
- name: Formatting
run: cargo fmt --all -- --check
- name: Generated semantic catalogs
run: |
python3 tools/semantic_catalog.py --check
python3 tools/operation_catalog.py --check
- name: Run the full test suite
run: cargo test --release
- name: Clippy
Expand All @@ -108,17 +113,12 @@ jobs:
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --no-deps
- name: Generated libraries (strict check against the stdlib, canonical formatting)
# The committed files are checked as candidates: SYSMLV2_AMBIENT=off
# keeps the toolkit's built-in copies out so they cannot collide.
run: |
SYSMLV2_AMBIENT=off cargo run --release -p sysmlv2-cli -- check --strict --lib spec-refs/SysML-v2-Release/sysml.library local-packages/Web.sysml local-packages/Template.sysml local-packages/Svelte.sysml local-packages/WebApp.sysml local-packages/SvelteKit.sysml
cargo run --release -p sysmlv2-cli -- fmt --check local-packages/Web.sysml local-packages/Template.sysml local-packages/Svelte.sysml local-packages/WebApp.sysml local-packages/SvelteKit.sysml
- name: Ambient libraries resolve without naming files
- name: Ambient library (strict candidate check; resolves without naming its file)
# SYSMLV2_AMBIENT=off keeps the built-in copy out of the candidate
# check so the two cannot collide.
run: |
# Qualified element kinds: an `Elements::*` import would bring the
# `<template>` element kind into scope and shadow the `Template` package.
printf 'package V { part shell : Web::HTML::Elements::Div { :>> id = "app"; } part t : Template::Text; part k : Svelte::KeyBlock; part a : WebApp::Application; part r : SvelteKit::RouteSegment; }\n' > /tmp/ambient.sysml
SYSMLV2_AMBIENT=off cargo run --release -p sysmlv2-cli -- check --strict --lib spec-refs/SysML-v2-Release/sysml.library local-packages/TransformMeta.sysml
printf 'package V {\n #TransformMeta::Generated part def G;\n}\n' > /tmp/ambient.sysml
cargo run --release -p sysmlv2-cli -- check --strict --lib spec-refs/SysML-v2-Release/sysml.library /tmp/ambient.sysml

msrv:
Expand Down Expand Up @@ -166,14 +166,23 @@ jobs:
rustup show active-toolchain
- name: Clippy (wasm32)
run: cargo clippy --release -p sysmlv2-wasm --target wasm32-unknown-unknown -- -D warnings
# The CLI's wasi branches compile for no other target, so the
# native clippy runs never see them. The features are the ones
# build.mjs ships the CLI with; change the two together.
- name: Clippy (wasi CLI — the features build.mjs ships)
run: cargo clippy --release -p sysmlv2-cli --no-default-features --features solve,viz --target wasm32-wasip1 -- -D warnings
- name: Install wasm-pack
# Pinned release binary. The rustwasm.github.io installer script
# is stale (the project moved to drager/wasm-pack) and serves
# 0.13.1 forever; old release URLs redirect to the new repo.
# 0.13.1 forever; old release URLs redirect to the new repo. Its
# pin also pins the optimizer: the binaryen release it fetches to
# optimize the module is the wasm-opt build.mjs runs on the CLI.
run: |
v=0.15.0
curl -sSfL "https://github.com/rustwasm/wasm-pack/releases/download/v${v}/wasm-pack-v${v}-x86_64-unknown-linux-musl.tar.gz" | tar xz
mv "wasm-pack-v${v}-x86_64-unknown-linux-musl/wasm-pack" "$HOME/.cargo/bin/"
tool_dir=$(mktemp -d)
trap 'rm -rf "$tool_dir"' EXIT
curl -sSfL "https://github.com/rustwasm/wasm-pack/releases/download/v${v}/wasm-pack-v${v}-x86_64-unknown-linux-musl.tar.gz" | tar xz -C "$tool_dir"
mv "$tool_dir/wasm-pack-v${v}-x86_64-unknown-linux-musl/wasm-pack" "$HOME/.cargo/bin/"
wasm-pack --version
# The runtime the smokes run under is pinned, not inherited. The
# image's own Node 22 on x86_64 faults inside its WASI host on this
Expand Down
31 changes: 30 additions & 1 deletion CBOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,35 @@ Which payload kind it is lives in the body's own header flags, never in the name

The type is unregistered vendor-tree for now; register it (and the application tag) before any public service exposes them.

## Selecting a graph contract

Existing codec functions continue to stamp scheme 2. For canonical compact
snapshots use `to_compact_cbor_with_format`,
`to_compact_cbor_explicit_with_format`, or
`to_compact_cbor_elided_with_format`; use `to_full_cbor_with_format` for full
emit views. Full encoding carries the caller's declared format and does not
certify semantic conformance.

`from_cbor_with_format` returns a compact document, unit paths, and its format.
`graph_format` reads header metadata without walking the payload; it is not a
payload validator. `assert_graph_format` checks a receiver's selected contract.
Legacy explicit-ID stamps retain historical compatibility; unknown elided stamps
are refused. A resolver artifact must pass `assert_compatible_with_format` before
use with the selected contract.

Deltas select the contract with `DeltaOptions::with_graph_format`; base and target
must already use that contract. Deltas are not an identity migration. Retain the
header's format alongside the returned JSON when using the generic apply APIs.
Sessions select the header automatically when encoding and reject incoming
snapshots or deltas whose header format differs from their library context.
Explicitly format-aware sessions also enforce conditional and constructor JSON shapes at their
boundaries. Historical legacy constructors and scheme-2 snapshot loading retain
their foreign-graph recovery/warning policy. Opening a compact
snapshot with `Session::from_compact_cbor` restores its recorded format. Scheme 2
does not serialize the stricter JSON-boundary policy selected by an explicit
LegacyV2 constructor; reopening it uses historical legacy recovery. JSON-only
consumers must pass the format explicitly when rebuilding a session.

## Layout

```
Expand Down Expand Up @@ -77,7 +106,7 @@ Where the bytes go, relative to compact JSON:

- **layout (u8)** — the array shapes, presence encoding, reference index spaces, and delta framing. Refused unconditionally on mismatch.
- **tables (u16)** — the generated metamodel tables (type codes, field ordinals, kinds, defaults; currently from the 20250201 normative release). Refused on any decode, since every element record reads through them — but independently of layout, so a tables-only regeneration is diagnosable as exactly that.
- **scheme (u8)** — the id-derivation scheme (`IDS.md`; wire scheme 1 is that document's graph-derived derivation). Consulted **only** where derivation is in play (id-elided payloads, snapshot or delta): explicit-id payloads decode regardless of it. Digest failures on matched-scheme payloads therefore come pre-diagnosed: not a scheme skew, so library skew or corruption.
- **scheme (u8)** — the lowering/identity contract (`IDS.md`): 2 is the default legacy graph; 3 is opt-in canonical lowering. Both use graph-derived identities. Elided snapshots and deltas accept these supported schemes; scheme 3 compact snapshots and applied deltas also validate their authored conditional and constructor shapes. Generic explicit-ID decoders retain historical scheme compatibility, but format-aware sessions require their selected contract. Digest failures on matched schemes indicate a different library context or corruption.

**Flags.** `elideIds` (1), `fullForm` (2), `delta` (4), `deltaPortable` (8), `unitPaths` (16), `impliedOwners` (32), and `explicitIds` (64): a compact snapshot whose ids are not all the graph derivation of `IDS.md` — a session that loaded a document from another producer, or under other unit names, keeps the ids it was given and marks the payload so a receiver never re-derives them; such a session refuses id elision. Informational for decoders, which always read the id table; `describe` reports it as `explicitIds`.

Expand Down
Loading
Loading