fix(calm-suite): adopt canonical nested relationship-type in CALMGuard for cross-tool interop#2683
Open
eddie-knight wants to merge 4 commits into
Open
fix(calm-suite): adopt canonical nested relationship-type in CALMGuard for cross-tool interop#2683eddie-knight wants to merge 4 commits into
eddie-knight wants to merge 4 commits into
Conversation
…d for cross-tool interop CALMGuard modeled `relationship-type` as a flat string discriminant with a sibling variant key, which is not canonical CALM 1.2. As a result it rejected nested documents authored by CALM Studio / the CLI / Hub at parse time, and its own PR write-backs were schema-invalid to those tools. - Rewrite the Zod schema to the canonical nested `relationship-type` object, enforcing exactly-one-variant via superRefine, and relax `node-type` to an open string so extension node-types (e.g. aws:lambda) interoperate. - Add getRelationshipVariant() and route all readers (calm extractor, calm-to-flow graph mapping, learning extractor) through the nested shape. - Emit the nested form from the v1.0 normalizer. - Add a compile-time conformance check against @finos/calm-models types (gated by tsc, not vitest), plus interop tests that parse real canonical fixtures authored by other CALM tools and reject the legacy flat form. - Convert demo examples and inline test fixtures to nested; update AGENTS.md. Adds @finos/calm-models as a direct dependency of calmguard. Signed-off-by: Eddie Knight <knight@linux.com>
Slim launcher wrapping the existing npm workspace scripts: guard / guard-docs / studio / studio-desktop dev servers, builds, and tests. Runs from the repo root and builds @calmstudio/calm-core before starting Studio (it ships from dist). Signed-off-by: Eddie Knight <knight@linux.com>
…nd build CALMGuard's compile-time conformance check (src/lib/calm/conformance.ts) imports types from @finos/calm-models. That package ships from dist/ and has no prepare script, so a clean `npm ci` does not build it — the Lint/Typecheck and Build jobs then fail to resolve `@finos/calm-models/types` (TS2307). Build it first in both jobs, matching how the calm-studio workflow already sequences it. Signed-off-by: Eddie Knight <knight@linux.com>
16 tasks
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.
Description
The journey this fixes: You model an architecture in CALM Studio, export it (or grab any CALM document the CLI / Hub produces), then open CALMGuard to run compliance analysis on it. Today that fails — the document is rejected the moment you upload it, before any analysis runs.
Concretely: take Studio's own
ecommercedemo export and drop it into CALMGuard's upload zone → it's refused at the CALM-schema step.The cause is a dialect mismatch. Canonical CALM 1.2 nests the relationship variant inside an object:
…but CALMGuard hand-rolled its own Zod schema using a flat string discriminant with a sibling key (
"relationship-type": "connects"+ a sibling"connects": {…}). So CALMGuard was the only tool in the suite speaking a private dialect: it couldn't read what Studio/CLI/Hub/Visualizer produce, and the remediation PRs it wrote back were schema-invalid to those same tools. It also enforced a closed 9-valuenode-typeenum, so Studio extension node-types (e.g.aws:lambda) were rejected too.After this PR, the round trip works:
calm validate, the Hub, and the Visualizer accept.node-typevalues from Studio packs are accepted.What changed
relationship-typeobject (exactly-one-variant enforced viasuperRefine) and relaxednode-typeto an open string, matching the CALM core spec.getRelationshipVariant()and routed every reader (CALM extractor, the React-Flow graph mapping, the learning extractor) through the nested shape.@finos/calm-modelstypes (gated bytsc, so drift fails the typecheck) plus interop tests that parse real canonical fixtures authored by other CALM tools and assert the legacy flat form is now rejected.calm-guard/AGENTS.md.This PR also includes a small unrelated convenience commit,
chore(calm-suite): add Makefile to launch suite apps on demand— happy to drop it if you'd prefer the PR scoped purely to the fix.Type of Change
Affected Components
cli/)calm/)calm-ai/)calm-hub/)calm-hub-ui/)calm-server/)calm-widgets/)docs/)shared/)calm-plugins/vscode/)Commit Message Format ✅
Conventional Commits, DCO signed-off:
fix(calm-suite): adopt canonical nested relationship-type in CALMGuard for cross-tool interopchore(calm-suite): add Makefile to launch suite apps on demandTesting
Verified on Node 22:
npm run typecheck,npm run lint,npm run test:run(117 tests, including new interop + conformance coverage), andnpm run buildforcalmguardall pass. Manually confirmed against a real Studio export: pre-fix CALMGuard rejects it at the upload zone; post-fix it parses and proceeds to analysis.Checklist