Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
518 changes: 518 additions & 0 deletions .github/workflows/ost-source-ci.yml

Large diffs are not rendered by default.

129 changes: 92 additions & 37 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,112 @@ All notable changes to this project are documented here.

## [Unreleased]

Nothing yet.

## [0.10.0] - 2026-08-23

Resolver-backed source identity and external resolver interoperability. The
release record is [docs/releases/v0.10.0.md](docs/releases/v0.10.0.md).

### Added

- The resolver-neutral `ResolverAssetIdentity` contract and
`Stable` / `Unstable` / `Unavailable` classification API in `usdGeoCache`,
with the OpenUSD-facing adapter centralized in the shared authoring cache
bridge so no format reader extracts identity itself.
- `usdgeo::cache::CacheDecision`: seven stable, transport-neutral categories
that explain a cache decision, `CacheDecisionName` as the machine-matchable
form, fixed `CacheDecisionMessage` constants, and `IdentityDecision` to map an
identity stability onto its category.
- `HasSupersededIdentityEntry`, which distinguishes a changed validation
identity from a source never generated before without persisting an
identifier or a token.
- Cache-decision reporting through `TryLoadPointCloudCache`, projected onto four
COPC codes: `COPC009` reuse disabled, `COPC010` reuse permitted or taken,
`COPC011` identity changed, `COPC012` entry invalidated. Every message names
its exact category.
- `kind: workspace` CI cells on Windows, macOS, and Linux for both lanes, which
configure the repository root and run its CTest suite. They are what makes the
Tier 1 resolver contract gate a CI gate.
- `tools/tier2_fixture_server.py`, a loopback origin that honours `Range` and
logs every request, and `tools/tier2_resolver_integration.py`, the harness
that composes it with an external resolver and the COPC FileFormat.
- The recorded Tier 2 baseline in
[docs/reference/RESOLVER_BASELINE.md](docs/reference/RESOLVER_BASELINE.md),
against `usd-http-resolver` v0.4.0 and the 81 MB Autzen COPC.

### Changed

- Generated cache entries are addressed by a generation key and a source
identity key rather than one combined key. Revisions of one source are now
siblings under one generation directory, which is what makes
`resolver-identity-changed` reportable. The generation key carries caller
intent; source size, modification time, the resolved georeference, and the
new `Descriptor::sourceDerived` group - which the conversion tool's tile-plan
key moved into - carry what was read out of the source.
- `Invalidate` removes an emptied generation directory, so an invalidated cache
root does not accumulate empty parents.
- Removed standalone `httpresolver` product CI cells. The relocated test double
is built transitively by the COPC Tier 1 integration test, which the workspace
cells and the local gate both run.
- Added a shared cache-layout construction entry point so producer and consumer
tests derive resolver-backed cache entries from the same descriptor contract.

### Fixed

- Windows CTest registrations for the authoring bridge, converter, and
FileFormat integrations now prepend the OpenUSD imported `lib` and `bin`
directories and the configured Python runtime to `PATH`, so all linked
OpenUSD, TBB, and Python DLLs resolve in workspace CI without hiding host
runtime DLLs.
- The PLY tiled-read integration test now writes payloads beside its fixture,
keeping the generated payload references relative when a Windows workspace
and the system temporary directory are on different volumes.
- Resolver cache Tier 1 coverage verifies cache hits, incomplete and corrupted
entry invalidation, and validation-token changes through cache artifacts
instead of process-local counters that are not shared across a FileFormat DLL
boundary on Windows.

### Documentation

