# LAVS-001 CRC32 scope clarification

| | |
|---|---|
| **Status** | Adopted clarification |
| **Version** | 1.0 |
| **Date** | 2026-05-27 |
| **Applies to** | All LAVS-001.X versions |
| **License** | CC BY 4.0 |
| **Companion section** | `LAVS-001.md` §8.2 (Signature), §8.3 (CRC32 footer) |

This document clarifies what the CRC32 footer at the end of every `.lavs` file actually covers, why the scope is restricted, and what other integrity mechanism (the optional signature blob, §8.2) handles full-file integrity. The clarification is normative: it formalizes an observation made operationally by the conformance test suite and is binding on any LAVS-001.X reader or verifier.

The short version, for impatient implementers: **the CRC32 footer covers ONLY the edition block bytes** (Edition object + optional signature blob). It does NOT cover the header, the property dictionary, or the scene stream. For full-file integrity, use the signature (§8.2), not the CRC.

---

## 1. What the CRC32 actually covers

Per `LAVS-001.md` §8.3, the CRC32 footer is computed over:

> The bytes from `editionBlockOffset` (the fixed-width uint32 LE field in the header, §3.5) to the byte immediately preceding the final 4 bytes of the file (the CRC footer itself).

Equivalently, the CRC scope is the **edition block**:

- The Edition object (Type 100) — title, author, edition number, license, etc.
- The optional signature blob (LEB128 length + signature bytes), if `signatureAlgorithm` is declared.

The CRC does NOT cover:

- The header (magic, spec major/minor, runtime ABI, file ID, edition block offset).
- The property dictionary.
- The scene stream (Profile, Artboard, Scene, Nodes, Buffers, Materials, Meshes, Lights, Cameras, etc.).

A producer that emits a `.lavs` file with a bit-flip in the scene stream (e.g., a corrupted vertex position) will produce a file whose CRC32 footer **still validates** as long as the edition block bytes are intact.

This is a deliberate design choice, not an oversight.

---

## 2. Why the scope is restricted to the edition block

The CRC's purpose is **fast tamper detection of edition metadata**. The use case:

- A gallery viewer or marketplace tool wants to display the edition badge (title, author, edition number, license) for hundreds of `.lavs` files in a directory listing.
- For each file, the tool reads the header (12-16 bytes), seeks to `editionBlockOffset`, reads the edition block (a few hundred bytes), and verifies the CRC32. Total bytes read per file: < 1 KB.
- This is orders of magnitude cheaper than parsing the full scene stream, which can be hundreds of KB to multiple MB.

If the CRC covered the full file, that 1 KB read becomes a multi-MB read on every file in the listing. The fast-path edition reader (§10.6 in the spec) is the format's load-bearing affordance for gallery operators, and it depends on the CRC being computable from just the edition block bytes.

---

## 3. Why the scene stream is NOT covered

If the CRC covered everything, scene-stream integrity would be guaranteed for any file that passes CRC verification. The format chooses NOT to provide that guarantee at the CRC level, instead delegating to the optional signature blob (§8.2).

The reasoning:

- **Unsigned editions are release candidates, not artifacts.** Per [`EDITIONS.md`](./EDITIONS.md) §6, an unsigned file is an RC. RCs are by definition revisable. Demanding full-file integrity on RCs would force premature commitment.
- **Signing is the integrity gate.** Per [`KEYS.md`](./KEYS.md) §6, no edition is signed until the YubiKey gate is passed. The signature, when present, covers the full file from byte 0 to the byte immediately preceding the signature length prefix — header + dictionary + scene stream + Edition object. CRC scope is a strict subset.
- **The CRC's job is to detect ACCIDENTAL corruption of edition metadata, not deliberate tampering.** Disks corrupt, network transfers truncate, viewers cache stale bytes. The CRC catches all of these on the small, fast-path region. Deliberate tampering of the scene stream is detected by the signature, not the CRC.

---

## 4. Implementer guidance — what to assume

A LAVS-001.X reader **MUST**:

- Compute and verify the CRC32 footer on every file. The CRC is mandatory per §8.3.
- Treat a CRC32 mismatch as a sign of edition-metadata corruption. Refuse to display the edition badge if CRC is invalid (or display with explicit "metadata corrupt" warning).
- NOT assume CRC validity implies scene-stream integrity. If the scene stream contains a corrupted vertex, the CRC will still validate.

A reader **SHOULD**:

- When a signature is present and a public key is available, verify the signature for full-file integrity (per §8.2). A passing signature guarantees the entire file is bit-identical to what the signer signed.
- When no signature is present, treat the file as a release candidate. Render it for review purposes; do not treat it as a canonical edition.
- Document this CRC scope behavior in the reader's user-facing materials. Users seeing "CRC OK" should understand the limited guarantee.

A marketplace operator or gallery viewer **SHOULD**:

- Always require a signature for any file displayed as a "signed edition" or "canonical edition I."
- Reject files where `signatureAlgorithm` is declared but the signature does not verify against a known public key from the [published keys URL](https://lavos-pubkey.projectlavos.com/pubkey.pem).
- Cache the revocation list ([`/revoked.txt`](https://lavos-pubkey.projectlavos.com/revoked.txt)) and flag editions signed under revoked keys.

---

## 5. What about scene-stream corruption in an unsigned RC?

Concrete scenario: an RC ships from `lavs-format` `main`, the file's CRC validates, but a bit flip in the scene stream corrupted a Material's `roughness` value from 0.4 to a NaN.

The reader's behavior is:

- CRC32: PASS (edition block bytes are intact).
- Conformance suite: `decode` may PASS or FAIL depending on whether the corruption produced a parseable value. If `roughness` is NaN, the decode succeeds (NaN is a valid float32 bit pattern) but the runtime may render with unexpected material behavior.

To detect this kind of corruption, the implementer can:

- Re-compute SHA-256 of the full file and compare against the manifest entry's `hash` field (when the manifest is published). The manifest hash covers the full file.
- Verify the signature when present.
- Run the conformance test suite, which performs structural checks that catch many (but not all) scene-stream corruptions.

The format's layered integrity model is:

| Layer | Scope | Mandatory | Purpose |
|---|---|---|---|
| CRC32 footer | Edition block only | Yes | Fast-path edition badge integrity |
| Signature (§8.2) | Full file (excluding sig blob + CRC) | Only if signed | Full-file integrity for canonical editions |
| SHA-256 manifest hash | Full file | No (manifest-level) | Cross-implementation distribution integrity |

---

## 6. Why this clarification needs to exist

This scope behavior was named operationally by the conformance test suite (`scripts/conformance.ts`) during the depth-pass execution on 2026-05-27. A test that flipped a bit in the scene stream of `cube.lavs` revealed that the CRC32 footer continued to validate — exposing the scope as a real surface for implementers to understand. The behavior is correct per the spec, but the spec did not previously make it explicit. This document closes that gap.

Without this clarification, an implementer might reasonably assume "CRC OK = full file integrity," wire that assumption into their viewer, and ship a tool that displays tampered scene streams as canonical. This clarification prevents that failure mode.

---

*This document is binding clarification of LAVS-001.X §8.3 behavior. Cross-referenced from `LAVS-001.md` §8.3.*
