Skip to content

feat(query): report the elementId Convert writes (#733) - #747

Merged
devin-ai-integration[bot] merged 3 commits into
Open-MBEE:developfrom
someshSandbox:feat/733-query-element-id
Oct 1, 2026
Merged

devin-ai-integration[bot] merged 3 commits into
Open-MBEE:developfrom
someshSandbox:feat/733-query-element-id

Conversation

@someshSandbox

@someshSandbox someshSandbox commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #733.

elementId is now a queryable property. It reports the elementId Convert writes for the element, from the writer's own identity tables.

// lib.sysml
package Lib { part def Engine { attribute mass : ScalarValues::Real; } }
// app.sysml
package App { private import Lib::*; part e : Engine; }

After ParseSources of both, select: ["@id", "elementId"]:

element @id (unchanged) elementId Convert api-json @id
Lib::Engine Lib::Engine Lib__Engine Lib__Engine
Lib::Engine::mass Lib::Engine::mass Lib__Engine__mass Lib__Engine__mass
App::e App::e App__e App__e
ScalarValues::Real (scope: ["ScalarValues::Real"]) ScalarValues::Real 14c0aa22-5489-59b5-b438-ded26e83ba31 the id every reference to it carries

On develop, select: ["elementId"] is INVALID_ARGUMENT (unknown query property "elementId").

Change:

  • query.PropertyElementID (elementId) joins the closed property set, and OSLC maps sysml:elementId to it.

    • PropertyReader.WithElementID supplies it; without one it is absent.
    • An empty select doesn't report it (query.DefaultProjection), since reading it converts the model. A query that names it in select or where gets it.
  • export.ElementIDs reads the ids from a conversion of the model, made the way Convert makes it for that model_hash:

    • one document is converted from its text (NewElementIDsOfDocument, as sysmlToRDFWith does);
    • several are converted from what parse read (NewElementIDs, modelToRDF, which ModelToRDFWith now wraps).

    So a library file's copy, a declared ElementId and scope qualification come out as written. A standard-library element the model doesn't declare reports the normative id every reference to it carries.

  • A model Convert refuses has no elementIds. A query reading elementId of it is FAILED_PRECONDITION with the conversion's reason, and a query not reading it is unaffected.

  • A library element the model gives an id of its own (metadata … ElementId about ScalarValues::Boolean { id = "custom-boolean"; }) reports no elementId. Convert writes no id for it: a reference to it is {"@ref": "ScalarValues::Boolean"}.

  • The service builds the ids once per cached model (CachedModel.elementIDs), in a structured query and in OSLC alike.

  • api.md documents the property. In a model of several identity scopes, the API JSON @id carries the scope qualifier (.one:P__A) while elementId is the element's own (P__A), as Convert writes it.

Tests:

  • internal/frontend/grpc/query_element_id_test.go: every element a whole-model query returns has elementId equal to Convert's elementId for the same qualified name, and equal to its @id where no scope qualifies it. The models:
    • two documents with a cross-document reference;
    • an unnamed member and a quoted name;
    • a declared ElementId;
    • two identity scopes.
  • The same file also checks:
    • ScalarValues::Real's normative id, both referenced from a model and in a parsed copy of ScalarValues.kerml;
    • a model Convert refuses (two documents declaring package P): FAILED_PRECONDITION when elementId is selected, success otherwise, and no elementId for an empty select;
    • no elementId for an annotated library element, alongside Convert's @ref for it.
  • internal/semantic/query/..., internal/translate/..., internal/frontend/grpc/..., tests/grpc/... and tests/export/... pass.

🤖 Generated with Claude Code

elementId joins the queryable properties (and sysml:elementId in OSLC).
It is read from the writer's own identity tables (export.ElementIDs, built
once per model), so a declared id, a derived id and a library element's
normative id are the ones a conversion of the model writes, and a query
result joins the converted graph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

Copy link
Copy Markdown
Contributor

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 3 potential issues.

2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread internal/translate/export/element_ids.go Outdated
Comment on lines +61 to +63
libraryFQN, ok := ids.library.libraryElement(sym)
if !ok {
return "", false

@devin-ai-integration devin-ai-integration Bot Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Distinct scoped elements share one reported ID

When separate identity scopes declare the same qualified name, byName overwrites one element's ID with the other's. Queries for both elements then report the same ID, even when conversion writes different IDs.

Learn more

A model's RDF conversion permits repeated qualified names in different identity scopes by qualifying their subject IRIs; modelToRDF activates this when multiple scopes exist. A map keyed only by qualified name cannot distinguish those subjects, and Of receives only the name rather than the queried symbol. If the scopes declare distinct IDs for the same name, one result necessarily receives the wrong ID.

Example: Two documents each declare package P in different ProjectRef scopes, with declared IDs first-p and second-p. Conversion writes two distinct scoped package subjects, but querying both P symbols returns second-p for both.

Recommended fix: Key the lookup by an identity that distinguishes the declaration, such as the document and node/symbol, and associate each converted subject with its declaration. Pass the queried symbol into Of instead of relying on a qualified name alone.

Devin Review


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

Comment thread internal/translate/export/element_ids.go Outdated
Review:
- the ids are read from a conversion of the model made as Convert makes it
  for the model hash (one document from its text, several from what parse
  read), so a library file's copy gets its normative ids;
- a model the conversion refuses has no elementIds: a query reading one is
  FAILED_PRECONDITION with the refusal, instead of silently lacking it;
- a library element a model annotates with its own id is referenced by name
  in a conversion, so it reports none, as Convert writes none;
- an empty select no longer reports elementId, which converts the model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Review: Convert refuses a model of several documents one of which the parser
could not read whole; elementId read ids from the recovered trees instead. It
is refused the same way now, and a query reading it fails with the syntax
error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@devin-ai-integration
devin-ai-integration Bot merged commit 00d3d90 into Open-MBEE:develop Oct 1, 2026
23 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.

Query: report the elementId Convert writes, so results join a converted graph

1 participant