Skip to content

chore(extensions): re-pin to the project-interchange upstream and prove the vendored copy is the published project - #1563

Merged
HuiJun merged 6 commits into
developfrom
chore/extensions-project-interchange-pin
Oct 27, 2026
Merged

HuiJun merged 6 commits into
developfrom
chore/extensions-project-interchange-pin

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Open-MBEE/OpenSysML-Extensions-Library is now a KerML 10.3 project interchange (its root holds .project.json and .meta.json, and scripts/build-kpar.py derives opensysml-extensions-library-<version>.kpar from them). This re-pins the vendored extension libraries to that upstream commit (b36b361f85af4764de8e2817cbae62fb9e74ffdb; no unit changed) and makes the vendored copy provably the published project:

  • scripts/sync-extension-libraries.sh vendors .project.json, .meta.json and LICENSE (the one recorded file that is not a unit) into internal/workspace/libs/extensions-project/, beside the units it writes flat under stdlib/OpenSysML Libraries/. It refuses an upstream without them, reports a drifted manifest under --check, and a stray file in either directory is an error as before. The identity comes from the pin, never a hand-kept copy.
  • internal/workspace/libs/extensions_project_test.go holds the embedded units to the manifests: each unit's SHA-256 equals checksum["libraries/<Unit>"], every recorded unit is embedded, and each unit declares exactly the root namespaces the index names for it. Verified load-bearing: a byte appended to MOSA.sysml fails the checksum test; an index key renamed MOSAs fails the index test.
  • tests/kpar/extensions_test.go lays out, from the vendored copy at test time (no fixture committed), a consumer whose .project.json uses pkg:git/github.com/Open-MBEE/OpenSysML-Extensions-Library@1.0.0 with the library installed as lib/open-mbee-opensysml-extensions-library_1.0.0/ (units under libraries/, so the checksums verify) beside an unclaimed acme/widgets, so the link is by publisher and name: the sixteen packages load from the install in both the directory and the .kpar form with no warning (-warnings-as-errors -validate passes); an archive with a changed unit is refused on its checksum; a copy named "OpenSysML Extension Libraries" is linked by elimination with the new warning; an archive of the project's folder with a misnamed index entry loads with its two notes.

Where the manifests live, and why not beside the units

internal/workspace/libs/extensions-project/, not stdlib/OpenSysML Libraries/. The Go embed of stdlib skips dotfiles and both library sources list only .sysml/.kerml, so the loader would not have noticed either way; but (1) the units are vendored flat, so a .meta.json beside them would record libraries/<Unit> paths the directory does not have, and (2) a .project.json there flips IsProjectDir on the standard-library directory, so a developer opening a vendored unit from disk would load it as an installed project with a manifest contradicting its tree. A directory holding only the manifests and LICENSE is never a load input. The snapshot generator reads through libs.BundledSource, which is unaffected.

Reader notes, adjudicated against develop (2c0f1750e)

a. Uses slug matching — kept as is; it is the contract docs/internals/design/package-management.md §3 settles. §4 now spells it out for library authors: a project meant to be used as pkg:git/<host>/<owner>/<repository> must give its name a slug equal to the repository's last path segment (and publisher the owner's); one that does not is still installable, linked by elimination when it is the one unclaimed candidate (with a warning, see b) and left unresolved with the ambiguity warning otherwise.

b. discovery.go:used elimination was silent. Probe: one installed project named "OpenSysML Extension Libraries" under lib/ for the usage above; sysml -validate and -warnings-as-errors -validate both passed with no text, and the in-process LoadReport.Found was empty. Root cause: the post-load warning pass (repl.loadWarnings → Discovery.Warnings(paths)) runs over every loaded path, so the installed project linked by elimination is among the enclosing projects on that pass, is claimed up front, and used has nothing left to link; the ambiguity case never had this problem because its candidates are not loaded. Fix: Around links an enclosing project that is itself installed under another's roots as installed again (it stays loaded), and used emits one warning per usage linked by elimination:

<consumer>/.project.json: usage pkg:git/github.com/Open-MBEE/OpenSysML-Extensions-Library@1.0.0 names no installed project by publisher and name; linked by elimination to open-mbee/opensysml-extension-libraries 1.0.0 (<install dir>), the one unclaimed installed project that satisfies it; end the resource with the project's publisher and name (…/open-mbee/opensysml-extension-libraries) to name it

It is judged by the exit policy like the ambiguity warning (-warnings-as-errors fails, -json reports it as project.load). A repository learnt from one link answers its other versions silently. Projects.Unlinked is renamed Linking, since a linked usage is now among them.

