Skip to content

Add handling for RRIs in serialised forms#5563

Draft
backspace wants to merge 7 commits into
mainfrom
cs-11450-instance-id-rri
Draft

Add handling for RRIs in serialised forms#5563
backspace wants to merge 7 commits into
mainfrom
cs-11450-instance-id-rri

Conversation

@backspace

Copy link
Copy Markdown
Contributor

No description provided.

backspace and others added 2 commits July 20, 2026 15:25
A card's in-memory `id` field is typed RealmResourceIdentifier but was
populated verbatim from the serialized `data.id`, which is URL form for a
mapped realm. Fold it onto the canonical interior form at the ingest
boundary so the `id` field, the identity-map key, and the relative-
resolution base share one opaque spelling — the runtime treats the id as
an RRI, matching how cross-resource references already canonicalize.

CardStore gains a `canonicalizeId` capability (the inverse of the
existing `resolveURL` boundary role): a mapped realm's URL collapses to
its `@scope/name` prefix, an already-canonical RRI is returned unchanged,
and an unmapped realm's URL or a local id passes through. Card code
canonicalizes without holding the VirtualNetwork, matching how stores
expose URL resolution.

Scoped to card instances; FileDef ids stay URL form for now (their
identity is entangled with the file-extract invalidation contract). The
transform is a no-op for unmapped realms, so serialization against a
realm with no prefix mapping is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With card instance ids folded to canonical RRI at the deserialize
boundary, the read paths that key or resolve by a card's id must accept
that form:

- gc-card-store keys card instances by canonical RRI (getCardItem /
  setCardItem fold the id through unresolveURL after stripping `.json`),
  so a lookup lands whether the caller passes the card's own RRI id or
  the resolved URL that store.asURL produces. File-meta buckets keep
  their URL keys.
- realm-index-query-engine resolves a relationship's `links.self`
  against the fetchable URL of the owning resource (vn.toURL) rather than
  the raw id, which may now be an RRI that resolveURL only accepts as a
  base for a registered prefix. Mirrors the sibling linkURL resolution.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files      1 suites   1h 34m 14s ⏱️
2 358 tests 2 345 ✅ 12 💤 0 ❌ 1 🔥
2 369 runs  2 355 ✅ 12 💤 1 ❌ 1 🔥

Results for commit 1ee0284.

For more details on these errors, see this check.

Realm Server Test Results

    1 files  ±0      1 suites  ±0   11m 19s ⏱️ -16s
1 919 tests ±0  1 919 ✅ ±0  0 💤 ±0  0 ❌ ±0 
1 998 runs  ±0  1 998 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit a8c460b. ± Comparison against earlier commit 5dea2c3.

backspace and others added 5 commits July 21, 2026 11:02
getCardItem/setCardItem already fold card ids to canonical RRI, but
delete() and makeTracked() read the card buckets with the raw id, so a
delete by the resolved URL (store.asURL) or a re-track missed the
RRI-keyed entry. Fold the id on those paths too (after the `.json`
file-meta split, which stays URL-keyed) so every card-bucket access
agrees on the canonical key.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Canonicalizing card ids folds every deserialize and every gc-card-store
keying / GC-sweep access through unresolveURL, whose mapping chase pays a
native `new URL()` per miss — enough per-op overhead to time out large
host renders. Cache the result like toURLHref already does: unresolveURL
is a pure function of the realm mappings, so memoize it and clear the
memo wherever the mappings change (addRealmMapping / removeRealmMapping /
addURLMapping). addURLMapping now also clears toURLHrefCache, which reads
urlMappings through toURL and was not invalidated before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diagnostic instrumentation (to be reverted): the four host shards hang
because a store-keyed deferred is stored under one id form and awaited
under another, so the await never settles. Race the two test-blocking
awaits (waitForCardLoad, wireUpNewReference's getCardInstance) against a
90s timer that logs the awaited key, its asURL form, and the live keys of
inflightGetCards / inflightCardLoads / referenceCount, then throws — so
CI fails fast and names the divergent key instead of timing out at ~75min.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
To be reverted. The host-shard hang is aggregate (tripwire silent,
hang-set varies), so instrument the two competing theories and force
hung shards to complete with retrievable logs:
- ci-host: timeout-minutes 35 so a hung shard fails fast instead of
  running to the 6h default (its logs stay unfetchable while in progress).
- virtual-network: log unresolveURLCache size growth (memory-growth theory).
- card-api: count per-id deserialize re-creations (identity-map miss /
  key-divergence storm theory).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant