# LAVS-001 property ID namespace assignments

| | |
|---|---|
| **Status** | Adopted |
| **Version** | 1.0 |
| **Date** | 2026-05-27 |
| **Applies to** | All LAVS-001.X versions |
| **License** | CC BY 4.0 |
| **Companion section** | `LAVS-001.md` Appendix B |
| **Canonical table** | [`property-table.toml`](./property-table.toml) |

This document formalizes the property ID namespace organization used by LAVS-001.X. The canonical assignments are in [`property-table.toml`](./property-table.toml); this document explains the organizing principle, the reasoning behind each namespace block, and the rules for implementer-defined extensions.

The namespace decision is load-bearing for forward compatibility: it lets v1.X minors introduce new property IDs without colliding with existing assignments, and it gives implementers a clearly-bounded range for non-standard extensions that won't be claimed by future spec versions.

---

## 1. The hundreds-digit organization

Property IDs are organized into ten 100-wide blocks. Each block has a semantic theme. Within a block, ranges may be sub-allocated by spec minor revisions as new features land.

| Range | Block | Status | Used by |
|---|---|---|---|
| 0–99 | _reserved_ | Reserved for future versions. Producers MUST NOT use. | — |
| 100–199 | Universal | LAVS-001.0 | name (100), transforms (140-148), lightType (150) |
| 200–299 | Material | LAVS-001.0 | baseColor (200), metallic (201), roughness (202), transmission/opacity/emissive/iridescence/sheen (203–207) |
| 220–249 | Light + Camera scalars | LAVS-001.0 | (within Material block; subdivided historically) color (220), intensity (230), range (231), angle (232), fov (240), near (241), far (242), aspect (243) |
| 250–299 | Animation scalars | LAVS-001.0 | duration (250), fps (251), loop (252) |
| 300–349 | Mesh / Buffer | LAVS-001.0 | bufferRef (300), materialRef (301), vertexCount (310), positions (311), normals (312), uvs (313), colors (314), indexCount (315), indices (316) |
| 350–399 | Environment | LAVS-001.2 | envType (350), skyTopColor (351), skyMidColor (352), skyBotColor (353), skyAccentColor (354), skyAccentDir{X,Y,Z} (355–357), skyAccentExponent (358), environmentIntensity (359) |
| 400–499 | Animation chain | LAVS-001.0 | targetRef (400), propertyId (401), keyframe timing + values (410–414) |
| 500–599 | State machine + palette + post-process | LAVS-001.0 | initialState (500), fromState/toState (501–502), triggerName (503), duration (504), animationRef (505), paletteName (510), postprocess effect (520) + strength/radius/threshold/effectColor (521–524) |
| 600–699 | Profile | LAVS-001.0 | features (600), minAbi (601) |
| 700–799 | Edition | LAVS-001.0 | title (700), author (701), editionNumber (702), editionTotal (703), year (704), license (705), description (706), palettePin (707), runtimeVersionMin (708), signatureAlgorithm (709), signaturePublicKey (710), provenance (711) |
| 800–899 | _reserved for future spec_ | LAVS-001.3+ planned | — |
| 900–999 | _reserved for future spec_ | LAVS-001.3+ planned | — |
| 1000+ | Implementer-defined | All versions | Non-standard extensions (see §3) |

---

## 2. Why the hundreds-digit organization

Three properties of this organization make forward compatibility tractable:

**1. Each Core type's properties cluster.** When an implementer reads an unknown property ID 354, they can identify it as "probably Environment" (in the 350–399 range) before consulting the spec. This makes debugging unknown-property warnings easier.

**2. Spec minor revisions can claim unused sub-ranges within blocks without renumbering existing assignments.** LAVS-001.2's Environment claimed 350–399 (the unused upper half of the 300–399 block). LAVS-001.3 may claim 220–224 (currently unused in the Light+Camera block) for new Light types. Existing v1.0 properties at 200, 220, 230 remain bound to their current meanings.

**3. The 800–999 range is reserved for future spec.** When v1.3 or v1.4 introduces new feature blocks, those blocks claim 800–899 or 900–999 first, leaving the 1000+ space available for implementers.

---

## 3. Implementer-defined property IDs (1000+)

Property IDs **1000 and above** are reserved for implementer-defined extensions. An implementer building a LAVS-001 producer or runtime MAY use this range to encode application-specific data not covered by the standard spec.

Rules:

- An implementer using property IDs >= 1000 **MUST** declare them in the property dictionary like any other property, with the appropriate wire type.
- An implementer using property IDs >= 1000 **MUST NOT** assume any other reader will recognize them. Other readers will treat them as unknown property IDs and skip them via the dictionary's wire-type tag table (per §5.3 of the main spec).
- Two implementers **MUST NOT** assign different meanings to the same property ID in the 1000+ range without coordination. Where coordination is needed, implementers SHOULD propose new property IDs to the standard spec rather than colliding on private IDs.
- An implementer SHOULD prefix their private property IDs with a recognizable block — e.g., `1000–1099` for vendor A, `1100–1199` for vendor B — to reduce collision risk.

The 1000+ range exists so the spec doesn't have to accommodate every conceivable use case to support implementer experimentation. If an experimental extension becomes broadly useful, it can be promoted into the standard ranges via a v1.X minor bump.

---

## 4. Why no property IDs below 100

Property IDs 0–99 are reserved as a guard band. Future spec revisions may use this range for:

- Format-level meta-properties (e.g., a per-object schema identifier).
- Wire-type extension markers (if the 2-bit tag space ever needs to expand).
- Backward-compatibility shims for v2.0 transition.

Producers MUST NOT use property IDs 0–99 today. Readers MUST treat property IDs in this range as malformed (an encoder violating this rule produces an invalid file).

---

## 5. Property ID 0 — the dictionary terminator

Per §5.1, property ID `0` is the terminator of the property ID list in the dictionary. The byte `0x00` after the last property ID's LEB128 encoding marks the end of the list.

Property ID `0` therefore cannot appear in the scene stream as a real property — the wire encoding would be ambiguous with the sentinel `0x00` byte ending an object's property list.

This is the only fixed semantic for the 0–99 reserved range as of LAVS-001.X.

---

## 6. Implementer checklist for namespace use

When adding a new property to a Core type:

1. **Identify the type's namespace block.** Material → 200s; Mesh/Buffer → 300s; etc.
2. **Pick the next available unused ID within that block.** Consult [`property-table.toml`](./property-table.toml) for the current assignments.
3. **Update [`property-table.toml`](./property-table.toml)** with the new entry. The property table is the canonical source of truth; the spec text references it.
4. **Update the spec at Appendix B** with the new range allocation if a new sub-range is being claimed.
5. **Bump the spec minor** if the new property is part of a coordinated feature release. The minor bump rules are in [`VERSIONING.md`](./VERSIONING.md) §1.

When designing a private extension that uses property IDs >= 1000:

1. **Pick a range you control** — e.g., 1000–1099 for your project. Document this in your project's README so others using the 1000+ space can avoid collision.
2. **Declare your IDs in the property dictionary** with their wire types like any standard property.
3. **Document the meaning** of each private ID in your project's documentation. The standard spec does not enumerate private IDs.
4. **Do NOT use property IDs in the 100–999 range for private extensions** — those are claimed by current or future spec.

---

## 7. Open questions deferred

These are unresolved questions about namespace organization, noted for future deliberation:

- **Should the 800–999 reserved range be partitioned ahead of time?** E.g., 800–899 for "scene authoring metadata" (markers, comments) and 900–999 for "post-process extensions"? Currently undecided; both ranges remain unallocated as a single block.
- **Should there be a registry for vendor extensions in the 1000+ space?** Voluntary; not a spec requirement. May be revisited if vendor collisions become common.
- **Should standardized vendor extensions get promoted from 1000+ to the canonical ranges via a v1.X bump?** Yes per the implementer checklist above, but the formal proposal process is not yet documented.

---

*This document is binding clarification of LAVS-001.X property namespace organization. Cross-referenced from `LAVS-001.md` Appendix B and from [`property-table.toml`](./property-table.toml).*
