ASO: Agnostic Spatial Objects
Inspiration
Generative media has a file problem. A spatial asset may begin as a prompt, pass through an image or geometry model, get converted by another tool, move into object storage, and finally appear in several engines or virtual worlds. At each handoff, important context is often lost. The result becomes another opaque URL: no durable identity, uncertain provenance, no reliable version history, and no machine-readable way to understand where it is used.
Software packages already have names, immutable versions, integrity checks, and exact dependency references. We built ASO around a simple question: what if generated spatial objects had those same guarantees?
ASO—Agnostic Spatial Objects—is an identity and dependency layer for spatial media. Its goal is to let an object keep its name, history, and meaning as it moves among generators, storage, runtimes, worlds, developers, and AI agents.
What it does
ASO gives each object a stable identity, immutable versions, portable representations, SHA-256 integrity records, generator provenance, and explicit runtime compatibility. Publishing a new version never overwrites an old one, so existing consumers continue to resolve the exact bytes they originally selected.
ASO worlds are immutable compositions. Each world pins exact object IDs and versions together with manifest URLs, transforms, and instance metadata. This creates a queryable dependency graph: developers and agents can discover which worlds use an object, which version each world references, and what an update could affect.
The protocol separates an object from any one file format or viewer. A mesh, point cloud, image, or future representation can remain a valid, integrity-verified ASO object even when the current browser has no compatible renderer. Humans can inspect records in the web application, developers can use the TypeScript SDK and HTTP API, runtimes can negotiate compatible representations, and AI agents can read canonical object and world documents.
How we built it
ASO is a deployed full-stack prototype built with Next.js, TypeScript, a reusable SDK, Postgres-backed registry metadata, Firebase authentication, and Google Cloud Run. Its schemas define object identities, versions, representations, provenance, runtime capabilities, exact world references, and agent-readable discovery resources.
Genblaze begins the media lineage. An authenticated ASO generation request invokes a Python Genblaze pipeline using Replicate. The current workflow creates a reference image for a spatial object and records the provider, model, prompt, run ID, timestamps, output dimensions, byte length, SHA-256 value, and a tamper-evident Genblaze run manifest. This reference image can later be attached as an exact provenance input to a downstream 3D object.
Backblaze B2 provides the durable media layer. Genblaze writes both the original generated image and its provenance manifest directly to B2 through the genblaze-s3 storage backend. ASO then reads the image back from B2 and checks the reported byte length and digest:
[ \operatorname{SHA256}(\text{downloaded bytes}) = \operatorname{recorded hash} ]
After verification, ASO publishes an identity-and-version-scoped immutable copy. Representations and manifests use predictable keys such as objects/{id}/versions/{version}/... and worlds/{id}/versions/{version}/.... B2 is therefore not merely an upload destination; it is the content-verifiable storage foundation beneath the provider-neutral registry. ASO also supports short-lived presigned uploads to a private B2 staging bucket before verified bytes are promoted into the public versioned namespace.
The resulting records are available through repository pages, exact-version routes, raw manifests, OpenAPI endpoints, agent documents, and a TypeScript SDK that can list objects, fetch exact versions and representations, verify integrity, resolve runtimes, and publish new records.
Challenges we ran into
Enforcing immutability across two systems. Registry metadata and representation bytes live in different systems. Backblaze B2 does not support the S3 conditional If-None-Match behavior on our upload path, so our MVP checks both the database identity and every destination key before writing. A collision fails instead of silently replacing an existing version. Stronger transactional reservations are planned for concurrent publishers.
Remaining runtime-neutral. Designing only for formats our browser could display would have produced a viewer manifest, not a protocol. We instead made representation semantics and runtime compatibility explicit. Our PLY demo is intentionally valid and integrity-verified while reporting that the installed browser runtime cannot render it.
Preserving provenance across boundaries. A generation crosses Python, Genblaze, Replicate, B2, the TypeScript publication service, and Postgres. We had to preserve one consistent relationship among the run, model, prompt, output, hashes, manifest, and final ASO version. We also learned to distinguish the model that generated media, the application that invoked it, and any adapter that transformed or published it.
Explaining infrastructure visually. Hashes, manifests, and compatibility diagnostics prove correctness, but they do not immediately communicate why the system matters. The clearest story is not a JSON document; it is one object reused across many worlds, updated without breaking any of them.
Accomplishments that we're proud of
We built a working path from Genblaze generation to B2 persistence, byte verification, immutable publication, world composition, SDK access, and agent discovery. The prototype supports stable identities and version histories, reverse references from objects to worlds, runtime compatibility resolution, authenticated publication, presigned staging uploads, canonical manifests, and honest fallback behavior for unsupported representations.
We are especially proud that one record serves several audiences without changing its meaning: a person can inspect it in the UI, a developer can load it through the SDK, a runtime can select a compatible representation, and an AI agent can reason over its exact identity and dependencies. ASO is not another asset gallery; it is credible protocol infrastructure with a usable product surface.
What we learned
Provenance is most useful when it is part of the object model rather than a detached activity log. A generation record matters only if its output remains connected to the exact object version eventually used in a world. We also learned that storage architecture can reinforce product semantics: B2's durable objects, immutable key layout, and verifiable manifests become part of ASO's trust model.
Most importantly, identity and representation must remain separate. An object is not its GLB, PLY, image, or storage URL. Those are representations of an identity that can evolve while every published version remains independently resolvable. Our shorthand for that lesson is: one object, many worlds, exact history, machine-readable meaning.
What's next for ASO: Agnostic Spatial Objects
Our next demonstration will center on one generated tree reused hundreds of times across a forest and a residential world. Its page will visualize every placement, semantic role, exact version, and affected world so the value of the dependency graph is immediately visible.
Beyond that, we plan to add interactive object-to-world graphs, visual thumbnails, side-by-side version comparison, immutable world editing, more runtime providers for meshes and point clouds, additional Genblaze providers and multi-step pipelines, and a complete reference-image-to-3D lineage workflow. We also want agents to perform impact analysis and propose safe version upgrades before a world changes.
Long term, we want ASO to become an open identity and dependency protocol for generated spatial media: a layer where Genblaze can generate, Backblaze B2 can durably preserve, worlds can reference, runtimes can resolve, and AI agents can reason about the same objects without losing their history.
Built With
- b2
- backblaze
- backblaze-b2
- drizzle-orm
- firebase
- genblaze
- googlecloudrun
- neon
- next.js
- postgressqul
- python
- react
- replicate
- tailwind
- typescript

Log in or sign up for Devpost to join the conversation.