Fix markdown skills from another realm silently failing to attach#5446
Conversation
Preview deploymentsHost Test Results 1 files 1 suites 2h 53m 29s ⏱️ Results for commit 57ede98. Realm Server Test Results 1 files ±0 1 suites ±0 10m 46s ⏱️ -50s Results for commit 57ede98. ± Comparison against earlier commit bf03570. |
5b0835f to
2f1230e
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes cross-realm relationship hydration for file links by ensuring cross-realm fetches use (or upgrade to) the file-meta MIME type when the target is a file, so downstream consumers receive the enriched file-meta shape (including index-derived fields like kind) instead of the minimal “raw file” document.
Changes:
- Extend cross-realm link context to track whether each URL is expected to resolve to file-meta.
- Request cross-realm links with
application/vnd.card.file-meta+jsonwhen the relationship is known to target a file. - When a
card+jsoncross-realm fetch returns a file-meta document, re-fetch once with the file-meta MIME to get the enriched payload.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2f1230e to
5936e6e
Compare
Stored relationships for linked files can carry only links.self (no data.type), so loadLinks falls back to fieldExpectsFileMeta, which infers file-ness from whether files of that type exist in the card's own realm — wrong for a cross-realm file link when the card's realm holds no such files. The cross-realm fetch then used the card mime, and a card-mime request for a file returned a minimal document built from the raw file (base attributes only), dropping index-derived fields like `kind`. That partial resource lands in the card document's included bucket, the host caches it, and markdown skills configured on a system card silently fail to attach (kind is unset, so the file no longer counts as a skill). Serve file-meta through one path that prefers the index-enriched document and falls back to the raw-file form only when the file isn't indexed — used by both the file-meta route and card-mime requests that turn out to target files. The response keeps the mime the route was matched on; callers discriminate the payload via data.type. fetchCrossRealmLinks now also asks for the file-meta mime outright when the relationship is known to expect a file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5936e6e to
1f183b8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f183b8946
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ? SupportedMimeType.FileMeta | ||
| : SupportedMimeType.CardJson; |
There was a problem hiding this comment.
Keep file-link fetches on an index-draining endpoint
When the relationship is already typed as file-meta, this switches the remote request to Accept: application/vnd.card.file-meta+json. I checked the serving path in Realm.getFileMeta, and unlike getCard it does not await incrementalIndexing() before fileMetaResponse; after a provider realm has just created or updated an indexed markdown skill, this can race the index, fall back to raw file metadata, and still omit attributes.kind, so the cross-realm skill can fail to attach intermittently. Either drain indexing in the file-meta GET path or avoid bypassing the card JSON path for these cross-realm loads.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
What are the scenarios when we don't know whether a skill RRI is a card or a file? If it ends in .md, it is a file, otherwise it is a card. Relying on that heuristic seems better than the changes proposed in this PR.
Happy to discuss further if I am missing something.
Whether a link targets a file or a card is knowable from the URL alone: card ids never carry a file extension, file URLs always do. Use that in loadLinks to classify relationships and to pick the accept mime for cross-realm link fetches, so a cross-realm file link is served the index-enriched file-meta document (a markdown skill only counts as a skill when its file-meta carries kind). This replaces fieldExpectsFileMeta, which consulted the field definition and then probed whether files of that type exist in the card's own realm — wrong for a cross-realm link when the card's realm holds no such files. The serving-side changes from the previous commit are reverted: with the requester asking correctly, they are no longer needed for this fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Card ids can legitimately contain dots (e.g. a versioned ModelConfiguration instance like model-4.6), so treating any dotted path segment as a file would misclassify such cross-realm card links and 404 them against the file-meta route. Count only extensions registered in FILEDEF_CODE_REF_BY_EXTENSION as file tells, and cover the dotted-id card link with a regression test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@lukemelia went with your approach, link classification now comes from the URL: a known FileDef extension (.md, .png, .gts, …) means file, otherwise card |
Markdown skills configured on a system card silently fail to attach to new AI assistant rooms (0 skills, only a
console.warn) when the skill file lives in a different realm than the card.Cause: for a cross-realm file link,
fetchCrossRealmLinksrequests the target with the card mime — the file-ness check behind it (fieldExpectsFileMeta) guesses from the card's own realm contents and gets cross-realm links wrong. A card-mime request for a file returns a minimal document built from the raw file, without index-derived fields likekind— so the host caches a partial file-meta and the file stops counting as a skill.Fix, in two halves: the serving realm now answers a card-mime request for an indexed file with the same index-enriched file-meta document the file-meta route serves (raw-file form only when unindexed), and
fetchCrossRealmLinksrequests the file-meta mime outright when the relationship is known to expect a file.Repro: link a
.mdskill file from another workspace into a system card's Default Skill Files, set the card active, reload the host, open a new room → 0 skills. Same-workspace links don't reproduce, which is why this stayed hidden.Before:

After:
🤖 Generated with Claude Code