Legacy Behavior Ledger#

This ledger is a per-behavior map for the current release. It is not a commitment to copy legacy resolver behavior. It is a map of which legacy behaviors are covered, deferred, or intentionally out of scope for this resolver.

Coverage labels used in the table below:

  • supported: the 0.1 behavior is implemented and covered by tests.

  • supported subset: the exact 0.1 subset is implemented and covered; this does not assert complete parity with every legacy resolver behavior.

  • deferred: intentionally later than the first release unless product priorities change.

  • out-of-scope: intentionally not owned by this resolver.

Legacy behavior

Coverage

Current owner

Notes

Identifier creation for existing assets

supported

identifier module

Covers local/remote distinction, relative remote joins, SDF format args, package identifiers, nested package identifiers, invalid package syntax, and S3 HTTPS host normalization.

Identifier creation for new assets

supported

OpenUSD resolver skeleton

_CreateIdentifierForNewAsset uses the same remote identifier normalization path as _CreateIdentifier. Write behavior ships in 0.1 for routes whose configured ovstorage backend advertises write support; see “Writable asset open” below.

Default context creation

supported

OpenUSD resolver skeleton, ScopedDefaultContext

_CreateDefaultContext, _CreateDefaultContextForAsset, and _CreateContextFromString all return an OpenUsdResolverContext wrapping the host-registered default runtime (setDefaultResolverRuntime) or an empty context when nothing is registered. The URI-resolver posture means UsdStage’s own dispatch of _CreateDefaultContextForAsset may not reach a URI resolver’s override in every OpenUSD version, so the portable pattern is to combine process registration with a ScopedDefaultContext on each thread that performs OpenUSD work. Covered by default_context smoke.

Context creation from strings

supported

OpenUSD resolver skeleton

_CreateContextFromString wraps the registered default runtime; the string is preserved as the debug-name suffix and has no configuration semantics. Covered by default_context smoke.

Context creation from assets

supported

OpenUSD resolver skeleton, ScopedDefaultContext

See “Default context creation” — same override family. Reliable dispatch for URI resolvers goes through ScopedDefaultContext (bound via ArResolverContextBinder) rather than relying on UsdStage’s automatic per-asset dispatch to URI-resolver overrides.

Context binding and unbinding

supported

ScopedDefaultContext RAII helper

ScopedDefaultContext wraps OpenUSD’s thread-local ArResolverContextBinder, giving the constructing thread one binding for the lexical scope without requiring the Open(url, context) overload. setDefaultResolverRuntime registers the process-wide runtime choice but does not bind worker threads. Covered by default_context smoke.

Context-dependent path checks

deferred

Resolver

Not required by the accepted explicit-remote-root and context-bound runtime contract.

Cache scopes (ArResolverScopedCache)

deferred

Resolver

The resolver holds no materialized-byte cache and does not integrate with OpenUSD scoped caches. The opt-in Resolve-existence cache is bounded metadata owned by each ResolverRuntime, not process-global or ArResolverScopedCache state.

Resolve for existing asset

supported

OpenUSD resolver, ResolverRuntime existence cache

Scheme-only resolution remains the generic default. With ResolverOptions::resolveVerifiesExistence, a context-bound provider stat returns the normalized path for success, empty for authoritative NotFound, and the path for all other errors. Positive/negative TTLs, bounded LRU eviction, concurrent coalescing, successful-write invalidation, package/SDF outer keys, generic missing asset composition, no-context behavior, and two-runtime isolation are covered. Legacy-replacement hosts enable the option when Resolve() must prove existence. A UDIM tile-set pattern resolves to itself without a stat, whether or not any tile exists, as legacy URI resolvers return it; concrete tiles keep the check (D-0010, #268).

Resolve for new asset

supported

OvStorageUsdResolver::_ResolveForNewAsset

Claims the build-advertised URI schemes (OVS_USD_RESOLVER_URI_SCHEMES; shipping default s3;http;https;hf) for identifier normalization. Writability is checked separately in _CanWriteAssetToPath against the bridge’s advertised capabilities. Local paths delegate to OpenUSD’s default resolver.

Extension lookup

supported

identifier module, OpenUSD resolver

Covers remote paths, SDF format args, anonymous layer names, package outer extensions for direct resolver calls, and OpenUSD package dispatch through the selected flavor.

Modification timestamps

supported

ovstorage bridge (stat mtime), OvStorageUsdResolver::_GetModificationTimestamp

The resolver strips SDF format args and package inner path, calls ResolverRuntime::stat, and returns ArTimestamp(mtimeUnixNanos / 1e9) when the backend reports one (S3 LastModified, HTTP Last-Modified, file mtime, …). Returns an invalid ArTimestamp when no mtime is available — mirroring OpenUSD’s “no timestamp” convention.

Asset info

supported

ovstorage bridge (stat size/etag/version), OvStorageUsdResolver::_GetAssetInfo

ArAssetInfo::version takes the ovstorage version when present, falling back to etag. resolverInfo is a VtDictionary with url (the resolved remote URL), size (backend-reported byte count), and etag when available. Callers get the resolved-remote metadata OpenUSD/USD tooling expects without inventing semantics ovstorage didn’t provide.

Asset open/read

supported subset

Runtime, storage bridge, bridge-owned LocalLeaseHandle

_OpenAsset holds a MaterializedAsset lease over the bridge-supplied local path. Concrete coverage includes real file://, loopback http://, native AWS s3://, and pinned native hf:// composition. Other S3-compatible profiles are inherited from ovstorage and not resolver-qualified in 0.1.

Read on opened assets

supported subset

Materialized OpenUSD asset wrapper

Covered through ArFilesystemAsset delegation after materialization. Direct bridge range reads pass offset and length through ovstorage; the OpenUSD-facing wrapper reads its materialized object through ArFilesystemAsset.

GetBuffer on opened assets

supported subset

Materialized OpenUSD asset wrapper

Delegated to ArFilesystemAsset for the 0.1 USD and USDZ coverage set.

GetFileUnsafe on opened assets

supported subset

Bridge-supplied LocalLeaseHandle inside MaterializedAsset

Delegated to ArFilesystemAsset while the bridge lease keeps the path alive for the caller’s use.

Writable asset open

supported

OvStorageUsdResolver::_OpenAssetForWrite, OvstorageWritableAsset

Temp-file staging via TfSafeOutputFile (Replace or Update mode). Close() PUTs the normalized whole-object target through ResolverRuntime::write; SDF format arguments are removed and package-member targets are rejected. The resolver holds no byte cache; the next materialize re-enters the bridge, while a successful write invalidates the affected Resolve-existence metadata key. ovstorage owns materialized bytes and read-your-writes coordination. All three preconditions are wired: LWW overwrite, create-only, and ETag match where the route advertises support.

Materialization

supported

MaterializedAsset lease over bridge-supplied LocalLeaseHandle

Concrete ovstorage bridge routes to LayerHandle::read_local_file when the Layer supports it (the ovstorage runtime owns the local file, GCs on LocalDelegate drop); it falls back to a bridge-owned TempFileLease for backends such as the shipped HTTP plugin whose Layer surface reports Unsupported. The resolver holds no on-disk cache: no maxCacheBytes, no LRU, no release() verb.

Native bridge materialization

supported

StorageBridge contract, concrete ovstorage bridge

Interface, lease handling, and concrete ovstorage bridge materialization smokes exist for file:// and loopback http://. Native s3:// plumbing ships; live AWS S3 materialization is gated by OVS_USD_RESOLVER_LIVE_S3_STAGE_URL.

Identifier-resolution caching

deferred

Resolver

Separate from materialization caching. Any implementation must account for ovstorage permalink/version semantics.

MDL module names

supported subset

identifier tests

Built-in-style MDL names are not mistaken for remote storage identifiers.

Remote MDL paths

supported subset

identifier tests

Identifier handling is covered. Renderer-side MDL byte IO is outside this resolver.

Package identifiers

supported for reads

identifier module, OpenUSD USDZ smoke

Covers identifier parsing/joining plus resolver-level package dispatch for a generated remote USDZ package. Package-member writes are rejected because the storage bridge writes whole provider objects; callers may replace the outer USDZ by naming it directly.

USDZ outer package materialization

supported

OpenUSD USDZ smoke (fake and concrete bridges), bridge-owned LocalLeaseHandle

A generated remote USDZ package materializes through the fake bridge (usdz_package) and through the concrete ovstorage HTTP bridge over the loopback fixture (openusd_ovstorage_bridge_usdz) — the outer package goes through libovstorage_plugin_http.so and the resolver holds a bridge-supplied MaterializedAsset lease over it while OpenUSD’s package resolver composes it. The composed-stage smoke asserts that SDF format arguments round-trip through CreateIdentifier, Resolve, and OpenAsset on absolute package inner paths, and that no lease files remain in the process’s temp directory after the runtime is released (proves the bridge’s TempFileLease destructor unlinks its file on drop). _OpenAsset strips both the SDF args and the package inner path before calling into ovstorage so the provider only sees the outer asset URL.

Package-relative and cross-scheme assets

supported

OpenUSD USDZ smokes

Generated USDZ coverage includes an inner layer, composed stage load through UsdStage::Open(path, context), a non-layer internal asset, and a missing inner asset. The deterministic cross_scheme_usdz smoke also proves that an absolute layer reference authored inside a package leaves the package context and resolves through a second advertised scheme on the same runtime.

Local file fallback

supported

URI resolver registration

The resolver registration/local fallback smoke proves local files still resolve and open through OpenUSD default filesystem behavior without an ovstorage context.

file:// ownership

out-of-scope

OpenUSD default resolver

file is rejected as a remote scheme. Native local filesystem paths remain owned by OpenUSD’s default resolver and are covered by the local fallback smoke.

http:// / https:// ownership

supported subset

Plugin metadata

Plugin registers http and https, and global ArGetResolver() dispatch is covered with an ovstorage context. Supported deployments have one owner for each scheme; duplicate ownership has no supported precedence contract.

Native s3:// ownership

supported subset

Bridge + plugin metadata

Bridge adopts an s3-carrying LayerHandle, loaded programmatically or through StackConfig. AWS S3 read/composition is the 0.1 qualified target; non-AWS compatibility profiles require separate qualification.

omni:// / omniverse:// ownership

configurable, outside the default scheme list

Host registration and provider routing

A host may advertise these schemes with matching ovstorage routes and a single resolver owner. The default leaves them unclaimed by this resolver; another installed resolver may own them. See coexistence.

ArResolver 1.0 support

out-of-scope

Compatibility posture

First target is OpenUSD resolver behavior for 25.11.kit.4-gl.21081; legacy resolver remains the reference for older ArResolver support.

ArResolver 2.0 support

supported subset

OpenUSD plugin

The implemented resolver operations build, register, and pass the 0.1 workflow suite against the selected Kit OpenUSD flavor. This is not a claim of exhaustive conformance to every optional resolver behavior.

Search paths and bare asset paths

supported

Identifier module

Bare root assets remain local/default-owned; explicit remote roots anchor relative remote dependencies; remote search roots and implicit discovery are deferred.

Diagnostics and tracing

supported

ResolverTraceSink, CLI

Trace sink events cover resolution, Resolve-existence cache hit/miss/wait/coalescing/invalidation, stat, materialization, metadata, and writes. CLI doctor, resolve, materialize, trace, put, and benchmark all ship; doctor includes an OpenUSD plugin discovery check and trace drives a full UsdStage::Open when the CLI is built with the OpenUSD plugin.

Provider request IDs / elapsed-time diagnostics

deferred

ovstorage bridge plus diagnostics

Not part of the 0.1 diagnostic contract.

Python bindings

deferred

Optional tooling

First release does not require Python; helper tooling may follow after C++ ABI stabilization.

Nucleus checkpoints/versioning

out-of-scope

Not owned

Out of scope for this resolver.

Live edit and subscriptions

out-of-scope

Not owned

Out of scope for this resolver.

Hidden omniclient fallback

out-of-scope

All resolver code

This resolver must not link, load, or silently delegate to omniclient.