
# Format data Scene {/* #scene-data-format */}

Untuk alur pendaftaran, login, dan ekstensi Chrome, lihat [perekaman manual dan peninjauan](/docs/id/manual-recording). Perekam memakai kontrak Scene yang sama dan menerbitkan gambar hanya setelah peninjauan Admin.

`reconstruct.scene.v1` menjelaskan antarmuka teramati secara independen dari framework UI sumber maupun tujuan. DOM/CSS Web dan tampilan/aksesibilitas Android adalah masukan adaptor. Konsumen dapat menghasilkan HTML, Compose, atau UI lain tanpa menjadikan struktur native tersebut model data kanonis.

[JSON Schema](https://reconstruct.dev/docs/schemas/scene-v1.schema.json) yang dapat diunduh menentukan nama kolom persis, anggota wajib, tipe nullable, dan enum. [SHA-256](https://reconstruct.dev/docs/schemas/scene-v1.schema.json.sha256) menyertai snapshot dokumentasi ini. Untuk tangkapan nyata, gunakan skema dan checksum yang dikembalikan server berjalan bersama ekspor tersebut.

[Contoh lengkap](https://reconstruct.dev/docs/examples/scene-export-v1.example.json) berisi bingkai dialog tertutup/terbuka dan dua transisi. Ini data ilustratif: bukti `example:` bersifat fiktif, bukan tangkapan produk terukur.

## Lingkungan Web Extension {/* #web-extension-environment */}

Tangkapan ekstensi Chrome desktop memakai lingkungan `web-extension` (`WebExtension` pada C# internal / Admin MCP, nilai protobuf `CAPTURE_TYPE_ENVIRONMENT_WEB_EXTENSION = 6`). Mobile tidak mendukung lingkungan ini. Kontrak geometri Scene tetap sama. Versi tangkapan dapat menyertakan metadata bertipe `browserExtension`: `id`, `name`, `version`, dan `packageSha256`; `displayName` berasal dari paket terverifikasi. Layar direkam oleh tugas Admin dan tetap tidak dipublikasikan sampai ditinjau. Lihat [perekaman manual](/docs/id/manual-recording) untuk kontrol operator dan batas privasi.

Permintaan klaim agen internal mencakup `expected_environment` (kolom 2). Kolom yang dihilangkan tetap memakai Web untuk worker lama. Antrean memeriksanya terhadap lingkungan agen dalam transaksi klaim, sehingga perubahan pengaturan Admin agen tidak membuat worker Web biasa merayapi halaman toko ekstensi. Kontrol antrean ini bukan alat Capture MCP publik.

## Transport dan perolehan {/* #transport-and-acquisition */}

Ekspor ternormalisasi saat ini tersedia melalui MCP [`get_interface_scene`](/docs/id/mcp-tools#platform-neutral-interface-scene). Kontrak katalog [REST](/docs/id/api/rest) dan [gRPC](/docs/id/api/grpc) terbitan saat ini tidak mendefinisikan operasi Scene terpisah. Respons katalog, insight, dan berkas tersimpannya adalah model berbeda, meskipun transportnya JSON.

Temukan tangkapan dengan `list_products`, `list_platforms`, `list_versions`, dan `list_pages`. Pertahankan produk, versi, lingkungan, halaman, dan `view` tersimpan persis yang dipilih. Opsi platform didukung tidak membuktikan adanya tangkapan. Minta tampilan tersimpan terpisah dan periksa profil serta bingkai setiap ekspor.

Contoh parameter MCP `tools/call`, dengan pilihan ilustratif:

```json
{
  "name": "get_interface_scene",
  "arguments": {
    "product": "example-product",
    "version": "1",
    "environment": "web",
    "page": "settings",
    "view": "mobile"
  }
}
```

Respons berupa **manifes** ringkas:

| Kolom | Makna |
| --- | --- |
| `schema` | Pengenal scene: `reconstruct.scene.v1`. |
| `artifactSchema` | Pengenal envelope: `reconstruct.scene-export.v1`. |
| `path`, `uri`, `sha256`, `bytes` | Lokasi ekspor, SHA-256, dan panjang byte. |
| `schemaPath`, `schemaUri`, `schemaSha256` | JSON Schema yang berlaku serta digest-nya. |
| `entryFrameId`, `frames`, `transitionCount` | Bingkai awal, inventaris bingkai ringkas, dan jumlah transisi. |
| `frameCount`, `profileCount`, `assetCount` | Jumlah inventaris ekspor. |
| `truncated` | Setidaknya satu bingkai tidak lengkap. |
| `issueCount`, `issues`, `issuesTruncated` | Jumlah total masalah dan pratinjau maksimal 30 masalah. |

Jalur milik **sistem berkas server**. Baca langsung hanya jika sistem berkas itu benar-benar dibagikan dengan klien. Jika tidak, resolusikan URI yang dikembalikan berdasarkan origin MCP dan unduh memakai otorisasi koneksi yang ada. Jangan menyusun URL transfer dari ID produk atau mengekspos kredensial. Verifikasi hash terhadap byte asli; memformat ulang JSON mengubah hash-nya.

## Envelope ekspor {/* #export-envelope */}

```json
{
  "schema": "reconstruct.scene-export.v1",
  "scene": {
    "schema": "reconstruct.scene.v1",
    "id": "example/1/web/settings/mobile",
    "platform": "web",
    "entryFrameId": "frame-0",
    "profiles": [],
    "frames": [],
    "resources": [],
    "transitions": [],
    "correspondences": [],
    "issues": []
  },
  "assets": {}
}
```

Ini menggambarkan bentuknya; contoh lengkap berisi bingkai yang terisi. Validasi **`scene`**, bukan envelope, terhadap JSON Schema Scene. `assets` memetakan ID sumber daya Scene ke byte arsip. Tiap entri berisi `path`/`uri` opsional, `mimeType`, `sha256`, dan `sizeBytes`. Sumber daya dapat tidak memiliki entri aset jika byte-nya tidak diarsipkan. URI sumber, nama keluarga font, atau kontainer media kosong tidak membuktikan adanya byte yang dapat dipakai.

## Dokumen dan identitas {/* #document-and-identity */}

| Anggota Scene | Makna |
| --- | --- |
| `schema`, `id`, `platform` | Format wajib, identitas dokumen, dan platform sumber (`unknown`, `web`, `android`). |
| `entryFrameId` | Bingkai pertama yang diamati, opsional, yang mungkin menampilkan persetujuan sebelum konten berikutnya yang telah ditutup/default. |
| `profiles` | Viewport logis serta kepadatan, skala font, inset aman, locale, dan tema opsional. |
| `frames` | Status yang diamati dan inventaris simpulnya. |
| `resources` | Deskriptor media/font yang dirujuk simpul dan teks. |
| `transitions` | Tindakan yang direkam dan hasil teramatinya. |
| `correspondences` | Hubungan simpul eksplisit antarbingkai. |
| `issues` | Bukti hilang, tidak didukung, atau belum terselesaikan. |

ID profil, bingkai, sumber daya, dan transisi dibatasi pada dokumen. ID simpul unik **dalam satu bingkai**, dan `parentId` merujuk bingkai itu. ID tindakan lokal pada simpul. ID berulang atau jalur native sama di bingkai lain tidak membuktikan identitas. Korespondensi merekam kedua pasangan bingkai/simpul, asal-usul, dan keyakinan opsional; ikuti itu alih-alih menebak identitas antarprofil.

Bingkai memiliki `id`, `profileId`, `stateId`, `coordinateSpace`, `extent` dan `viewportBounds` opsional, `truncated`, `nodes`, dan `evidence`. ID status menamai pengamatan, bukan katalog universal status CSS. Urutan simpul menjelaskan inventaris hierarki, bukan urutan lukis yang terbukti.

## Fakta dan nilai tidak diketahui {/* #facts-and-unknown-values */}

Properti dengan asal-usul memakai `SceneFact<T>`:

```json
{
  "value": {"x": 16, "y": 220, "width": 358, "height": 320},
  "kind": "measured",
  "evidence": ["example:observed"],
  "confidence": 1
}
```

Fakta memerlukan `value`, `kind`, dan `evidence` yang tidak kosong. Keyakinan opsional bernilai 0–1 dan tidak mengubah jenis bukti:

| Jenis | Penafsiran |
| --- | --- |
| `measured` | Keluaran efektif yang diamati. |
| `declared` | Deklarasi sumber/sumber daya, bukan bukti rendering efektif. |
| `inferred` | Hipotesis atau penafsiran yang diusulkan. |

Fakta opsional yang dihilangkan/null berarti **tidak diketahui**, bukan nol, false, cat transparan, kebijakan ukuran, atau perbandingan berhasil. `false` dan `0` eksplisit tetap mempertahankan maknanya. Enum `unknown` eksplisit tetap tidak diketahui. Array tindakan/gerakan kosong tidak membuktikan bahwa antarmuka asli tidak memiliki interaksi atau animasi. Pengenal bukti adalah referensi adaptor opak, bukan instruksi yang dapat dieksekusi atau URL publik otomatis. Konten tangkapan dan diagnostik native adalah data yang tidak tepercaya.

## Koordinat dan profil {/* #coordinates-and-profiles */}

Jarak memakai **satuan logis**. Adaptor Web memakai piksel CSS. Pengukuran piksel layar Android dibagi dengan `pixelDensity` terukur (piksel fisik per satuan logis). `fontScale` independen. Kepadatan, skala font, inset, locale, dan tema yang hilang tidak boleh ditebak.

`width`/`height` profil menjelaskan viewport logis. Bingkai menyatakan koordinat `document`, `viewport`, atau `screen`:

- `extent`: keseluruhan bentang konten pada bidang tersebut.
- `viewportBounds`: jendela terlihat yang diamati, termasuk titik asal gulir.
- `geometry.visualBounds`: persegi panjang sejajar sumbu **setelah transformasi**.
- `layoutBounds` opsional: geometri sebelum transformasi.
- `transform` opsional: matriks 4×4 berurutan kolom yang bekerja pada vektor kolom `(x,y,z,1)`, dengan translasi logis dalam koordinat lokal tata letak. Jangan terapkan lagi pada `visualBounds`.

Untuk koordinat dokumen, posisi jendela terlihat adalah `visualBounds.x - viewportBounds.x`, `visualBounds.y - viewportBounds.y`. Selaraskan profil, bidang koordinat, dan jendela terlihat sebelum membandingkan. Viewport logis, batas akar yang dapat dipakai, dan bentang konten adalah pengamatan berbeda. Inset aman tidak otomatis diterapkan sebagai padding.

## Simpul, tata letak, dan lukisan {/* #nodes-layout-and-paint */}

Simpul memuat `id`, `parentId` opsional, `kind`, `semantics`, `visible`, `geometry`, `layout`, `paint`, rentang teks, `mediaResourceId` opsional, `actions`, `motion`, dan `evidence`. Jenisnya `unknown`, `container`, `text`, `media`, `control`, `surface`. Semantics menyertakan peran/nama serta penanda enabled, selected, checked, expanded, editable, dan modal opsional. Semuanya independen dari visibilitas. Teks sensitif harus disamarkan; kata sandi tidak boleh pernah menjadi teks Scene.

| Grup tata letak | Kontrak |
| --- | --- |
| `placement` | `unknown`, `flow`, `anchored`, `overlay`, `sticky`. |
| `arrangement` | `unknown`, `row`, `column`, `grid`, `stack`, `free`, `flow`. Stack menumpangtindihkan anak; free menjelaskan penempatan independen. |
| `horizontal`, `vertical` | Fakta kebijakan/nilai/minimum/maksimum independen; kebijakannya `unknown`, `intrinsic`, `fixed`, `fill`, `proportional`. |
| Jarak/penyelarasan | Padding, gap baris/kolom, pembungkusan, urutan terbalik, penyelarasan sumbu utama/silang. |
| Track | Alokasi baris/kolom numerik pada satu profil, bukan aturan responsif yang ditulis pembuatnya. |
| Jangkar | `referenceId` berbukti ditambah jarak atas/kanan/bawah/kiri opsional; merujuk simpul lokal bingkai, `$viewport`, atau `$frame`. |

Jarak fixed/min/max dan jangkar memakai satuan logis. Nilai proporsional adalah pecahan tanpa satuan dari sumbu tersedia yang dirujuk; `fill` tidak memiliki pengali. Persegi panjang terukur tidak membuktikan ukuran tetap, containing block, jangkar, atau breakpoint. Penempatan native absolute/fixed dapat dipetakan ke `overlay` tanpa mengarang jangkar. Margin bukan gap antarelemen kanonis.

Paint memakai dimensi numerik dan kanal RGBA ternormalisasi 0–1, garis, bayangan, opacity, blur, dan referensi media. `edges` opsional untuk garis solid adalah subset unik tidak kosong dari `top`, `right`, `bottom`, `left`; jika dihilangkan, seluruh batas dilukis. Bayangan merekam offset, blur, spread, inset, dan asal-usul. `cornerRadii` saat ini memakai empat kolom berbentuk inset; adaptor Web menghasilkan nilai sama untuk sudut seragam. Sudut Web tidak seragam/elips tetap tidak didukung, bukan diberi pemetaan sudut yang dikarang.

Penempatan media (`content`, `background`, `surface`) independen dari jenis simpul. Fit adalah `unknown`, `contain`, `cover`, `stretch`, atau `original`. Posisi `(x,y)` adalah jangkar pecahan pada ruang tersisa: 0 rata awal, 0.5 tengah, 1 rata akhir; pecahan di luar rentang diizinkan. Fit latar tidak boleh berasal dari gambar konten yang tidak terkait.

Rentang teks memuat `text` asli, batas opsional, dan tipografi: keluarga/sumber daya font, ukuran, ketebalan, tinggi baris, jarak huruf, warna, arah, penyelarasan, pembungkusan, dekorasi, dan kapitalisasi. Kapitalisasi (`none`, `uppercase`, `lowercase`, `capitalize`) mengubah penyajian secara independen dari teks asli dan nama aksesibel. Lukisan/gradien/efek teks yang tidak didukung tetap menjadi masalah. Ekspresi CSS native sembarang bukan nilai tata letak atau lukisan kanonis.

## Sumber daya dan font {/* #resources-and-fonts */}

Sumber daya memiliki `id`, `kind`, `uri` opsional, `mimeType`, `sha256`, `bytes`, dan face font. Jenisnya `unknown`, `image`, `vector`, `font`, `video`, `audio`, `paint`. Referensi sumber daya simpul dan tipografi diselesaikan dalam dokumen ini. Face font merekam keluarga, jenis/referensi bukti, rentang ketebalan opsional, status miring, dan cakupan codepoint Unicode. Pertahankan byte arsip dan pilih face yang sesuai. Nama keluarga atau URL saja tidak membuktikan font yang dimaksud termuat atau fallback setara.

## Tindakan dan status modal {/* #actions-and-modal-states */}

Tindakan menyatakan kemampuan interaksi: `unknown`, `activate`, `edit`, `scroll`, `navigate`, `focus`, `hover`, `back`, dengan tujuan opsional. Transisi memiliki bingkai sumber, simpul sumber opsional dan bingkai tujuan, tindakan, hasil, serta asal-usul. `nodeId`-nya selalu milik **bingkai sumber**.

| Hasil | Makna |
| --- | --- |
| `unknown` | Hasil belum dibuktikan. |
| `changed` | Perubahan hasil diamati. |
| `unchanged` | Tidak ada perubahan diamati. |
| `failed` | Tindakan gagal. |
| `performedUnverified` | Input terkirim tanpa membuktikan hasil yang diharapkan. |

ID snapshot baru atau caret berubah tidak membuktikan menu terbuka. Modal terbuka harus mempertahankan bingkai lengkap yang diamati: latar, panel, anak, dan konten di bawahnya. Ikuti `entryFrameId` dan transisi untuk membedakan persetujuan, konten yang ditutup, tab dialog, pencarian, dan menu terbuka. Pengukuran status paksa dan input pointer/sentuh nyata tetap memiliki bukti berbeda. Pemutaran ulang sumber bukan uji fungsional antarmuka baru yang dihasilkan.

## Gerakan {/* #motion */}

Catatan gerakan simpul/transisi memuat `property`, `durationMs`, `keyframes`, `kind`, `evidence`, serta `delayMs`, `iterations`, dan `easing` Bézier kubik (`x1`, `y1`, `x2`, `y2`) opsional. Waktu dalam milidetik; offset 0–1 dalam urutan meningkat. Koordinat x easing adalah 0–1.

| Properti | Komponen `value` keyframe |
| --- | --- |
| `opacity` | `[alpha]`, 0–1. |
| `translation` | `[x, y, z]`, satuan logis. |
| `scale` | `[x, y, z]`, pengali. |
| `rotation` | `[x, y, z]`, radian. |
| `bounds` | `[x, y, width, height]`, satuan logis. |
| `color` | `[red, green, blue, alpha]`, 0–1. |

Opsi yang dihilangkan tetap tidak diketahui. Iterasi nol berarti tidak diputar. Pengulangan tidak diketahui atau tanpa batas tidak boleh diubah menjadi jumlah terbatas tebakan. Deklarasi CSS/WAAPI bersifat `declared`; sampel teramati dapat `measured`. Gambar diam atau dua titik akhir tidak membuktikan waktu maupun easing.

## Validasi dan cakupan {/* #validation-and-coverage */}

Validasi struktur dengan skema ekspor, lalu validasi semantik: ID unik sesuai cakupan, referensi valid, induk tanpa siklus, geometri berhingga, ukuran nonnegatif, warna ternormalisasi, rentang font/codepoint, penyamaran, dan dimensi gerakan. `SceneValidator` backend menegakkan invariant tambahan ini. JSON Schema sendiri bukan validator graf atau privasi lengkap.

Skema struktural saat ini menolak kolom tidak dikenal dan nilai enum integer. Tetapkan pengenal serta hash-nya; gunakan adaptor eksplisit untuk versi format berbeda. Jangan tafsirkan ulang data tidak dikenal sebagai tata letak native. Kolom yang ada mempertahankan makna; perubahan makna tidak kompatibel memerlukan pengenal format baru. Pembaruan server dapat mengubah byte skema yang berlaku: simpan skema/hash bersama tiap ekspor arsip.

`SceneIssue` memiliki `code`, `message`, dan `frameId`/`nodeId` opsional. Baca artefak lengkap, bukan hanya pratinjau manifes, dan perhatikan pemotongan bingkai. Batas validator saat ini adalah 100 profil, 500 bingkai, 20.000 sumber daya, 100.000 simpul total, dan 20.000 simpul per bingkai. Perolehan/transport dapat memiliki batas lebih rendah; angka ini tidak menjanjikan cakupan tangkapan.

Tangkapan Web baru menghasilkan Scene bersama diagnostik native. Data Web lama dapat dikonversi dengan celah eksplisit. Adaptor Android dapat menormalkan pengukuran native, tetapi akses API/MCP tetap memerlukan Scene native terbitan. Dukungan model data tidak membuat lingkungan yang belum ditangkap tersedia. Status, sumber daya, gerakan, dan pengamatan responsif yang hilang tetap tidak diketahui. Keberhasilan ekspor atau validitas skema tidak membuktikan kesetiaan reproduksi.


## Kebijakan pengajuan permintaan {/* #request-submission-policy */}

Ketersediaan permintaan independen dari ketersediaan tangkapan katalog. Administrator mengaturnya melalui Requests → Job defaults → Request submissions. `ProductRequestJobDefaults.Submission` tersimpan berisi `Enabled` dan `Targets` bertipe (`Type`, `Environment`). Pengaturan lama tanpa anggota ini mempertahankan default: Desktop/Web, Desktop/WebExtension, dan Mobile/Web. Menonaktifkan pengajuan mempertahankan pilihan dan permintaan yang ada. API platform dan MCP terautentikasi sama-sama memvalidasi kebijakan terkini sebelum membuat permintaan. Request-options mengembalikan daftar `platforms` kosong saat ditutup; MCP juga mengembalikan `enabled: false`. ID lingkungan publik tetap `web` dan `web-extension`, bukan nama enum. Pemilih katalog memakai ketersediaan tangkapan per produk dan menyembunyikan pasangan yang tidak tersedia.


### Target permintaan berkelompok {/* #grouped-request-targets */}

Klien baru mengirim `CreateRequestRequest.targets` sebagai pasangan platform/lingkungan eksplisit. Contohnya:

```json
{
  "requestType": "PRODUCT_REQUEST_TYPE_ADD",
  "url": "https://metamask.io/",
  "webExtensionUrl": "https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn",
  "targets": [
    { "view": "desktop", "implementation": "web-extension" },
    { "view": "mobile", "implementation": "web" }
  ]
}
```

Server memvalidasi tiap pasangan terhadap ketersediaan permintaan terkini dan menyimpannya dalam detail permintaan bertipe. Persetujuan hanya membuat pasangan yang dipilih: contoh ini tidak membuat tugas Desktop/Web. `views` dan `implementations` tetap diterima untuk klien lama dan mewakili produk Kartesius keduanya; jangan gabungkan dengan `targets`. Sumber situs adalah `url`; tugas ekstensi memakai `webExtensionUrl`. Untuk pembaruan, kirim `catalogId` yang ada dan target tanpa tautan sumber. Pilih produk dahulu: platform hanya menawarkan pasangan platform/lingkungannya yang telah ditangkap dan kini diaktifkan untuk permintaan. Server secara mandiri menolak target yang tidak ada pada produk itu, menentukan sumber tiap lingkungan dari tangkapan terbitan produk tersebut, dan mengabaikan tautan pengganti dari klien. Ringkasan permintaan publik menghilangkan sumber ekstensi bersama detail permintaan privat.

## Bukti Scene tambahan {/* #additional-scene-evidence */}

Skema terkini menyertakan `themes` dengan token bertipe dan `layoutSamples` dengan pengukuran jarang pada lebar lain. Sampel merujuk node `frameId`; bukan frame dan tidak mengukur ulang teks atau tampilan. Node yang tidak disampel tidak berarti tersembunyi. `nodes[].states` memuat perubahan tampilan: bidang `patch` yang ada mengganti nilai, yang tidak ada tetap, dan daftar diganti seluruhnya. Layout mendukung `flow`, `grow`, `shrink`, `basis`, `selfAlignment`, `order`, `gridCell`; paint mencakup gradien dan gaya/posisi goresan. Bukti opsional ini bisa tidak ada pada tangkapan lama. Pertahankan asal dan jangan simpulkan aturan responsif dari satu pengukuran.
