Skip to content

feat: ECMA-427 package identities (pkg:generic with the Annex B.3.5 vcs_url qualifier) - #2

Merged
HuiJun merged 9 commits into
developfrom
feat/ecma-427-identities
Oct 28, 2026
Merged

HuiJun merged 9 commits into
developfrom
feat/ecma-427-identities

Conversation

@devin-ai-integration

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

Copy link
Copy Markdown
Contributor

Summary

Package identities become ECMA-427 Package-URLs. A repository package is identified by the generic type carrying the Annex B.3.5 vcs_url qualifier:

pkg:generic/<name>?vcs_url=<vcs>+<transport>://<host>/<path>[@<version>][#<subpath>]

with the qualifier value percent-encoded (every byte outside A-Z a-z 0-9 - . _ ~ and : becomes %XX, as in the purl canonical form; e.g. pkg:generic/OpenSysML-Extensions-Library?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2FOpen-MBEE%2FOpenSysML-Extensions-Library%401.0.0). <name> is the last segment of the repository path with a .git suffix stripped; the path itself is kept and cloned exactly as written (…/repo and …/repo.git are two locations); <version> is a tag naming a semantic version (v<semver> or <semver>); a commit id is refused with a message saying so. The vcs_url schemes are those of Annex B.3.5 (git, git+git, git+https, git+http, git+ssh; hg+http, hg+https, hg+static-http, hg+ssh; svn, svn+svn, svn+http, svn+https, svn+ssh) plus <vcs>+file:///path for a repository on this machine (pip's notation, which Annex B.3.5 says the syntax follows). Resource IRIs follow KerML 1.1 §10.3 Table 12: resource is an IRI identifying the project; a dereferenceable http(s) IRI is only ever read as a project interchange file (.kpar), and user:password@ in it is refused (credentials belong in the netrc).

