Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
32d92c2
docs: document SysML v1 migration on the API, guide and roadmap
devin-ai-integration[bot] Sep 15, 2026
a16d986
chore(proto): regenerate the TypeScript and Rust stubs for the Conver…
devin-ai-integration[bot] Sep 15, 2026
dc54116
docs: recount the test-suite figure for the Go client migration test
devin-ai-integration[bot] Sep 15, 2026
6d255fa
ci: rerun the PR workflow
devin-ai-integration[bot] Sep 15, 2026
6d107ec
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 15, 2026
60c1bb1
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
b5d50c4
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
8e68356
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
11e3d93
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
e5693d2
docs(guide): follow the migration report's counts after the signal ma…
devin-ai-integration[bot] Sep 16, 2026
fb66e00
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
7398621
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
92170c2
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
f34e17c
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
5aaeddf
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
38423e8
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
824c3d9
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
5c2f4f7
docs: recount the test-suite figure after merging develop
devin-ai-integration[bot] Sep 16, 2026
e145714
Merge remote-tracking branch 'origin/develop' into docs/v1-migration-…
devin-ai-integration[bot] Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions api/proto/sysml.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions api/proto/sysml.proto
Original file line number Diff line number Diff line change
Expand Up @@ -759,11 +759,14 @@ message ConvertRequest {
string content = 2;
string model_hash = 6;
}
// "sysml", "kerml", "text", "ttl", "turtle" or "rdf". Empty infers from
// file_path's extension, and is notation for a model_hash, since that is what
// parse reads; inline content has neither, so it must say.
// "sysml", "kerml", "text", "ttl", "turtle" or "rdf", or "xmi", "uml" or
// "mdzip" for a SysML v1 model, which is read and migrated to v2 and never
// written. Empty infers from file_path's extension, and is notation for a
// model_hash, since that is what parse reads; inline content has neither, so
// it must say.
string from_format = 3;
// Format to write, named as in from_format. Empty is rejected.
// Format to write, named as in from_format; the v1 names are refused, since
// a v2 model has no v1 form. Empty is rejected.
string to_format = 4;
// Write notation back out even when the parser could not read all of it,
// reporting its syntax errors as diagnostics. Notation to notation only:
Expand All @@ -786,7 +789,8 @@ message ConvertResponse {
// Set when either format is RDF, whose mapping is experimental: it covers
// model structure and the behavior its bodies state, refuses what it cannot
// write back, and its vocabulary may change without a compatibility path.
// Notation to notation is stable and leaves this unset.
// Also set when the source is SysML v1, whose migration is experimental in
// the same sense. Notation to notation is stable and leaves this unset.
bool experimental = 6;
// What is experimental about the conversion, in the wording every surface
// reports it in. Empty when experimental is false.
Expand Down
2 changes: 2 additions & 0 deletions changes/unreleased/sysml-v1-migration-docs.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- **SysML v1 migration is documented on every surface it reaches.** `ConvertRequest.from_format` and `ConvertResponse.experimental` in `api/proto/sysml.proto`, `docs/reference/wire-contract.md` and `docs/reference/api.md` now name `xmi`, `uml` and `mdzip` as input-only formats, the extensions they are inferred from, the canonical `xmi` a response answers, and that a migration marks the response experimental as an RDF conversion does; the Python client's `convert` docstrings and guide chapter 9 say the same. Guide chapter 11 walks one migration through — running it with `-migration-report`, reading the four verdicts, finishing units, behaviors and operations by hand, and checking the result as a v2 model — and the roadmap records the migration's open items: behaviors, operations and receptions, units and quantity kinds, the report over gRPC, and stable identity for a re-migration.
- **The Go client names SysML v1 as a conversion source.** `opensysml.FormatXMI` is the format a `Conversion` answers when `ConvertFile` read UML XMI, an Eclipse UML2 `.uml` file or a `.mdzip` archive; the `Conversion` is `Experimental` with the migration notice, and asking to write `FormatXMI` is refused with `CodeInvalidArgument`.
2 changes: 1 addition & 1 deletion client/opensysml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ inst, err := client.Instantiate(ctx, model, "Demo::Vehicle")
| Choose who answers | `ListEngines`, `WithEngine`, `Engine`, `CalcEngine` |
| Search it | `Query`, `QueryOSLC` |
| Report on it | `RunDocumentQuery`, `RenderDocument` |
| Write it out | `Convert`, `ConvertFile`, `ConvertSource` |
| Write it out, or migrate a SysML v1 model in | `Convert`, `ConvertFile`, `ConvertSource` |
| Change its source | `ApplyEdits` |

Execution and verification take the same handles the rest of the API takes:
Expand Down
13 changes: 8 additions & 5 deletions client/opensysml/authoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
// Format is a representation a model is written in or read from.
type Format string

// The formats conversion accepts. There are two canonical ones, FormatSysML and
// FormatTTL, and a Conversion answers by those names whichever alias was asked
// for. RDF, in any spelling, is an experimental mapping, which a Conversion
// reports.
// The formats conversion accepts. There are two canonical ones that are written,
// FormatSysML and FormatTTL, and a Conversion answers by those names whichever
// alias was asked for. RDF, in any spelling, is an experimental mapping, which a
// Conversion reports; so is migration from FormatXMI, which is only ever read.
const (
FormatSysML Format = "sysml"
FormatTTL Format = "ttl"
Expand All @@ -25,6 +25,9 @@ const (
// serialization written.
FormatTurtle Format = "turtle"
FormatRDF Format = "rdf"
// FormatXMI is SysML v1 as UML XMI, an Eclipse UML2 .uml file or a .mdzip
// archive, migrated to v2 on the way in. Asking to write it is refused.
FormatXMI Format = "xmi"
)

// ConvertOption configures Convert and ConvertFile.
Expand Down Expand Up @@ -59,7 +62,7 @@ type Conversion struct {
From Format
To Format
// Experimental is set when either format is RDF, whose vocabulary may change
// without a compatibility path.
// without a compatibility path, or the source is SysML v1, whose migration may.
Experimental bool
// ExperimentalNotice says what is experimental about the conversion, empty
// when it is not.
Expand Down
24 changes: 24 additions & 0 deletions client/opensysml/surface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"net/http"
"net/http/httptest"
"path/filepath"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -676,6 +677,29 @@ func TestAFormatAliasIsAnsweredCanonically(t *testing.T) {
}
}

func TestConvertFileMigratesSysMLv1(t *testing.T) {
client := newClient(t)
xmi := filepath.Join("..", "..", "internal", "core", "migrate", "testdata", "xmi", "vehicle.xmi")
conversion, err := client.ConvertFile(context.Background(), xmi, opensysml.FormatSysML)
if err != nil {
t.Fatalf("ConvertFile: %v", err)
}
if conversion.From != opensysml.FormatXMI || conversion.To != opensysml.FormatSysML {
t.Errorf("conversion = %s to %s, want xmi to sysml", conversion.From, conversion.To)
}
if !strings.Contains(conversion.Content, "part def Vehicle") {
t.Errorf("conversion does not carry the migrated model:\n%s", conversion.Content)
}
if !conversion.Experimental || !strings.Contains(conversion.ExperimentalNotice, "SysML v1 migration") {
t.Errorf("a migration does not report itself as experimental: %q", conversion.ExperimentalNotice)
}

_, err = client.ConvertFile(context.Background(), xmi, opensysml.FormatXMI)
if !errors.Is(err, opensysml.CodeInvalidArgument) {
t.Errorf("writing xmi: err = %v, want CodeInvalidArgument", err)
}
}

func TestConvertSourceReadsInlineContent(t *testing.T) {
client := newClient(t)
conversion, err := client.ConvertSource(context.Background(), editableSource, opensysml.FormatSysML,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading