Skip to content

fix(project): link a usage by elimination only when its resource spells a location - #1561

Merged
HuiJun merged 6 commits into
developfrom
fix/usage-elimination-named-forms
Oct 28, 2026
Merged

HuiJun merged 6 commits into
developfrom
fix/usage-elimination-named-forms

Conversation

@devin-ai-integration

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

Copy link
Copy Markdown
Contributor

What and why

Follow-up to the reader's usage linking (internal/workspace/project/discovery.go): a usage that names no installed project by publisher/name is linked by elimination among the unclaimed installed projects — needed because a version-control IRI spells a repository's path (pkg:git/github.com/MBSE4U/sysmod-sysmlv2 for the project mbse4u/sysmod), not the project. Two corrections to that rule:

  • Elimination only for resources that spell a location. Usage.spellsLocation(): a version-control package URL (pkg:git/, pkg:svn/, pkg:hg/) or a plain scheme URL (https://…, ssh://…, file://…, git@host:…). Every other pkg:<type>/<publisher>/<name> form (pkg:sysand/…, pkg:registry/…, …) names a project: it is matched by name alone and stays unresolved when that project is not installed. Before, such a usage could fall back to the one unrelated installed project and the model validated against the wrong one.
  • The ambiguity warning names the candidates that deferred the usage. The final pass of used no longer recomputes a deferred usage's candidates (a list a later claim could have emptied); they travel on the pending record. A single remaining candidate still links.
  • A deferred usage is revisited after every claim. The elimination pass repeats while anything was claimed — including a claim of a project that is both installed and enclosing, which enqueues nothing — so a deferred usage whose candidates narrow to one links it instead of being reported as ambiguous with a stale list.

The rule, as the guide and docs/internals/design/package-management.md §3 now state it: slug match of publisher/name first; else, for a location-spelling resource only, among the installed projects no usage claims (a claimed project's other versions count as claimed) those satisfying the usage's constraint — one publisher/name → that project at the highest satisfying version; several → unresolved, one warning naming each candidate; none → unresolved. Installed projects no usage claims are not loaded.

Behaviour change: named forms no longer fall back to an unrelated install (they are unresolved, as before the elimination rule). No fixture moved; no update flag re-recorded anything.

Left as is here: a named usage whose version is not installed (pkg:registry/acme/gears@1.0.0 with only 2.0.0 under lib/) still takes the latest installed version of that project, silently — develop's "exact, else latest" rule from #1517, which this PR does not touch. #1568 replaces it on both the named and the elimination path: highest installed version the constraint admits, else a project.load warning at the consumer's .project.json naming the installed versions and the usage selects nothing.

Merged with develop at 12e4fc392 (one merge commit, no rebase). The merge keeps the elimination-link warning that landed with #1563 — Projects.Linking, eliminationUsage, the installedKey exemption for an enclosing project installed under the roots, and pickUnclaimed never picking the consumer itself — beside the spellsLocation restriction: a location-spelling usage linked by elimination is said once as a warning, a named usage says nothing and links by name alone. The guide's and the design doc's §3 paragraphs carry both. The exhaustion test now expects its two elimination links said (Linking has two entries) rather than silence.

How it was verified

  • internal/workspace/project: TestUsedLeavesAMissingNamedUsageUnresolved (pkg:registry/acme/gears, pkg:sysand/acme/gears@1.0.0, pkg:npm/acme/gears beside a lone acme/widgets → nothing used, nothing unlinked), TestSpellsLocation (11 resources), TestUsedSurvivesADeferredUsageWhoseCandidatesAreAllClaimedLater (unconstrained pkg:git usage deferred, later usages claim both candidates → both linked by elimination, each said once, no ambiguity, no panic), TestUsedRevisitsADeferredUsageAfterAClaimOfASelectedProject (consumer and installed Gears both input paths; a later usage claims Gears without a queue entry → the deferred usage links Widgets, its one remaining candidate); the existing TestUsed* and tests/kpar fixtures (MBSE4U reproducer, two-version Gears, ambiguous usage, exit policy, quiet) unchanged and passing.
  • Gate: gofmt -l . empty; go vet ./..., go build ./...; go test -count=1 -timeout 40m ./... with OPENSYSML_REQUIRE_TRAINING_CORPUS, _PILOT_CORPORA, _SPEC_EXAMPLES, _PILOT_LIBRARY_XMI, _PSSM_SUITE set → all packages ok; make lint; make man-check; make docs-counts; python3 scripts/changelog.py check; tests/wasm budgets.

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/020c7f4cdced4720a9afe70d9e4490ae
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/020c7f4cdced4720a9afe70d9e4490ae?variant=devin
Requested by: @HuiJun

devin-ai-integration Bot and others added 3 commits October 26, 2026 09:07
…deferred it

The final pass no longer recomputes a deferred usage's candidates, which a
later claim could have emptied; the list that deferred it is carried on the
pending record and is what the warning names.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit acd68dfea3f81ed794442f547da77946f7d981c8)
…ls a location

A resource that names a project (pkg:sysand/<publisher>/<name>, any other
pkg:<type>/<publisher>/<name>) is matched by name alone and stays unresolved
when that project is not installed; only a version-control purl (pkg:git, svn,
hg) or a plain URL, which spell where a project is kept, is linked by
elimination among the unclaimed installed projects.

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
devin-ai-integration Bot marked this pull request as ready for review October 27, 2026 01:29
devin-ai-integration[bot]

This comment was marked as resolved.

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

# Conflicts:
#	docs/guide/03-command-line.md
#	docs/internals/design/package-management.md
#	internal/workspace/project/discovery.go
devin-ai-integration[bot]

This comment was marked as resolved.

…hing

A usage constrained to a project that is both installed and enclosing claims it
without a queue entry; the elimination pass now repeats while anything was
claimed, so the deferred usage links its one remaining candidate.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 04eb908 into develop Oct 28, 2026
31 of 59 checks passed
@HuiJun
HuiJun deleted the fix/usage-elimination-named-forms branch October 28, 2026 13:08
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