Files
editor/packages/mcp/test-reports/phase8/casa-sol-v2.json
T
Adrian PerezandClaude Opus 4.7 0b84e7b7b1 fix(mcp,editor): close URL-validation bypasses surfaced by Phase 8 P4
Phase 8 parallel validation flagged two boundaries where malicious URLs
(javascript:, file:, external http:, data:text/html, ...) could be
persisted despite the AssetUrl allowlist added in Phase 7 A7:

1. `save_scene({ includeCurrentScene: false, graph })` — the graph arg
   was treated as opaque (`z.record(z.string(), z.unknown())`) and
   written to the store without re-running AnyNode.safeParse.

2. `POST /api/scenes { graph }` in the editor API — same issue; the
   Zod `graphSchema` accepted anything object-shaped.

Fixes:
- `save-scene.ts`: when `includeCurrentScene === false`, iterate every
  node and run `AnyNode.safeParse`; collect issues and throw
  `McpError(InvalidParams, 'graph_invalid', { errors })` on any
  failure.
- `app/api/scenes/route.ts`: replace `graphSchema` with a structured
  `z.object({ nodes, rootNodeIds, collections? })` + `superRefine`
  that runs `AnyNode.safeParse` on every node. Invalid → 400 with
  detailed issue paths.

Tests:
- Added `save_scene` regression test for the P4 attack
  (item.asset.src = 'javascript:alert(1)') — expected error.
- Fixed the existing `includeCurrentScene=false` test to use a
  schema-compliant site node id (the prior `id: 'root'` now fails
  the AnyNode parse, which is the desired strict behaviour).
- Full suite: 294 pass / 0 fail.