- Recorded the v0.10.0 direction: resolver-backed source identity and external
resolver interoperability, with transport owned by the resolver.
- Added the
[resolver-backed source contract](docs/architecture/RESOLVER_SOURCE.md),
covering the responsibility boundary, the transport-neutral `SourceIdentity`
model, `Stable` / `Unstable` / `Unavailable` identity classification,
generated-cache ownership and reuse rules, diagnostics categories, the
no-secrets rule, and the Tier 1 / Tier 2 test split.
model, identity classification, generated-cache ownership and reuse rules,
the diagnostics categories, the no-secrets rule, and the Tier 1 / Tier 2 test
split. Every section is now marked shipped or explicitly not implemented.
- Stated that no resolver implementation is a build-time dependency, and that
`usd-http-resolver` is one compatible implementation composed at runtime.
- Relocated the repository-local resolver test double to
`tests/plugins/httpresolver` and documented that it is excluded from the
product surface and release matrix.
- Updated the Tier 2 plan for the released
[`usd-http-resolver`](https://github.com/animu-sphere/usd-http-resolver)
implementation and its resolver-neutral `ArAssetInfo` identity contract.
`tests/plugins/httpresolver` and documented its exclusion from the product
surface and release matrix.
- Recorded the cache layout change in
[MIGRATION.md](docs/compatibility/MIGRATION.md).
- Added an OpenStrata 0.22.2 dogfooding record for the external resolver
skeleton; it identifies repository setup work, not an OpenStrata defect.

### Added

- Added the resolver-neutral `ResolverAssetIdentity` contract and
`Stable` / `Unstable` / `Unavailable` classification API to `usdGeoCache`.
- Added resolver identity conversion tests and cache-key invalidation coverage
for changed opaque validation tokens.

The OpenUSD-facing resolver adapter is centralized in the shared authoring
cache bridge. Stable-identity generated-cache reuse and recovery are complete;
diagnostic completion and recorded external interoperability remain planned.

### Changed
### Compatibility

- Removed standalone `httpresolver` product CI cells. The relocated test double
is built transitively by the COPC Tier 1 integration test in the root build,
keeping the local gate independent of external resolver repositories. Note
that Tier 1 is not yet part of the CI matrix: every declared cell builds a
single plugin bundle, where `USDGEO_BUILD_TESTS` is undefined, so neither the
fixture nor `pointcloudCopc_tests` is compiled there. Wiring Tier 1 into CI
is tracked as follow-up work.
- Added a shared cache-layout construction entry point so producer and
consumer tests derive resolver-backed cache entries from the same descriptor
contract.
- A `v0.9.0` cache root is never looked up under the new layout, so the first
run after upgrading is a miss that regenerates. Cache entries are derived
data; delete an old root to reclaim the space.
- `StableCacheKey`, `TryBuildLayout`, `Inspect`, `IsCacheHit`, and `Invalidate`
keep their signatures and meanings. Tooling that enumerated entries with a
single-level glob needs a second level.
- Existing LAS, LAZ, COPC, and PLY format ids, arguments, authored stage shape,
and fixed-grid tiling behavior remain compatible with v0.9.0.

### Fixed
### Known limitations

- Resolver cache Tier 1 coverage now verifies cache hits, incomplete and
corrupted entry invalidation, and validation-token changes through cache
artifacts instead of process-local counters that are not shared across a
FileFormat DLL boundary on Windows.
- Nothing publishes a generated cache entry for a COPC source:
`usd-pointcloud-convert` accepts `.las` and `.laz` local inputs only. Lookup,
the reuse rules, and the decision diagnostics are complete; a measurable
generated-cache hit ratio for a remote source waits on COPC generation.
- `usd-pointcloud-convert` does not accept resolver-addressable identifiers.
- The Tier 2 origin is loopback, so the recorded numbers are protocol and
selectivity numbers rather than latency numbers.
- Raw byte-range caching and its hit ratios belong to the resolver.
- COPC writing and new public USD schemas remain deferred.

## [0.9.0] - 2026-08-15

Expand Down
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ endif()
option(USDGEO_BUILD_BENCHMARKS
"Build explicit OpenUSD streaming benchmark executables" OFF)

function(usdgeo_configure_openusd_test_runtime test_name)
if(WIN32)
string(REPLACE ";" "\\;" _usdgeo_host_path "$ENV{PATH}")
set_property(TEST "${test_name}" APPEND PROPERTY
ENVIRONMENT
"PATH=$<TARGET_FILE_DIR:usdGeom>\\;$<TARGET_FILE_DIR:usdGeom>/../bin\\;$<TARGET_FILE_DIR:Python3::Python>\\;${_usdgeo_host_path}")
endif()
endfunction()

set(_usdgeo_build_usd_default OFF)
if(DEFINED pxr_ROOT OR DEFINED OpenUSD_ROOT)
set(_usdgeo_build_usd_default ON)
Expand Down
39 changes: 24 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,12 @@ and tests without it. The repository-local
fixture in memory; it is not a network transport or product bundle.

Generated-USDC cache reuse for resolver-backed sources requires stable source
identity and stays disabled when the resolver cannot supply it. The boundary,
the identity model, and the planned `v0.10.0` work are in the
[resolver-backed source contract](docs/architecture/RESOLVER_SOURCE.md).
identity and stays disabled when the resolver cannot supply it, with the reason
reported through a stable category rather than silently. The boundary and the
identity model are in the
[resolver-backed source contract](docs/architecture/RESOLVER_SOURCE.md); what a
remote read actually costs is recorded in the
[resolver read baseline](docs/reference/RESOLVER_BASELINE.md).

## Quick Start

Expand Down Expand Up @@ -287,8 +290,10 @@ dataset coverage remains open.
`ConflictingCrs` diagnostic.
- The deterministic USDC cache is available to the conversion tool through
`--cache-root`; direct FileFormat lookup reuses committed entries through
`USDGEO_CACHE_ROOT`. Resolver-backed sources are excluded from reuse until a
stable source identity is available; enabling that case is `v0.10.0` work.
`USDGEO_CACHE_ROOT`. Reuse requires either a stable local filesystem identity
or a `Stable` resolver identity, and fails closed otherwise. Only the
conversion tool publishes entries, and it accepts `.las` and `.laz` local
inputs, so a COPC read has nothing to reuse yet.
- HTTP, cloud SDKs, authentication, retries, and raw byte-range caching are
out of scope; they belong to the resolver implementation.
- Writing LAS, LAZ, or COPC is out of scope; all three plugins export as
Expand All @@ -299,16 +304,20 @@ See the [implementation status](docs/roadmap/implementation-status.md) and

## Status

Latest release: **v0.9.0** — TilePlan convergence across sequential and COPC
native planning, plus a reproducible host-responsiveness baseline. The v0.3.0 module and
bundle rename is recorded in [MIGRATION.md](docs/compatibility/MIGRATION.md).
See the [release record](docs/releases/v0.9.0.md) and [CHANGELOG.md](CHANGELOG.md).

Next: **v0.10.0** — resolver-backed source identity and external resolver
interoperability, so generated output can be reused safely for
resolver-provided sources while transport stays with the resolver. Scope and
exit gate are in the
[infrastructure maturity roadmap](docs/roadmap/infrastructure-maturity.md).
Latest release: **v0.10.0** — generated-cache decisions explained through a
stable transport-neutral vocabulary, a revision-aware cache layout, the Tier 1
resolver contract gate running in CI on every host, and recorded
interoperability with a released external resolver. The cache layout change is
recorded in [MIGRATION.md](docs/compatibility/MIGRATION.md), along with the
v0.3.0 module and bundle rename. See the
[release record](docs/releases/v0.10.0.md) and
[CHANGELOG.md](CHANGELOG.md).

Next: format-independent depth continues over format count. The nearest open
items are publishing generated cache entries for COPC sources and accepting
resolver-addressable identifiers in the conversion tool, both of which the
[infrastructure maturity roadmap](docs/roadmap/infrastructure-maturity.md)
places before any new format.

Direction is fixed in the [design policy](docs/design/DESIGN_POLICY.md); the
structure is fixed in the
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.0
0.10.0
5 changes: 4 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ workspace contract wins; structural changes must update that contract first.
| Category | Answers | Start here |
| --- | --- | --- |
| [architecture/](architecture/) | How the workspace is structured, which dependency directions are legal, and what each cross-cutting contract requires. | [WORKSPACE.md](architecture/WORKSPACE.md) |
| [reference/](reference/) | What point-cloud input is accepted today and how it maps to USD. | [CAPABILITY_MATRIX.md](reference/CAPABILITY_MATRIX.md), [POINTCLOUD_METADATA.md](reference/POINTCLOUD_METADATA.md) |
| [reference/](reference/) | What point-cloud input is accepted today, how it maps to USD, and what a resolver-backed read costs. | [CAPABILITY_MATRIX.md](reference/CAPABILITY_MATRIX.md), [POINTCLOUD_METADATA.md](reference/POINTCLOUD_METADATA.md), [RESOLVER_BASELINE.md](reference/RESOLVER_BASELINE.md) |
| [guides/](guides/) | How to build, test, install, and redistribute the plugins. | [BUILDING.md](guides/BUILDING.md), [INSTALL.md](guides/INSTALL.md) |
| [compatibility/](compatibility/) | Which OpenUSD and OpenStrata versions are supported, and how to migrate across renames. | [OPENUSD.md](compatibility/OPENUSD.md), [MIGRATION.md](compatibility/MIGRATION.md) |
| [roadmap/](roadmap/) | What remains incomplete and in what order it lands. | [README.md](roadmap/README.md) |
Expand Down Expand Up @@ -47,6 +47,9 @@ workspace contract wins; structural changes must update that contract first.
boundary toward external resolvers: resolver-backed byte access,
transport-neutral source identity, generated-cache ownership, and the
diagnostics that explain a cache decision.
- [reference/RESOLVER_BASELINE.md](reference/RESOLVER_BASELINE.md) records the
Tier 2 numbers for reading a COPC asset through an external resolver: request
counts, bytes fetched over source size, and local/remote output equivalence.
- [architecture/PLUGIN_ADAPTER.md](architecture/PLUGIN_ADAPTER.md) is the
thin-adapter rule every FileFormat Plugin is held to.
- [architecture/DIAGNOSTICS.md](architecture/DIAGNOSTICS.md) defines the typed
Expand Down
22 changes: 19 additions & 3 deletions docs/architecture/DIAGNOSTICS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,25 @@ Codes are owned per plugin and listed in
[pointcloud-las diagnostics](../../plugins/pointcloud-las/docs/DIAGNOSTICS.md) and
[pointcloud-laz diagnostics](../../plugins/pointcloud-laz/docs/DIAGNOSTICS.md).
The existing import-stage codes are fatal, because none of them leave a stage
that can be opened. Resolver-backed cache decisions are recoverable warnings;
COPC reports disabled reuse with `COPC009` and continues by reading and
authoring from the source.
that can be opened.

Generated-cache decisions are the exception: they are recoverable, because a
cache decision changes what is reused and never what is read. `usdGeoCache`
owns their vocabulary as `usdgeo::cache::CacheDecision`, whose seven stable
category names are listed in the
[resolver-backed source contract](RESOLVER_SOURCE.md). COPC projects them onto
four codes, and every emitted message names its exact category:

| Code | Severity | Categories |
| --- | --- | --- |
| `COPC009` | warning | `resolver-identity-unavailable`, `resolver-identity-unstable`, `generated-cache-reuse-disabled` |
| `COPC010` | status | `resolver-identity-stable`, `generated-cache-hit` |
| `COPC011` | status | `resolver-identity-changed` |
| `COPC012` | warning | `generated-cache-invalidated` |

Category names obey rule 1 below: a name is never reused for a different
meaning. Decision messages are fixed constants owned by `usdgeo::cache`, so no
transport specific and no token content can reach one.

Remaining limitations of the current migration:

Expand Down
Loading
Loading