fix(demos): realign catalogs with the cmcp-runtime catalog schema - #62
Merged
Conversation
The demo catalogs predate three schema changes and no longer load, which
is why CI has been red on main independently of any workflow change.
- definition_hash is required and was absent. Added to all 11 entries,
computed the way loader._compute_definition_hash does it: sha256 over
json.dumps(approved_definition, sort_keys, separators=(",",":"),
ensure_ascii).
- server.rotation_mode is rejected by additionalProperties: false, even
though the loader still reads it. Every entry set "key-pinned", which
is exactly the loader default, so dropping the field preserves
behaviour. The schema and loader disagreeing is a cmcp bug and is
tracked there, not worked around here.
- The placeholder tls_fingerprint carried 45 base64 characters where the
pattern allows 43 to 44. Trimmed to a well-formed value; it is not
checked at runtime because the demo servers are plain http on
localhost.
demo-04 and demo-05 still fail on compliance_domain values that are not
in the schema enum. That is a question about what those demos are meant
to show, not a mechanical fix, so it is deliberately left out.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
…n_mode Follows cmcp-runtime 0.5.0. demo-04 and demo-05 classify tools as finance, clinical and external-analytics. None is a built-in cMCP compliance domain, and until 0.5.0 the catalog schema pinned a closed seven value enum, so those catalogs could not load at all. The demos now declare their own domains in cmcp-config.yaml, which is the capability rather than a workaround, and say whether leaving each one is a compliance boundary crossing. demo-05 is the demo about compliance domains, so declaring two with opposite regulated flags is the thing it is there to show. rotation_mode comes back to every catalog. It was removed in the previous commit because the schema rejected a field the loader read; 0.5.0 fixed that, so the demos can state the pinning mode again. Floor raised to cmcp-runtime>=0.5.0, since both are 0.5.0 behaviours. Verified against the published 0.5.0 wheel in a clean venv rather than a local checkout: all five catalogs load, with their domains and rotation modes intact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
With the catalogs loading again, the next layer surfaced: every call returned CATALOG_DRIFT. The approved definitions did not match the definitions server/server.py advertises in tools/list, and cMCP was right to refuse them. Two systematic mismatches, both in the catalog rather than the server: - write_file and read_file declared an output_schema. The server advertises none, and definition_digest covers the output schema precisely because both sides have to agree on it. An approved output schema the server never offers is drift by definition. - list_dir omitted the "default": "" the server declares on its path property. Neither was visible before, because the catalogs did not load at all, so no call ever reached the drift check. The catalog records what was approved and the server states what the tool currently is; drift detection compares them, so the fix is to make the approved definition say what was actually approved. definition_hash is recomputed for every entry touched. Verified against the published cmcp-runtime 0.5.0 wheel: all five catalogs load and every shared tool's definition_digest matches the server's. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
With demos 1-5 running again, 6-9 surfaced. weight-custody-manifest
0.27.0 added an authority check to the release gate: a caller supplied
manifest is not its own trust root, so the KBS releases only for a
manifest identity its operator pinned. The demos never passed one, so
manifest_authorized failed on every release.
demo-06 crashed on it, at EnclaveSession.from_release, but the more
telling symptom was two lines earlier. Step 2 is the attestation gate,
the headline of the demo, and it printed
gate released key : False
directly under a heading claiming the key releases into the certified
stack. The demo has been demonstrating its own gate refusing. It now
prints True, and demo-07 shows the contrast it exists to show: released
for the approved enclave, refused for the unapproved one.
demos 06, 07 and 09 pass trusted_manifest_identities. demo-08 does not
construct a KBS and needed nothing.
Verified against the published weight-custody-manifest 0.27.0 wheel: all
four run clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
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.
Gets demos CI green. It has been red on
mainsince before this work, for reasons unrelated to any workflow change, and the causes stack four deep.Why it was red
The demo catalogs had drifted from the cmcp-runtime catalog schema:
definition_hashis required and was absent on all 11 entries. Added, computed the wayloader._compute_definition_hashdoes it: SHA-256 overjson.dumps(approved_definition, sort_keys=True, separators=(",", ":"), ensure_ascii=True).tls_fingerprintcarried 45 base64 characters where the pattern allows 43 to 44. Trimmed. It is not checked at runtime, because the demo servers are plain HTTP on localhost.server.rotation_modewas rejected byadditionalProperties: falseeven though the loader read it.compliance_domainwas a closed enum, sofinance,clinicalandexternal-analyticscould not be expressed at all.3 and 4 were cMCP bugs rather than demo mistakes, and are fixed in cmcp-runtime 0.5.0 (agentrust-io/cmcp#610 and #613) rather than worked around here.
What this does
Declares the custom domains.
demo-04classifies tools asfinance;demo-05usesclinicalandexternal-analytics. Theircmcp-config.yamlnow declares each one and says whether leaving it is a compliance boundary crossing:demo-05is the demo about compliance domains, so declaring two with oppositeregulatedflags is exactly what it exists to show. This is the new capability, not a workaround.Restores
rotation_modeon every catalog. It was removed in the first commit here because the schema rejected a field the loader read; 0.5.0 makes it expressible again.Floor raised to
cmcp-runtime>=0.5.0, since both behaviours are 0.5.0's.Verification
Validated against the published 0.5.0 wheel in a clean venv, not a local checkout, since that is what CI installs:
All five load with their domains and rotation modes intact. This should also unblock #61, the workflow pinning PR, which has been sitting on a red check it did not cause.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t