feat(query): add relationship-derived projection columns - #368
Merged
Merged
Conversation
`RelatedColumn(name, relationshipKind, direction, maxDepth, aggregate)` is a `Project` column beside `Column(...)`: for each row it traverses one relationship kind with the breadth-first walk `RelatedElements` uses and yields the related elements as a multi-valued cell, their count, or whether there are any. The cells are read downstream by `WhereFeature`, `OrderBy` and a table's `groupBy`, so one query produces a traceability matrix over every requirement. The manual gains a "Traceability matrix" cookbook recipe and a rendered traceability report example; the verdict engine deduplicates satisfaction assertions by declaration rather than scope-tree symbol, so a document indexed twice no longer doubles a requirement's satisfaction row. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ty-matrix-columns
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
The PDF stylesheet sized tables to their content, so a cell holding long unbreakable tokens — a list of qualified names, say — pushed the rightmost columns past the page edge where they were cut off. Tables now take the text width, as the HTML backend's tables do, and cells wrap wherever they must. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ty-matrix-columns
…ty-matrix-columns Co-Authored-By: jason.han <hanhuijun@gmail.com>
An event posted from outside the run has no behavior or object, so its row's Declaration() is nil and an outgoing lineage traversal dereferenced it. The column now returns a typed undeclared-row error naming the column and the row before traversing. Co-Authored-By: jason.han <hanhuijun@gmail.com>
WhereFeature refused an element value as an unsupported operator and OrderBy held every element equal, so a RelatedColumn list (and a verdict's assertion) could not be filtered or sorted. Elements now compare under the text operators and order as the qualified name a cell prints them by. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Merge feature/query-coverage-set-operations so RelatedColumn shares the callback-based relationship traversal WhereRelated introduced; the cookbook coverage figures now include the Traceability package's downlink requirement. Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration
Bot
changed the base branch from
develop
to
feature/query-coverage-set-operations
September 18, 2026 06:31
The any aggregate is an existence test, yet it walked the whole frontier and could exhaust the visit budget after its answer was already known. It now shares hasRelated with WhereRelated and stops at the first element. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Base automatically changed from
feature/query-coverage-set-operations
to
develop
September 18, 2026 07:03
…ty-matrix-columns
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
The document-query engine could list the satisfiers of one requirement (
RelatedElements(relationshipKind = "satisfaction", direction = "incoming")withreqbound), but aProjectcolumn could only read the row's own features, so the classic traceability matrix — every requirement with its satisfiers and verifiers in one table — could not be written; the worked example emits one table per requirement.RelatedColumn(name, relationshipKind, direction, maxDepth, aggregate = "list")is a newcolumns = (...)entry ofProject, besideColumn(name, expression):RelatedElementsuses —related.gonow exposesvalidateRelationship/traverseRelated, shared by both, so every kindsupportedRelationshipaccepts is accepted here and the visit budget is charged the same way.list(default) yields the related elements as one multi-valued cell in traversal order (an empty cell when none:(none)in the CLI report, blank in a document);countan integer;anya Boolean.WhereFeature(verifications = 0for unverified requirements),OrderBy, and a document table'sgroupBy(docplan.columnNamesnow sees related columns).RelatedElementsraises, reported with the column name; an unsupported aggregate is a typed planning error.data-element), gRPCrun_queryand the Python client carry the multi-valued cell through the existing multi-value contract — no serialisation change was needed.Also fixed on the way:
runtime.distinctAssertions/satisfactionKeydeduplicated satisfaction assertions by*symbols.Symbol, so an assertion reached through two scope trees over the same document (the runtime's cached tree and a re-indexed one) was checked and reported twice inVerdicts. They now key on the declaration, the identitysameDeclarationalready uses.Also: the PDF stylesheet sized tables to their content, so a cell holding long unbreakable tokens (a list of qualified names) pushed the rightmost columns past the page edge, where they were cut off — the count column of the traceability matrix was invisible. Tables now take the text width, as the HTML backend's do, and cells wrap wherever they must.
Docs: cookbook "Traceability matrix" recipe with real console output; new
docs/manual/examples/traceability.sysml+ renderedtraceability.md(requirement list, one matrix table,Verdictstable) wired intodocs/manual/README.mdandmkdocs.yml; worked-example closing note; CLI/REPL reference, introduction and authoring mentions;DocumentQueries.sysmlvocabulary (+ regeneratedstdlib.snapshot).Specification basis
OpenSysML non-normative extension (
DocumentQueries); no SysML v2 clause. Adds two rows to the document-query sections ofdocs/project/spec-compliance.mdand extends thegroupByrow.How it was verified
queryplan/columns_test.go:TestCompileRelatedColumns,TestCompileRelatedColumnDiagnostics(argument validation, aggregates, duplicate names).queryexec/related_column_test.go: matrix overtestdata/trace_matrix.sysml, depth/direction, column-named errors, visit budget,WhereFeature/OrderByover projected cells, object rows.grpc/related_column_test.go: repeated values, empty list, count and any overRunDocumentQuery.docplan/runs_test.go:TestCompileGroupedTableSeesRelatedColumns.runtime/validate_test.go:TestValidateObjectReportsACarriedSatisfactionOnceAcrossScopeTrees(fails ondevelop).docpdf/docpdf_test.go:TestStyleSheetKeepsTablesWithinThePage.cmd/sysml/manual_examples_test.go:TestManualTraceabilityExample:-run-query, byte-for-byte Markdown against the committedtraceability.md, HTMLdata-elementcells.gofmt -l .empty,go vet ./...,go build ./...,make lint,OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 go test -count=1 ./...(incl.TestCorpusRoundTrip,TestTrainingExamples|TestPilotCorpora),python3 scripts/changelog.py check,check-doc-links.py,check-doc-ids.py,check-doc-figures.py,go run ./cmd/doc-counts -check,python -m mkdocs build --strict.verifiedBycell renders as linked element spans / comma-separated text, no literal markup in the PDF text, and every column of the matrix and verdict tables is within the page.Checklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelogLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/3f84250d945648d39a5010aebc4f829a
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/3f84250d945648d39a5010aebc4f829a?variant=devin
Requested by: @HuiJun