Skip to content

feat(queryexec): Differ, a keyed value comparison of two projected tables - #1690

Merged
NicolasRouquette merged 12 commits into
developfrom
feature/differ
Oct 29, 2026
Merged

NicolasRouquette merged 12 commits into
developfrom
feature/differ

Conversation

@devin-ai-integration

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

Copy link
Copy Markdown
Contributor

What and why

Except and Union identify rows, so a value that changed on an element present on both sides is invisible to them. Comparing a model with its reflection (Open-MBEE/qvts reflection-compare.sysml, one Changed_C_p per mirrored property) needs a keyed value comparison. DocumentQueries::Differ(left, right, key, column) — declared in Open-MBEE/OpenSysML-Extensions-Library#16 and listed in its engine contract by #17 (both merged) — is now evaluated:

// evaluateDiffer (internal/doc/queryexec/differ.go)
// one row (key, left, right) per key value on both sides whose column cells differ,
// in left order; the row's element (and Tree depth) is the left row's.
step := Step{Kind: StepDiffer, Argument: key + ", " + column}          // labelled Differ(key, column)
key == "left" || "right"      → invalid-argument (they are the result's side columns)
side projects no key/column   → &Error{Kind: ErrorUnknownColumn, Parameter: side, Property: name, Candidates: columns,
                                      Outcome: path error at step}
key on two rows of one side   → Finding{Constraint: ConstraintDuplicateKey, Element: row, Observed: "… also carried by …"}
key cell not single-valued    → Finding{Constraint: ConstraintMultiplicity}
any finding                   → &Error{Kind: ErrorDuplicateKey, Outcome: model error with every finding}   // fail closed
cells differ                  ⇔ !cellsEqual(left, right)   // sequence equality under valuesEqual (KerML ==)
keys match                    ⇔ valuesEqual(leftKey, rightKey)   // bucketed by keyBucketOf: rows by identity
                                                                 // (setKeyOf), numbers by value, quantities by base magnitude

New plan operation OperationDiffer, step kind Differ, constraint duplicateKey, error kinds unknown-column / duplicate-key — names matching the QVTS-Core specification (qvts docs/qvts-core.md §5.8) and its Lean record (Step.differ, Constraint.duplicateKey).

Dependency: the vendored extension libraries are pinned to main's merge commit of #17, b87334ffd1bbc7461806e8a0858823be6f8335c1 (scripts/extension-libraries-pin.sh, EXTENSIONS_REF=main), which declares Differ and lists it in engine-contract.json; nothing upstream is pending.

What the pin move touched, and the rule that follows: the vendored libraries are an input to gates far from internal/workspace/libs, and each surfaced in a separate full-tier round here. So this PR also (a) re-records both pilot-differential baselines (docs/project/pilot-differential-baseline.json: only the opensysml-libraries digest moved, 0 entries; api-json-differential-baseline.json: the digest, +1008 pilotLibraryElements for the new declarations, and 34 WhereType calls moving from present-equal to present-different on InvocationExpression.parameter/.input — the pilot lists a defaulted parameter the call does not bind, our writer lists the bound ones; adjudicated in api-json-differential.md, a writer follow-up); (b) renames the REPL quoting-hint fixture that was literally left, now shadowed by Differ::left in the stdlib (assertions unchanged); (c) adds make extension-libraries-pin-check — the Java-free gates (sync, snapshot, engine-contract hygiene, both provenance guards, REPL/query tests) — the AGENTS.md §6.1 checklist, and a reminder printed by scripts/sync-extension-libraries.sh whenever it changes the tree; (d) makes TestGRPCRobustnessAuthStartup/health_binds_the_same_host wait for the health listener's log line instead of reading the log the instant the main address appears (an unrelated flake this run hit).

Specification basis

OpenSysML DocumentQueries surface (Extensions Library) with the QVTS-Core §5.8 semantics; not an OMG clause, no row of docs/project/spec-compliance.md moves.

How it was verified

  • internal/doc/queryexec/differ_test.go: ChangedMasses over Before/After returns the one part whose mass changed as (b, 2, 5) with columns name left right, and nothing against itself; integer 1/2.5 keys match real 1.0/2.50 keys; a Tree-arranged left side keeps outer@0 inner@1; a key named left is invalid-argument; a side carrying one key on two rows is duplicate-key with a duplicateKey finding at Differ(mass, name) naming both rows; a side without the column is unknown-column naming the side, the column and the side's columns, as a path error at Differ(name, mass).
  • make extension-libraries-pin-check green; go run -C tools ./cmd/pilot-diff / ./cmd/pilot-apijson-diff run fresh and compared entry by entry against the committed baselines before -update; make docs-counts current.
  • go build ./..., go vet ./..., gofmt -l . clean; go test ./internal/doc/queryexec ./internal/ir/queryplan ./internal/workspace/libs ./internal/frontend/repl, tests/hygiene TestEngineContractCoversEveryBoundName; scripts/changelog.py check.
  • Cookbook: Keyed comparison: Differ under the set operations; docs/internals/design/query-outcomes.md gains the Differ row; changelog fragment changes/unreleased/differ.added.md.

Checklist

  • make test and make lint pass locally (targeted packages; the full tier runs in CI)
  • 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
  • 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/18ad47adf36f44e9b6824a4472f9678d
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/18ad47adf36f44e9b6824a4472f9678d?variant=devin
Requested by: @NicolasRouquette

devin-ai-integration Bot and others added 2 commits October 29, 2026 15:43
…bles — (key, left, right) per key on both sides whose column differs; unknown-column path error, duplicate-key model error

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
…-Extensions-Library#16 (Differ)

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
@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

@NicolasRouquette
NicolasRouquette marked this pull request as ready for review October 29, 2026 15:44
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 3 commits October 29, 2026 15:47
…ity, numbers by value, quantities by base magnitude — not by spelling

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
…lumns) and keeps the left row's Tree depth

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
…/right are not key names

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
… name with a library parameter (Differ::left)

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
devin-ai-integration Bot and others added 2 commits October 29, 2026 16:11
…ary chore/engine-contract-differ, whose engine contract lists Differ

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
…-Extensions-Library#17 (engine contract lists Differ)

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
… line instead of reading the log the instant the main address appears

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