c. OMG release archives. tests/kpar/testdata/omg/*.kpar are the SysML-v2-Release kpar/ builds, whose manifests are at the top level with a correct index — they did not show we read the omg.org releases. Probe with the actual https://www.omg.org/spec/SysML/20250201/Requirement-Derivation-Domain-Library.kpar: its members are Requirement Derivation/{.project.json,.meta.json,RequirementDerivation.sysml,DerivationConnections.sysml} and its index maps RequirementsDerivation → RequirementsDerivation.sysml, a file that does not exist. On develop the archive is refused twice over — no .project.json at the top level of the archive; Requirement Derivation/.project.json is nested in a directory, so the archive holds a folder rather than a project (a warning under lib/ or -library-root, an error when named on the command line); and, had the folder been accepted, index entry "RequirementsDerivation" names "RequirementsDerivation.sysml", which is not a member. Name resolution never reads the index (deps.go:rootIndex and workspace.go parse the units), so the index is not trusted; but the mismatch lost the whole archive, not just the package. Fix: an archive whose every member lies under one folder holding both manifests is read as the project in that folder, and an index entry naming no member no longer refuses the archive; each is a note, surfaced as a warning on the archive's path. KerML 1.1 §10.3 says the manifests sit "at its top level", so both are read-through-with-warning, not silent acceptance. TestParseArchiveReadsTheProjectInsideAFolder, TestParseArchiveNotesAnIndexEntryNamingNoMember and the tests/kpar folder-archive test cover it; the OMG archive itself is not committed (PR #1529 owns testdata/omg).

d. Bundle — the sibling PR.

Docs

docs/project/extension-libraries.md (the published project, both manifests, archive name and layout, tagged tree vs derived archive, the consumer usage IRI, where OpenSysML reads it from, the vendoring decision), docs/internals/design/package-management.md §3 (elimination warning; archive-only checksum verification stated plainly — an installed directory's .meta.json is not verified, the tagged tree is read as it stands) and §4 (present tense, the name-slug contract), docs/guide/03-command-line.md (the warning and the two archive read-throughs). README and docs/manual/introduction.md were still accurate and are untouched. Upstream has since tagged v1.0.0 at the pinned commit and published opensysml-extensions-library-1.0.0.kpar as its release asset; the pin stays on the commit SHA, and no test fetches anything over the network.

Specification basis

KerML 1.1 Beta 2 §10.3 (Model Interchange Projects): the archive holds the manifests at its top level and a model interchange file per root namespace; the .meta.json index and checksums per Table 13. No row in docs/project/spec-compliance.md moves.

How it was verified

  • ./scripts/sync-extension-libraries.sh --check → Extension libraries in sync with b36b361f85af4764de8e2817cbae62fb9e74ffdb; a byte appended to the vendored .meta.json → changed internal/workspace/libs/extensions-project/.meta.json and exit 1; a stray file there → error: unexpected file(s): …/stray.txt; EXTENSIONS_COMMIT=5c5deea6… --check → error: upstream holds no .project.json; refusing to sync a tree that is not a project interchange. The three vendored files are byte-identical to the upstream tree (cmp).
  • go test ./internal/workspace/libs -run VendoredExtension, go test ./internal/workspace/project, go test ./tests/kpar pass.
  • Full gate on this branch: go build ./... ok, go vet ./... ok, gofmt -l . empty, make lint (staticcheck + gosec, both modules) ✓, go test ./... with OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 OPENSYSML_REQUIRE_SPEC_EXAMPLES=1 after the three download scripts — all packages ok (the 46 packages depending on internal/workspace/project re-run on the final head after the review fixes, all ok), python3 scripts/changelog.py check ok, python3 scripts/check-doc-links.py → 0 broken links, python -m mkdocs build --strict ok, make extension-libraries-check → in sync with b36b361f….
  • Dry-merges: clean against origin/develop, against fix(project): bundle the files a project's .meta.json records #1566 (the sibling), and textually clean against chore(pilot): pin the OMG pilot implementation to release 2026-09 (0.63.0) #1529's head for every file this PR touches — chore(pilot): pin the OMG pilot implementation to release 2026-09 (0.63.0) #1529's own conflicts with develop (docs/project/api-json-differential*, spec-compliance.md, validation-constraints.md) are files this PR does not change.
  • Devin Review: two rounds (the mixed-load regression of the first Around change, the sync script's directory blind spot, two comment lengths), each fixed in its own commit and the thread resolved; the current head has no open finding of any severity, flags included.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/1e9164f57f814014a9f0aba35666e2a3
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/1e9164f57f814014a9f0aba35666e2a3?variant=devin
Requested by: @HuiJun

devin-ai-integration Bot and others added 4 commits October 27, 2026 01:09
…dor its manifests

The pin moves to the commit that makes Open-MBEE/OpenSysML-Extensions-Library
a KerML 10.3 project interchange. The sync script vendors .project.json,
.meta.json and LICENSE into internal/workspace/libs/extensions-project/,
refuses an upstream without them, and reports drift or stray files there as
it does beside the units. A gate holds every vendored unit to the SHA-256 the
upstream .meta.json records and to the root namespace its index names.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…'s folder, note an index entry naming no member

A usage linked by elimination was silent: the post-load warning pass saw the
installed project among the enclosing ones and had nothing left to link. It is
now a warning on the consumer's .project.json naming the project taken and the
publisher/name the resource should end with, judged by the exit policy. An
archive holding the project's folder with the manifests inside, as the OMG
library releases are, is read as the project in that folder, and an index
entry naming no member is noted rather than refusing the archive, since the
members' declarations are what name resolution reads.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
… a tree and as an archive

The consumer lays the vendored units out under libraries/ with the vendored
manifests, beside an unclaimed project so the name decides the link, and loads
the sixteen packages from the install in both forms; a changed unit fails the
archive's checksum, a misnamed project is linked by elimination with the
warning, and a folder-layout archive with a misnamed index entry loads with
its notes.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…I and the linking warnings

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

…ing the elimination link; flag stray directories in the vendored copy

An enclosing project installed under the roots stays in the usage traversal
and may still answer a usage by elimination, never its own; the sync script's
compare reports a directory or other non-file entry in a vendored directory as
unexpected, as the check did before.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…ests

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 27, 2026 02:17
@HuiJun
HuiJun merged commit 57767f1 into develop Oct 27, 2026
53 checks passed
@HuiJun
HuiJun deleted the chore/extensions-project-interchange-pin branch October 27, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant