Repository navigation
feat: report what a runtime can read through formats() - #4
Merged
Merged
Conversation
docs/design/sdk.md left the contract of formats() open: whether it reports the capabilities the composition resolved, the extensions OpenUSD registered, or their intersection. It reports none of the three. The two lists differ exactly when a plugin fails to load, which is when the answer matters most, so every extension carries the state that says which source claimed it: available for both, not_loaded for a composed plugin OpenUSD did not register, and undeclared for a registered format no capability declared, which is how OpenUSD's own usda, usdc, and usdz appear. Collapsing the lists would report a broken composition as a healthy one, or hide the failure entirely. The split between the lanes follows the rule runtime_info already follows: describing a runtime must not require loading it. Only the registered list needs a loaded OpenUSD, so formats() is in the USD lane while format_support(), the join, is in the core lane and is tested per commit against a fixture lock and a fixed registered list. Its serialized form is schemas/formats.v1.json, held from both sides the way runtime-info is: the SDK is asserted to produce sdk/core/tests/data/formats.json byte for byte, and the tooling tests validate that same document against the schema and against the lock it was read from. The fixture lock gains a second file-format plugin so the committed document carries all three states. open() now builds the capability name it reports through the core lane, so the capability a UGEO-E031 names and the one formats() reports cannot drift. The two failure paths the tests could not reach are covered. runtime_info() refuses a lock that is not a regular file rather than leaving it to the stream, because opening a directory fails on some platforms and succeeds and reads as empty on others, and the caller must get UGEO-E012 either way. UGEO-E032 needs an asset of a composed format that OpenUSD refuses, which fixtures/malformed.usda now supplies. The OpenUSD lane still has no CI runner, so formats() and the new open() coverage remain unproven until it exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The state that justified reporting both lists could not be reached for the failure it names. SdfFileFormat::FindAllFileFormatExtensions builds its index from plugInfo.json metadata and never loads a plugin, while open() dispatches through FindByExtension, which does; a plugin that ships and whose library fails to load was therefore reported available by formats() and capability_unavailable by open() in the same process, and not_loaded was unreachable. registered_extensions now asks OpenUSD for the file format of each candidate extension, which is the same call open() makes, so the report agrees with the operation it predicts. Answering costs the load of every registered format plugin, and that cost is documented where the operation is. The capability of a composed format is now the canonical spelling of its extension rather than the lock's literal string. The two are the same in every conforming lock; where they differ, an entry that kept the raw name would name a capability its own extension contradicts and would fail schemas/formats.v1.json. The USD-lane test counts declared formats as extensions rather than capabilities for the same reason. The unreadable-lock test built its fixture at a fixed path under the temp directory, so two runs of the suite at once -- a multi-config build, ctest -j, two jobs on one runner -- would delete each other's fixture and fail on runtime_not_found instead. The path is now unique per process. Two comments were wrong rather than the code. runtime_info's new guard listed a dangling symlink as a case it catches, but exists() follows links, so that is already runtime_not_found. malformed.usda was called an asset of a composed format, when usda is the canonical undeclared format under the vocabulary this same change introduces: OpenUSD provides it, no capability declares it. The roadmap's "so nothing about them is proven" reversed the sense of a contrast. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Closes the
formatshalf of P2 in docs/roadmap/current.md.inspectis untouched: it still has no defined result, so it stays intent.The contract this settles
docs/design/sdk.mdleft open whetherformats()reports the capabilities the composition resolved, the extensions OpenUSD registered, or their intersection. It reports none of the three. The two lists differ exactly when a plugin fails to load — which is when the answer matters most — so each extension carries the state that says which source claimed it:availableopenwill dispatch on itnot_loadedcomponentnames what to look atundeclaredusda,usdc,usdzLane split
The same rule
runtime_infofollows — describing a runtime must not require loading it. Only the registered list needs a loaded OpenUSD, soformats()sits in the USD lane while the join,format_support(), sits in the core lane and is tested per commit against a fixture lock and a fixed registered list. No signature in the USD-lane header exposes apxr::type, so a future binding can projectformatswithout projecting OpenUSD.schemas/formats.v1.jsonis held from both sides the way runtime-info is:test_core.cppasserts the SDK producessdk/core/tests/data/formats.jsonbyte for byte, andtests/toolingvalidates that same document against the schema and against the lock it was read from. The fixture lock gains a second file-format plugin so the committed document carries all three states.Also here
open()builds itscapabilitydetail through the core lane, so the capability aUGEO-E031names and the oneformats()reports cannot drift.runtime_info()refuses a lock that is not a regular file instead of leaving it to the stream (opening a directory fails on some platforms and reads as empty on others; the caller must getUGEO-E012either way), andfixtures/malformed.usdasupplies the asset of a composed format that OpenUSD refuses, which is the only route toUGEO-E032.Test plan
Run locally, all passing:
cmake -S sdk -B build/sdk-core -DUSDGEOSPATIAL_BUILD_USD=OFF+ build +ctest— clean build, no warningspython tests/tooling/test_metadata_tools.py— 17 tests, including the two new formats contractspython tools/validate_metadata.py— all checks passedNot run: the OpenUSD lane. There is no composed prefix on this machine and no CI runner for that lane, so
sdk/usd/src/formats.cpp, the newtest_open.cppcases, and thetests/native-consumeraddition are uncompiled. They depend onSdfFileFormat::FindAllFileFormatExtensions(). Anyone with a composed prefix can check them with the commands in sdk/README.md.🤖 Generated with Claude Code