The exact-head run on e829e23 fails Go race tests (rest) on TestCommittedBaselineStatesThisRepositorysProvenance in both tools/referee/apijson and tools/referee/diff (provenance.inputs[opensysml-libraries].digest moved); every other test in the job passes.

Cause: this branch re-pins the extension libraries (internal/workspace/libs/extensions-project/.meta.json 7cad8b83… → c8f30ccf…, and stdlib.snapshot), which are the opensysml-libraries input of both committed differential baselines, without re-recording them — the same break #1689 introduced and #1679 repaired on develop (b835c3c). The merge-base here is ade0359, before that repair, so merging develop alone will not make it green: the recorded digest still differs from this branch's library.

Fix, on this branch: merge origin/develop (merge commit), then

go run -C tools ./cmd/pilot-apijson-diff -update
go run -C tools ./cmd/pilot-diff -update

and account the movement per object in the body (expect at least the libraries digest + date; if any count or scorecard row moves, restate docs/project/api-json-differential.md and run make docs-counts). The body's "baselines regenerated … (none moved)" line does not hold on this head. Please hold the merge until the re-recorded head's run is green, or develop goes red again on this test.

devin-ai-integration Bot and others added 2 commits October 29, 2026 17:49
…ndored libraries with WhereType exact and Differ (34 WhereType calls move on InvocationExpression.parameter/input: the pilot lists defaulted parameters, our writer the bound ones); make extension-libraries-pin-check and the AGENTS.md pin-bump checklist

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
…p, re-recorded next for the merged libraries)

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Head 624b2a8a6 re-records both baselines but is still based on ade03595d, before develop's own re-record (#1679, develop b835c3c4f), so the PR now conflicts with develop on docs/project/api-json-differential-baseline.json and docs/project/pilot-differential-baseline.json, and no PR workflow run was created for this head (GitHub cannot build the merge ref). Remaining step: git merge origin/develop (merge commit; take develop's two baselines and api-json-differential.md on conflict), then re-run go run -C tools ./cmd/pilot-apijson-diff -update and go run -C tools ./cmd/pilot-diff -update on the merged tree — relative to develop only the opensysml-libraries digest and whatever the new Extensions pin adds should move — restate the .md figures if a count moves, and push once.

… examples digest, this branch's libraries digest; 810 pilot-library elements for Differ, no other movement)

Co-Authored-By: Nicolas Rouquette <nicolas.f.rouquette@jpl.nasa.gov>
@NicolasRouquette
NicolasRouquette merged commit f9745aa into develop Oct 29, 2026
33 checks passed
@NicolasRouquette
NicolasRouquette deleted the feature/differ branch October 29, 2026 18:58
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.

2 participants