Accepted inputs (syspi add and .project.json usages; add writes the canonical form):

  • the canonical pkg:generic/<name>?vcs_url=… (any valid percent-encoding, e.g. %3A for :);
  • pkg:git/<host>/<path>[@<version>][#<subpath>], an alias for git+https;
  • the bare vcs_url notation git+https://…, git+ssh://…, git://…, hg+https://…, hg+static-http://…, svn://…, svn+https://…, svn+ssh://…, <vcs>+file:///…, each with optional @<version> and #<subpath>.

Removed inputs, each refused with a message naming the accepted spellings: pkg:svn/…, pkg:hg/…, pkg:sysand/…, plain https://host/path[.git]@v clone URLs, ssh://…, scp-style git@host:path, file:///path@v and /path@v repositories, pkg:git//<local path>.

Removed features: pkg:sysand resolution, the static index client (discovery, URL templates, index credentials), syspi index emit, the -index/-no-index flags and index environment variables, .sysand/lib/ reading. Remote .kpar downloads keep their netrc credentials.

Lock entries keep vcs, source, tag, revision, sha256; resource is the canonical purl without its version. A lock entry is matched to a usage by one repository key (origin.Key: the identity with a .git suffix dropped from the repository path), applied to the lock as read (keyResources), so a lock written in an older spelling (pkg:git/…, bare git+https://…) or with the other .git spelling still matches its usage and the installed tree offline, provided the entry's recorded source is the requested location (lockedRepository compares locationKey: a <vcs>+ scheme prefix, host case and the file scheme are ignored, so an older git+ssh://… source still matches ssh://…, while …/repo and …/repo.git stay two repositories and never serve each other's tree); the entry is then written under the usage's identity and current source spelling. Install naming is unchanged (lib/<publisher>-<name>_<version>).

netrc for .kpar downloads: credentials are matched per host; after a redirect to another origin only an explicit machine entry is sent, never the default entry. URLs in diagnostics are shown without user info or query (netrc.RedactURL).

Open point for the maintainer (review thread left open): git+ssh://git@host/path is refused per Annex B.3.5, so a host that requires the git account needs Host … User git in ~/.ssh/config; the alternative is accepting a bare user name (no password) for the +ssh transports as input sugar.

Gate

go build ./..., go vet ./..., gofmt -l . empty, SYSPI_REQUIRE_VCS=1 go test ./... ok (unit: parse/normalise/encode round-trip of every accepted input and the refusals in internal/origin, lock canonicalisation, netrc redirect and redaction; e2e: git, hg and svn fixtures via git+file, hg+file, svn+file, git over dumb HTTP as git+http://…, hg as hg+static-http://…, svn as svn://…).

Real check

Two fresh projects, one add each, against the released v1.0.0 of OpenSysML-Extensions-Library:

$ syspi add 'pkg:generic/OpenSysML-Extensions-Library?vcs_url=git%2Bhttps%3A%2F%2Fgithub.com%2FOpen-MBEE%2FOpenSysML-Extensions-Library%401.0.0'
pkg:generic/OpenSysML-Extensions-Library?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2FOpen-MBEE%2FOpenSysML-Extensions-Library: tag v1.0.0: .meta.json records no checksum for 21 of 38 files; their integrity rests on the tree hash
installed OpenSysML Extensions Library 1.0.0 (git v1.0.0 b36b361f85af4764de8e2817cbae62fb9e74ffdb) -> lib/Open-MBEE-OpenSysML_Extensions_Library_1.0.0
10 package(s) locked: 1 installed, 0 already present, 9 not installed (standard libraries and local directories); .project.lock.json updated

$ syspi add 'pkg:git/github.com/Open-MBEE/OpenSysML-Extensions-Library@1.0.0'
(same three lines)

$ cmp a/.project.lock.json b/.project.lock.json && echo LOCKS-IDENTICAL
LOCKS-IDENTICAL

Both .project.json files carry the canonical usage pkg:generic/OpenSysML-Extensions-Library?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2FOpen-MBEE%2FOpenSysML-Extensions-Library%401.0.0; the lock's resource is the version-free form with "source": "https://github.com/Open-MBEE/OpenSysML-Extensions-Library", "tag": "v1.0.0", "revision": "b36b361f85af4764de8e2817cbae62fb9e74ffdb". Re-run after the review round with the same result.

devin-ai-integration Bot and others added 2 commits October 27, 2026 05:58
…reading

pkg:sysand resolution, the index discovery and credential code behind it,
the index emit command and the -index flags are gone; remote .kpar downloads
keep their netrc credentials.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…l qualifier

The canonical identity of a repository package is
pkg:generic/<name>?vcs_url=<vcs>+<transport>://<host>/<path>[@<version>][#<subpath>]
with the qualifier percent-encoded; pkg:git/<host>/<path> and the bare
vcs_url notation are accepted as input and normalised to it, and `add`
writes the canonical form. pkg:svn, pkg:hg, scp-style, ssh://, plain
http(s) clone URLs and file:// repositories are refused with a message
naming the accepted spellings; <vcs>+file:/// addresses a repository on
this machine.

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 and others added 2 commits October 27, 2026 06:05
README, docs/packages.md and AGENTS.md describe the pkg:generic identity with
the Annex B.3.5 vcs_url qualifier and its two input spellings, name what was
removed, and cite ECMA-427 Clause 5 / Annex B.3.5 and KerML 1.1 §10.3
Table 12; changelog fragments for the change and the removals.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
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 06:07

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 6 potential issues.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread internal/origin/origin.go
Comment thread internal/origin/origin.go Outdated
Comment thread internal/origin/origin.go Outdated
Comment on lines +348 to +349
default: // git, ssh
return transport + "://" + host + "/" + p

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 SSH Git repositories lose their account

For a Git host requiring git@host, source() connects as the local user. parseVCSURL rejects git+ssh://git@host, leaving those repositories inaccessible without external SSH configuration.

Learn more

Git uses the username in an SSH URL to choose the remote account. This implementation emits ssh://host/path for every git+ssh repository and rejects userinfo in parseVCSURL. On services that require the git account, the OS account is used instead and the clone fails unless the user configured an SSH alias for that host.

Example: A user writes git+ssh://github.com/org/repo@1.0.0 on a machine logged in as alice; Git connects as alice@github.com, not git@github.com. Supplying git+ssh://git@github.com/org/repo@1.0.0 is rejected.

Recommended fix: Define a way to retain the required SSH account in the VCS connection source without placing credentials or provider-specific data in the canonical package identity. Verify both bare and canonical spellings retain that connection behavior.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed as described: git+ssh://host/path connects as the local user and git+ssh://git@host/path is refused, so a host that requires the git account needs Host … User git in ~/.ssh/config. The refusal follows ECMA-427 Annex B.3.5 (a user name or password in the vcs_url host is unsupported). Whether to stay strict and document the ssh-config route, or accept a bare user name without a password for the +ssh transports as input sugar (pip's notation), is a maintainer decision; leaving this thread open until it is made.

Comment thread internal/install/install.go
Comment thread internal/install/install.go Outdated
Comment thread internal/origin/origin.go
- lock resources that still parse as a repository are canonicalised on read,
  so a lock written with an alias spelling matches offline
- a git+http(s) path is cloned exactly as written; only <name> drops .git
- download errors show the archive URL without user info or query
- user:password@ in an http(s) .kpar IRI is refused in favour of the netrc
- after a redirect to another origin only an explicit netrc machine entry is
  sent, never the default entry

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

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits October 27, 2026 06:26
…p; lock migration restores a .git suffix kept only in source

Co-Authored-By: jason.han <hanhuijun@gmail.com>
… ignores a .git suffix

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

This comment was marked as resolved.

… is the requested location

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

This comment was marked as resolved.

…tion, rewrite it on reuse

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 7a65007 into develop Oct 28, 2026
3 checks passed
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