Also adds Phase 8 test-reports/phase8/** (10 agents, ~15 scripts +
markdown reports) documenting the validation run, plus minor biome
cleanups to the Phase 5/7 test artefacts (removed stale
`// biome-ignore` suppression comments that now resolve to the
already-off `noConsole` rule).

Phase 8 result summary (10 parallel agents, stdio MCP transport with
isolated data dirs):
- P1 templates: 18/18 PASS
- P2 variants: 6/7 mutations + determinism + save + combined + error
- P3 locking: 12/12 PASS (MCP + editor HTTP If-Match)
- P4 URL hardening: fixed 2 bypasses (see above)
- P5 photo-to-scene: 6/6 PASS
- P6 Casa del Sol via save_scene: 13/13 PASS
- P7 editor HTTP API: 18/18 PASS
- P8 concurrency: 4/5 PASS, flagged 2 real filesystem-store races
  (expectedVersion CAS gap + .index.json drift under parallel writes)
- P9 edge cases: 13/13 PASS (size cap, slug safety, bad inputs)
- P10 full sweep: 37/37 PASS (30 tools + 4 resources + 3 prompts)

Known follow-ups:
- FilesystemSceneStore needs a proper lockfile / atomic CAS to fix
  the P8 concurrency bugs (low priority: single-writer MCP is the
  typical case).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:26:26 +02:00

837 lines
22 KiB
JSON

{
"nodes": {
"site_nxji43wtm3aiv7th": {
"object": "node",
"id": "site_nxji43wtm3aiv7th",
"type": "site",
"parentId": null,
"visible": true,
"metadata": {},
"polygon": {
"type": "polygon",
"points": [[-15, -15], [15, -15], [15, 15], [-15, 15]]
},
"children": [
{
"object": "node",
"id": "building_16mw8oy88f952is9",
"type": "building",
"parentId": null,
"visible": true,
"metadata": {},
"children": ["level_3jbpcuma0wfwclex"],
"position": [0, 0, 0],
"rotation": [0, 0, 0]
}
]
},
"building_16mw8oy88f952is9": {
"object": "node",
"id": "building_16mw8oy88f952is9",
"type": "building",
"parentId": null,
"visible": true,
"metadata": {},
"children": ["level_3jbpcuma0wfwclex"],
"position": [0, 0, 0],
"rotation": [0, 0, 0]
},
"level_3jbpcuma0wfwclex": {
"object": "node",
"id": "level_3jbpcuma0wfwclex",
"type": "level",
"parentId": null,
"visible": true,
"metadata": {},
"children": [
"wall_j3ymyd8zrn1tm3vw",
"wall_ch18gs2ztca3ev6w",
"wall_5vkgxbr2yy7g73ne",
"wall_kgzojan8e7v59e98",
"wall_3jnpbahwg9lxy986",
"wall_ovunx8saqwfu1v4v",
"wall_zutd5kdbx2arrg9h",
"wall_x0pcifb7x4glmarr",
"wall_f7kmekmgvmfsrm7o",
"zone_o7ke6p48ne5vca23",
"zone_xqv8a3g282kfsqni",
"zone_9cbw5gy7huqn00kn",
"zone_4x1y6af3q099sequ",
"zone_dftxlw40a4iwnqpt",
"zone_2qu75mqpfvty8d1q",
"zone_92x5t8808vyw1ik0",
"zone_lnki9rxnoyq72rwi",
"slab_rfyzzvcxlkbgif1w",
"fence_rj9vb67pvbkxj291",
"fence_4yf9yt0x8i27l8ol",
"fence_b8d9n2j3987egkq4",
"fence_7v9k8hfa4gejy8mb",
"fence_6mosl7txfxj0wxyq",
"zone_6l4ls8mr4rtfvsye"
],
"level": 0
},
"wall_j3ymyd8zrn1tm3vw": {
"object": "node",
"id": "wall_j3ymyd8zrn1tm3vw",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": [
"door_u3esm5o28gjglczx",
"door_d83emijui1hbi4ai",
"window_j75zxpkawiriwu3n",
"window_3ow9tht3fymvnasw"
],
"thickness": 0.2,
"height": 2.7,
"start": [-8, 4],
"end": [4, 4],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_ch18gs2ztca3ev6w": {
"object": "node",
"id": "wall_ch18gs2ztca3ev6w",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["door_hf6glt3wf2yrtbez", "window_ge40ad7xouig550s"],
"thickness": 0.2,
"height": 2.7,
"start": [-8, -4],
"end": [4, -4],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_5vkgxbr2yy7g73ne": {
"object": "node",
"id": "wall_5vkgxbr2yy7g73ne",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["window_5cp5kjonpq0pf741"],
"thickness": 0.2,
"height": 2.7,
"start": [-8, -4],
"end": [-8, 4],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_kgzojan8e7v59e98": {
"object": "node",
"id": "wall_kgzojan8e7v59e98",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["window_rma26zrn7dkanen3", "window_sp6a94rwh54afdnj"],
"thickness": 0.2,
"height": 2.7,
"start": [4, -4],
"end": [4, 4],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_3jnpbahwg9lxy986": {
"object": "node",
"id": "wall_3jnpbahwg9lxy986",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": [],
"thickness": 0.2,
"height": 2.7,
"start": [-1, 0],
"end": [-1, 4],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_ovunx8saqwfu1v4v": {
"object": "node",
"id": "wall_ovunx8saqwfu1v4v",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["door_ysujgio81ptoofe7"],
"thickness": 0.2,
"height": 2.7,
"start": [-1, -4],
"end": [-1, 0],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_zutd5kdbx2arrg9h": {
"object": "node",
"id": "wall_zutd5kdbx2arrg9h",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["door_dwn4l10ctn9uqibm"],
"thickness": 0.2,
"height": 2.7,
"start": [-4, -4],
"end": [-4, 0],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_x0pcifb7x4glmarr": {
"object": "node",
"id": "wall_x0pcifb7x4glmarr",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": [],
"thickness": 0.2,
"height": 2.7,
"start": [-4, -1],
"end": [-1, -1],
"frontSide": "unknown",
"backSide": "unknown"
},
"wall_f7kmekmgvmfsrm7o": {
"object": "node",
"id": "wall_f7kmekmgvmfsrm7o",
"type": "wall",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"children": ["door_gclhf676wdn8643p"],
"thickness": 0.2,
"height": 2.7,
"start": [-4, -2],
"end": [-1, -2],
"frontSide": "unknown",
"backSide": "unknown"
},
"zone_o7ke6p48ne5vca23": {
"object": "node",
"id": "zone_o7ke6p48ne5vca23",
"type": "zone",
"name": "living-dining",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-8, 0], [-1, 0], [-1, 4], [-8, 4]],
"color": "#3b82f6"
},
"zone_xqv8a3g282kfsqni": {
"object": "node",
"id": "zone_xqv8a3g282kfsqni",
"type": "zone",
"name": "kitchen",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-1, 0], [4, 0], [4, 4], [-1, 4]],
"color": "#3b82f6"
},
"zone_9cbw5gy7huqn00kn": {
"object": "node",
"id": "zone_9cbw5gy7huqn00kn",
"type": "zone",
"name": "bedroom-2",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-8, -4], [-4, -4], [-4, 0], [-8, 0]],
"color": "#3b82f6"
},
"zone_4x1y6af3q099sequ": {
"object": "node",
"id": "zone_4x1y6af3q099sequ",
"type": "zone",
"name": "hallway",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-4, -2], [-1, -2], [-1, -1], [-4, -1]],
"color": "#3b82f6"
},
"zone_dftxlw40a4iwnqpt": {
"object": "node",
"id": "zone_dftxlw40a4iwnqpt",
"type": "zone",
"name": "bathroom-2",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-4, -4], [-1, -4], [-1, -2], [-4, -2]],
"color": "#3b82f6"
},
"zone_2qu75mqpfvty8d1q": {
"object": "node",
"id": "zone_2qu75mqpfvty8d1q",
"type": "zone",
"name": "bathroom-1",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-4, -1], [-1, -1], [-1, 0], [-4, 0]],
"color": "#3b82f6"
},
"zone_92x5t8808vyw1ik0": {
"object": "node",
"id": "zone_92x5t8808vyw1ik0",
"type": "zone",
"name": "master-bedroom",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[-1, -4], [4, -4], [4, 0], [-1, 0]],
"color": "#3b82f6"
},
"door_u3esm5o28gjglczx": {
"object": "node",
"id": "door_u3esm5o28gjglczx",
"type": "door",
"parentId": "wall_j3ymyd8zrn1tm3vw",
"visible": true,
"metadata": {},
"position": [0.2, 1.05, 0],
"rotation": [0, 0, 0],
"wallId": "wall_j3ymyd8zrn1tm3vw",
"width": 0.9,
"height": 2.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"door_d83emijui1hbi4ai": {
"object": "node",
"id": "door_d83emijui1hbi4ai",
"type": "door",
"parentId": "wall_j3ymyd8zrn1tm3vw",
"visible": true,
"metadata": {},
"position": [0.75, 1.05, 0],
"rotation": [0, 0, 0],
"wallId": "wall_j3ymyd8zrn1tm3vw",
"width": 2.2,
"height": 2.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"door_hf6glt3wf2yrtbez": {
"object": "node",
"id": "door_hf6glt3wf2yrtbez",
"type": "door",
"parentId": "wall_ch18gs2ztca3ev6w",
"visible": true,
"metadata": {},
"position": [0.65, 1.05, 0],
"rotation": [0, 0, 0],
"wallId": "wall_ch18gs2ztca3ev6w",
"width": 0.9,
"height": 2.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"door_ysujgio81ptoofe7": {
"object": "node",
"id": "door_ysujgio81ptoofe7",
"type": "door",
"parentId": "wall_ovunx8saqwfu1v4v",
"visible": true,
"metadata": {},
"position": [0.3, 1.05, 0],
"rotation": [0, 0, 0],
"wallId": "wall_ovunx8saqwfu1v4v",
"width": 0.8,
"height": 2.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"door_dwn4l10ctn9uqibm": {
"object": "node",
"id": "door_dwn4l10ctn9uqibm",
"type": "door",
"parentId": "wall_zutd5kdbx2arrg9h",
"visible": true,
"metadata": {},
"position": [0.5, 1.05, 0],
"rotation": [0, 0, 0],
"wallId": "wall_zutd5kdbx2arrg9h",
"width": 0.8,
"height": 2.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"door_gclhf676wdn8643p": {
"object": "node",
"id": "door_gclhf676wdn8643p",
"type": "door",
"parentId": "wall_f7kmekmgvmfsrm7o",
"visible": true,
"metadata": {},
"position": [0.5, 1, 0],
"rotation": [0, 0, 0],
"wallId": "wall_f7kmekmgvmfsrm7o",
"width": 0.7,
"height": 2,
"frameThickness": 0.05,
"frameDepth": 0.07,
"threshold": true,
"thresholdHeight": 0.02,
"hingesSide": "left",
"swingDirection": "inward",
"segments": [
{
"type": "panel",
"heightRatio": 0.4,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
},
{
"type": "panel",
"heightRatio": 0.6,
"columnRatios": [1],
"dividerThickness": 0.03,
"panelDepth": 0.01,
"panelInset": 0.04
}
],
"handle": true,
"handleHeight": 1.05,
"handleSide": "right",
"contentPadding": [0.04, 0.04],
"doorCloser": false,
"panicBar": false,
"panicBarHeight": 1
},
"window_j75zxpkawiriwu3n": {
"object": "node",
"id": "window_j75zxpkawiriwu3n",
"type": "window",
"parentId": "wall_j3ymyd8zrn1tm3vw",
"visible": true,
"metadata": {},
"position": [0.3, 0.7, 0],
"rotation": [0, 0, 0],
"wallId": "wall_j3ymyd8zrn1tm3vw",
"width": 2,
"height": 1.4,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"window_3ow9tht3fymvnasw": {
"object": "node",
"id": "window_3ow9tht3fymvnasw",
"type": "window",
"parentId": "wall_j3ymyd8zrn1tm3vw",
"visible": true,
"metadata": {},
"position": [0.45, 0.7, 0],
"rotation": [0, 0, 0],
"wallId": "wall_j3ymyd8zrn1tm3vw",
"width": 1.4,
"height": 1.4,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"window_5cp5kjonpq0pf741": {
"object": "node",
"id": "window_5cp5kjonpq0pf741",
"type": "window",
"parentId": "wall_5vkgxbr2yy7g73ne",
"visible": true,
"metadata": {},
"position": [0.25, 0.55, 0],
"rotation": [0, 0, 0],
"wallId": "wall_5vkgxbr2yy7g73ne",
"width": 1,
"height": 1.1,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"window_rma26zrn7dkanen3": {
"object": "node",
"id": "window_rma26zrn7dkanen3",
"type": "window",
"parentId": "wall_kgzojan8e7v59e98",
"visible": true,
"metadata": {},
"position": [0.25, 0.7, 0],
"rotation": [0, 0, 0],
"wallId": "wall_kgzojan8e7v59e98",
"width": 1.4,
"height": 1.4,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"window_sp6a94rwh54afdnj": {
"object": "node",
"id": "window_sp6a94rwh54afdnj",
"type": "window",
"parentId": "wall_kgzojan8e7v59e98",
"visible": true,
"metadata": {},
"position": [0.75, 0.7, 0],
"rotation": [0, 0, 0],
"wallId": "wall_kgzojan8e7v59e98",
"width": 1.4,
"height": 1.4,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"window_ge40ad7xouig550s": {
"object": "node",
"id": "window_ge40ad7xouig550s",
"type": "window",
"parentId": "wall_ch18gs2ztca3ev6w",
"visible": true,
"metadata": {},
"position": [0.3, 0.3, 0],
"rotation": [0, 0, 0],
"wallId": "wall_ch18gs2ztca3ev6w",
"width": 0.8,
"height": 0.6,
"frameThickness": 0.05,
"frameDepth": 0.07,
"columnRatios": [1],
"rowRatios": [1],
"columnDividerThickness": 0.03,
"rowDividerThickness": 0.03,
"sill": true,
"sillDepth": 0.08,
"sillThickness": 0.03
},
"zone_lnki9rxnoyq72rwi": {
"object": "node",
"id": "zone_lnki9rxnoyq72rwi",
"type": "zone",
"name": "pool",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {
"kind": "pool",
"depthM": 1.8,
"finish": "tile"
},
"polygon": [[5, -1.5], [10, -1.5], [10, 1.5], [5, 1.5]],
"color": "#3b82f6"
},
"slab_rfyzzvcxlkbgif1w": {
"object": "node",
"id": "slab_rfyzzvcxlkbgif1w",
"type": "slab",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"polygon": [[5, -1.5], [10, -1.5], [10, 1.5], [5, 1.5]],
"holes": [],
"holeMetadata": [],
"elevation": -1.8,
"autoFromWalls": false
},
"fence_rj9vb67pvbkxj291": {
"object": "node",
"id": "fence_rj9vb67pvbkxj291",
"type": "fence",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"start": [-10, 7.5],
"end": [-1, 7.5],
"height": 1.8,
"thickness": 0.08,
"baseHeight": 0.22,
"postSpacing": 2,
"postSize": 0.1,
"topRailHeight": 0.04,
"groundClearance": 0,
"edgeInset": 0.015,
"baseStyle": "grounded",
"color": "#ffffff",
"style": "privacy"
},
"fence_4yf9yt0x8i27l8ol": {
"object": "node",
"id": "fence_4yf9yt0x8i27l8ol",
"type": "fence",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"start": [1, 7.5],
"end": [10, 7.5],
"height": 1.8,
"thickness": 0.08,
"baseHeight": 0.22,
"postSpacing": 2,
"postSize": 0.1,
"topRailHeight": 0.04,
"groundClearance": 0,
"edgeInset": 0.015,
"baseStyle": "grounded",
"color": "#ffffff",
"style": "privacy"
},
"fence_b8d9n2j3987egkq4": {
"object": "node",
"id": "fence_b8d9n2j3987egkq4",
"type": "fence",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"start": [10, 7.5],
"end": [10, -7.5],
"height": 1.8,
"thickness": 0.08,
"baseHeight": 0.22,
"postSpacing": 2,
"postSize": 0.1,
"topRailHeight": 0.04,
"groundClearance": 0,
"edgeInset": 0.015,
"baseStyle": "grounded",
"color": "#ffffff",
"style": "privacy"
},
"fence_7v9k8hfa4gejy8mb": {
"object": "node",
"id": "fence_7v9k8hfa4gejy8mb",
"type": "fence",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"start": [10, -7.5],
"end": [-10, -7.5],
"height": 1.8,
"thickness": 0.08,
"baseHeight": 0.22,
"postSpacing": 2,
"postSize": 0.1,
"topRailHeight": 0.04,
"groundClearance": 0,
"edgeInset": 0.015,
"baseStyle": "grounded",
"color": "#ffffff",
"style": "privacy"
},
"fence_6mosl7txfxj0wxyq": {
"object": "node",
"id": "fence_6mosl7txfxj0wxyq",
"type": "fence",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {},
"start": [-10, -7.5],
"end": [-10, 7.5],
"height": 1.8,
"thickness": 0.08,
"baseHeight": 0.22,
"postSpacing": 2,
"postSize": 0.1,
"topRailHeight": 0.04,
"groundClearance": 0,
"edgeInset": 0.015,
"baseStyle": "grounded",
"color": "#ffffff",
"style": "privacy"
},
"zone_6l4ls8mr4rtfvsye": {
"object": "node",
"id": "zone_6l4ls8mr4rtfvsye",
"type": "zone",
"name": "garden",
"parentId": "level_3jbpcuma0wfwclex",
"visible": true,
"metadata": {
"kind": "garden"
},
"polygon": [[-10, -7.5], [10, -7.5], [10, 7.5], [-10, 7.5]],
"color": "#3b82f6"
}
},
"rootNodeIds": ["site_nxji43wtm3aiv7th"],
"collections": {}
}