Now I have all the context I need. Let me generate the section content.

# Section 01: Value Parser Raw Key Addition

## Overview

This section covers a single, backward-compatible modification to the existing `decompose_transform3d()` function in `/Users/salvatorefarruggio/Desktop/godotiq/src/godotiq/parsers/value_parser.py`. The change adds a `"raw"` key to the returned dictionary, preserving the original 12-float tuple alongside the decomposed `position`, `rotation`, and `scale` values.

This is needed because later sections (scene resolver world-transform calculation) must compose parent and child transforms using raw basis matrices. Working with Euler angles during composition causes gimbal lock errors. By storing the original 12 floats, downstream code can extract column vectors directly without reverse-engineering them from decomposed angles.

## Background

The `decompose_transform3d()` function currently accepts a tuple of 12 floats in Godot's column-major order and returns a dict with three keys:

```python
{"position": (ox, oy, oz), "rotation": (rx, ry, rz), "scale": (sx, sy, sz)}
```

The 12 floats represent a 3x3 basis matrix (columns 0-2) plus a 3D origin:

- Column 0 (X axis): values[0], values[1], values[2]
- Column 1 (Y axis): values[3], values[4], values[5]
- Column 2 (Z axis): values[6], values[7], values[8]
- Origin: values[9], values[10], values[11]

After this change, the returned dict will have a fourth key:

```python
{"position": ..., "rotation": ..., "scale": ..., "raw": values}
```

Where `raw` is the original 12-float tuple passed into the function, stored as-is.

## File to Modify

`/Users/salvatorefarruggio/Desktop/godotiq/src/godotiq/parsers/value_parser.py`

## Test (Add to Existing File)

**File:** `/Users/salvatorefarruggio/Desktop/godotiq/tests/test_parsers/test_value_parser.py`

Add the following test to the existing `TestTransform3DDecomposition` class (which starts at line 118 of the current file):

```python
def test_decompose_transform3d_has_raw(self) -> None:
    """Verify that decompose_transform3d() returns the original 12-float tuple under 'raw'."""
    values = (1, 0, 0, 0, 1, 0, 0, 0, 1, -36.117, 0, -1.947)
    result = decompose_transform3d(values)
    assert "raw" in result
    assert result["raw"] == values
```

This test verifies two things:

1. The `"raw"` key exists in the returned dictionary.
2. The value stored under `"raw"` is exactly the same 12-float tuple that was passed in, with no transformation or copying.

It is also worth confirming that `parse_value()` passes the raw values through when parsing a full `Transform3D(...)` string. The existing tests for `parse_value` with Transform3D strings will implicitly exercise this path since `parse_value` delegates to `decompose_transform3d`, but an explicit check through the full pipeline is good practice:

```python
def test_parse_value_transform3d_has_raw(self) -> None:
    """Verify that parsing a Transform3D string includes the raw key."""
    result = parse_value("Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 0)")
    assert isinstance(result, dict)
    assert "raw" in result
    assert result["raw"] == (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 5.0, 0.0, 0.0)
```

Note that when going through `parse_value()`, the values are `float()` converted from string splits, so the raw tuple will contain `float` values (e.g., `1.0` not `1`).

## Implementation

The change is a single line addition to the `decompose_transform3d()` function in `/Users/salvatorefarruggio/Desktop/godotiq/src/godotiq/parsers/value_parser.py`.

The function's return statement is currently at line 257:

```python
return {"position": position, "rotation": rotation, "scale": scale}
```

Change it to:

```python
return {"position": position, "rotation": rotation, "scale": scale, "raw": values}
```

No other changes are needed. The function signature, parameter types, and all existing behavior remain identical. The `values` parameter is already a tuple, so it is immutable and safe to store directly without copying.

## Backward Compatibility

This change is fully backward compatible:

- Existing code that accesses `result["position"]`, `result["rotation"]`, or `result["scale"]` continues to work unchanged.
- No existing callers reference a `"raw"` key, so there is no conflict.
- The return type annotation on the function signature (`dict[str, tuple[float, float, float]]`) is technically slightly inaccurate now since `raw` is a 12-tuple rather than a 3-tuple. The annotation could be broadened to `dict[str, tuple[float, ...]]` but this is optional and cosmetic. The existing type annotation is already a simplification (it does not capture that each key has a different semantic meaning), so leaving it as-is or updating it are both acceptable.

## Dependencies

- **No dependencies on other sections.** This is a standalone, leaf-level change.
- **Blocks sections 03 and 04.** The scene resolver core (section 03) and world transform calculation (section 04) both rely on the `"raw"` key to extract column vectors from node transforms for basis matrix composition.

## Verification

After implementation, run the existing value parser tests plus the new test:

```bash
cd /Users/salvatorefarruggio/Desktop/godotiq && python -m pytest tests/test_parsers/test_value_parser.py -v
```

All existing tests must continue to pass (they do not inspect the presence or absence of extra keys in the returned dict). The new `test_decompose_transform3d_has_raw` and `test_parse_value_transform3d_has_raw` tests must also pass.