Skip to content

fix(libs): record a document whose metadata names undeclared types or elements - #1314

Merged
HuiJun merged 11 commits into
developfrom
fix/spec-examples-interface-record
Oct 21, 2026
Merged

HuiJun merged 11 commits into
developfrom
fix/spec-examples-interface-record

Conversation

@devin-ai-integration

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

Copy link
Copy Markdown
Contributor

What and why

Closes gap G14 of docs/project/spec-examples.md (the spec-examples corpus of #1302, now on develop; this PR was stacked on it and is retargeted to develop). The branch carries origin/develop 5db0f74 (#1313, #1318, #1323, #1325, #1358 included) and, ahead of its merge, the head of #1307 (958008f), each as a merge commit, so it dry-merges clean once that lands. The only conflicts were in spec-examples.md's gaps record, resolved by taking their text whole — the intro, the "Closed" paragraph with G1–G5 and the G6–G8 reclassification, and the re-worded G9–G13 rows — and adding one sentence closing G14 to that paragraph while dropping the G14 row, as the paragraph does for the other closed gaps. Every ratchet and count block was regenerated from the merged tree with examples/spec-examples re-extracted first: pilot-differential-baseline.json byte-identical to the committed one, make docs-counts current, spec_examples_expected.txt unchanged — this fix moves no verdict, only recordability.

With examples/spec-examples added to corpusRoots in tests/model, TestInterfaceRecordDifferentialCorpora had six failures, two kinds, both in the interface recorder rather than in the extracted files (which are not edited):

  1. provisional supertypes of Kerml 7.4.13 example 11::Save (also 12::previousAction, 14::Save, 15::Save). semanticMetadataBases returned complete=false whenever an annotation's metadata type did not resolve (behavior Save { @Command; } with no Command declared), and DirectSupertypes marked the element's supertypes provisional on that flag. Provisional means "a resolver guard cut a lookup short, recompute later" — the recorder rightly refuses those. A name no declaration supplies is not that: it is the reference's unresolved diagnostic, and the answer is final. The flag is gone; the guard-cut case was already covered, since a lookup that re-enters a type under computation calls Resolver.CutShort and Leave() reports it. A declaration arriving later still updates the answer, because the lookup read the name and Resolver.Invalidate drops the memoized closure when that name is registered (pinned by TestSemanticMetadataTypeDeclaredLaterContributesItsBase).
  2. the interface record was written among other documents: kerml/7.4.13/3.kerml (and sysml/7.27.2/3.sysml). metadata securityDesignAnnotation : SecurityRelated about SecurityDesign; names elements that do not resolve, so the record's About list is empty. The workspace-wide about gather admitted a recorded symbol only when len(Facts.About) > 0, so the recorded document dropped out of the \0about contributors while its loaded form (judged syntactically by AnnotatesOthers) was in them; the record's provenance then disagreed with the receiving workspace and OpenRecorded reported it stale. The record now carries ModAnnotatesOthers for a metadata usage written with an about clause, resolved or not, and collectAbout reads it, so the contributor set is the same loaded and recorded. interfaceFormatVersion 18 → 19; Modifiers widens to uint64 (the 32 bits were full).

examples/spec-examples joins corpusRoots, so the incremental and interface-record differentials run over it.

Specification basis

KerML 1.1 Beta 2 §7.4.13 / SysML v2.1 Beta 2 §7.27.2–7.27.3: a metadata annotation whose type does not resolve contributes no implicit specialization; the reference is reported. An about clause is a syntactic property of the metadata usage (SysML 8.2.2.21.1 MetadataUsage, KerML 8.2.4.3 Annotation), independent of whether annotatedElement resolves. No row of docs/project/spec-compliance.md moves: diagnostics are unchanged (below), only the document's recordability changes.

Behaviour changes

  • A document whose annotation names an undeclared metadata type, or whose about metadata usage names undeclared elements, now has an interface record (was refused / written off as stale). Diagnostics on such a document are identical before and after.
  • Model.SupertypesProvisional is false for an element whose annotation type is unresolved (was true), so its supertype closure is memoized. TestAllSupertypesNotMemoizedWhileMetadataProvisional pinned the old rule as a stand-in for invalidation; it is rewritten as TestAllSupertypesMemoizedWhileMetadataTypeUnresolved, and the later-declaration guarantee it protected is pinned where it actually lives (the workspace's invalidation) by TestSemanticMetadataTypeDeclaredLaterContributesItsBase.

Probe table

Ours = sysml -validate with a fresh XDG_CACHE_HOME on the base branch's build (before) and this branch's (after); pilot = pinned validate-kerml / validate-sysml-batch (2026-08, 0.62.0).

Probe Ours before Ours after Pilot
package Annot { behavior Save { @Command; } } (.kerml) 1:34 error[unresolved]: unresolved reference: Command same 1:34 Couldn't resolve reference to Type 'Command', Must have a concrete type
package About { metadata securityDesignAnnotation : SecurityRelated about SecurityDesign; } (.kerml) 1:53 unresolved reference: SecurityRelated, 1:75 unresolved reference: SecurityDesign same 1:17 Must have a concrete type, unresolved proxies at 1:53 (type) and 1:75 (annotatedElement)
package P { #Command action def Save; } (.sysml) 1:14 error[unresolved]: unresolved reference: Command same 1:14 Couldn't resolve reference to Type 'Command', A metadata usage must be typed by one metadata definition, Must have a concrete type
Interface record of the above (TestInterfaceRecordOfUnresolvedMetadataReferences) save refused (provisional supertypes), about stale (written among other documents) 3 of 3 recorded n/a (no pilot counterpart)

How it was verified

Red → green on the gate named in the G14 row:

  • Before: go test ./tests/model -run TestInterfaceRecordDifferentialCorpora/spec-examples with the root in corpusRoots — 6 failures (11, 12, 14, 15.kerml provisional supertypes of … Save/previousAction; kerml/7.4.13/3.kerml and sysml/7.27.2/3.sysml written among other documents).
  • After: TestInterfaceRecordDifferentialCorpora/spec-examples kerml 176 of 176 recorded, sysml 335 of 335 recorded; TestIncrementalEqualsFreshCorpora/spec-examples passes.
  • New tests, each red on the base tree and green here: semantics.TestUnresolvedMetadataTypeLeavesSupertypesSettled (KerML @Command; and SysML #Command), semantics.TestAllSupertypesMemoizedWhileMetadataTypeUnresolved, model.TestSemanticMetadataTypeDeclaredLaterContributesItsBase, tests/model.TestInterfaceRecordOfUnresolvedMetadataReferences.
  • Ratchets: TestSpecExamplesDiagnostics passes unchanged (spec_examples_expected.txt moves no line — the fix changes recordability, not a verdict). rm -rf build/pilot-diff && go run -C tools ./cmd/pilot-diff -update re-recorded docs/project/pilot-differential-baseline.json byte-identical (no movement: no example or diagnostic changed), and make docs-counts reports every figure current, so neither file is in the diff.
  • go build ./..., go vet ./..., gofmt -l . (empty), python3 scripts/changelog.py check, make lint (staticcheck + gosec) pass. go test -count=1 -timeout 60m ./... with OPENSYSML_REQUIRE_SPEC_EXAMPLES, _TRAINING_CORPUS, _PILOT_CORPORA and _PILOT_LIBRARY_XMI set: every package ok (internal/frontend/lsp re-run alone, 18 s, ok — its first run timed out only because a stray git worktree under /tmp was being indexed by the wire tests, which open file:///tmp/wire.sysml). go test -C tools ./...: ok. The whole gate was re-run on the final merged tree (origin/develop 5db0f74, fix(parser): recover from the erratum spellings in the specification examples #1307 958008f) with examples/spec-examples re-extracted by scripts/download-spec-examples.sh first (the root is gitignored and feat(parser): parse the five productions the specification examples use #1315 changed the extractor, so a stale extraction moves the root digest in the baseline): every package ok, pilot-diff -update identical to the committed baseline except its recorded date (left as committed), make docs-counts current, TestSpecExamples* green, spec-examples kerml 176/176 and sysml 335/335 recorded.
  • Parser contract (AGENTS.md §5.1): no lexer/parser/grammar code is touched, so no golden AST moves; TestStdlibConformance is part of the full run.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (docs/internals/interface-records.md, docs/project/spec-examples.md G14)
  • Changelog entry added as changes/unreleased/interface-record-unresolved-metadata-references.fixed.md
  • baselines regenerated and make docs-counts run if a gate count moved (re-recorded; nothing moved)
  • No internal work-item labels in the body, docs, or changelog

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

devin-ai-integration Bot and others added 2 commits October 20, 2026 08:35
… elements

An annotation naming a metadata type no declaration supplies contributed no
supertype but marked the element's supertypes provisional, so the interface
recorder refused the document; the unresolved reference is the document's
diagnostic, and a lookup a resolver guard cut short is already accounted for
by the frames DirectSupertypes opens. A recorded about metadata usage whose
targets did not resolve dropped out of the workspace-wide about gather, so
its record was written off as stale among its neighbours; the record now
marks the usage with ModAnnotatesOthers and the gather reads it.

The spec-examples root joins corpusRoots in tests/model.

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 20, 2026 09:15
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits October 20, 2026 09:18
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit b1d632e into develop Oct 21, 2026
28 checks passed
@HuiJun
HuiJun deleted the fix/spec-examples-interface-record branch October 21, 2026 21:25
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